Fix host-endian related pack errors. See below for details.

Ruby treats endianess in pack operators in the opposite way
of python. For example, using pack('<I') actually ignores the
endianess specifier. These need to be 'I<' or better yet, 'V'.
The endian specify must occur after the pack specifier and
multiple instances in meterpreter and exe generation were
broken in thier usage.

The summary:

Instead of I/L or I< use V
Instead of I/L or I> use N
For Q, you need to always use Q< (LE) or Q> (BE)
For c/s/l/i and other lowercase variants, you probably dont
need or want a *signed* value, so stick with vV nN and cC.
bug/bundler_fix
HD Moore 2014-06-30 02:03:53 -05:00
parent a60dfdaacb
commit 255e792ed3
5 changed files with 25 additions and 25 deletions

View File

@ -340,22 +340,22 @@ require 'msf/core/exe/segment_injector'
# look for section with entry point
sections_header.each do |sec|
virtualAddress = sec[1][virtualAddress_offset,0x4].unpack('L')[0]
sizeOfRawData = sec[1][sizeOfRawData_offset,0x4].unpack('L')[0]
characteristics = sec[1][characteristics_offset,0x4].unpack('L')[0]
virtualAddress = sec[1][virtualAddress_offset,0x4].unpack('V')[0]
sizeOfRawData = sec[1][sizeOfRawData_offset,0x4].unpack('V')[0]
characteristics = sec[1][characteristics_offset,0x4].unpack('V')[0]
if (virtualAddress...virtualAddress+sizeOfRawData).include?(addressOfEntryPoint)
importsTable = pe.hdr.opt.DataDirectory[8..(8+4)].unpack('L')[0]
importsTable = pe.hdr.opt.DataDirectory[8..(8+4)].unpack('V')[0]
if (importsTable - addressOfEntryPoint) < code.length
#shift original entry point to prevent tables overwritting
addressOfEntryPoint = importsTable - (code.length + 4)
entry_point_offset = pe._dos_header.v['e_lfanew'] + entryPoint_offset
exe[entry_point_offset,4] = [addressOfEntryPoint].pack('L')
exe[entry_point_offset,4] = [addressOfEntryPoint].pack('V')
end
# put this section writable
characteristics |= 0x8000_0000
newcharacteristics = [characteristics].pack('L')
newcharacteristics = [characteristics].pack('V')
exe[sec[0],newcharacteristics.length] = newcharacteristics
end
end
@ -572,20 +572,20 @@ require 'msf/core/exe/segment_injector'
"\x5B\x5B\x61\x59\x5A\x51\xFF\xE0\x58\x5F\x5A\x8B\x12\xEB\x86\x5D" +
"\x6A\x00\x68\x70\x69\x33\x32\x68\x61\x64\x76\x61\x54\x68\x4C\x77" +
"\x26\x07\xFF\xD5"+pushed_service_name+"\x89\xE1" +
"\x8D\x85"+[svcmain_code_offset].pack('<I')+"\x6A\x00\x50\x51\x89\xE0\x6A\x00\x50\x68" +
"\x8D\x85"+[svcmain_code_offset].pack('V')+"\x6A\x00\x50\x51\x89\xE0\x6A\x00\x50\x68" +
"\xFA\xF7\x72\xCB\xFF\xD5\x6A\x00\x68\xF0\xB5\xA2\x56\xFF\xD5\x58" +
"\x58\x58\x58\x31\xC0\xC3\xFC\xE8\x00\x00\x00\x00\x5D\x81\xED" +
[hash_code_offset].pack('<I')+pushed_service_name+"\x89\xE1\x8D" +
"\x85"+[svcctrlhandler_code_offset].pack('<I')+"\x6A\x00\x50\x51\x68\x0B\xAA\x44\x52\xFF\xD5" +
[hash_code_offset].pack('V')+pushed_service_name+"\x89\xE1\x8D" +
"\x85"+[svcctrlhandler_code_offset].pack('V')+"\x6A\x00\x50\x51\x68\x0B\xAA\x44\x52\xFF\xD5" +
"\x6A\x00\x6A\x00\x6A\x00\x6A\x00\x6A\x00\x6A\x00\x6A\x04\x6A\x10" +
"\x89\xE1\x6A\x00\x51\x50\x68\xC6\x55\x37\x7D\xFF\xD5\x31\xFF\x6A" +
"\x04\x68\x00\x10\x00\x00\x6A\x54\x57\x68\x58\xA4\x53\xE5\xFF\xD5" +
"\xC7\x00\x44\x00\x00\x00\x8D\x70\x44\x57\x68\x2E\x65\x78\x65\x68" +
"\x6C\x6C\x33\x32\x68\x72\x75\x6E\x64\x89\xE1\x56\x50\x57\x57\x6A" +
"\x44\x57\x57\x57\x51\x57\x68\x79\xCC\x3F\x86\xFF\xD5\x8B\x0E\x6A" +
"\x40\x68\x00\x10\x00\x00\x68"+[code.length].pack('<I')+"\x57\x51\x68\xAE\x87" +
"\x40\x68\x00\x10\x00\x00\x68"+[code.length].pack('V')+"\x57\x51\x68\xAE\x87" +
"\x92\x3F\xFF\xD5\xE8\x00\x00\x00\x00\x5A\x89\xC7\x8B\x0E\x81\xC2" +
[shellcode_code_offset].pack('<I')+"\x54\x68"+[code.length].pack('<I') +
[shellcode_code_offset].pack('V')+"\x54\x68"+[code.length].pack('V') +
"\x52\x50\x51\x68\xC5\xD8\xBD\xE7\xFF" +
"\xD5\x31\xC0\x8B\x0E\x50\x50\x50\x57\x50\x50\x51\x68\xC6\xAC\x9A" +
"\x79\xFF\xD5\x8B\x0E\x51\x68\xC6\x96\x87\x52\xFF\xD5\x8B\x4E\x04" +
@ -654,8 +654,8 @@ require 'msf/core/exe/segment_injector'
msi = fd.read(fd.stat.size)
}
section_size = 2**(msi[30..31].unpack('s')[0])
sector_allocation_table = msi[section_size..section_size*2].unpack('l*')
section_size = 2**(msi[30..31].unpack('s<')[0])
sector_allocation_table = msi[section_size..section_size*2].unpack('l<*')
buffer_chain = []
current_secid = 5 # This is closely coupled with the template provided and ideally
@ -841,8 +841,8 @@ require 'msf/core/exe/segment_injector'
elf[0x60,8] = [elf.length].pack('Q>') #p_filesz
elf[0x68,8] = [elf.length + code.length].pack('Q>') #p_memsz
else # little endian
elf[0x60,8] = [elf.length].pack('Q') #p_filesz
elf[0x68,8] = [elf.length + code.length].pack('Q') #p_memsz
elf[0x60,8] = [elf.length].pack('Q<') #p_filesz
elf[0x68,8] = [elf.length + code.length].pack('Q<') #p_memsz
end
else
raise RuntimeError, "Invalid ELF template: EI_CLASS value not supported"

View File

@ -49,7 +49,7 @@ module Arch
when ARCH_X86
[addr].pack('V')
when ARCH_X86_64
[addr].pack('Q')
[addr].pack('Q<')
when ARCH_MIPS # ambiguous
[addr].pack('N')
when ARCH_MIPSBE

View File

@ -27,8 +27,8 @@ module PointerUtil
case platform
when PlatformUtil::X86_64
# XXX: Only works if attacker and victim are like-endianed
[pointer].pack('Q')
# Assume little endian
[pointer].pack('Q<')
when PlatformUtil::X86_32
[pointer].pack('V')
else
@ -40,8 +40,8 @@ module PointerUtil
def self.unpack_pointer(packed_pointer, platform)
case platform
when PlatformUtil::X86_64
# XXX: Only works if attacker and victim are like-endianed
packed_pointer.unpack('Q').first
# Assume little endian
packed_pointer.unpack('Q<').first
when PlatformUtil::X86_32
packed_pointer.unpack('V').first
else

View File

@ -324,8 +324,8 @@ class Util
#
def unpack_pointer(packed_pointer)
if is_64bit
# XXX: Only works if attacker and victim are like-endianed
packed_pointer.unpack('Q')[0]
# Assume little endian
packed_pointer.unpack('Q<')[0]
else
packed_pointer.unpack('V')[0]
end

View File

@ -251,7 +251,7 @@ class Tlv
elsif (self.type & TLV_META_TYPE_UINT == TLV_META_TYPE_UINT)
raw = [value].pack("N")
elsif (self.type & TLV_META_TYPE_QWORD == TLV_META_TYPE_QWORD)
raw = [ self.htonq( value.to_i ) ].pack("Q")
raw = [ self.htonq( value.to_i ) ].pack("Q<")
elsif (self.type & TLV_META_TYPE_BOOL == TLV_META_TYPE_BOOL)
if (value == true)
raw = [1].pack("c")
@ -312,7 +312,7 @@ class Tlv
elsif (self.type & TLV_META_TYPE_UINT == TLV_META_TYPE_UINT)
self.value = raw.unpack("NNN")[2]
elsif (self.type & TLV_META_TYPE_QWORD == TLV_META_TYPE_QWORD)
self.value = raw.unpack("NNQ")[2]
self.value = raw.unpack("NNQ<")[2]
self.value = self.ntohq( self.value )
elsif (self.type & TLV_META_TYPE_BOOL == TLV_META_TYPE_BOOL)
self.value = raw.unpack("NNc")[2]
@ -335,7 +335,7 @@ class Tlv
if( [1].pack( 's' ) == [1].pack( 'n' ) )
return value
end
return [ value ].pack( 'Q' ).reverse.unpack( 'Q' ).first
return [ value ].pack( 'Q<' ).reverse.unpack( 'Q<' ).first
end
def ntohq( value )