示例#1
0
    def register_alloc_memory(self):
        ExAllocatePoolWithTag = self.kdbg.get_symbol_offset("nt!ExAllocatePoolWithTag")
        if ExAllocatePoolWithTag is None:
            raise ValueError("Could not resolve <ExAllocatePoolWithTag>")

        INPUT_BUFFER_ALLOC_TYPE = x86.mem('[ECX]')
        INPUT_BUFFER_ALLOC_SIZE = x86.mem('[ECX + 4]')
        INPUT_BUFFER_ALLOC_TAG = x86.mem('[ECX + 8]')

        Alloc_IOCTL = x86.MultipleInstr()
        Alloc_IOCTL += x86.Cmp(self.IO_STACK_INPUT_BUFFER_LEN, 0xc)
        Alloc_IOCTL += x86.Jnz(':FAIL')
        Alloc_IOCTL +=     x86.Mov('ECX', self.IO_STACK_INPUT_BUFFER)
        Alloc_IOCTL +=     x86.Mov('EBX', INPUT_BUFFER_ALLOC_TAG)
        Alloc_IOCTL +=     x86.Push('EBX')
        Alloc_IOCTL +=     x86.Mov('EBX', INPUT_BUFFER_ALLOC_SIZE)
        Alloc_IOCTL +=     x86.Push('EBX')
        Alloc_IOCTL +=     x86.Mov('EBX', INPUT_BUFFER_ALLOC_TYPE)
        Alloc_IOCTL +=     x86.Push('EBX')
        Alloc_IOCTL +=     x86.Mov('EAX', ExAllocatePoolWithTag)
        Alloc_IOCTL +=     x86.Call('EAX')
        Alloc_IOCTL +=     x86.Mov('EDX', self.IRP_OUTPUT_BUFFER)
        Alloc_IOCTL +=     x86.Mov(x86.mem('[EDX]'), 'EAX')
        Alloc_IOCTL +=     x86.Xor('EAX', 'EAX')
        Alloc_IOCTL +=     x86.Ret()
        Alloc_IOCTL += x86.Label(":FAIL")
        Alloc_IOCTL += x86.Mov('EAX', 0x0C000000D)
        Alloc_IOCTL += x86.Ret()
        self.upgrade_driver_add_new_ioctl_handler(DU_MEMALLOC_IOCTL, Alloc_IOCTL.get_code())
示例#2
0
def perform_manual_getproc_loadlib_32_for_dbg(target, dll_name):
    dll = "KERNEL32.DLL\x00".encode("utf-16-le")
    api = "LoadLibraryA\x00"
    dll_to_load = dll_name + "\x00"

    RemoteManualLoadLibray = x86.MultipleInstr()
    code = RemoteManualLoadLibray
    code += x86.Mov("ECX", x86.mem("[ESP + 4]"))
    code += x86.Push(x86.mem("[ECX + 4]"))
    code += x86.Push(x86.mem("[ECX]"))
    code += x86.Call(":FUNC_GETPROCADDRESS32")
    code += x86.Push(x86.mem("[ECX + 8]"))
    code += x86.Call("EAX")  # LoadLibrary
    code += x86.Pop("ECX")
    code += x86.Pop("ECX")
    code += x86.Ret()
    RemoteManualLoadLibray += nativeutils.GetProcAddress32

    addr = target.virtual_alloc(0x1000)
    addr2 = addr + len(dll)
    addr3 = addr2 + len(api)
    addr4 = addr3 + len(dll_to_load)
    target.write_memory(addr, dll)
    target.write_memory(addr2, api)
    target.write_memory(addr3, dll_to_load)
    target.write_qword(addr4, addr)
    target.write_qword(addr4 + 4, addr2)
    target.write_qword(addr4 + 0x8, addr3)
    t = target.execute(RemoteManualLoadLibray.get_code(), addr4)
    return t
示例#3
0
    def register_kernel_call(self):
        # expect in buffer: the address to call and all dword to push on the stack
        CCall_IOCTL = x86.MultipleInstr()
        CCall_IOCTL += x86.Mov('EAX', self.IO_STACK_INPUT_BUFFER_LEN)
        CCall_IOCTL += x86.Cmp('EAX', 0)
        CCall_IOCTL += x86.Jz(":FAIL")  # Need at least the function to call
        CCall_IOCTL += x86.Mov('ECX', self.IO_STACK_INPUT_BUFFER)
        CCall_IOCTL += x86.Label(':PUSH_NEXT_ARG')
        CCall_IOCTL += x86.Cmp('EAX', 4)
        CCall_IOCTL += x86.Jz(":DO_CALL")
        CCall_IOCTL += x86.Sub('EAX', 4)
        INPUT_BUFFER_NEXT_ARG = x86.create_displacement(base='ECX', index='EAX')
        CCall_IOCTL += x86.Mov('EBX', INPUT_BUFFER_NEXT_ARG)
        CCall_IOCTL += x86.Push('EBX')
        CCall_IOCTL += x86.Jmp(':PUSH_NEXT_ARG')
        CCall_IOCTL += x86.Label(":DO_CALL")
        CCall_IOCTL += x86.Mov('EAX', x86.mem('[ECX]'))
        CCall_IOCTL += x86.Call('EAX')

        CCall_IOCTL += x86.Mov('EDX', self.IRP_OUTPUT_BUFFER)
        CCall_IOCTL += x86.Mov(x86.mem('[EDX]'), 'EAX')
        CCall_IOCTL += x86.Xor('EAX', 'EAX')
        CCall_IOCTL += x86.Ret()
        CCall_IOCTL += x86.Label(":FAIL")
        CCall_IOCTL += x86.Mov('EAX', 0x0C000000D)
        CCall_IOCTL += x86.Ret()
        self.upgrade_driver_add_new_ioctl_handler(DU_KCALL_IOCTL, CCall_IOCTL.get_code())
示例#4
0
for library in imports.keys():
    lib = binary32.add_library(library)
    for function in imports[library].keys():
        lib.add_entry(function)

for library in imports.keys():
    for function in imports[library].keys():
        imports[library][function] = binary32.predict_function_rva(
            library, function) + binary32.optional_header.imagebase

code = x86.MultipleInstr()
code += x86.Mov("EBP", "ESP")
code += x86.Sub("ESP", 0x100)
# GetStdHandle(STD_OUTPUT_HANDLE)
code += x86.Push(STD_OUTPUT_HANDLE)
code += x86.Call(call_import(imports["kernel32.dll"]["GetStdHandle"]))
# WriteFile(eax, welcome, len_welcome, &esp+8, 0)
code += x86.Lea("EDI", x86.mem("[ESP + 0x8]"))
code += x86.Push(0)
code += x86.Push("EDI")
code += x86.Push(len(welcome))
code += x86.Push(data[welcome])
code += x86.Push("EAX")  # hConsoleOutput
code += x86.Call(call_import(imports["kernel32.dll"]["WriteFile"]))
# GetStdHandle(STD_INPUT_HANDLE)
code += x86.Push(STD_INPUT_HANDLE)
code += x86.Call(call_import(imports["kernel32.dll"]["GetStdHandle"]))
# ReadFile(eax, &esp+80, 0x50, &esp+8, 0)
code += x86.Lea("EBX", x86.mem("[ESP + 0x80]"))
code += x86.Push(0)
示例#5
0
def hook_ntcreatefile(kdbg, ignore_jump_space_check=False):
    """Hook NtCreateFile, the hook write the filename to a shared memory page"""
    nt_create_file = kdbg.resolve_symbol("nt!NtCreateFile")
    if not ignore_jump_space_check:
        # Check that function begin with mov edi, edi for the hook short jump
        if kdbg.read_word(nt_create_file) != 0xff8b:  # mov edi, edi
            print(hex(kdbg.read_word(nt_create_file)))
            raise ValueError(
                "Cannot hook fonction that doest not begin with <mov edi,edi> (/f to force if hook already in place)"
            )
        # Check there is 5 bytes free before for the hook long jump
        if kdbg.read_virtual_memory(nt_create_file - 5,
                                    5) not in ["\x90" * 5, "\xCC" * 5
                                               ]:  #NOP * 5 ; INT 3 * 5
            print(kdbg.read_virtual_memory(nt_create_file - 5, 5))
            raise ValueError(
                "Cannot hook fonction that is not prefixed with 5 nop/int 3")

    # Allocate memory for the shared buffer kernel<->user
    # the format is:
    # [addr] -> size of size already taken
    # then:
    #   DWORD string_size
    #   char[string_size] filename
    data_kernel_addr = kdbg.alloc_memory(0x1000)
    kdbg.write_pfv_memory(data_kernel_addr, "\x00" * 0x1000)
    # Map the shared buffer to userland
    data_user_addr = kdbg.map_page_to_userland(data_kernel_addr, 0x1000)
    # Allocate memory for the hook
    shellcode_addr = kdbg.alloc_memory(0x1000)
    # shellcode
    shellcode = x86.MultipleInstr()
    # Save register
    shellcode += x86.Push('EAX')
    shellcode += x86.Push('ECX')
    shellcode += x86.Push('EDI')
    shellcode += x86.Push('ESI')
    # Check that there is space remaining, else don't write it
    shellcode += x86.Cmp(x86.deref(data_kernel_addr), 0x900)
    shellcode += x86.Jnb(":END")
    # Get 3rd arg (POBJECT_ATTRIBUTES ObjectAttributes)
    shellcode += x86.Mov('EAX', x86.mem('[ESP + 0x1c]'))  # 0xc + 0x10 for push
    # Get POBJECT_ATTRIBUTES.ObjectName (PUNICODE_STRING)
    shellcode += x86.Mov('EAX', x86.mem('[EAX + 0x8]'))
    shellcode += x86.Xor('ECX', 'ECX')
    # Get PUNICODE_STRING.Length
    shellcode += x86.Mov('CX', x86.mem('[EAX + 0]'))
    # Get PUNICODE_STRING.Buffer
    shellcode += x86.Mov('ESI', x86.mem('[EAX + 4]'))
    # Get the next free bytes in shared buffer
    shellcode += x86.Mov('EDI', data_kernel_addr + 4)
    shellcode += x86.Add('EDI', x86.deref(data_kernel_addr))
    # Write (DWORD string_size) in our 'struct'
    shellcode += x86.Mov(x86.mem('[EDI]'), 'ECX')
    # update size taken in shared buffer
    shellcode += x86.Add(x86.deref(data_kernel_addr), 'ECX')
    shellcode += x86.Add(x86.deref(data_kernel_addr), 4)
    # Write (char[string_size] filename) in our 'struct'
    shellcode += x86.Add('EDI', 4)
    shellcode += x86.Rep + x86.Movsb()
    shellcode += x86.Label(":END")
    # Restore buffer
    shellcode += x86.Pop('ESI')
    shellcode += x86.Pop('EDI')
    shellcode += x86.Pop('ECX')
    shellcode += x86.Pop('EAX')
    # Jump to NtCreateFile
    shellcode += x86.JmpAt(nt_create_file + 2)

    # Write shellcode
    kdbg.write_pfv_memory(shellcode_addr, shellcode.get_code())
    long_jump = x86.Jmp(shellcode_addr - (nt_create_file - 5))
    # Write longjump to shellcode
    kdbg.write_pfv_memory(nt_create_file - 5, long_jump.get_code())
    # Write shortjump  NtCreateFile -> longjump
    short_jmp = x86.Jmp(-5)
    kdbg.write_pfv_memory(nt_create_file, short_jmp.get_code())
    # Return address of shared buffer in userland
    return data_user_addr
GetProcAddress64 += x64.Label(":DLL_NOT_FOUND")
GetProcAddress64 += x64.Mov("RAX", 0xfffffffffffffffe)
GetProcAddress64 += x64.Jmp(":RETURN")
GetProcAddress64 += x64.Label(":API_NOT_FOUND")
GetProcAddress64 += x64.Pop("RAX")
GetProcAddress64 += x64.Mov("RAX", 0xffffffffffffffff)
GetProcAddress64 += x64.Jmp(":RETURN")
# Ajout des dependances
GetProcAddress64 += StrlenW64
GetProcAddress64 += StrlenA64

###### 32 bits #######

StrlenW32 = x86.MultipleInstr()
StrlenW32 += x86.Label(":FUNC_STRLENW32")
StrlenW32 += x86.Push("EDI")
StrlenW32 += x86.Mov("EDI", x86.mem("[ESP + 8]"))
StrlenW32 += x86.Push("ECX")
StrlenW32 += x86.Xor("EAX", "EAX")
StrlenW32 += x86.Xor("ECX", "ECX")
StrlenW32 += x86.Dec("ECX")
StrlenW32 += x86.Repne + x86.ScasW()
StrlenW32 += x86.Not("ECX")
StrlenW32 += x86.Dec("ECX")
StrlenW32 += x86.Mov("EAX", "ECX")
StrlenW32 += x86.Pop("ECX")
StrlenW32 += x86.Pop("EDI")
StrlenW32 += x86.Ret()

StrlenA32 = x86.MultipleInstr()
StrlenA32 += x86.Label(":FUNC_STRLENA32")