-
Notifications
You must be signed in to change notification settings - Fork 14k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resurrect PSEXEC Powershell #2073
Conversation
This commit rewires the existing work on PSExec performed by R3dy, HDM, and countless others, to execute a powershell command instead of a binary written to the disk. This particular iteration uses PSH to call .NET, which pull in WINAPI functions to execute the shellcode in memory. The entire PSH script is compressed with ZLIB, given a decompressor stub, encoded in base64 and executed directly from the command-line with powershell -EncodedCommand. In practice, this prevents us from having to write binaries with shellcode to the target drive, deal with removal, or AV detection at all. Moreover, the powershell wrapper can be quickly modified to loop execution (included), or perform other obfu/delay in order to confuse and evade sandboxing and other HIDS mechanisms. This module has been tested with x86/x64 reverse TCP against win6, win7 (32 and 64), and Server 2008r2. Targets tested were using current AV with heuristic analysis and high identification rates. In particular, this system evaded Avast, KAV current, and MS' own offerings without any issue. In fact, none of the tested AVs did anything to prevent execution or warn the user. Lastly, please note that powershell must be running in the same architecture as the payload being executed, since it pulls system libraries and their functions from unmanaged memory. This means that when executing x86 payloads on x64 targets, one must set the RUN_WOW64 flag in order to forcibly execute the 32bit PSH EXE.
The original module suffered from a small problem - interactive process notification from Desktop 0 for users currently logged in. Although acheiving full AV evasion, we were setting off UserAlert. This commit updates the module itself to match rapid7#1379 in R7's repo. The size of powershell payloads has been reduced, and a wrapper added to hide the actual payload process entirely.
payload using a similar technique to the "psexec" utility provided by SysInternals. The | ||
payload is encoded in base64 and executed from the commandline using the -encodedcommand | ||
flag. Using this method, the payload is never written to disk, and given that each payload | ||
is unique, is not prone to signature based detection. Since executing shellcode in .NET |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"not prone to signature based detection"
This is a bold claim. Major pieces of the payload are the same every time, most notably the beginning, which makes signature detection only slightly more difficult than a big chunk of 0x90 bytes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The final payload is (in this PR) deflated and b64 encoded, so any variance introduced by dynamic var names and the shellcode itself alter the final chunk of script being sent over the wire pretty considerably. I could see a lot of wasted NIDS cycles decompressing and base64 decoding all the text going over SMB or WinRM.
#2075 introduces the PSH parser which handles all of this along with some basic obfuscation techniques to alter the resulting script.
This outdated payload still beats every AV on the market, and its been public in several forms for over a year :).
I think i released updated PSH payloads in 2075 as well which use gzip instead of deflate to compress the payload even more, and along the way provides another method to change whats on the wire. I tried to base32 the result, but psh doesn't seem to have a neat way to deal with b32 (which produces a MUCH smaller payload coupled with gzip).
I would propose pulling the payload and executing from within powershell. That way you dont have to mess with passing the payload as an argument. Thoughts? |
@jakxx executing what from within powershell? Do you mean just run an interactive powershell? |
Pulling the script and executing in one command. Something like this: https://github.com/jakxx/metasploit-framework/blob/master/modules/exploits/windows/powershell/powershell_psexec.rb |
Ah you mean like: #2133 ;) |
Yep! Is it worth making a pull request for the module I wrote or do you think this is sufficient? |
Currently the payload gets compressed passed in one command already. Adding a HTTPHandler adds an additional level of complexity that doesn't gain us anything here? Or am I missing something? [edit: I guess the download would be good for abnormally large payloads that cant be done in one pull but this would be rare?] This is @sempervictus's code for the most part and need to get round to integrating the rest of his lovely PSH stuff! My other pull integrates the IEX strategy, and makes it quite feasible for someone to type it in with RDP/cmd shell access etc. I guess a powershell cmdstager would also be handy at some stage that uses one or both of the above methods. |
True, however the only advantage to the module I have written is that is extensible beyond metasploit by allowing you to specify an alternate payload (such as powersploit, custom script, etc) |
Resurrect #1343 @sempervictus
Dragged in depdendency from #1379
Refactored to use PSEXEC mixin
Small tidyup of module and user warnings etc.
PERSIST and RUN_WOW64 work for me.
PSH_OLD_METHOD doesn't seem to work but this seems more likely to be an underlying issue with that payload or just that the old method isn't compatible with later powershells and I need to find a dated system?