Github-ioctlfuzzer&ioctlbf

来源:互联网 发布:android直播软件源码 编辑:程序博客网 时间:2024/06/02 03:02

最近做二进制安全研究实习生,主要看的东西是驱动,在Github上发现了款做Fuzz的工具,适用场景说大不大,说小不小。因为它支持的系统只到Windows7(x86+x64)。但是漏洞挖掘嘛,Fuzz还是很重要的,有源码自然要看看了,学习下前辈们的Fuzz方法
大部分的记录我都是直接标记在了源码中,有兴趣的可以直接在我的Github上Clone或者Fork<请务必先仔细看Readme.md>都行,这里放出的只是在看源码中遇见的一些比较重要的问题
由于编码的原因,所以都是英文记录,英语渣,凑合看吧
Github:https://github.com/Iolop/ioctlfuzzer

Important Funtion src\driver\src\driver.cpp

  • KernelGetModuleBase src\driver\src\r0_common\common.cpp
  • KernelGetExportAddress
  • KeAddSystemServiceTable

    seems like an interesting function. Not sure how does this routine works , here is its assembly code.a way to find ssdt in x64 platform

kd> uf nt!KeAddSystemServiceTablent!KeAddSystemServiceTable:83dc40f2 8bff            mov     edi,edi83dc40f4 55              push    ebp83dc40f5 8bec            mov     ebp,esp // create stack,but no sub esp??83dc40f7 837d1801        cmp     dword ptr [ebp+18h],183dc40fb 7760            ja      nt!KeAddSystemServiceTable+0x6b (83dc415d)  Branch <END>nt!KeAddSystemServiceTable+0xb:83dc40fd 8b4518          mov     eax,dword ptr [ebp+18h]83dc4100 c1e004          shl     eax,483dc4103 83b8c009da8300  cmp     dword ptr nt!KeServiceDescriptorTable (83da09c0)[eax],083dc410a 7551            jne     nt!KeAddSystemServiceTable+0x6b (83dc415d)  Branchnt!KeAddSystemServiceTable+0x1a:                                                            Check the instructions before and the valid address83dc410c 8d88000ada83    lea     ecx,nt!KeServiceDescriptorTableShadow (83da0a00)[eax]83dc4112 833900          cmp     dword ptr [ecx],083dc4115 7546            jne     nt!KeAddSystemServiceTable+0x6b (83dc415d)  Branchnt!KeAddSystemServiceTable+0x25:83dc4117 837d1801        cmp     dword ptr [ebp+18h],183dc411b 8b5508          mov     edx,dword ptr [ebp+8]83dc411e 56              push    esi83dc411f 8b7510          mov     esi,dword ptr [ebp+10h]83dc4122 57              push    edi83dc4123 8b7d14          mov     edi,dword ptr [ebp+14h]83dc4126 8911            mov     dword ptr [ecx],edx83dc4128 8b4d0c          mov     ecx,dword ptr [ebp+0Ch]83dc412b 8988040ada83    mov     dword ptr nt!KeServiceDescriptorTableShadow+0x4 (83da0a04)[eax],ecx83dc4131 89b0080ada83    mov     dword ptr nt!KeServiceDescriptorTableShadow+0x8 (83da0a08)[eax],esi83dc4137 89b80c0ada83    mov     dword ptr nt!KeServiceDescriptorTableShadow+0xc (83da0a0c)[eax],edi83dc413d 7418            je      nt!KeAddSystemServiceTable+0x65 (83dc4157)  Branchnt!KeAddSystemServiceTable+0x4d:83dc413f 8990c009da83    mov     dword ptr nt!KeServiceDescriptorTable (83da09c0)[eax],edx83dc4145 8988c409da83    mov     dword ptr nt!KeServiceDescriptorTable+0x4 (83da09c4)[eax],ecx83dc414b 89b0c809da83    mov     dword ptr nt!KeServiceDescriptorTable+0x8 (83da09c8)[eax],esi83dc4151 89b8cc09da83    mov     dword ptr nt!KeServiceDescriptorTable+0xc (83da09cc)[eax],edint!KeAddSystemServiceTable+0x65:83dc4157 5f              pop     edi83dc4158 b001            mov     al,183dc415a 5e              pop     esi83dc415b eb02            jmp     nt!KeAddSystemServiceTable+0x6d (83dc415f)  Branchnt!KeAddSystemServiceTable+0x6b:83dc415d 32c0            xor     al,alnt!KeAddSystemServiceTable+0x6d:83dc415f 5d              pop     ebp83dc4160 c21400          ret     14h
  • SetUpHooks-Hook x64 platform src\driver\src

    Keep walking in this file, I found this tool seems store fuzz options in register
    It contains three functions

    • SaveFuzzerOptions
    • DeleteSavedFuzzerOptions
    • LoadFuzzerOptions
  • DriverDispatch

    most important and complicated

NTSTATUS DriverDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp){    PIO_STACK_LOCATION stack;    NTSTATUS ns = STATUS_SUCCESS;    Irp->IoStatus.Status = ns;    Irp->IoStatus.Information = 0;    stack = IoGetCurrentIrpStackLocation(Irp);    if (stack->MajorFunction == IRP_MJ_DEVICE_CONTROL)    {        ULONG Code = stack->Parameters.DeviceIoControl.IoControlCode;               ULONG Size = stack->Parameters.DeviceIoControl.InputBufferLength;        PREQUEST_BUFFER Buff = (PREQUEST_BUFFER)Irp->AssociatedIrp.SystemBuffer;   #ifdef DBG_IO        DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): IRP_MJ_DEVICE_CONTROL 0x%.8x\n", Code);#endif        Irp->IoStatus.Information = Size;        switch (Code)        {        case IOCTL_DRV_CONTROL:            {                Buff->Status = S_ERROR;                if (Size >= sizeof(REQUEST_BUFFER))//inputBufferLength >= struct<REQUEST_BUFFER>                {                    ULONG KdCommandLength = 0;                    IOCTL_FILTER Flt;                                       RtlZeroMemory(&Flt, sizeof(Flt));                    if (Buff->AddObject.bDbgcbAction && Size > sizeof(REQUEST_BUFFER))                    {                        // check for zero byte at the end of the string                        if (Buff->Buff[Size - sizeof(REQUEST_BUFFER) - 1] != 0)                        {                                     goto _bad_addobj_request;                        }                        // debugger command available                        KdCommandLength = strlen(Buff->Buff) + 1;                    }                    switch (Buff->Code)                    {                    case C_ADD_DRIVER:                    case C_ADD_DEVICE:                    case C_ADD_PROCESS:                    case C_ADD_IOCTL:                        {                            // check for zero byte at the end of the string                            if (Buff->AddObject.szObjectName[MAX_REQUEST_STRING - 1] != 0)                            {                                         goto _bad_addobj_request;                            }                            if (Buff->Code == C_ADD_IOCTL)                            {                                Flt.IoctlCode = Buff->AddObject.IoctlCode;                            }                            else                            {                                ANSI_STRING asName;                                RtlInitAnsiString(                                    &asName,                                    Buff->AddObject.szObjectName                                );                                NTSTATUS status = RtlAnsiStringToUnicodeString(&Flt.usName, &asName, TRUE);                                if (!NT_SUCCESS(status))                                {                                    DbgMsg(__FILE__, __LINE__, "RtlAnsiStringToUnicodeString() fails; status: 0x%.8x\n", status);                                    goto _bad_addobj_request;                                }                            }                                                       switch (Buff->Code)                            {                            case C_ADD_DRIVER:                                // filter by driver file name/path                                Flt.Type = FLT_DRIVER_NAME;                                break;                            case C_ADD_DEVICE:                                // filter by device name                                Flt.Type = FLT_DEVICE_NAME;                                break;                            case C_ADD_PROCESS:                                // filter by caller process executable file name/path                                Flt.Type = FLT_PROCESS_PATH;                                break;                            case C_ADD_IOCTL:                                // filter by IOCTL control code value                                Flt.Type = FLT_IOCTL_CODE;                                break;                            }                               KeWaitForMutexObject(&m_CommonMutex, Executive, KernelMode, FALSE, NULL);                            __try                            {                                PIOCTL_FILTER f_entry = NULL;                                if (Buff->AddObject.bDbgcbAction)                                {                                    // add rule into the debugger commands list                                    if (f_entry = FltDbgcbAdd(&Flt, KdCommandLength))                                    {                                        Buff->Status = S_SUCCESS;                                        if (!m_bEnableDbgcb)                                        {                                            // try to reload symbols                                            if (dbg_exec(".reload"))                                            {                                                // kernel debugger communication engine is available and initialized                                                m_bEnableDbgcb = TRUE;                                            }                                                                   else                                            {                                                DbgMsg(                                                    __FILE__, __LINE__,                                                    __FUNCTION__"(): Kernel debugger interaction is not available\n"                                                );                                            }                                        }                                                                           }                                }                                else if (Buff->AddObject.bAllow)                                {                                    // add filter rule into the ALLOW list                                    if (f_entry = FltAllowAdd(&Flt, KdCommandLength))                                    {                                        Buff->Status = S_SUCCESS;                                    }                                }                                   else                                {                                    // add filter rule into the DENY list                                    if (f_entry = FltDenyAdd(&Flt, KdCommandLength))                                    {                                        Buff->Status = S_SUCCESS;                                    }                                }                                if (f_entry)                                {                                    f_entry->bDbgcbAction = Buff->AddObject.bDbgcbAction;                                    if (KdCommandLength > 0)                                    {                                        strcpy(f_entry->szKdCommand, Buff->Buff);                                        if (Buff->Code == C_ADD_IOCTL)                                        {                                            DbgPrint(                                                "<?dml?>" __FUNCTION__ "(): ControlCode=0x%.8x KdCommand=<exec cmd=\"%s\">%s</exec>\n",                                                f_entry->IoctlCode, f_entry->szKdCommand, f_entry->szKdCommand                                            );                                        }                                        else                                        {                                            DbgPrint(                                                "<?dml?>" __FUNCTION__ "(): Object=\"%wZ\" KdCommand=<exec cmd=\"%s\">%s</exec>\n",                                                &f_entry->usName, f_entry->szKdCommand, f_entry->szKdCommand                                            );                                        }                                    }                                }                            }                               __finally                            {                                KeReleaseMutex(&m_CommonMutex, FALSE);                            }                               if (Buff->Status != S_SUCCESS &&                                Buff->Code != C_ADD_IOCTL)                            {                                RtlFreeUnicodeString(&Flt.usName);                            }_bad_addobj_request:                            break;                        }                    case C_DEL_OPTIONS:                        {                            DeleteSavedFuzzerOptions();                            break;                        }                                       case C_SET_OPTIONS:                        {                            KeWaitForMutexObject(&m_CommonMutex, Executive, KernelMode, FALSE, NULL);                               __try                            {                                m_FuzzOptions = Buff->Options.Options;                                if (!(m_FuzzOptions & FUZZ_OPT_NO_SDT_HOOKS))                                {                                    // hook nt!NtDeviceIoControlFile() syscall                                    m_bHooksInitialized = SetUpHooks();                                }                                if (!(m_FuzzOptions & FUZZ_OPT_LOG_IOCTL_GLOBAL) && m_hIoctlsLogFile)                                {                                    ZwClose(m_hIoctlsLogFile);                                    m_hIoctlsLogFile = NULL;                                    DbgMsg(__FILE__, __LINE__, "[+] IOCTLs log closed \"%wZ\"\n", &m_usIoctlsLogFilePath);                                }                                m_FuzzingType = Buff->Options.FuzzingType;                                m_UserModeData = Buff->Options.UserModeData;#ifdef _X86_                                m_FuzzThreadId = (HANDLE)Buff->Options.FuzzThreadId;#elif _AMD64_                                PLARGE_INTEGER FuzzThreadId = (PLARGE_INTEGER)&m_FuzzThreadId;                                FuzzThreadId->HighPart = 0;                                FuzzThreadId->LowPart = Buff->Options.FuzzThreadId;#endif                                                                 if (m_FuzzOptions & FUZZ_OPT_FUZZ_BOOT)                                {                                    // fair fizzing is not available in the boot fuzzing mode                                    m_FuzzOptions &= ~FUZZ_OPT_FUZZ_FAIR;                                    // boot fuzzing mode has been enabled                                    SaveFuzzerOptions();                                    m_FuzzOptions = 0;                                }                                else                                {                                    DeleteSavedFuzzerOptions();                                }                                if ((m_FuzzOptions & FUZZ_OPT_LOG_EXCEPTIONS) &&                                    Buff->Options.KiDispatchException_Offset > 0)                                {                                    // ofsset of unexported function for exceptions monitoring                                    m_KiDispatchException_Offset = Buff->Options.KiDispatchException_Offset;                                    if (!m_bKiDispatchExceptionHooked)                                    {                                        // set up hooks for exception monitoring                                        m_bKiDispatchExceptionHooked = ExcptHook();                                    }                                    m_bLogExceptions = TRUE;                                }                                                           else                                {                                    m_bLogExceptions = FALSE;                                }                                Buff->Status = S_SUCCESS;                            }                                                       __finally                            {                                KeReleaseMutex(&m_CommonMutex, FALSE);                            }                                                       break;                        }                    case C_GET_DEVICE_INFO:                        {                            // check for zero byte at the end of the string                            if (Size > sizeof(REQUEST_BUFFER) &&                                Buff->Buff[Size - sizeof(REQUEST_BUFFER) - 1] == 0)                            {                                         ANSI_STRING asDeviceName;                                UNICODE_STRING usDeviceName;                                RtlInitAnsiString(                                    &asDeviceName,                                    Buff->Buff                                );                                NTSTATUS status = RtlAnsiStringToUnicodeString(&usDeviceName, &asDeviceName, TRUE);                                if (NT_SUCCESS(status))                                {                                    // open disk device object                                    PDEVICE_OBJECT TargetDeviceObject = NULL;                                    PFILE_OBJECT TargetFileObject = NULL;#ifdef USE_IoGetDeviceObjectPointer                                    status = IoGetDeviceObjectPointer(                                        &usDeviceName,                                        GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,                                        &TargetFileObject,                                        &TargetDeviceObject                                    );                                    if (NT_SUCCESS(status))     #else                                    if (TargetFileObject = GetDeviceObjectPointer(&usDeviceName))                                    {                                        TargetDeviceObject = TargetFileObject->DeviceObject;                                    }                                    if (TargetFileObject)#endif                                    {                                        // pass device object information to the caller                                        Buff->DeviceInfo.DeviceObjectAddr = TargetDeviceObject;                                        if (TargetDeviceObject->DriverObject)                                        {                                            Buff->DeviceInfo.DriverObjectAddr = TargetDeviceObject->DriverObject;                                            // get driver object name by pointer                                            POBJECT_NAME_INFORMATION NameInfo = GetObjectName(TargetDeviceObject->DriverObject);                                            if (NameInfo)                                            {                                                ANSI_STRING asDriverName;                                                status = RtlUnicodeStringToAnsiString(&asDriverName, &NameInfo->Name, TRUE);                                                if (NT_SUCCESS(status))                                                {                                                    strncpy(                                                        Buff->DeviceInfo.szDriverObjectName,                                                        asDriverName.Buffer,                                                        min(MAX_REQUEST_STRING - 1, asDriverName.Length)                                                    );                                                    RtlFreeAnsiString(&asDriverName);                                                }                                                else                                                {                                                    DbgMsg(__FILE__, __LINE__, "RtlUnicodeStringToAnsiString() fails; status: 0x%.8x\n", status);                                                                                               }                                                ExFreePool(NameInfo);                                            }                                            // get loader information entry for the driver                                            PLDR_DATA_TABLE_ENTRY pModuleEntry = (PLDR_DATA_TABLE_ENTRY)                                                TargetDeviceObject->DriverObject->DriverSection;                                            if (pModuleEntry &&                                                MmIsAddressValid(pModuleEntry) &&                                                ValidateUnicodeString(&pModuleEntry->FullDllName))                                            {                                                ANSI_STRING asDllName;                                                status = RtlUnicodeStringToAnsiString(&asDllName, &pModuleEntry->FullDllName, TRUE);                                                if (NT_SUCCESS(status))                                                {                                                    strncpy(                                                        Buff->DeviceInfo.szDriverFilePath,                                                        asDllName.Buffer,                                                        min(MAX_REQUEST_STRING - 1, asDllName.Length)                                                    );                                                    RtlFreeAnsiString(&asDllName);                                                }                                                else                                                {                                                    DbgMsg(__FILE__, __LINE__, "RtlUnicodeStringToAnsiString() fails; status: 0x%.8x\n", status);                                                                                               }                                            }                                            Buff->Status = S_SUCCESS;                                        }                                                                         ObDereferenceObject(TargetFileObject);                                    }#ifdef USE_IoGetDeviceObjectPointer                                    else                                    {                                        DbgMsg(                                            __FILE__, __LINE__,                                            "IoGetDeviceObjectPointer() fails for \"%wZ\", status: 0x%.8x\n",                                            &usDeviceName, status                                        );                                                                                   }#endif                                    RtlFreeUnicodeString(&usDeviceName);                                         }                                else                                {                                    DbgMsg(__FILE__, __LINE__, "RtlAnsiStringToUnicodeString() fails; status: 0x%.8x\n", status);                                }                            }                            break;                        }                    case C_GET_OBJECT_NAME:                        {                            PFILE_OBJECT pFileObject = NULL;                            NTSTATUS ns = ObReferenceObjectByHandle(                                Buff->ObjectName.hObject,                                0,                                *IoFileObjectType,                                KernelMode,                                (PVOID *)&pFileObject,                                NULL                            );                            if (NT_SUCCESS(ns))                            {                                if (pFileObject->DeviceObject)                                {                                    // get name of the object                                    POBJECT_NAME_INFORMATION NameInfo = GetObjectName(pFileObject->DeviceObject);                                    if (NameInfo)                                    {                                                               ANSI_STRING asName;                                        ns = RtlUnicodeStringToAnsiString(&asName, &NameInfo->Name, TRUE);                                        if (NT_SUCCESS(ns))                                        {                                            strncpy(                                                Buff->ObjectName.szObjectName,                                                asName.Buffer,                                                min(MAX_REQUEST_STRING - 1, asName.Length)                                            );                                            Buff->Status = S_SUCCESS;                                            RtlFreeAnsiString(&asName);                                        }                                        else                                        {                                            DbgMsg(__FILE__, __LINE__, "RtlUnicodeStringToAnsiString() fails; status: 0x%.8x\n", ns);                                        }                                        M_FREE(NameInfo);                                    }                                }                                ObDereferenceObject(pFileObject);                            }                            else                            {                                DbgMsg(__FILE__, __LINE__, "ObReferenceObjectByHandle() fails; status: 0x%.8x\n", ns);                            }                                             break;                        }                    case C_CHECK_HOOKS:                        {                            if (m_bKiDispatchExceptionHooked ||                                m_bHooksInitialized)                            {                                Buff->CheckHooks.bHooksInstalled = TRUE;                            }                            else                            {                                Buff->CheckHooks.bHooksInstalled = FALSE;                            }                            break;                        }                    }                }                break;            }                   default:            {                ns = STATUS_INVALID_DEVICE_REQUEST;                Irp->IoStatus.Information = 0;                break;            }                   }    }    else if (stack->MajorFunction == IRP_MJ_CREATE)    {        DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): IRP_MJ_CREATE\n");#ifdef DBGPIPE        DbgOpenPipe();#endif        KeWaitForMutexObject(&m_CommonMutex, Executive, KernelMode, FALSE, NULL);        __try        {            // delete all filter rules            FltAllowFlushList();            FltDenyFlushList();            FltDbgcbFlushList();            m_FuzzProcess = PsGetCurrentProcess();            ObReferenceObject(m_FuzzProcess);        }               __finally        {            KeReleaseMutex(&m_CommonMutex, FALSE);        }           }    else if (stack->MajorFunction == IRP_MJ_CLOSE)    {        DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): IRP_MJ_CLOSE\n");               KeWaitForMutexObject(&m_CommonMutex, Executive, KernelMode, FALSE, NULL);           __try        {            // delete all filter rules            FltAllowFlushList();            FltDenyFlushList();            FltDbgcbFlushList();            m_FuzzOptions = 0;            if (m_FuzzProcess)            {                ObDereferenceObject(m_FuzzProcess);                m_FuzzProcess = NULL;            }        }        __finally        {            KeReleaseMutex(&m_CommonMutex, FALSE);        }               #ifdef DBGPIPE        DbgClosePipe();#endif        if (m_hIoctlsLogFile)        {            ZwClose(m_hIoctlsLogFile);            m_hIoctlsLogFile = NULL;            DbgMsg(__FILE__, __LINE__, "[+] IOCTLs log closed \"%wZ\"\n", &m_usIoctlsLogFilePath);        }    }    if (ns != STATUS_PENDING)    {               Irp->IoStatus.Status = ns;        IoCompleteRequest(Irp, IO_NO_INCREMENT);    }    return ns;}

After fixing the path,i get sys file. But when I run the ioctlfuzzer.exe in Win7 x86,it seems this exe autoload sys!
What…?
Found a piece of code in ioctlfuzzer.cpp,it could release resources.Fuxx.

Seems this exe only load the driver and set it on boot mode.So the DriverDispatch() is the actually fuzzer function.

Ring3:

  • DrvDeviceRequest()-DeviceIoControl(IOCTL_DRV_CONTROL)
    这里写图片描述
    这里写图片描述

In DriverDispatch()
A important struct REQUEST_BUFFER

typedef struct _REQUEST_BUFFER{    // operation status (see S_* definitions)    ULONG Status;    // operation code (see C_* definitions)    ULONG Code;    union    {        struct        {            ULONG Options;            ULONG FuzzThreadId;            FUZZING_TYPE FuzzingType;            PUSER_MODE_DATA UserModeData;            ULONG KiDispatchException_Offset;        } Options;        struct        {            PVOID DeviceObjectAddr;            PVOID DriverObjectAddr;            char szDriverObjectName[MAX_REQUEST_STRING];            char szDriverFilePath[MAX_REQUEST_STRING];        } DeviceInfo;        struct        {            // for C_ADD_IOCTL            ULONG IoctlCode;            // for all C_ADD_*            BOOLEAN bAllow;            // for C_ADD_DEVICE,  C_ADD_DRIVER and C_ADD_PROCESS            char szObjectName[MAX_REQUEST_STRING];            /*                If TRUE -- debugger command, that stored in Buff[],                must be executed for every IOCTL, that has been matched                by this object.            */            BOOLEAN bDbgcbAction;        } AddObject;        struct        {            HANDLE hObject;            char szObjectName[MAX_REQUEST_STRING];        } ObjectName;        struct        {            BOOLEAN bHooksInstalled;        } CheckHooks;    };       
  • ParseAllowDenySection() src\application\src\ioctlfuzzer.cpp

This function create the REQUEST_BUFFER in ring3 and complete it.


I was wrong,DriverDispatch() just check the options,
Fuzz function is here.

  • new_NtDeviceControlFile()
  • Fuzz_NtDeviceIoControlFile()
  • FuzzContinue_NtDeviceIoControlFile()—this is the real fuzz function
//--------------------------------------------------------------------------------------void FuzzContinue_NtDeviceIoControlFile(    KPROCESSOR_MODE PrevMode,    HANDLE FileHandle,    HANDLE Event,    PIO_APC_ROUTINE ApcRoutine,    PVOID ApcContext,    PIO_STATUS_BLOCK IoStatusBlock,    ULONG IoControlCode,    PVOID InputBuffer,    ULONG InputBufferLength,    PVOID OutputBuffer,    ULONG OutputBufferLength){                           // allocate temporary buffer for original request    PUCHAR NewBuff = (PUCHAR)M_ALLOC(InputBufferLength);    if (NewBuff)    {        RtlCopyMemory(NewBuff, InputBuffer, InputBufferLength);        if (m_FuzzingType == FuzzingType_Random)        {            /**            * Fuzzing with random values            */            for (int i = 0; i < RANDOM_FUZZING_ITERATIONS; i++)            {                ULONG TmpInputLength = InputBufferLength;                if (m_FuzzOptions & FUZZ_OPT_FUZZ_SIZE)                {                    TmpInputLength = getrand(1, TmpInputLength * 4);                }                // fill buffer with random data                for (ULONG s = 0; s < InputBufferLength; s++)                {                    *((PUCHAR)InputBuffer + s) = (UCHAR)getrand(1, 0xff);                }                // change previous mode to UserMode                SetPreviousMode(PrevMode);//why here?                // send fuzzed request                NTSTATUS status = old_NtDeviceIoControlFile(                    FileHandle,                    Event, ApcRoutine,                    ApcContext,                    IoStatusBlock,                    IoControlCode,                    InputBuffer,                    TmpInputLength,                    OutputBuffer,                    OutputBufferLength                );            }        }        else if (m_FuzzingType == FuzzingType_Dword)        {                         /**            * Fuzzing with predefined dwords            */            // check buffer length            ULONG FuzzingLength = XALIGN_DOWN(InputBufferLength, sizeof(ULONG));            if (FuzzingLength <= DWORD_FUZZING_MAX_LENGTH && FuzzingLength >= sizeof(ULONG))            {                // fuzz each dword value in input buffer                for (ULONG i = 0; i < FuzzingLength; i += DWORD_FUZZING_DELTA)                {                    for (ULONG i_v = 0; i_v < sizeof(m_DwordFuzzingConstants) / sizeof(ULONG); i_v++)                    {                                               // put dword constant into the buffer                        ULONG OldBuffVal = *(PULONG)((PUCHAR)InputBuffer + i);                        *(PULONG)((PUCHAR)InputBuffer + i) = m_DwordFuzzingConstants[i_v];                                               // set previous mode to UserMode                        SetPreviousMode(PrevMode);                        // send fuzzed request                        NTSTATUS status = old_NtDeviceIoControlFile(                            FileHandle,                            Event, ApcRoutine,                            ApcContext,                            IoStatusBlock,                            IoControlCode,                            InputBuffer,                            InputBufferLength,                            OutputBuffer,                            OutputBufferLength                        );                        // restore changed dword                        *(PULONG)((PUCHAR)InputBuffer + i) = OldBuffVal;                                           }                }            }        }        // restore buffer        RtlCopyMemory(InputBuffer, NewBuff, InputBufferLength);               ExFreePool(NewBuff);    }    else    {        DbgMsg(__FILE__, __LINE__, "M_ALLOC() ERROR\n");    }    // try to fuzz missing output buffer length checks    if (OutputBufferLength > 0)    {               // ... with user-mode buffer addresses        PVOID TmpOutputBuffer = USER_BUFFER_ADDRESS;        // set previous mode to UserMode        SetPreviousMode(PrevMode);        // send fuzzed request        NTSTATUS status = old_NtDeviceIoControlFile(            FileHandle,            Event, ApcRoutine,            ApcContext,            IoStatusBlock,            IoControlCode,            InputBuffer,            InputBufferLength,            TmpOutputBuffer, 0        );               // ... with kernel-mode buffer addresses        TmpOutputBuffer = KERNEL_BUFFER_ADDRESS;        // set previous mode to UserMode        SetPreviousMode(PrevMode);        // send fuzzed request        status = old_NtDeviceIoControlFile(            FileHandle,            Event, ApcRoutine,            ApcContext,            IoStatusBlock,            IoControlCode,            InputBuffer,            InputBufferLength,            TmpOutputBuffer, 0        );    }    ULONG Method = IoControlCode & 3;    if (Method != METHOD_BUFFERED)    {        // try to fuzz buffer addresses, if method is not buffered        for (int i = 0; i < BUFFERED_FUZZING_ITERATIONS; i++)        {            // ... with user-mode addresses            PVOID TmpInputBuffer  = USER_BUFFER_ADDRESS;            PVOID TmpOutputBuffer = USER_BUFFER_ADDRESS;            ULONG TmpInputBufferLength  = getrand(0, 0x100);            ULONG TmpOutputBufferLength = getrand(0, 0x100);            // set previous mode to UserMode            SetPreviousMode(PrevMode);            // send fuzzed request            NTSTATUS status = old_NtDeviceIoControlFile(                FileHandle,                Event, ApcRoutine,                ApcContext,                IoStatusBlock,                IoControlCode,                TmpInputBuffer,                TmpInputBufferLength,                TmpOutputBuffer,                TmpOutputBufferLength            );        }        for (int i = 0; i < BUFFERED_FUZZING_ITERATIONS; i++)        {            // ... with kernel-mode addresses            PVOID TmpInputBuffer  = KERNEL_BUFFER_ADDRESS;            PVOID TmpOutputBuffer = KERNEL_BUFFER_ADDRESS;            ULONG TmpInputBufferLength  = getrand(0, 0x100);            ULONG TmpOutputBufferLength = getrand(0, 0x100);            // change previous mode to UserMode            SetPreviousMode(PrevMode);            // send fuzzed request            NTSTATUS status = old_NtDeviceIoControlFile(                FileHandle,                Event,                ApcRoutine,                ApcContext,                IoStatusBlock,                IoControlCode,                TmpInputBuffer,                TmpInputBufferLength,                TmpOutputBuffer,                TmpOutputBufferLength            );        }    }}

After hooking the nt!NtDeviceIoControlFile,new_NtDeviceControlFile()
takes place of it,and it calls FuzzContinue_NtDeviceIoControlFile().

As u see,it will generate random buffer and length.


However,there is a bad news. DeviceIoControlFile() is deprecated and replaced by DeviceIoControl(), which means we need to hook it. So,we need to re-compile the source code to get a new sys&exe file.


既然DeviceIoControlFile()已经被标记废弃,想继续使用这要工具就得自己修改源码来hook DeviceIoCotrol(),hook之后是拦截正常通信,来修改我们的buffer区域,换一个思路,我们也可直接和一个有Symbol name的对象通信,只不过这样就需要我们自己来测试或者拦截到可能的参数(ex:ControlCode BufferSize),所以想要直接通信,我们还需要其他的工具,具体的请参照此仓库https://github.com/koutto/ioctlbf中的Readme.md最后几行。

原创粉丝点击