DEV Community

Harsh Kanojia
Harsh Kanojia

Posted on

⚙️ Endpoint Evasion Lessons Learned

Abstract
This post dissects a subtle technique observed in post-exploitation phases where adversaries bypass common endpoint detection and response (EDR) hooks. We move beyond simple API hooking to examine memory artifact manipulation techniques that often slip past heuristic scanning. The focus is on practical application for threat hunters and defenders.

High Retention Hook
I remember staring at a seemingly clean process dump, convinced the malware process had vanished. My initial assumption was a sloppy cleanup or an in memory execution that terminated cleanly. It took three days and a deep dive into kernel debugging reveals to see the residual artifact—a ghost process lingering just long enough for C2 beaconing, deliberately coded to evade standard process enumeration tools. It was a frustrating, yet clarifying, lesson in attacker patience.

Research Context
The modern threat landscape demands adversaries move beyond relying on easily signatured binaries. Fileless malware and in memory execution are standard fare. What is increasingly common, and frankly more interesting from a research perspective, is the calculated manipulation of legitimate operating system artifacts to maintain persistence or achieve stealthy command and control. Organizations are heavily invested in EDR solutions tuned to detect common process injection methods, but the signal to noise ratio demands we look deeper into the memory space itself.

Problem Statement
Many security teams rely heavily on EDR visibility into the process lifecycle events. When an attacker achieves code execution, the immediate goal is often to hide the execution environment or the payload itself. The gap lies in defenders often focusing on the injection mechanism (e.g., suspicious parent child relationships or known injection DLLs) rather than the subtle, persistent corruption of the host's legitimate memory structures that an attacker might exploit for long term command and control callbacks. We assume if the process entry looks okay, the activity is benign. That assumption is dangerous.

Methodology or Investigation Process
My investigation began post-exploitation simulation using a modified Cobalt Strike beacon configured to utilize an advanced reflective DLL injection technique targeting a legitimate lsass.exe process, similar to techniques documented in various red team engagements. Crucially, the payload was configured with a custom sleep routine designed to terminate the injected thread and zero out key process memory regions shortly after beaconing, but not entirely. I used Volatility 3 for memory acquisition and analysis, specifically focusing on the process environment block (PEB) and thread information block (TIB) structures. Reproducibility was key, so I ensured the memory dump captured the brief window post sleep return but pre complete self-cleaning routine execution.

Findings and Technical Analysis
The critical finding revolved around thread context manipulation. While the injected thread was terminated, and the allocated memory section marked for release, remnants in the EPROCESS structure, specifically related to linked list pointers (like ActiveProcessLinks), were not fully zeroed out by the malware’s self-clean routine. The malware was aggressive in wiping the code segment but left the thread information slightly tangled.

Specifically, I observed that the ThreadBasePriority and CurrentPriority fields within the KTHREAD structure associated with the dormant injected thread retained values inconsistent with standard thread states after the routine terminated. Although not actively running malicious code, these pointers represented a potential pivot point for subsequent memory scraping tools looking for anomalous thread states tied to known execution flows, or worse, a persistence mechanism if the malware had been designed to re-enter execution via a different trigger later. We see parallels in how some nation state actors, though perhaps not achieving this level of subtlety in public reports, utilize kernel object manipulation for evasion, as noted in analyses concerning advanced persistent threats.

Risk and Impact Assessment
The immediate business impact is compromised visibility. If a threat hunter is only checking process trees or active handle lists, this "ghost" thread context might be missed entirely. In the context of a major incident like the SolarWinds supply chain attack, where the initial ingress was highly stealthy, any subsequent activity that leverages weak process visibility becomes exponentially more dangerous. This technique allows an adversary to maintain a low footprint connection or flag within the kernel's view of running threads, effectively lying to the monitoring tools about the process's true execution state. It is a failure of assumption management in defense.

Mitigation and Defensive Strategies
Defending against this requires moving beyond user-mode hooks. Defenders need robust kernel-level integrity checks.

  1. Implement direct kernel object verification: Regularly compare process and thread object structures retrieved via standard APIs against direct reads from kernel memory where feasible and supported by your EDR/Honeypot framework.
  2. Thread state baseline: Establish and monitor anomalies in thread priority, wait blocks, and stack residue within the KTHREAD block. Static analysis tools often miss this temporal aspect.
  3. Enhance memory forensics tooling: Ensure your DFIR kits are primed to look for non-standard termination signatures in the TIB/TEB areas, specifically pointers that point outside expected system memory ranges or terminate abruptly.

Researcher Reflection
This reinforces a fundamental truth: if you are only looking where the EDR tells you to look, you are already behind. Attackers are not just bypassing signatures; they are exploiting the inherent complexity and trusted boundaries of the OS internals. My initial failure was trusting the exit condition reported by the malware itself. Lesson learned: verify every termination. I owe a debt of gratitude to the publicly available kernel documentation; without it, this rabbit hole would have been inescapable.

Conclusion
Attacks targeting subtle memory artifacts like thread context manipulation represent the current leading edge of stealthy post-exploitation. Defense requires deeper, kernel-aware inspection beyond surface-level process enumeration. Visibility is earned through verification, not assumed through reported status.

Discussion Question
For those deep in kernel development or DFIR, what specific kernel callback routines do you find most reliable for detecting anomalous thread state manipulation that bypasses standard user mode telemetry? 🤔

Written by - Harsh Kanojia

LinkedIn - https://www.linkedin.com/in/harsh-kanojia369/

GitHub - https://github.com/harsh-hak

Personal Portfolio - https://harsh-hak.github.io/

Community - https://forms.gle/xsLyYgHzMiYsp8zx6

Top comments (0)