Raven
An AI malware analyst. Upload a suspicious file and an AI agent takes it apart in a sealed container and reports exactly what it does. The malware is never run.
Raven hands a hostile file to a Claude-powered agent with a small set of analysis tools inside an isolated container. On a real malware sample it peeled back every layer: unscrambled the code, recovered the encryption key, unlocked the hidden payload, and reported exactly what the malware does and where it sends stolen data. Built in under 24 hours at HackUSF 2026, where it took 2nd place in the NextEra Energy Challenge.
What Raven does
Raven accepts a suspicious file, copies it into an isolated Docker container, and gives Claude a small set of sandboxed tools to investigate it. The agent deobfuscates the sample, recovers encryption keys, decrypts the hidden payload, decompiles it, and extracts indicators of compromise. A RAG chat then lets an analyst interrogate the findings in plain language.
Highlights
- Award winner. 2nd place in the NextEra Energy Challenge at HackUSF 2026.
- Real result. Recovered all four stages of a live malware sample's attack chain, including its encryption keys and the servers it reports to.
- Safe by design. The malware is analyzed inside an isolated container and never executed.
- Transparent. Every AI action streams live to the screen, and the findings can be queried in plain English.
What it recovered
On its reference sample, the pipeline recovered all four stages of a real threat: an obfuscated 4 MB JScript dropper, a hidden PowerShell stage with an AMSI bypass that disables Defender, an AES-256-CBC-encrypted payload, and a reflectively loaded .NET FTP infostealer. It pulled the AES key and IV, the C2 host and exfiltration credentials, and the full capability set: keylogging, clipboard capture, and credential theft from 20+ applications. All of it came from static analysis, decompiling with ILSpy rather than running the malware.
The stack
| Layer | Technology | What it does |
|---|---|---|
| Agent | Claude Agent SDK · Sonnet | Drives analysis via custom tools over a scripted 5-step plan. |
| Orchestrator | FastAPI · uvicorn | Upload, job tracking, event streaming, report, RAG chat. |
| Isolation | Docker (malware-sandbox) | Runs analysis commands against the sample away from the host. |
| RE tooling | pefile · ILSpy (ilspycmd) · restringer | PE parsing, .NET decompilation, JS deobfuscation. |
| RAG store | Snowflake Cortex / SQLite | Cortex similarity search when configured; SQLite keyword fallback. |
| Chat | Claude Sonnet (Anthropic SDK) | Answers grounded strictly in retrieved findings. |
| Frontend | Next.js 16 · React 19 | Analysis dashboard + streaming event log + chat panel. |
How the pieces fit together
The FastAPI orchestrator never analyzes anything itself. It copies the sample into the sandbox container, spawns the agent pipeline as a subprocess, and streams the agent's tool calls back to the browser as a live event log. The agent is the analyst; the tools are its hands.
%%{init: {'theme':'base','themeVariables':{'background':'#0c0c0e','primaryColor':'#151517','primaryTextColor':'#e6e6e6','primaryBorderColor':'#00ff41','lineColor':'#555','secondaryColor':'#111','tertiaryColor':'#0a0a0a','clusterBkg':'#0c0c0e','clusterBorder':'#262626','fontFamily':'JetBrains Mono, monospace','fontSize':'13px','textColor':'#c0c0c0'}}}%%
flowchart TB
subgraph CLIENT["Browser · Next.js 16"]
UI["Dashboard · streaming event log"]
CHAT["RAG chat panel"]
end
subgraph API["FastAPI orchestrator"]
UP["/analyze · upload + docker cp"]
ST["/status · stream events"]
RP["/report · structured findings"]
CH["/chat · RAG"]
end
subgraph AGENT["Agent pipeline (subprocess)"]
CL["Claude Sonnet
Claude Agent SDK"]
T1["sandbox
(docker exec)"]
T2["host_analyze
(host bash)"]
T3["extract_file
(docker cp out)"]
end
subgraph ISO["Isolation + tooling"]
BOX["Docker: malware-sandbox"]
HOST["Host: pefile · ILSpy"]
end
subgraph DATA["Findings + RAG"]
WS[("workspace/
findings · events")]
SNOW[("Snowflake Cortex
/ SQLite fallback")]
end
UI --> UP & ST & RP
CHAT --> CH
UP --> CL
CL --> T1 & T2 & T3
T1 --> BOX
T2 --> HOST
T3 --> BOX
CL --> WS
WS -->|"regex IOC parse"| RP
WS -->|"ingest"| SNOW
CH --> SNOW
CH -->|"grounded answer"| CL
ST -.->|"tool-call events"| UI
Fig. 1 · Component architecture. Every agent tool call streams to the browser live.
The analysis run, step by step
The pipeline is a fixed sequence of prompts. Each step asks the agent to perform one concrete action with one tool, so the run is legible and every move shows up in the event stream.
%%{init: {'theme':'base','themeVariables':{'background':'#0c0c0e','primaryColor':'#151517','primaryTextColor':'#e6e6e6','primaryBorderColor':'#00ff41','lineColor':'#555','actorBkg':'#151517','actorBorder':'#00ff41','actorTextColor':'#e6e6e6','signalColor':'#666','signalTextColor':'#c0c0c0','noteBkgColor':'#111','noteTextColor':'#c0c0c0','noteBorderColor':'#333','fontFamily':'JetBrains Mono, monospace','fontSize':'12px'}}}%%
sequenceDiagram
participant U as Analyst
participant A as FastAPI
participant C as Claude (agent)
participant S as Sandbox (Docker)
participant H as Host tools
U->>A: POST /analyze (upload)
A->>S: docker cp sample
A->>C: run pipeline (subprocess)
C->>S: hash + read obfuscated JS
C->>C: strip noise, base64 + UTF-16LE decode → PowerShell
C->>C: recover AES key/IV, AES-256-CBC decrypt
C->>H: extract_file → decrypted .NET binary
C->>H: pefile + ILSpy decompile + grep IOCs
C->>A: write findings report
A->>A: regex-parse IOCs / MITRE / hashes
A-->>U: report + streamed events
U->>A: POST /chat (question)
A-->>U: Cortex/SQLite retrieval → Claude answer
Fig. 2 · An analysis run. Deobfuscation and decompilation only; the sample is never executed.
The engineering behind it
An agent with tools instead of a hardcoded analyzer
The core design bet is to give a capable model a few sharp tools rather than script every analysis branch. Three tools are exposed through an in-process MCP server: sandbox (run bash inside the Docker container), host_analyze (run pefile and ILSpy, which need the .NET runtime), and extract_file (copy an artifact out of the container). The agent decides how to use them; the pipeline sequences the goals.
Static analysis, by design
Raven never detonates the sample. It defeats obfuscation and decrypts the payload through analysis: stripping the JScript's noise delimiters, base64- and UTF-16LE-decoding the embedded PowerShell, recovering the AES key and IV from the script, decrypting the payload, then decompiling the resulting .NET assembly with ILSpy. Static recovery is harder to build but safer and more complete: it reads the malware's real logic instead of hoping it reveals itself at runtime. Every recovered artifact, from the AES key to the C2 credentials, was verified against the decompiled source.
Reporting: readable text, then structured extraction
The agent writes a full findings report, and the orchestrator extracts structured IOCs from it: IPs, domains, URLs, file paths, SHA-256 and MD5 hashes, and MITRE ATT&CK technique IDs. The report also separates confirmed facts from inference, flagging the malware family as unconfirmed rather than guessing.
RAG chat over the findings
Completed findings are chunked and stored. When Snowflake is configured, retrieval uses Cortex similarity search; otherwise it falls back to a local SQLite keyword search, so the chat still works offline. Retrieved chunks become the context for a Claude Sonnet answer that is instructed to use only that context and cite specific IOCs and MITRE IDs.
Handling hostile input safely
A malware analyzer's input is hostile by definition, so the safety decisions are the design. Raven's answer is containment plus a hard rule: read the malware, never run it.
Docker containment
The sample is copied into an isolated container, and analysis commands against it run inside that container, away from the host.
Never executed
Every finding comes from deobfuscation, decryption, and decompilation. The malware's code is read, not trusted to behave at runtime.
Grounded answers
The chat can only answer from retrieved findings and is instructed to cite specific IOCs and MITRE technique IDs, so it can't embellish the analysis.
Facts vs. inference
The output report labels what was confirmed against decompiled source and what is inference, the same discipline a human analyst is held to.
One script, two services
# Backend (port 8001) + frontend (port 3000) pip install -r requirements.txt # fastapi, anthropic, claude-agent-sdk, ... # Set ANTHROPIC_API_KEY (+ optional Snowflake creds) in .env ./start.sh
The analysis machine needs Docker with the sandbox container running and the .NET 8 runtime with ilspycmd for decompilation. The RAG chat needs an Anthropic key; Snowflake is optional and the chat falls back to local SQLite search without it.
Unreadable file to full threat report in four minutes
Against the reference sample, a single run goes from a file nobody could read to a complete kill chain:
- 0:00The raw sample: a 4 MB obfuscated JScript, completely unreadable.
- 0:30Analyze starts the run. The event log streams each of the agent's actual tool calls live: sandbox commands, decoding, decryption.
- 1:30The AES key and IV come out of the script and the hidden .NET payload decrypts.
- 2:15ILSpy decompiles the binary, surfacing the C2 host, FTP credentials, and capability strings.
- 3:00The report assembles: kill chain, stage hashes, C2 infrastructure, MITRE techniques, and capabilities.
- 3:30Chat: asking where it phones home and how it exfiltrates gets a grounded answer citing the FTP host and credentials.