-
Notifications
You must be signed in to change notification settings - Fork 13.7k
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
ASPX writes to file rather than straight to memory? #2130
Conversation
I tried the same thing when I wrote the original aspx encoder. I had done memory injection in c# a while ago (http://www.mattandreko.com/2012/02/23/using-net-to-bypass-av/) but could not get IIS to actually execute it, where it worked fine as a standalone .exe. I generated an aspx payload from the master branch using the following command:
When executed, I got a meterpreter:
I then checked out your branch, and did similarly:
However, I got no shell. I do get 2 errors in my event log:
and
I tested using Windows 2008 R2 x64. Do you get different results? I'd LOVE to see in-memory loading of aspx pages. I'm available on IRC under the name 'hostess' typically as well if you want to work through it. |
So on Windows 2008 R2 x64, it requires a x64/meterpreter to work, but it does work.
Looks like that works just fine, you just have to remember what architecture you're running! derp. Now you have me wondering what I was missing last year... |
I just used this on an engagement, and it's totally awesome. Worked like a charm. |
Starting with review here! |
There are two modules using Msf::Util::EXE.to_exe_aspx. Are the next ones, and there is the use they do of the changed function:
# Generate the ASPX containing the EXE containing the payload
exe = generate_payload_exe
aspx = Msf::Util::EXE.to_exe_aspx(exe)
# Generate the ASPX containing the EXE containing the payload
exe = generate_payload_exe
aspx = Msf::Util::EXE.to_exe_aspx(exe) I guess with the current modules should be modified to make something like: # Generate the ASPX containing the EXE containing the payload
aspx = Msf::Util::EXE.to_exe_aspx(payload.encoded) Am I wrong? Maybe I'm forgetting something but looks like the current modules should be modified with this pull request to avoid them stop working if it is landed. On the other hand, the existing modules affected for the modification should be re-tested to be sure they continue working after changes. Any testing has been done? Finally, this code is awesome :) executing the payload from memory is a nice feature! But I feel like Msf::Util::EXE.to_exe_aspx isn't the place to put this code. Since the aspx isn't dropping an EXE anymore I have the feeling this code should be included in another place. BTW, While reviewing, I've also the feeling which to_win32pe_psh_net and to_win32pe_psh are confusing, because they are not embedding and dropping a win32pe, but putting code directly on memory and executing it... So the function names are not well described, and maybe the Msf::Util::EXE class isn't the place neither.... just saying in case someone ask me haha :) |
@mandreko Glad you had some luck with it :) All .NET injection requires the correct architecture - that issue also applies to current powershell techniques as that uses .NET framework for injection. I didn't try this with existing modules (guess would need to check if they use filedropper or do cleanup too). Just with msfvenom. The Msf::Util::Exe library really needs refactoring in general (but is a larger job):
Instead of replacing the exe method I could add a second method for in-memory aspx generation and modify msfvenom to point to this rather than the existing method. This would reduce the testing burden and leave both techniques available for module authors. I expect the majority of people using the .aspx file generated by msf is for manual upload via ftp/file upload vulns/sqlinjection file writes rather than module use. |
@Meatballs1 , agree, full check of the modules using a changed method should be done. "Instead of replacing the exe method I could add a second method for in-memory aspx generation and modify msfvenom to point to this rather than the existing method" => Totally agree, since the current method is being used by modules, and still could be useful, maybe, in some situation, I think adding the new method as a new feature would be better. Also I would love to listen some discussion about the place where to add this new method/feature. While Msf::Util::EXE is the easy place, I'm not sure if semantically is the best option, there isn't exe involved anymore, but you're generating an ASPX piece of code to put an arbitrary sequence of bytes in memory and execute them through a new thread... Maybe a new class into rex ?? not sure if there isn't a suitable place into rex already... |
I disagree with @jvazquez-r7 here that it should be a new method. If it works in all the same places as the previous method, I see no reason to keep an inferior version around. |
As long as it works with the umbraco_upload_aspx and avaya_ccr_imageupload_exec, I'd agree. My original aspx encoder is inferior, due to the file dropping. I don't really see much of a scenario where it'd be used but an in-memory one wouldn't. It's just getting those 2 tested... |
If @jlee-r7 feels comfortable with the change then it's okey for me. I guess all which should be done is test (modify if necessary) exploits/windows/http/avaya_ccr_imageupload_exec.rb and exploits/windows/http/umbraco_upload_aspx.rb to ensure they work still after the modification. |
@jvazquez-r7 Do you have environments for Avaya and umbraco available? I haven't looked at those exploits to see how difficult they are to obtain/setup yet... I will wait for some of the incoming changes to Util::Exe anyway and update this as a template file @jlee-r7 I actually can think of a good reason to keep the EXE dropping technique - it can be Architecture agnostic. .NET memory injection requires the correct architecture which the user may not know ahead of time. |
@Meatballs1 No I haven't environments for them anymore :\ If you can't find the applications ping me, maybe I've installers saved around! (I can't promise!) |
Aww I imagined you guys had a nice datastore with a ton of VMs so you could regression test some exploits :) |
As I can see a use for aspx-exe (if you don't know arch and have a nice exe that skips AV) I've left it in for now and left the existing modules as they are. @jlee-r7 's RandomIdGen is pretty neat, if it could be treated as a hash you wouldn't even have to initialize the values except the ones that depend on each other (e.g. shellcode -> byte array name). |
# Returns the @value_by_name hash | ||
# | ||
# @return [hash] | ||
def get_hash |
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.
This should probably be to_h
to match Ruby conventions.
rig.init_var(:var_threadId) | ||
rig.init_var(:var_bytearray) | ||
|
||
rig.store(:shellcode, Rex::Text.to_csharp(code, 100, rig.init_var(:var_bytearray))) |
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.
We discussed this in IRC. I still don't like using store
this way, as it is a totally different meaning from what RIG was designed for. Why not something like this instead:
rig.init_var(:var_bytearray)
hash_sub = rig.to_h
hash_sub[:shellcode] = Rex::Text.to_csharp(code, 100, rig[:var_bytearray])
return read_replace_script_template("to_mem.aspx.template", hash_sub)
Wait, did you make additional changes in the merge commit when merging master? This looks super weird. |
@jlee-r7 Yes I merged and made changes - there were conflicts in the file anyway. I no longer use the store technique so hopefully you are happy for this to be an example method going forwards? |
IntPtr rather than UIntPtr was used to follow the practice laid down by: http://msdn.microsoft.com/en-us/library/ms973190.aspx
Never, ever, under any circumstances should you make additional changes in a merge commit. |
Even if said merge commit breaks functionality? I'll create new pr |
Is there a reason we are writing a PE to a file when we could be injecting into memory as per:
#1156