PSV-2020-0437:Buffer-Overflow-on-Some-Netgear-Routers
2022-6-30 21:43:0 Author: bestwing.me(查看原文) 阅读量:18 收藏

距离上一篇 Blog 更新已经快一个月了,想了想应该给长草的 Blog 除除草了。于是从我的笔记文档里翻了一下, 把这个漏洞翻出来给大家分享分享。具体官方通告可以参考:

众所周知 UPNP相关的程序在路由器上是经常出现漏洞的。这次也不例外, PSV-2020-0437 的漏洞也是出现在 UPNP 的相关处理代码中。我们从刚解压出来的文件系统中提取出 upnpd 程序, 然后我们用 ida pro 打开。

该函数会对输入的数据进行部分解析,例如 M-SEARCHssdp:discover 等关键词, 本次的漏洞是在 sub_22D20 函数中发生的, 我们点进去查看下这个函数。

由于漏洞的根本原因是 strncpy 的缓冲区溢出, 我们知道 strncpy 函数在溢出的时候会存在 \x00 截断。然而程序每次不同链接使用的是同一块内存, 我们可以在第一次 recvfrom 的时候在栈上布局好 rop, 然后通过栈迁移跳转到布局好的 rop 上。

另外最终我期望通过调用 system 函数执行任意命令, 因此我需要在 bss 这样全局的地址上写入命令, 因此我需要找对应可以往任意地址写入值的 gadget 。 在 arm 的汇编中,写入值的汇编指令为 str

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$ ropper -f usr/sbin/upnpd --search "str r?"
[INFO] Load gadgets from cache
[LOAD] loading... 100%
[LOAD] removing double gadgets... 100%
[INFO] Searching for gadgets: str r?

[INFO] File: usr/sbin/upnpd
0x000299e8: str r0, [r3,
0x000167e0: str r0, [r4,
0x0000ba2c: str r0, [r5]; mov r0, r4; pop {r3, r4, r5, r6, r7, pc};
0x0002d448: str r2, [r3,
0x0002d468: str r2, [r3,
0x0002b360: str r2, [r3,
0x000182ec: str r2, [r3,
0x000167f0: str r2, [r3,
0x0002b458: str r2, [r3]; add sp, sp,
0x0002af38: str r2, [r3]; bl
0x0000ba6c: str r2, [r3]; bx lr;
0x0000ba60: str r2, [r3]; mov r2,
0x00017da0: str r2, [r3]; pop {r3, pc};
0x0002b524: str r2, [r3]; pop {r4, pc};
0x0000f120: str r3, [ip]; bl
0x00029950: str r3, [r2,
0x000182fc: str r3, [r2,
0x00013d80: str r3, [r2]; mov r0,
0x00013900: str r3, [r2]; mov r0,
0x00013af4: str r3, [r2]; mov r0,
0x00017d64: str r3, [r4,
0x0000bac8: str r3, [r4]; add r0, r0,
0x000272ec: str r3, [r4]; pop {r4, pc};
0x0002dd64: str r3, [r5]; pop {r3, r4, r5, r6, r7, pc};
0x0000bc1c: str r3, [sp,
0x00014188: str r4, [sp,
0x00017e98: str r5, [sp,
0x0002dd4c: str r6, [r5]; pop {r3, r4, r5, r6, r7, pc};

对于这样的需求,我从这些 gadget 中选取了 0x0002dd4c: str r6, [r5]; pop {r3, r4, r5, r6, r7, pc}; 这条指令, 通过控制 r5、 r6 寄存器,我们可以将任意值从r6 写到 r5 所指向到地址中。然后我通过 for 循环就可以构造出将任意字符串,写到任意地址中的 rop 链

最后呢,在找一条 mov r0, r?, bl system 这样的gadget, 将为可控的 R3R7 寄存器中的一个覆写成刚刚写入了命令的地址,然后将值 mov 到 r0 寄存器上。 因为 arm 到参数传递是由寄存器传递的,通过控制 r0 寄存器, 我们就可以控制 system 执行任意命令。


文章来源: https://bestwing.me/PSV-2020-0437-Buffer-Overflow-on-Some-Netgear-outers.html
如有侵权请联系:admin#unsafe.sh