Firmware analysis
Firmware download:TL-WDR5620千兆版 V2.0升级软件20200302_2.6.60-Tp-link无线路由器及网络设备-恩山无线论坛 (right.com.cn)
Advanced decompression and firmware extraction using binwalk
1 | unzip TL-WDR5620千兆版 V2.0升级软件20200302_2.6.60.zip |
It was found that this firmware is based on the VxWorks system (a real-time operating system, RTOS). After decompression and analysis through binwalk, a complete file system similar to that of most other routers cannot be obtained.
As can be seen from the binwalk analysis results, the u-Boot program is located at the beginning of the file, followed by LZMA compressed data. To extract the u-Boot program, you need to determine its size or use a specific byte offset, which is 46560. According to this length, use the dd command to extract the uBoot program.
1 | dd if=TL-WDR5620千兆版_V2.0_2.6.60_Build_200302_Rel.57804n.bin of=uboot.raw bs=1 skip=46560 count=1093216 |
You can confirm it with binwalk analysis.
After extracting the uBoot program, we noticed that the size of the first piece of LZMA data immediately following the u-Boot program is the largest piece of all LZMA data. Generally speaking, this is the location of the main program. We use the same method to extract the main program. . Main program length = 1139776 - 62464 = 1,077,312
1 | dd if=TL-WDR5620千兆版_V2.0_2.6.60_Build_200302_Rel.57804n.bin of=main.lzma bs=1 skip=62464 count=1077312 |
After getting the lzma compressed package file of the main program, decompress it through lzma (the main file is actually the F400 file extracted by the binwalk -Me
command. We can also use it directly without extracting it)
1 | lzma -d main.lzma |
After decompression, you get the main file. Use binwalk to perform decompression analysis. You can see that it is a VxWorks operating system, little endian.
1 | binwalk main |
From the output of binwalk -A main
, you can see that there are a large number of MIPSEL instruction sequences in the firmware file main
. These are usually machine codes in Little Endian format under the MIPS architecture. MIPSEL is a variant of the MIPS architecture designed for little-endian mode.
When using disassembly tools such as ida or ghidra for analysis, you need to know the loading address of the VxWorks system, otherwise the system cannot be analyzed correctly. The loading address of the VxWorks system is the same as the stack initialization address. According to the official instructions given by VxWorks, it uses usrInit for stack initialization, and usrInit is the first function that runs after the VxWorks system boots, so the VxWorks system files can be directly thrown to ida , first use 0 as the loading address, and then find the location where the sp register first appears, which is the loading base address of the VxWorks system.
For this firmware, I used the following method: search for the string “MyFirmware” in the firmware, and then search upwards for the beginning of a segment. This is easy to identify. Generally, the beginning of a segment is filled with 0xFF or 0x00 before the previous segment. After finding the starting position of the segment, count 0x18 bytes back. These two four-byte values are the loading address of the VxWorks system. (Note: It is not universal. For detailed methods, see:VxWorks固件加载地址分析方法研究 | Hexo (unrav31.github.io))
But after setting the loading address to 0x80001000, IDA still did not load any functions.
However, by pressing the “C” key at some addresses, functions can be automatically analyzed, but there are still very few functions identified.
Use the firmware_fix plug-in to identify more functions, and fill in the load base address 0x80001000 (usually filled in, You just need to tick)
The effect is as follows
But both Imports
and Exports
are empty. It may be because the symbol table is not imported. However, through binwalk analysis and search for the flag string, it is found that neither the internal nor the external symbol table can be found. It can be judged that this is an unsigned table. firmware
I tried using some plug-ins to restore the function name
lscan for identification
Not used successfully
Use Finger for identification
1 | pip install finger_sdk |
Put finger_plugin.py into plugins
It took me a long time to identify this, but no one was identified.
lumina for identification
Recognition failed
Use Rizzo for identification
I tried several firmwares, but none of them matched.
There is no other way but to manually review the code and analyze it.
I searched for information on the Internet and found this article: VxWorks固件系统研究 | CTF导航 (ctfiot.com)It seems that the research is also TL-WDR5620, according to this article You can know the following four functions:
printf:
vprintf:
strcapy:
strncapy:
Then I restored the function name of this main file with reference to the function names of the firmware “TL-WDR7660 2.0.30” and “TL-WDR5620 V3.0_171128 Standard Edition”. First, I based on the error information returned by sending the error packet: “ error_code “
Search for the string “error_code” in the main program files of these three firmwares, compare them one by one, and guess to repair the function name of the main file pair of TL-WDR5620v2.0
After the functions related to “error_code” are fixed, it can be found that there is a vulnerability in the httpProcDataSrv
function.
The function starts by parsing a JSON object from some data source (perhaps the request body). If parsing fails or the method
field is not "do"
, the function will jump to label LABEL_70, perform some cleanup operations and exit.
If method
is "do"
, the function next attempts to match the session. If no valid session is found, it will jump to LABEL_18, set the HTTP status code to 401 (unauthorized), and exit.
If a valid session exists, the function checks the JSON object for the presence of the “login” field and attempts to obtain the password. If the password verification fails or does not meet the requirements, it will jump to LABEL_26, set the HTTP status code to 401, and exit.
The code checks the number of unauthorized attempts and locks the client if the limit is exceeded.
If the JSON object contains the field "cfgsync"
and the value of the "get_config_info"
field is null
, the function will call the sub_8030BAFC
function, which may bypass the user authorization check.
The problem is that if the JSON data we send contains "method":"do"
and "cfgsync":{"get_config_info":null}
, they may be able to bypass the httpDoAuthorize
function (which is supposed to be responsible for user authorization ) call.
Exploit
Product: TL-WDR5620 Gigabit version v2.3
The initial login interface requires a password.
Run the poc
You can see that the wifi name has been reset
The password has also been reset
1 | import sys |
Reference documentation
揭秘VxWorks路由器破解之路_哔哩哔哩_bilibili
VxWorks固件加载地址分析方法研究 | Hexo (unrav31.github.io)
TL-WDR7660 httpProcDataSrv任意代码执行漏洞复现分析_tl-fw防火墙漏洞复现-CSDN博客
二进制静态分析—库函数识别_ida lumina-CSDN博客