Back

Carter Dack, 2026.

Using GOAD for C2 Evaluation

As offensive security tooling continues to mature, Command and Control (C2) frameworks have evolved beyond simple session management platforms into highly integrated operational ecosystems. Modern frameworks now attempt to streamline many of the repetitive and operationally expensive tasks associated with post-exploitation activity, ranging from payload generation and process injection to credential harvesting and lateral movement.

While nearly every mature framework successfully solves the core problem of agent management, the differentiating factor increasingly becomes operator usability and workflow efficiency. A framework should reduce operational friction wherever possible. The more frequently an operator is forced to fall back to primitive tooling or manual tradecraft throughout an engagement, the less effective the framework ultimately becomes from a practical standpoint and the more OPSEC degradation may occur.

To evaluate some of these operational differences firsthand, I decided to deploy GOAD (Game of Active Directory) and use the environment to test various C2 frameworks, payload configurations, and evasion workflows.

GOAD Setup

The deployment process for GOAD is already well documented, so there is little value in repeating the setup process in depth. In short, Vagrant handles the majority of the provisioning and automates much of the virtual machine deployment and configuration workflow.

One notable caveat during deployment was the requirement for WSL version 1 rather than WSL2 due to network bridging behavior. Without this adjustment, network communication between systems became unreliable.

In addition to the standard GOAD-Light infrastructure, I deployed two custom virtual machines, including:

  1. A Kali Linux attacker system; and
  2. Windows 10 “team server”.

Many C2 frameworks (aside from cobalt strike) continue to heavily favor Linux-based infrastructure, which limited how frequently I could practically leverage the Windows-based team server during testing, so this VM wound up being mostly useless to me.

Service Enumeration

In many Active Directory assessments, testers are provided with low-privileged credentials through a ceded access model. Since I had limited prior experience with GOAD and decided not to read much of the documentation, I approached the environment blindly.

That said, the GOAD documentation does expose the rough infrastructure layout. For the GOAD-Light deployment, this consisted of:

  1. Two domain controllers located at x.x.x.10 and x.x.x.11; and
  2. A web server hosted at x.x.x.22.

While domain controllers tend to be somewhat boilerplate from a service enumeration perspective, the web server presented a more interesting initial attack surface, so I began there.

The server appeared to be listening on port 80, so I launched my browser and navigated to its web application.

The application immediately appeared to expose some form of file upload functionality. My initial assumptions centered around several common attack vectors, including:

  1. XML External Entity (XXE) injection;
  2. Directory traversal vulnerabilities; or
  3. Remote File Inclusion (RFI) style behavior.

To better understand the application’s functionality, I proxied traffic through Burp Suite and began analyzing the behavior.

It quickly became apparent that the application was running ASPX based on the file type in the URI.

Further directory enumeration revealed an /upload directory where uploaded files were stored. More importantly, uploaded filenames appeared to remain intact and directly accessible via the web application.

With this information, a web shell upload became the most likely path to remote code execution. I downloaded a basic ASPX web shell sourced from the first github repository I could find and uploaded it to the target application.

After navigating to the uploaded shell and supplying a command parameter, remote code execution was confirmed successfully.

Havoc C2

At this point, the objective shifted from transient web shell access to establishing a more stable and operationally flexible foothold.

Recently, I have spent more time working with Cobalt Strike, so I wanted to use a framework that offered a similarly visual operator experience. Historically, I have primarily used Sliver, which is highly capable but far more terminal-driven in its operation.

For this exercise, I chose to evaluate Havoc.

The first step involved creating a listener and generating a payload through the Havoc interface. Once generated, I hosted the payload externally and retrieved it through the ASPX web shell.

When the payload is executed, the original web shell session becomes unstable because the beacon process remains attached as a child of the executing cmd.exe instance. To improve reliability, process migration became necessary.

To accomplish this, I generated raw beacon shellcode and injected it into a more stable process running on the target host. The result was a significantly cleaner and more reliable session than the original web shell context.

From here, basic file system pilfering reveals an sql configuration file continuing plaintext credentials. We will keep these in mind when moving forward.

Privilege Escalation

Enumeration of the compromised system (running whoami) revealed that the current account possessed the SeImpersonatePrivilege privilege, immediately suggesting several well-known privilege escalation techniques.

Using PrintSpoofer to launch a new beacon process via PowerShell successfully resulted in a SYSTEM-level session.

With elevated privileges established, I proceeded to dump the Security Account Manager (SAM) database for offline analysis and credential extraction.

The resulting data included:

Offline cracking of the MSCACHE hashes successfully recovered the password for robb.stark, providing the first legitimate Active Directory credential within the environment.

At this stage, the engagement transitioned from local post-exploitation into broader domain-level operations.

Active Directory Enumeration

With valid domain credentials established, I shifted focus toward Active Directory reconnaissance and privilege path analysis using BloodHound.

The resulting graph made the escalation path relatively straightforward.

The robb.stark account appeared to possess administrative rights within the north.sevenkingdoms.local domain and inherited a WriteDACL relationship over the Domain Admins group.

To validate administrative access against the domain controller directly, I leveraged SMBExec successfully.

At this point, full credential dumping across the domain becomes trivial. With NTLM hashes collected, both offline cracking and pass-the-hash techniques are viable options for continued lateral movement and persistence. Here it is easy to get carried away and I almost forgot that I was evaluating the Havoc framework. I will now pivot into some evasion tactics, to see how malleable this C2 really is.

Evasion

Modern defensive tooling has become increasingly effective at identifying offensive security payloads through static signatures, heuristic analysis, and behavioral monitoring. As a result, understanding how defensive products identify malicious binaries is just as important as understanding how to deploy them operationally.

To begin evaluating the default Havoc beacon from a detection standpoint, I first executed the payload against ThreatCheck. The purpose of ThreatCheck is to identify which exact byte ranges within a binary are responsible for triggering detection by Microsoft Defender.

The initial scan confirmed that the vanilla beacon executable was immediately detected.

With the offending byte ranges identified, I imported the beacon executable into Ghidra for further analysis. Using Ghidra’s memory search functionality, I navigated directly to the signatured byte sequence (C8 4C 8D 0C ...) identified by ThreatCheck.

The bytes resolved to an ADD instruction located within an unnamed function inside the decompiled beacon.

At this stage, the objective became identifying the corresponding logic within the beacon’s original source code so that the routine could be modified without impacting functionality.

Reviewing the decompiled pseudocode revealed a suspicious operation involving an addition operation between param_3 and param_1. More importantly, the generated pseudocode suggested that the surrounding function structure itself was likely contributing to the Defender signature.

From there, I began tracing the logic back into the pre-patched Havoc beacon source files. To locate the corresponding implementation, I used an intentionally primitive but effective approach: grepping the source tree for strings and comparison logic that resembled the Ghidra pseudocode output.

Searching for the string "< 4" (which appeared directly in the decompiled routine) narrowed the possibilities down to two source files:

  1. Parser.c; and
  2. AesCrypt.c.

Given the context of the detected routine, cryptographic operations immediately appeared to be the more likely target for static signature generation. If I were authoring a defensive signature myself, cryptographic primitives and shellcode-related routines would be among the first places I would prioritize.

Inspection of AesCrypt.c quickly revealed a function that closely matched the decompiled logic observed inside Ghidra.

Rather than removing the function outright, I rewrote it while preserving its operational behavior. The objective was not to disable encryption or alter execution flow, but rather to modify the compiled instruction patterns sufficiently enough to invalidate the static signature being used by Defender.

Once the modified AesCrypt.c file was saved, I recompiled the beacon and executed ThreatCheck against the newly generated binary.

ThreatCheck still identified malicious content, but the detection occurred at an entirely different offset within the executable. This strongly suggested that the original function rewrite had successfully bypassed the previous signature.

From there, the process became iterative:

  1. Identify the detected byte sequence;
  2. Trace the associated logic within Ghidra;
  3. Locate the corresponding source code implementation;
  4. Rewrite the routine while preserving functionality; and
  5. Recompile and test again.

After a few rounds of modification and recompilation, the beacon eventually passed ThreatCheck successfully without triggering Microsoft Defender signatures.

From an operational standpoint, the process was fairly standard. One notable strength of Havoc is how accessible the beacon source code is for modification and experimentation. The framework makes it straightforward to trace detection points, adjust implementation details, and rapidly rebuild payloads without introducing major instability into the compilation process.

Observations and Evaluation

Overall, I found the Havoc interface intuitive and (mostly) operationally efficient. The workflow closely resembles Cobalt Strike in several ways, which significantly lowers the learning curve for operators already familiar with more traditional commercial frameworks.

That said, several shortcomings became apparent during testing.

One of the more frustrating operational limitations involved file retrieval. Downloaded files become deeply nested within Havoc’s internal directory structure, and retrieving them locally is unnecessarily cumbersome and impossible via the GUI. The lack of streamlined artifact management quickly becomes noticeable during longer operations.

I also found myself repeatedly missing several native quality-of-life features present in Cobalt Strike. For example:

  1. Native file hosting functionality;
  2. Built-in payload delivery workflows; and
  3. Website cloning capabilities.

In comparison, manually serving files via python3 -m http.server always feels primitive and operationally clunky.

While Havoc provides a strong foundation and a polished interface for an open-source framework, several aspects of operational workflow still feel immature compared to more established commercial alternatives.

As modern defensive tooling continues to improve, operational success increasingly depends not only on exploit capability, but on how effectively operators can blend into normal system behavior while maintaining reliable command and control over compromised infrastructure.

Citations

Havoc, havocframework.com/. Accessed 24 May 2026.

Orange-Cyberdefense. “Orange-Cyberdefense/Goad: Game of Active Directory.” GitHub, github.com/Orange-Cyberdefense/GOAD. Accessed 24 May 2026.

Rasta-Mouse. “Rasta-Mouse/Threatcheck: Identifies the Bytes That Microsoft Defender / AMSI Consumer Flags On.” GitHub, github.com/rasta-mouse/threatcheck. Accessed 24 May 2026.