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
Add module for AppLocker bypass #6588
Conversation
This commit includes a new module that allows for payloads to be uploaded and executed from disk while bypassing AppLocker in the process. This module is useful for when you're attempting to generate new shells on the target once you've already got a session. It is also a handy way of switching between 32 and 64 bit sessions (in the case of the InstallUtil technique). The code is taken from Casey Smith's AppLocker bypass research (added in the references), and includes just one technique at this point. This technique uses the InstallUtil feature that comes with .NET. Other techiques can be added at any time. The code creates a C# file and uploads it to the target. The csc.exe compiler is used to create a .NET assembly that contains an uninstaller that gets invoked by InstallUtil behind the scenes. This function is what contains the payload. This was tested on Windows 7 x64. It supports running of both 32 and 64 bit payloads out of the box, and checks to make sure that .NET is installed on the target as well as having a payload that is valid for the machine (ie. don't run x64 on x86 OSes). This appears to work fine with both staged and stageless payloads.
# Run Method for when run command is issued | ||
def exploit | ||
if datastore['TECHNIQUE'] == 'INSTALLUTIL' | ||
if payload.arch.first == 'x64' and !(sysinfo['Architecture'] =~ /64/) |
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.
Prefer &&
and !~
.
This looks great! No references missed. Let me know if you need any additional details. Great Work! |
Cheers mate! |
@OJ Excellent work as always. Just a little suggestion (hope I am not on crack). def exploit
if payload.arch.first == 'x64' && sysinfo['Architecture'] !~ /64/
fail_with(Failure::NoTarget, 'The target platform is x86. 64-bit payloads are not supported.')
end
# sysinfo is only on meterpreter sessions
print_status("Running module against #{sysinfo['Computer']}") if not sysinfo.nil?
if datastore['TECHNIQUE'] == 'INSTALLUTIL'
execute_installutil
end
end |
Hi @void-in, is the suggestion to add the comment? The session type is currently listed as Meterpreter only, hence why I didn't think it was worth adding such a comment. Am I missing something else? Thanks! |
@OJ Sorry I wasn't clear. You tested for |
@void-in I guess I am paving the way for future techniques, where the |
This is what #5393 is actually for - you dont need to call binaries or touch disk, this can be done neatly in memory via PSH, and you can deal with the architecture differences via the elevator/wrapper approach. |
I'd argue this serves a different purpose. There are cases where I'd opt
for this over injection. Will comment more when I'm back at my desk!
|
And looks like it works:
|
@wchen-r7 you need to use it from |
@firefart ah you're right. Found it. |
@OJ @wchen-r7 I think the |
@firefart I'll work on that. |
@wchen-r7 maybe this blog post helps: https://msdn.microsoft.com/en-us/library/hh925568.aspx But it contains no info about how to detect the latest clr available on the system :( |
Here is also a mapping of .NET version <--> CLR. Maybe we should hardcode it? |
@firefart In that case maybe that part of the code should be in a mixin, and not on the module's level? |
@wchen-r7 definitely a mixin. Just did a quick grep for the path and it seems like no other module is using hardcoded paths yet so only this module needs a change. |
@firefart OK cool. Writing that in a mixin might take a while. It seems #5393 is also related, so I imagine there's probably a bit more discussion on where this code should be, and how to do it. And then we write it, doc it, rspec it, wait for someone to review it, tweak some more, etc. I'm not sure if I can complete all that before the weekly release is closed... probably not. Is it okay with you I go ahead and just land this PR first (since it already works for me), file an issue on Github about turning #get_dotnet_path into a mixin, and then work on it? If you feel the mixin should be in this pull request, I can do that as well. Let me know. Thanks. |
@wchen-r7 I think it's sufficient to do this in a seperate PR. We could just add some rudimentary checking into this version like this:
This should select the greatest version with |
Damn forgot about that. .NET 3.x didn't include a runtime update, it just
added new libraries and API features. Good catch!
I'll get this fixed pronto.
|
I think this approach of fine for now. Registry enumeration is another way
but seems overkill and probably isn't any faster.
|
@firefart Thanks for the patch, but there is a slight problem. My .Net 3.5 directory happens to have csc.exe, but not InstallUtil.exe, so that patch wouldn't work for me. I think instead of looking for csc.exe, I'll just let it look for InstallUtil.exe. Other than that, code looks good, thanks again everyone. |
Thanks guys!
|
👍 |
This is great to see! Excellent work. |
n.b. this could have been implemented as a format for msfvenom? |
@OJ another method which could be implmented: http://www.theregister.co.uk/2016/04/22/applocker_bypass/ |
Yeah saw that. It's on the list :) |
This commit includes a new module that allows for payloads to be uploaded and executed from disk while bypassing AppLocker in the process. This module is useful for when you're attempting to generate new shells on the target once you've already got a session via other means. It is also a handy way of switching between 32 and 64 bit sessions (in the case of the InstallUtil technique).
The code is taken from Casey Smith's (@subTee) AppLocker bypass research (added in the references), and includes just one technique at this point. This technique uses the InstallUtil feature that comes with .NET. Other techniques can be added at any time.
The code creates a C# file and uploads it to the target. The csc.exe compiler is used to create a .NET assembly that contains an uninstaller that gets invoked by InstallUtil behind the scenes. This function is what contains the payload.
This was tested on Windows 7 x64. It supports running of both 32 and 64 bit payloads out of the box, and checks to make sure that .NET is installed on the target as well as having a payload that is valid for the machine (ie. don't run x64 on x86 OSes).
This appears to work fine with both staged and stageless payloads.
Sample Run
Verification
Notes
I have noticed that when using http/s payloads, inline handlers doesn't respond correctly (they hang). I honestly don't know what's going on here. However, if
DisablePayloadHandler
is set totrue
and an external listener is used, then things work just fine.@subTee if I have missed any better references please let me know.