Akira decryptor and responder tools
| File | Purpose |
|---|---|
akira_decrypt.py |
The decryptor (Python 3.8+, standard library only). Commands: decrypt (with --keys, --seeds, or the operator’s --private-key; --journal for interrupted .arika files), recover (rebuild keys from timestamps, no ransom key), info, benchmark, selftest |
akira_fast.py |
Optional compiled search engine for recover (pip install numpy numba). It checks itself against the Python reference at load and falls back to Python if any check fails. Takes a file from about 30 min to about 25 s |
collect_clock_and_times.ps1 |
Responder collector (read-only). Records QPC/system-time pairs, a file listing with SHA-256 and timestamps, and the operator logs. Run -Tag post on the victim on the same boot as the attack, before any reboot |
SHA-256:
akira_decrypt.py091701682454a75dfb57324e29a6270977186f68209a7c3a93178ab76fe9fc4b. This is the 2026-10-14 version with the PDF stage-2 fallback (recover --stage2). The blind runs used870c6db9…, the same tool without the fallback; the case folders keep that hash in their frozen logs.akira_fast.py07352777bff09eb30f14a8c826c503e9247948d1385b7dcc8cd02288f4606927collect_clock_and_times.ps115fbf5794497b64ac954ba86bc012776971105a6a37a21137d2c4dd45eee7ff4
akira_fast.py and the collector are byte-identical to the files the blind tests ran.
Recovering a file without keys
- On the victim, same boot: run
collect_clock_and_times.ps1 -Tag post. From thePAIRlines, take the median offiletime − (qpc_before + qpc_after)/2, skipping the first pair. That value is--qpc-offset. Each.akirafile’s last-write FILETIME is--mtime. - Known bytes at offset 0: PNG
89504e470d0a1a0a0000000d49484452, PDF255044462d312e, JFIF JPEGffd8ffe000104a46494600. For DOCX/XLSX/ZIP, rebuild the first local header from the central directory, which Spot mode leaves unencrypted.run6_blind_recover.pyinanalysis/…/04-dynamic/run6-blind/does this per file type, and runs both passes for a whole folder. - Pass 1:
python akira_decrypt.py recover f.akira --qpc-offset … --mtime … --known-hex … --out f. - Pass 2, only if pass 1 misses: add
--anchor iv2 --mtime-window 2.5:0.1 --gap 8001:30000. - Large PDFs: nothing extra is needed. When the generic ChaCha8 check finds nothing in a
.pdf,recoverretries the same window with the PDF checks: exact object headers from the xref, then continuing a page-content stream’s deflate. This took about 2–6 minutes per file in pure Python.--stage2 pdfruns only the PDF checks;--stage2 heuristicturns them off.
Limits:
- the victim must not have been rebooted, or you need a memory image;
- the timestamps must survive;
- at least 7 known bytes are needed at offset 0;
- for files with ChaCha8 chunks (Spot files over about 262 KB, Full-mode databases, Part files over 2 MB), the ChaCha8 key search needs zeros or text in the first ChaCha chunk. PDFs have the fallback above, which needs either objects inside the ChaCha8 chunks or a page-content stream at the chunk boundary. Other compressed files come back partly decrypted.
The full reference, test suites and fixtures are in
analysis/2026-10-11_101bd45ab673_akira-ransomware/06-decryptor/.