Filter resources

Blog

Gaining system privileges via DLL hijacking

Misconfigured folders may look harmless. But our red team demonstrated that weak folder permissions can enable DLL hijacking — turning low privileges into full SYSTEM control.

4 minutes read

Danijel Grah

Offensive Security Techical Lead at NIL (part of Conscia Group)

Andrej Urankar

Cybersecurity Analyst at NIL (part of Conscia Group)

Gaining system privileges via DLL hijacking – featured image

During a recent red team engagement, we exploited a DLL hijacking vulnerability in the Checkmk Windows agent to escalate privileges to SYSTEM and establish persistence. Although CVE-2024-28827 had already been disclosed, no public proof-of-concept was available at the time. Our demonstration was carried out in a controlled lab environment using version 2.2.0p23 of the agent, and focused solely on exploitation, not evasion.

Understanding DLL hijacking

DLL hijacking is a well-known technique that abuses the way Windows searches for and loads DLLs. If an attacker can place a malicious DLL in a directory that is searched before the legitimate DLL’s location — and if that directory is writable — arbitrary code execution can be achieved.

The standard DLL search order in Windows is as follows:

  1. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\KnownDLLs
  2. Application directory
  3. C:\Windows\System32
  4. C:\Windows\System
  5. C:\Windows
  6. Current working directory
  7. Directories listed in the PATH environment variable

Recon: Discovering a vulnerable agent

After gaining access with a low-privileged account, we began our standard privilege escalation checks. Among scheduled tasks, service permissions, and file ACLs, we identified a vulnerable Checkmk agent installation:

  • Executable: C:\Program Files (x86)\checkmk\service\check_mk_agent.exe
  • Child binary: C:\ProgramData\checkmk\agent\bin\cmk-agent-ctl.exe

The advisory for CVE-2024-28827 highlighted weak folder permissions in C:\ProgramData\checkmk\agent\bin. In our case, the ACLs had not been hardened. Because this subfolder was writable by our low-privileged user — and the binary ran as SYSTEM during service startup — it created an ideal privilege escalation scenario.

Searching for hijackable DLLs

We used Crassus, a tool by Will Dormann, to analyse the behaviour of cmk-agent-ctl.exe via Sysinternals` Procmon logs. Crassus identifies missing DLLs requested by an application and checks whether the current user has write access to the relevant directories.

The tool generated the following output:

Figure 1 – Identifying viable DLL injection points with Crassus

The tool flagged several missing DLLs that could be hijacked:

  • secur32.dll
  • CRYPTBASE.dll
  • SSPICLI.dll
  • OpenHardwareMonitorCLI.exe

We selected secur32.dll for our payload.

Crafting the malicious DLL

Crassus auto-generates .cpp source and .def files for proxying the DLL. It includes a placeholder Payload() function, which by default launches calc.exe. We modified this to instead launch a Meterpreter reverse HTTPS payload.

  • Step 1 – Generate the reverse shell
    Using Metasploit’s msfvenom, we created a Meterpreter executable.
  • Step 2 – Modify Payload() in secur32.cpp
    We replaced the default code with a CreateProcess function to launch the Meterpreter executable. A short delay (Sleep) was added to allow us to monitor the successful DLL load in Procmon.

Compiling and deploying

We compiled the DLL using Visual Studio Build Tools and deployed it as follows:

  • Placed secur32.dll into the vulnerable directory: C:\ProgramData\checkmk\agent\bin
  • Dropped the Meterpreter executable (shell.exe) into the user’s Desktop folder.

Setting up the listener

Before rebooting the target machine, we configured a Metasploit handler to listen for the reverse connection.

Execution and SYSTEM Shell

Upon reboot, cmk-agent-ctl.exe executed as SYSTEM, loaded our malicious secur32.dll, and spawned shell.exe, which connected back to us — giving full SYSTEM access.

Procmon logs below confirm that event “Load Image” occurred, where the malicious DLL was loaded.

Below figure (also from Procmon) shows us that cmk-agent-ctl.exe process created process shell.exe.

And lastly, we got a SYSTEM shell on our listening device.

Lessons learned

This engagement illustrates how seemingly minor misconfigurations — such as writable folders under ProgramData — can lead to complete system compromise when combined with DLL hijacking in auto-starting SYSTEM-level services.

Organisations running Checkmk or similar agents should:

  • Monitor for unsigned DLLs loaded by privileged processes
  • Audit folder permissions, especially under %ProgramData%
  • Harden ACLs on service directories
  • Upgrade to patched versions that fix weak default permissions

About the author

Danijel Grah

Offensive Security Techical Lead at NIL (part of Conscia Group)

Danijel Grah has over ten years of experience in cybersecurity. He currently works as a Offensive Security Techical Lead.

Andrej Urankar

Cybersecurity Analyst at NIL (part of Conscia Group)

Andrej Urankar works in Conscia’s Security Operations Centre/Managed MDR and specialises in incident analysis, penetration testing, and exploit development.

Danijel Grah

Offensive Security Techical Lead at NIL (part of Conscia Group)

Andrej Urankar

Cybersecurity Analyst at NIL (part of Conscia Group)

Recent Blog posts

Related

Resources