Modifying Security Descriptor to Protect Processes in Windows

Listen to this Post

In this article, we explore how to modify the Security Descriptor of a running process in Windows to control access and enhance security. This technique uses Security Descriptor Definition Language (SDDL) to define permissions and applies them via Windows API functions. The goal is to restrict access to the process, making it harder for debuggers, task managers, or security tools to interact with it.

Proof of Concept (PoC):

PoC Link

How It Works:

The process involves setting a restrictive Discretionary Access Control List (DACL) on the running process. This DACL denies access to everyone (WD) except the System (SY) and the Owner (OW). By doing so, other processes—such as debuggers (e.g., OllyDbg, x64dbg) or task managers—are prevented from opening a handle to your process using OpenProcess.

Practical Applications:

  • Malware and C2 Agents: This technique can be used to ensure persistence and resist termination by endpoint detection and response (EDR) systems or manual intervention. It ensures uninterrupted communication with the attacker’s server.
  • Red Teaming: Useful for maintaining control over processes during offensive operations.

Example Code:

Here’s a sample implementation in C++ using Windows API:

#include <windows.h>
#include <sddl.h>
#include <iostream>

void SetRestrictiveDACL(HANDLE hProcess) {
// Define the SDDL string to restrict access
LPCWSTR sddl = L"D:(D;;GA;;;WD)(A;;GA;;;SY)(A;;GA;;;OW)";
PSECURITY_DESCRIPTOR pSD = nullptr;

// Convert SDDL string to a security descriptor
if (ConvertStringSecurityDescriptorToSecurityDescriptor(sddl, SDDL_REVISION_1, &pSD, nullptr)) {
// Set the security descriptor for the process
if (SetKernelObjectSecurity(hProcess, DACL_SECURITY_INFORMATION, pSD)) {
std::cout << "Security Descriptor applied successfully!" << std::endl;
} else {
std::cerr << "Failed to set security descriptor: " << GetLastError() << std::endl;
}
LocalFree(pSD);
} else {
std::cerr << "Failed to convert SDDL: " << GetLastError() << std::endl;
}
}

int main() {
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
if (hProcess) {
SetRestrictiveDACL(hProcess);
CloseHandle(hProcess);
} else {
std::cerr << "Failed to open process: " << GetLastError() << std::endl;
}
return 0;
}

What Undercode Say:

This technique is a powerful way to protect processes from unauthorized access, particularly in scenarios where process integrity is critical. By leveraging Windows API functions and SDDL, you can create a robust security mechanism that prevents debugging, termination, or memory dumping by unauthorized entities. However, it’s important to note that this method may not be effective against processes with `SeDebugPrivilege` enabled, as they can bypass these restrictions.

For further exploration, consider experimenting with other Windows security features like Access Control Entries (ACEs) and Security Identifiers (SIDs). Additionally, tools like Sysinternals Process Explorer can help you analyze and test the effectiveness of your security configurations. Always ensure you have proper authorization before testing these techniques in real-world environments.

For more advanced red teaming techniques, refer to resources like MITRE ATT&CK and Windows API documentation.

References:

Reported By: Kavinarasue Hello – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification āœ…Featured Image