TP-Link Archer A7 AC1750是中国普联(TP-Link)公司的一款无线路由器。固件版本为190726中tdpServer服务在未经身份验证情况下,可进行命令注入,但仅可被路由器LAN端的攻击者利用。
CVE-2020-10882
A7(US)_V5_200220
本文分析基于:tdpServer守护程序/usr/bin/tdpServer,固件版本190726
在tdpServer接口上开启本地0.0.0.0的UDP端口20002监听
tdpServer格式
从上图可知,通过数据包类型判断守护程序调用服务
tdpd服务:使用特定的TETHER_KEY哈希值的数据包进行回复(与此漏洞无关),type为0
onemesh服务:type为 0xf0,(产生漏洞)
TP-Link在其许多路由器的最新固件版本中引入了其专有的技术OneMesh。
设备启动,调用tdpd_pkt_handler_loop()(地址:0x40d164)——监听端口20002接收到数据传递——tpdp_pkt_parser()(地址:0x40cfe0)
tpdp_pkt_parser()
第一部分:检查数据包、校验和的验证
第二部分:type判断即调用服务选择
第三部分:标志字段onemesh_flag为1,进入onemesh_main()(地址:0x40cd78),onemesh_main()根据操作码字段调用相应函数,举例:操作码为6——调用onemesh_slave_key_offer()(地址:0x414d14)
tdpd_pkt_parser()#1
首先检查UDP套接字标头大小是否至少为0x10;
调用tdpd_get_pkt_len()(地址:0x40d620),该函数返回在包头中声明的包长度,如果数据包长度超过0x410,则此函数返回-1;
最后再通过tdpd_pkt_sanity_checks()(地址:0x40c9d0),检查数据包版本(版本字段,数据包中的第一个字节)是否等于1,接着,使用自定义校验和函数tpdp_pkt_calc_checksum()(地址:0x4037f0)计算数据包的校验和。
由于tpdp_pkt_calc_checksum()内容较多,借助lao_bomb漏洞利用代码的calc_checksum()分析
lao_bomb漏洞利用代码的calc_checksum()
校验和的计算:
首先,在数据包的校验和字段中设置魔术变量0x5a6b7c8d,然后使用带有1024个字节的表reference_tbl来计算整个数据包(包括报头)的校验和;
校验和通过验证并且所有结果正确之后,tdpd_pkt_sanity_checks()返回0。
tdpd_pkt_parser()#2
onemesh_slave_key_offer()(漏洞处)
第一部分:将payload传递给tpapp_aes_decrypt()(地址:0x40b190)——功能:使用AES算法和静态密钥“TPONEMESH_Kf!xn?gj6pMAt-wBNV_TDP”解密payload
第二部分:对onemesh对象做一些设置后,解析payload(一个json对象)获取json键及其值
第三部分:按顺序处理获取的键与值(若键不存在,直接退出函数),json对象中的值传递给堆栈变量slaveMac、slaveIp等,调用create_csjon_obj()(地址:0x405fe8)函数处理
第四部分:create_csjon_obj()处理:堆栈变量slaveMac被传递给systemCmd变量,然后由system(systemCmd)执行
onemesh_slave_key_offer()#1
onemesh_slave_key_offer()#2
onemesh_slave_key_offer()#3
onemesh_slave_key_offer()#4
假设json对象如下:
want_to_join必须为false,type设置为0xf0,将opcode设置为6,将flags设置为1,并正确获取校验和字段
加密payload
AES算法,固定密钥:TPONEMESH_Kf!xn?gj6pMAt-wBNV_TDP,使用CBC模式(IV固定值:1234567890abcdef1234567890abcdef),实际使用其中的128位密钥的AES-CBC,256位密钥和IV中有一半没有使用。
实现代码执行
本文整理资源来自网络,不代表我的任何观点和立场
来源:https://www.zerodayinitiative.com/blog/2020/4/6/exploiting-the-tp-link-archer-c7-at-pwn2own-tokyo