PG: Shifty
| ターゲット // Shifty | |
|---|---|
| Platform | OffSec Proving Grounds |
| OS | Linux |
| Difficulty | Hard |
| IP | 192.168.244.59 |
Enumeration#
Nmap#
▶ Nmap output
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u7 (protocol 2.0)
80/tcp open http nginx 1.10.3
5000/tcp open http Werkzeug httpd 1.0.1 (Python 3.5.3)
11211/tcp open memcached Memcached 1.4.33 (uptime 388 seconds)
Four ports, but two of them talk to each other. Port 5000 is a Flask app (Werkzeug/Python), and port 11211 is memcached — sitting wide open with no auth. That pairing is the whole box.
Port 5000 - Flask App#
The app has a login form, and the stock admin:admin gets you in. Logging in and out while watching memcached shows session keys popping in and out of the cache:
session:2ddbaeff-f2ff-4256-8f7a-d516c346cd67
That exact string is also your session cookie in the browser. The app is storing server-side sessions in memcached, keyed by the cookie value — and the stored blob is a Python pickle. You can watch it in the login request:

Port 11211 - Memcached#
Memcached 1.4.33 has public exploits, but none of them are the way in here. What matters is that it’s unauthenticated and it holds pickled Flask sessions. When Flask reads your session, it fetches the value for your cookie key from memcached and calls pickle.loads() on it. Control the value, control the deserialization.
Foothold#
Pickle Deserialization via Memcached Poisoning — CVE-2021-33026#
Unauthenticated memcached + a Flask app that unpickles whatever is stored under the session key = remote code execution. Overwrite the cache entry for your own cookie with a malicious pickle whose __reduce__ returns os.system(cmd), then send a request with that cookie to trigger the pickle.loads().
Public PoC: CarlosG13/CVE-2021-33026. The core of it is trivial:
| |
Grab a live session cookie from the app, start a listener, and fire the exploit with a reverse shell as the command:
| |
Shell lands as jerry, and local.txt is right there in the home directory:

Privilege Escalation#
DES Backup Script — Reverse the Cipher, Recover Root’s Key#
Poking around from jerry’s shell, /opt/backups/ stands out. It holds a Python script (backup.py) and a data/ directory of encrypted output. Reading the script shows it DES-encrypts files into data/ — and because it’s symmetric with a hardcoded key, the same script decrypts them.
Pull the whole backups/ directory back to your box, flip the operation in the script from encrypt to decrypt, and run it against the blobs in data/:
| |
Out falls root’s SSH private key. From there it’s a one-liner:
| |
Root.
Proof#

Key Takeaways#
- An unauthenticated memcached paired with an app that stores serialized sessions there is a code-execution primitive — poison the session key with a malicious pickle and let the app deserialize it (CVE-2021-33026).
- When a session cookie shows up verbatim as a cache key, the server is trusting the cache blindly. Watch what appears in memcached as you log in and out.
- Symmetric backup/encryption scripts left on disk are a gift: if the script can encrypt, it can decrypt. Reverse the operation instead of attacking the cipher.
- DES with a hardcoded key protecting an SSH private key is not protection — it’s a speed bump.