Exemplo n.º 1
0
 def get_peb_addr(self):
     dest = self.virtual_alloc(0x1000)
     if self.bitness == 32:
         store_peb = x86.MultipleInstr()
         store_peb += x86.Mov('EAX', x86.mem('fs:[0x30]'))
         store_peb += x86.Mov(x86.create_displacement(disp=dest), 'EAX')
         store_peb += x86.Ret()
         get_peb_code = store_peb.get_code()
         self.write_memory(dest, "\x00" * 4)
         self.write_memory(dest + 4, get_peb_code)
         self.create_thread(dest + 4, 0)
         time.sleep(0.01)
         peb_addr = struct.unpack("<I", self.read_memory(dest, 4))[0]
         return peb_addr
     else:
         store_peb = x64.MultipleInstr()
         store_peb += x64.Mov('RAX', x64.mem('gs:[0x60]'))
         store_peb += x64.Mov(x64.create_displacement(disp=dest), 'RAX')
         store_peb += x64.Ret()
         get_peb_code = store_peb.get_code()
         self.write_memory(dest, "\x00" * 8)
         self.write_memory(dest + 8, get_peb_code)
         self.create_thread(dest + 8, 0)
         time.sleep(0.01)
         peb_addr = struct.unpack("<Q", self.read_memory(dest, 8))[0]
         return peb_addr
Exemplo n.º 2
0
def get_current_process_syswow_peb_addr():
    current_process = windows.current_process
    dest = current_process.allocator.reserve_size(8)
    get_peb_64_code = x64.MultipleInstr()
    get_peb_64_code += x64.Mov('RAX', x64.mem('gs:[0x60]'))
    get_peb_64_code += x64.Mov(x64.create_displacement(disp=dest), 'RAX')
    current_process.write_memory(dest, "\x00" * 8)
    execute_64bits_code_from_syswow(get_peb_64_code.get_code())
    peb_addr = struct.unpack("<Q", current_process.read_memory(dest, 8))[0]
    return peb_addr
Exemplo n.º 3
0
 def test_execute_to_64(self):
     with Calc64() as calc:
         data = calc.virtual_alloc(0x1000)
         shellcode = x64.MultipleInstr()
         shellcode += x64.Mov('RAX', 0x4242424243434343)
         shellcode += x64.Mov(x64.create_displacement(disp=data), 'RAX')
         shellcode += x64.Ret()
         calc.execute(shellcode.get_code())
         time.sleep(0.1)
         dword = struct.unpack("<Q", calc.read_memory(data, 8))[0]
         self.assertEqual(dword, 0x4242424243434343)
Exemplo n.º 4
0
 def register_kernel_call(self):
     # expect in buffer: the address to call and all dword to push on the stack
     CCall_IOCTL = x64.MultipleInstr()
     CCall_IOCTL += x64.Mov('RAX', self.IO_STACK_INPUT_BUFFER_LEN)
     CCall_IOCTL += x64.Cmp('RAX', 0)
     CCall_IOCTL += x64.Jz(":FAIL")  # Need at least the function to call
     CCall_IOCTL += x64.Mov('R15', 4 * 8)  # Size to pop on the stack at the end (4 * push RDI)
     CCall_IOCTL += x64.Mov('R10', self.IO_STACK_INPUT_BUFFER)
     CCall_IOCTL += x64.Label(':PUSH_NEXT_ARG')
     CCall_IOCTL += x64.Cmp('RAX', (8 * 5))
     CCall_IOCTL += x64.Jbe(":SETUP_REG_ARGS")
     CCall_IOCTL += x64.Sub('RAX', 8)
     INPUT_BUFFER_NEXT_ARG = x64.create_displacement(base='R10', index='RAX')
     CCall_IOCTL += x64.Mov('RBX', INPUT_BUFFER_NEXT_ARG)
     CCall_IOCTL += x64.Push('RBX')
     CCall_IOCTL += x64.Add('R15', 8)  # Add at Size to pop on the stack at the end
     CCall_IOCTL += x64.Jmp(':PUSH_NEXT_ARG')
     CCall_IOCTL += x64.Label(":SETUP_REG_ARGS")
     # Could be done in a loop
     # But do I really want to generate x86 in a loop..
     CCall_IOCTL += x64.Cmp('RAX', (8 * 5))
     CCall_IOCTL += x64.Jz(":SETUP_4_ARGS")
     CCall_IOCTL += x64.Cmp('RAX', (8 * 4))
     CCall_IOCTL += x64.Jz(":SETUP_3_ARGS")
     CCall_IOCTL += x64.Cmp('RAX', (8 * 3))
     CCall_IOCTL += x64.Jz(":SETUP_2_ARGS")
     CCall_IOCTL += x64.Cmp('RAX', (8 * 2))
     CCall_IOCTL += x64.Jz(":SETUP_1_ARGS")
     CCall_IOCTL += x64.Jmp(":SETUP_0_ARGS")
     CCall_IOCTL += x64.Label(":SETUP_4_ARGS")
     CCall_IOCTL += x64.Mov('R9', x64.mem('[R10 + 0x20]'))
     CCall_IOCTL += x64.Label(":SETUP_3_ARGS")
     CCall_IOCTL += x64.Mov('R8', x64.mem('[R10 + 0x18]'))
     CCall_IOCTL += x64.Label(":SETUP_2_ARGS")
     CCall_IOCTL += x64.Mov('RDX', x64.mem('[R10 + 0x10]'))
     CCall_IOCTL += x64.Label(":SETUP_1_ARGS")
     CCall_IOCTL += x64.Mov('RCX', x64.mem('[R10 + 8]'))
     CCall_IOCTL += x64.Label(":SETUP_0_ARGS")
     CCall_IOCTL += x64.Mov('RAX', x64.mem('[R10]'))
     # Fix Reserve space (calling convention)
     CCall_IOCTL += x64.Push('RDI')
     CCall_IOCTL += x64.Push('RDI')
     CCall_IOCTL += x64.Push('RDI')
     CCall_IOCTL += x64.Push('RDI')
     CCall_IOCTL += x64.Call('RAX')
     CCall_IOCTL += x64.Mov('RDX', self.IRP_OUTPUT_BUFFER)
     CCall_IOCTL += x64.Mov(x64.mem('[RDX]'), 'RAX')
     CCall_IOCTL += x64.Xor('RAX', 'RAX')
     CCall_IOCTL += x64.Add('RSP', 'R15')
     CCall_IOCTL += x64.Ret()
     CCall_IOCTL += x64.Label(":FAIL")
     CCall_IOCTL += x64.Mov('RAX', 0x0C000000D)
     CCall_IOCTL += x64.Ret()
     self.upgrade_driver_add_new_ioctl_handler(DU_KCALL_IOCTL, CCall_IOCTL.get_code())
Exemplo n.º 5
0
def get_current_process_syswow_peb_addr():
    current_process = windows.current_process
    dest = current_process.virtual_alloc(0x1000)
    get_peb_64_code = codecs.decode(b"65488B042560000000", 'hex')
    store_peb = x64.MultipleInstr()
    store_peb += x64.Mov(x64.create_displacement(disp=dest), 'RAX')
    get_peb_64_code += store_peb.get_code()
    current_process.write_memory(dest, "\x00" * 8)
    windows.syswow64.execute_64bits_code_from_syswow(get_peb_64_code)
    peb_addr = struct.unpack("<Q", current_process.read_memory(dest, 8))[0]
    return peb_addr
Exemplo n.º 6
0
    def _upgrade_driver_inject_base_upgrade(self):
        kldbgdrv = self.kldbgdrv
        upgrade = x64.MultipleInstr()
        # R14 : IOCODE
        # RSI -> IO_STACK_LOCATION
        # RDI -> IRP
        upgrade = x64.MultipleInstr()
        upgrade += x64.Cmp('R14', self.NORMAL_IO_CODE)
        upgrade += x64.Jz(self.normal_io_offset - (self.init_driver_offset + len(upgrade.get_code())))
        upgrade += x64.Mov('Rax', x64.create_displacement(disp=kldbgdrv + self.HANDLE_ARRAY_ADDR))
        upgrade += x64.Label(":LOOP")
        upgrade +=      x64.Mov('RCX', x64.create_displacement('RAX'))
        upgrade +=      x64.Cmp('R14', 'RCX')
        upgrade +=      x64.Jnz(':END')
        upgrade +=          x64.Mov('RAX', x64.create_displacement('RAX', disp=8))
        upgrade +=          x64.Call('RAX')
        upgrade +=          x64.Mov('RBX', 'RAX')
        upgrade +=          x64.JmpAt(kldbgdrv + self.normal_end_offset)
        upgrade +=      x64.Label(":END")
        upgrade +=      x64.Cmp('RCX', 0)
        upgrade +=      x64.Jnz(':NEXT')
        upgrade +=          x64.JmpAt(kldbgdrv + self.fail_offset)
        upgrade +=      x64.Label(":NEXT")
        upgrade +=      x64.Add('RAX', 0x10)
        upgrade += x64.Jmp(':LOOP')

        self.kdbg.write_pfv_memory(kldbgdrv + self.init_driver_offset, str(upgrade.get_code()))
        # Write first array dest
        self.write_pfv_ptr(kldbgdrv + self.HANDLE_ARRAY_ADDR, kldbgdrv + self.FIRST_ARRAY_ADDR)
        self.write_pfv_ptr(kldbgdrv + self.FIRST_ARRAY_ADDR, 0)
        self.write_pfv_ptr(kldbgdrv + self.FIRST_ARRAY_ADDR + 8, 0)
        # Jump hijack
        jump_init_function = x64.Jmp(self.init_driver_offset - (self.hijack_offset))
        self.kdbg.write_pfv_memory(kldbgdrv + self.hijack_offset, str(jump_init_function.get_code()))

        self.ioctl_array = kldbgdrv + self.FIRST_ARRAY_ADDR
        self.ioctl_array_ptr = kldbgdrv + self.HANDLE_ARRAY_ADDR
        self.next_code_addr = kldbgdrv + self.init_driver_offset + len(upgrade.get_code())
        self.is_upgraded = True
Exemplo n.º 7
0
def generate_syswow64_call(target):
    nb_args = len(target.prototype._argtypes_)
    target_addr = get_syswow_ntdll_exports()[target.__name__]
    argument_buffer_len = (nb_args * 8)
    argument_buffer = windows.current_process.allocator.reserve_size(argument_buffer_len)
    alignement_information = windows.current_process.allocator.reserve_size(8)

    nb_args_on_stack = max(nb_args - 4, 0)

    code_64b = x64.MultipleInstr()
    # Save registers

    code_64b += x64.Push('RBX')
    code_64b += x64.Push('RCX')
    code_64b += x64.Push('RDX')
    code_64b += x64.Push('RSI')
    code_64b += x64.Push('RDI')
    code_64b += x64.Push('R8')
    code_64b += x64.Push('R9')
    code_64b += x64.Push('R10')
    code_64b += x64.Push('R11')
    code_64b += x64.Push('R12')
    code_64b += x64.Push('R13')

    # Alignment stuff :)
    code_64b += x64.Mov('RCX', 'RSP')
    code_64b += x64.And('RCX', 0x0f)
    code_64b += x64.Mov(x64.deref(alignement_information), 'RCX')
    code_64b += x64.Sub('RSP', 'RCX')
    # retrieve argument from the argument buffer
    if nb_args >= 1:
        code_64b += x64.Mov('RCX', x64.create_displacement(disp=argument_buffer))
    if nb_args >= 2:
        code_64b += x64.Mov('RDX', x64.create_displacement(disp=argument_buffer + (8 * 1)))
    if nb_args >= 3:
        code_64b += x64.Mov('R8', x64.create_displacement(disp=argument_buffer + (8 * 2)))
    if nb_args >= 4:
        code_64b += x64.Mov('R9', x64.create_displacement(disp=argument_buffer + (8 * 3)))
    for i in range(nb_args_on_stack):
        code_64b += x64.Mov('RAX',  x64.create_displacement(disp=argument_buffer + 8 * (nb_args - 1 - i)))
        code_64b += x64.Push('RAX')
    # reserve space for register (calling convention)
    code_64b += x64.Push('R9')
    code_64b += x64.Push('R8')
    code_64b += x64.Push('RDX')
    code_64b += x64.Push('RCX')
    # Call
    code_64b += x64.Mov('R13', target_addr)
    code_64b += x64.Call('R13')
    # Realign stack :)
    code_64b += x64.Add('RSP', x64.deref(alignement_information))
    # Clean stack
    code_64b += x64.Add('RSP', (4 + nb_args_on_stack) * 8)
    code_64b += x64.Pop('R13')
    code_64b += x64.Pop('R12')
    code_64b += x64.Pop('R11')
    code_64b += x64.Pop('R10')
    code_64b += x64.Pop('R9')
    code_64b += x64.Pop('R8')
    code_64b += x64.Pop('RDI')
    code_64b += x64.Pop('RSI')
    code_64b += x64.Pop('RDX')
    code_64b += x64.Pop('RCX')
    code_64b += x64.Pop('RBX')
    return try_generate_stub_target(code_64b.get_code(), argument_buffer, target)