Vulnerability Information
Viewing the base information of this CVE from CVE-2019-10999, we know that this is a stack overflow vulnerability, where an attacker can execute an arbitrary command attack by sending an extra-long WEPEncryption parameter to wireless.htm while logged in, resulting in a stack overflow. We will now use the Shambles Desktop tool to locate this vulnerability and perform a stack overflow attack. Check the Dlink website for devices and versions that are vulnerable. We select v2.17.01 of the DCS-932L. Download the corresponding firmware.
Reproducibility
First, open the firmware with Shambles Desktop, use Shambles Desktop's online unpacking function to unpack the firmware and extract the file system, so that the contents of the firmware package will be displayed in the form of a visual file directory tree (shown on the left side of Figure 1), which is convenient for analysis. At the same time, Shambles Cloud will analyze the unpacked information to determine the device, manufacturer, chip architecture, device type and other information. As shown in the Hardware Information of Firmware Info on the right side of Figure 1, the device is an embedded camera device with MIPS chip architecture from D-Link.
1. Static analysis
Figure 1
First of all, we analyzed the static code of the firmware through Shambles Desktop to determine the code location of the vulnerability.
CVE vulnerability information mentioned that the vulnerability exists in the device's web server executable file alphapd, the attackers in the request wireless.htm file, in the request parameter WEPEncryption constructed in the long parameter can lead to a stack overflow to execute arbitrary commands.
So first search for "alphapd" keyword in file manager, so as to find the corresponding file for static decompile operation, and then search for "WEPEncryption" keyword in the current decompile window, the result returns Then search "WEPEncryption" keyword in the current decompile window, the result returns more than ten matches (as shown in Figure 2), and then analyze it together with the detection result of "ELF Vunerability Info" on the right side of the code risk detection window (as shown in Figure 2).
Both messages mention the address near sub_43b7c0 several times, and the code risk detection directly points out the stack overflow risk associated with the address <sub_43b7c0+1b4>strcpy. So <sub_43b7c0+1b4> is more likely, double click <sub_43b7c0+1b4> to jump to strcpy(&var30, v2) to view ASM code.
Figure 2
ASM code can only see the place is a strcpy call, press F5 shortcut key to switch to the "pseudo view" to view the disassembly code. As shown in Figure 3, line 25 copies the content of v2 to the address of the stack variable &var30. The logic of the decompiled code in line 11 to 19 is: "When the WEPEncryption parameter does not exist in the p0 memory address, no valid operation is performed and it is returned directly, while when the WEPEncryption parameter exists in the p0 memory address, websGetVar returns the contents of the WEBEncryption parameter". Combined with the CVE information and the meaning of the function name websGetVar, it is hypothesized that sub_43b7c0 may be the function that handles the network request parameter WEPEncryption. Verifying this speculation requires proving that sub_43b7c0 is executed when a web request with the WEPEncryption parameter is sent against wireless.htm, which requires dynamic simulation to run the firmware.
Figure 3
2. Dynamic debugging
According to the conclusion of the static analysis above, we know the cause of the vulnerability and the possible location of the command, and then enter the second stage of the dynamic verification process: using Shambles Desktop's firmware emulation "Virtual Machine" (Hereinafter referred to as "VM" )function to debug the firmware dynamically. To enter the simulation function, first we need to switch the file management module of Shambles Desktop to "Cloud Mode", and then click New in the right toolbar of the VM management tool, select the file system where alphapd is located, and create a simulator (as shown in Figure 4). Then select the file system where alphapd is located in the file manager and right click to open a terminal (hereinafter referred to as the file system terminal). As shown in Figure 5 below, the firmware's file system is mounted.
Figure 4
Figure 5
/bin/alphapd
alphapd: Startup!
alphapd: cannot openpidfile#
Typing :"/bin/alphapd" in a newly opened filesystem terminal, starts** alphapd**, an error is returned, there was an error starting alphapd.
Searching for the corresponding error message "cannot open pid file" in alphapd, there are only two references, one in .rodata (the area where strings are stored in executables) and the other in the code snippet. Prioritize the code snippet, analyze the function (as shown in Figure 6), the if statement at line 62 indicates that when a file does not exist, it will throw an error "cannot open pid file". Click the Tab key at line 62 to switch to ASM View, and infer from the ASM decompilation aid (shown in Figure 7) that the file should be /var/run/alphapd.pid.
Figure 6
Figure 7
Manually create "alphapd.pid" with the command shown in Figure 8. Run alphapd again, the old error has been resolved and there is a new error. Again, searching for this error, the cause was found to be a non-existent /var/run/nvramd.pid file.
#mkdir/var/run
#touch/var/run/alphapd.pid
#/bin/alphapd
alphapd: Startup!
alphapd: waiting fornvram_daemonalphapd: .alphapd: .alphapd: .alphapd:
.alphapd: .alphapd: .alphapd: .alphapd: .alphapd: .alphapd: .alphapd:
.alphapd: .alphapd: .alphapd: .alphapd: please executenvram_daemonfirst!#
Figure 8
Create the file "/var/run/nvramd.pid" , run alphapd again. the old error is resolved, a new one appears.
#touch/var/run/nvramd.pid
#/bin/alphapd
alphapd: Startup!
alphapd: Can't getlanipfromsysinfo!
alphapd: failed toconvert tobinaryipdataalphapd: Shutdown!
Again searching for the corresponding error, we found that nvram_bufget could not get the "IPAddress" (as shown below). nvram_bufget's function is to read the information. the simulation environment of Shambles supports to initialize the device parameter configurations from the configuration file. So we just need to do the right configuration, first check if the configuration file exists in the firmware, and if it doesn't, then we need to query the device operation parameters from the executable file. Global search for "IPAddress" keyword, there are multiple file references, because it is looking for configuration files, so first exclude executable files, sh files and cgi files, only RT2860_default_vlan this file is left, check RT2860_default_vlan, found that there are a variety of parameter configuration "IPAddress" is also among them, so RT2860_default_vlan is the probability of device parameter configuration file can be used to test it. vlan, found that there are a variety of parameter configurations, "IPAddress" is also among them, so RT2860_default_vlan is the probability of the device parameter configuration file is relatively large, you can use it to test. Luckily for us, there is more elimination work to be done when there are many search results.
The Shambles simulation environment comes with libnvram.so pre-built in the /shambles directory, which loads the device parameter information from the configuration file. Copy RT2860_default_vlan to the directory where libnvram.so is located, rename it to nvram.ini, and run alphapd again, because this time we are going to use libnvram to simulate the device information, so we need to preload libnvram.so when we run it. Enter the command "LD_PRELOAD=/shambles/libnvram.so /bin/alphapd" , the results are as follows, although there are some other errors thrown, but alphapd does not interrupt, indicating that the successful start.
#mkdir-p /shambles/libnvram
#cp /etc_ro/Wireless/RT2860AP/RT2860_default_vlan /shambles/nvram.ini
#LD_PRELOAD=/shambles/libnvram.so /bin/alphapd
nvram_get_buf:IPAddress
sem_get: Key: 41370002
sem_get: Key: 41370002
nvram_get_buf: = "2.65.87.200"
alphapd: Can't getlanipfromsysinfo!
alphapd: Version 2.1.8 running at address 2.65.87.200:80
nvram_get_buf:AccessControlEnable
sem_get: Key: 41370002
sem_get: Key: 41370002
nvram_get_buf: = "0"
nvram_get_buf: User1
sem_get: Key: 41370002
sem_get: Key: 41370002
nvram_get_buf: = ""
nvram_get_buf: User2
sem_get: Key: 41370002
sem_get: Key: 41370002
nvram_get_buf: = ""
nvram_get_buf: User3
sem_get: Key: 41370002
sem_get: Key: 41370002
nvram_get_buf: = ""
nvram_get_buf: User4
sem_get: Key: 41370002
sem_get: Key: 41370002
nvram_get_buf: = ""
nvram_get_buf: User5
sem_get: Key: 41370002
sem_get: Key: 41370002
nvram_get_buf: = ""
nvram_get_buf: User6
sem_get: Key: 41370002
sem_get: Key: 41370002
nvram_get_buf: = ""
nvram_get_buf: User7
sem_get: Key: 41370002
sem_get: Key: 41370002
nvram_get_buf: = ""
nvram_get_buf: User8
sem_get: Key: 41370002
sem_get: Key: 41370002
nvram_get_buf: = ""
The default web service port for general alphapd is 80 (as shown in Figure 9). set up port forwarding and visit http://127.0.0.1:80 to try it.
Figure 9
Figure 10
Figure 11
Visit http://127.0.0.1 with a browser, it shows the interface as shown in Figure 10 above, on this device, the default admin secret is empty. Click login and see the interface as shown in Figure 11 above, proving that the alphapd web service is running normally.
3. CVE reproduction
In the following section, we will reproduce the CVE in conjunction with our static analysis in Section 1. First, we verify that alphapd can respond to requests for wireless.htm. The method is as follows: send a request with WEPEncryption to wireless.htm, and if it returns a normal message, then alphapd can respond to the request. Enter "curl http://127.0.0.1/wireless.htm?WEPEncryption=FEWFEW" at the local command line, the return message is shown in Figure 12 , which indicates that alphapd responds to the request with WEPEncryption.
Figure 12
Then verify that a web request with WEBEncryption is sent to wireless.htm by executing strcpy at sub_43b7c0+1b4. First start alphapd in debug mode. press ctrl+c in the file system terminal where you just ran alphapd to close the process. Then click on Debug Configuration in Shambles Desktop's alphapd decompile screen and configure libnvram.so as a preloaded library. (This does the same thing as running LD_PRELOAD=/shambles/libnvram.so /bin/alphapd). Start debugging, and the event log window returns the log shown in Figure 13. The log is the same as the one displayed by running alphapd from a file system terminal, proving that the debugging started properly.
Figure 13
First in the following figure marked position breakpoints (as shown in Figure breakpoint 1), send the corresponding network request, the debugging process will indeed stay in breakpoint 1, proving that sending a network request with the WEPEncryption parameter to wireless.html will be executed to strcpy.
Breakpoint 1
Finally, we verified that when the WEPEncryption parameter is too long, it causes a stack overflow.
The verification method is as follows, send the parameter request of WEPEncryption with normal length and the parameter request of WEPEncryption with excessive length to wireless.html respectively, and compare the information in the pc register after the network request is completed. As shown in breakpoint 2 in the figure below, check whether the information in the pc register has been modified after the execution of jr. The value ra in breakpoint 2 is the jump address of the funtion sub_43b7c0 in breakpoint 1 strcpy after the execution is completed. Jr instruction will copy the value in ra to the pc register.
Finding breakpoint 2 proceeds as follows.
Place the cursor at the return of the sub_43b7c0 function (as shown in Figure 14) and press the tab key to switch to "ASM View". Find the corresponding jr instruction position. It is the breakpoint 2 shown in the figure below.
Figure 14
Breakpoint 2
Test 1.
Start alphapd debugging and enter "curl http://127.0.0.1/wireless.htm?WEPEncryption=ewfwefwefewf" on the local command line. The debugging process will stop at breakpoints 1 and 2, and after the execution is completed, the content of the pc register is the address of an instruction (as shown in Figure 15), and the network request will return normally.
Test 2.
Input "curl http://127.0.0.1/wireless.htm?WEPEncryption=ewfwefwefewffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeefwefwefwefwefwwwwwwwwwwvvvvewfwefwefwefwefwefwefwefweffweeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" on the command line of computer terminal. The debugging process will stop back and forth at breakpoint 1 and breakpoint 2. After the execution is completed, the content in the pc register is no longer the address of a particular instruction, but has been modified to a certain memory address (as shown in Figure 16), and at this point the execution will continue, and alphapd will crash, indicating that the stack has been destroyed.
Comparison of the results of the above two tests indicates that sending a network request with the WEPEncryption parameter to will execute strcpy. this function will allow the user input variable to be copied to the stack memory. This results in the user input variable being able to arbitrarily modify the stack memory. With clever parameter construction of WEPEncryption, the attacker can execute arbitrary command attacks by modifying the pc register contents to the address of other arbitrary commands.
At this point, the reproduction of CVE-2019-10999 on Shambles is complete.
Figure 15
Figure 16