Case: akira-ransomware

Field Value
SHA-256 101bd45ab673fd6547386dff4339f1649e61b9f5c318260d365f766fbdc2d3c9
MD5 427eba9f6ff2cd312c72770f13e279c1
File name 101bd45ab673fd6547386dff4339f1649e61b9f5c318260d365f766fbdc2d3c9.exe
Type / Arch PE32+ / x86-64, MSVC 14.37 C++20, GUI subsystem
Size 1,043,180 bytes mapped (on-disk size not recorded)
Compiled 2023-12-28 14:49:57 UTC (PE timestamp)
Family (assessed) Akira ransomware (self-branded: .akira, akira_readme.txt, Akira onion URLs)
Verdict Malicious
Confidence High: our own static analysis plus five controlled live runs; no external reporting used
Analyst Claude Code + Ghidra MCP + x64dbg MCP
Opened 2026-10-11
Closed 2026-10-11

Executive summary

The sample is a self-contained 64-bit C++ ransomware that brands itself Akira. It:

It has no C2, persistence or exfiltration. Its key weakness: every per-file key comes from a fresh Yarrow-256 seeded only with the uptime counter (QPC × 100 ns), so keys can be brute-forced without the RSA key. Our decryptor does this on the sample’s real output in all three modes.

Capability summary

Capability Present Evidence
Persistence No none in code
Privilege escalation No none in code
Defense evasion / anti-analysis Minimal per-string mod-127 obfuscation of 3 string groups; hidden WMI-spawned PowerShell; no anti-debug (01-triage/)
Credential access No –
Discovery Yes drive and share classification, process list (WTSEnumerateProcessesW, RmGetList), CPU count (03-static/02-…)
C2 / exfiltration No no sockets; the data-theft claim in the note is not carried out by this file
Payload delivery No single PE
Destruction / ransom Yes shadow-copy deletion, ChaCha8 + KCipher-2 + RSA-4096 encryption, .akira, note in every folder; live-confirmed (03-static/05-…, 04-dynamic/)

Key IOCs

Full set in 02-strings-iocs/01-strings-iocs.md and artifacts/iocs.csv.

ATT&CK techniques

See 05-detections/01-detections.md: T1486, T1490, T1489, T1047, T1059.001, T1564.003, T1027, T1057, T1083, T1135, T1082.

Recovery

06-decryptor/akira_decrypt.py (Python 3.8+, standard library only; optional numpy + numba engine akira_fast.py):

Folder map

| Path | Contents | |—|—| | report.md | full analysis report (export of the Claude Docs report, rev 56 of 2026-10-14, which covers run 6, build 2 and the PDF stage-2 fallback; the diagrams are embedded from artifacts/diagrams/). HTML/PDF copies are no longer kept; python export/process_report_export.py export/report-rev56 --html-pdf regenerates them | | 00-intake/ … 05-detections/ | case notes per the workspace layout | | 03-static/ | 01 main flow · 02 targeting · 03 pre-encryption · 04 modes · 05 crypto · 06 file format · 07 string obfuscation · 08 function map · 09 API calls per behaviour | | 04-dynamic/ | run 1 (escape) · run 2 (crypto validation) · run 3 (end-to-end capture) · run 4 (native seed gap, with seed-gap/ CSVs) · 05 timestamp seed anchors (timestamps/ probes + analysis) · 06 run 5 blind recovery of real files (run5-blind/: probes, .akira inputs, decrypted outputs) | | 05-detections/ | detections write-up + akira_win64_encryptor_101bd45a.yar | | 06-decryptor/ | decryptor, README, tests, real .akira fixtures + captures.txt; stage2-investigation/ (how the run-6 PDF’s ChaCha8 key was found) | | blog/ | akira-recovery-blog.html, the public blog draft (private artifact); the GitHub download links are placeholders until the repository is live | | scripts/ | first-pass validation models (akira_crypto.py, akira_ciphers.py) | | artifacts/ghidra/ | raw Ghidra outputs (decompile, 1.65 MB disassembly, .rdata dump, imports, strings, metadata) | | artifacts/decoded/ | decoded DB-extension list + per-table keys | | artifacts/diagrams/ | execution, encryption and decryption flow diagrams (.png renders + .widget.jsx sources) | | artifacts/ | RSA public key (.der / .pem), ransom note, iocs.csv, test run log, decryptor demo log |

Open questions

  1. RESOLVED (run 4): the natural seed-to-seed gap is ~0.4 ms (key2 → iv2 median 4,121 ticks, range 3,889–27,109). It was measured with an in-process QPC hook and no seed breakpoints, and checked by decrypting with the logged seeds. See 04-dynamic/04-run4-native-seed-gap.md.
  2. Decryption via the operator’s private key is tested only with our own RSA key.
  3. --share_file and Part mode with percent < 50 were not exercised live.
  4. The YARA rule has not been run by a YARA engine or against a benign corpus.
  5. VM: revert the snapshot (run 5 encrypted samples\data; Desktop holds inv.ps1, post.ps1, inv_pre.txt, post_run5.txt and the operator log). Ghidra /decrypt_test raw imports can be deleted.
  6. RESOLVED (2026-10-12): victim timestamps place key2 to within a few ms when the QPC offset is measured on the same boot. Still untested: hosts at the default 15.6 ms clock tick, large files (where encryption time widens mtime − key2), and trace files kept from the attack boot that might hold an exact QPC↔clock pair after a reboot.
  7. RESOLVED (2026-10-12): run 5’s first PNG had a key2→iv2 gap of 26,718 ticks. It was recovered hash-exact by an iv2-anchored search with gaps 8,001–30,000 (recover --anchor iv2, 1,240 s). See addendum 4 of artifacts/run5-blind-decryption-evidence-2026-10-12.txt.