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最后几行。
- Github-ioctlfuzzer&ioctlbf
- github
- github
- github
- GitHub
- github
- GitHub
- GitHub
- github
- github
- github
- github
- GitHub
- GitHub
- Github
- github
- github
- github
- 数据结构实验之查找三:树的种类统计
- sdk修改时需要注意
- BZOJ3673 可持久化并查集 by zky <可持久化数组+主席树>
- community declares a dependency from configuration 'compile' to configuration 'default' which is not
- Java消息队列--JMS概述
- Github-ioctlfuzzer&ioctlbf
- Memcached、Redis以及Memcached与Redis的区别
- mysql分库分表实战及php代码操作完整实例
- bootstrapValidator 中文API
- 关于module.exports与exports
- HDU 6103 Kirinriki 【dp】
- 针对 dash3 license 破解 dash4
- 【linux相识相知】独立硬盘冗余阵列-RAID
- Laravel 速查 5.2