Ejemplo n.º 1
0
    def register_io_in(self):
        in_ioctl = x64.MultipleInstr()

        INPUT_BUFFER_SIZE =  x64.mem('[RCX]')
        INPUT_BUFFER_PORT =  x64.mem('[RCX + 8]')

        in_ioctl += x64.Cmp(self.IO_STACK_INPUT_BUFFER_LEN, 0x10)  # size indicator / port
        in_ioctl += x64.Jnz(":FAIL")
        in_ioctl +=    x64.Mov('RCX', self.IO_STACK_INPUT_BUFFER)
        in_ioctl +=    x64.Mov('RDX', INPUT_BUFFER_PORT)
        in_ioctl +=    x64.Mov('RCX', INPUT_BUFFER_SIZE)
        in_ioctl +=    x64.Cmp('RCX', 0x1)
        in_ioctl +=    x64.Jnz(":OUT_2_OR_4")
        in_ioctl +=    x64.In('AL', 'DX')
        in_ioctl +=    x64.Jmp(':SUCCESS')
        in_ioctl +=    x64.Label(":OUT_2_OR_4")
        in_ioctl +=    x64.Cmp('RCX', 0x2)
        in_ioctl +=    x64.Jnz(":OUT_4")
        in_ioctl +=    x64.In('AX', 'DX')
        in_ioctl +=    x64.Jmp(':SUCCESS')
        in_ioctl +=    x64.Label(":OUT_4")
        in_ioctl +=    x64.In('EAX', 'DX')
        in_ioctl +=    x64.Label(":SUCCESS")
        in_ioctl += x64.Mov('RDX', self.IRP_OUTPUT_BUFFER)
        in_ioctl += x64.Mov(x64.mem('[RDX]'), 'RAX')
        in_ioctl += x64.Xor('RAX', 'RAX')
        in_ioctl += x64.Ret()
        in_ioctl += x64.Label(":FAIL")
        in_ioctl += x64.Mov('RAX', 0x0C000000D)
        in_ioctl += x64.Ret()

        self.upgrade_driver_add_new_ioctl_handler(DU_IN_IOCTL, in_ioctl.get_code())
Ejemplo n.º 2
0
    def register_io_out(self):
        out_ioctl = x64.MultipleInstr()

        INPUT_BUFFER_SIZE =  x64.mem('[RCX]')
        INPUT_BUFFER_PORT =  x64.mem('[RCX + 8]')
        INPUT_BUFFER_VALUE = x64.mem('[RCX + 0x10]')

        out_ioctl += x64.Cmp(self.IO_STACK_INPUT_BUFFER_LEN, 0x18)  # size indicator / port / value
        out_ioctl += x64.Jnz(":FAIL")
        out_ioctl +=    x64.Mov('RCX', self.IO_STACK_INPUT_BUFFER)
        out_ioctl +=    x64.Mov('RDX', INPUT_BUFFER_PORT)
        out_ioctl +=    x64.Mov('RAX', INPUT_BUFFER_VALUE)
        out_ioctl +=    x64.Mov('RCX', INPUT_BUFFER_SIZE)
        out_ioctl +=    x64.Cmp('RCX', 0x1)
        out_ioctl +=    x64.Jnz(":OUT_2_OR_4")
        out_ioctl +=    x64.Out('DX', 'AL')
        out_ioctl +=    x64.Jmp(':SUCCESS')
        out_ioctl +=    x64.Label(":OUT_2_OR_4")
        out_ioctl +=    x64.Cmp('RCX', 0x2)
        out_ioctl +=    x64.Jnz(":OUT_4")
        out_ioctl +=    x64.Out('DX', 'AX')
        out_ioctl +=    x64.Jmp(':SUCCESS')
        out_ioctl +=    x64.Label(":OUT_4")
        out_ioctl +=    x64.Out('DX', 'EAX')
        out_ioctl +=    x64.Label(":SUCCESS")
        out_ioctl +=    x64.Xor('RAX', 'RAX')
        out_ioctl +=    x64.Ret()
        out_ioctl += x64.Label(":FAIL")
        out_ioctl += x64.Mov('RAX', 0x0C000000D)
        out_ioctl += x64.Ret()

        self.upgrade_driver_add_new_ioctl_handler(DU_OUT_IOCTL, out_ioctl.get_code())
Ejemplo n.º 3
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())
Ejemplo n.º 4
0
def sc_64_LoadLibrary(dll_path):
    dll = bytes("KERNEL32.DLL\x00".encode("utf-16-le"))
    api = b"LoadLibraryA\x00"

    if PY3 and isinstance(dll_path, str):
        dll_path = bytes(dll_path.encode())

    LoadLibrary64_sc = x64.MultipleInstr()

    LoadLibrary64_sc += shellcraft.amd64.pushstr(dll)
    LoadLibrary64_sc += x64.Mov("RCX", "RSP")
    LoadLibrary64_sc += shellcraft.amd64.pushstr(api)
    LoadLibrary64_sc += x64.Mov("RDX", "RSP")
    LoadLibrary64_sc += x64.Call(":FUNC_GETPROCADDRESS64")
    LoadLibrary64_sc += x64.Mov("R10", "RAX")
    LoadLibrary64_sc += shellcraft.amd64.pushstr(dll_path)
    LoadLibrary64_sc += x64.Mov("RCX", "RSP")
    LoadLibrary64_sc += x64.Sub("RSP", 0x30)
    LoadLibrary64_sc += x64.And("RSP", -32)
    LoadLibrary64_sc += x64.Call("R10")
    LoadLibrary64_sc += x64.Label(":HERE")
    LoadLibrary64_sc += x64.Jmp(":HERE")
    LoadLibrary64_sc += windows.native_exec.nativeutils.GetProcAddress64

    return LoadLibrary64_sc.get_code()
Ejemplo n.º 5
0
def sc_64_WinExec(exe):
    dll = bytes("KERNEL32.DLL\x00".encode("utf-16-le"))
    api = b"WinExec\x00"

    if PY3 and isinstance(exe, str):
        exe = bytes(exe.encode())

    WinExec64_sc = x64.MultipleInstr()
    WinExec64_sc += shellcraft.amd64.pushstr(dll)
    WinExec64_sc += x64.Mov("RCX", "RSP")
    WinExec64_sc += shellcraft.amd64.pushstr(api)
    WinExec64_sc += x64.Mov("RDX", "RSP")
    WinExec64_sc += x64.Call(":FUNC_GETPROCADDRESS64")
    WinExec64_sc += x64.Mov("R10", "RAX")
    WinExec64_sc += shellcraft.amd64.pushstr(exe)
    WinExec64_sc += x64.Mov("RCX", "RSP")
    WinExec64_sc += x64.Sub("RSP", 0x30)
    WinExec64_sc += x64.And("RSP", -32)
    WinExec64_sc += x64.Call("R10")
    WinExec64_sc += x64.Label(":HERE")
    WinExec64_sc += x64.Jmp(":HERE")
    WinExec64_sc += windows.native_exec.nativeutils.GetProcAddress64  # Dirty infinite loop
    #WinExec64_sc +=# x64.Ret(),

    return WinExec64_sc.get_code()
Ejemplo n.º 6
0
 def test_get_context_address_64(self, proc64):
     code = x64.MultipleInstr()
     code += x64.Mov("RAX", 0x4242424243434343)
     code += x64.Label(":LOOP")
     code += x64.Jmp(":LOOP")
     t = proc64.execute(code.get_code())
     time.sleep(0.5)
     cont = t.context
     assert cont.Rax == 0x4242424243434343
Ejemplo n.º 7
0
 def test_get_context_address_64(self):
     with Calc64() as calc:
         code = x64.MultipleInstr()
         code += x64.Mov("RAX", 0x4242424243434343)
         code += x64.Label(":LOOP")
         code += x64.Jmp(":LOOP")
         t = calc.execute(code.get_code())
         time.sleep(0.5)
         cont = t.context
         self.assertEqual(cont.Rax, 0x4242424243434343)
Ejemplo n.º 8
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
Ejemplo n.º 9
0
 def test_set_thread_context_64(self, proc64):
     code =  x64.MultipleInstr()
     code += x64.Label(":LOOP")
     code += x64.Jmp(":LOOP")
     data_len = len(code.get_code())
     code += x64.Ret()
     t = proc64.execute(code.get_code())
     time.sleep(0.1)
     assert proc64.is_exit ==  False
     t.suspend()
     ctx = t.context
     ctx.Rip += data_len
     ctx.Rax = 0x11223344
     t.set_context(ctx)
     t.resume()
     time.sleep(0.1)
     assert t.exit_code == 0x11223344
Ejemplo n.º 10
0
def sc_64_LoadLibrary(dll_path):
    dll = "KERNEL32.DLL\x00".encode("utf-16-le")
    api = "LoadLibraryA\x00"
    LoadLibrary64_sc = x64.MultipleInstr()
    map(LoadLibrary64_sc.__iadd__, [
        shellcraft.amd64.pushstr(dll),
        x64.Mov("RCX", "RSP"),
        shellcraft.amd64.pushstr(api),
        x64.Mov("RDX", "RSP"),
        x64.Call(":FUNC_GETPROCADDRESS64"),
        x64.Mov("R10", "RAX"),
        shellcraft.amd64.pushstr(dll_path),
        x64.Mov("RCX", "RSP"),
        x64.Sub("RSP", 0x30),
        x64.And("RSP", -32),
        x64.Call("R10"),
        x64.Label(":HERE"),
        x64.Jmp(":HERE"), # Dirty infinite loop
        # x64.Ret(),
        windows.native_exec.nativeutils.GetProcAddress64,
    ])
    return LoadLibrary64_sc.get_code()
Ejemplo n.º 11
0
 def is_driver_already_upgraded(self):
     """Check if the driver have already been upgraded by checking if the jump hijack is in place"""
     jump_hijack = x64.Jmp(self.init_driver_offset - (self.hijack_offset)).get_code()
     mem = self.kdbg.read_virtual_memory(self.kldbgdrv + self.hijack_offset, len(jump_hijack))
     return mem == str(jump_hijack)
Ejemplo n.º 12
0
    x64.mem("[RAX + 32]"))  # RBX : first base ! (base of current module)
#GetProcAddress64 +=     x64.Mov("RBX ", x64.mem("[RAX + 32]")) # RBX : first base ! (base of current module)
GetProcAddress64 += x64.Cmp("RBX", 0)
GetProcAddress64 += x64.Jz(":DLL_NOT_FOUND")
GetProcAddress64 += x64.Mov(
    "RCX", x64.mem("[RAX + 80]"))  # RCX = NAME (UNICODE_STRING.Buffer)
GetProcAddress64 += x64.Call(":FUNC_STRLENW64")
GetProcAddress64 += x64.Mov("RDI", "RCX")
GetProcAddress64 += x64.Mov("RCX", "RAX")
GetProcAddress64 += x64.Mov("RSI", "R11")
GetProcAddress64 += x64.Rep + x64.CmpsW(
)  #;cmp with current dll name (unicode)
GetProcAddress64 += x64.Test("RCX", "RCX")
GetProcAddress64 += x64.Jz(":DLL_FOUND")
GetProcAddress64 += x64.Mov("RDX", x64.mem("[RDX]"))
GetProcAddress64 += x64.Jmp(":a_dest")
GetProcAddress64 += x64.Label(":DLL_FOUND")  # here rbx = base
GetProcAddress64 += x64.Mov("EAX", x64.mem("[RBX + 60]"))  # rax = PEBASE RVA
GetProcAddress64 += x64.Add("RAX", "RBX")  # RAX = PEBASE
GetProcAddress64 += x64.Add("RAX", 24)  # ;OPTIONAL HEADER
GetProcAddress64 += x64.Mov("ECX",
                            x64.mem("[rax + 112]"))  # ;rcx = RVA export dir
GetProcAddress64 += x64.Add("RCX", "RBX")  # ;rcx = export_dir
GetProcAddress64 += x64.Mov("RAX", "RCX")  # ;RAX = export_dir
GetProcAddress64 += x64.Push("RAX")  # ;Save it for after function search
# ; EBX = BASE | EAX = EXPORT DIR
GetProcAddress64 += x64.Mov("ECX", x64.mem("[RAX  + 24] "))
GetProcAddress64 += x64.Mov("R13", "RCX")  # ;r13 = NB names
GetProcAddress64 += x64.Mov("EDX",
                            x64.mem("[RAX  + 32] "))  # EDX = names array RVA
GetProcAddress64 += x64.Add("RDX", "RBX")  #  RDX = names array