Running log
Append-only. Newest entries at the bottom. One entry per work session or finding.
2026-10-13 10:13 - Case opened
- The analyst supplied a second Akira-branded build to test build 1’s decryptor. SHA-256 verified by Ghidra at import; MD5
4aecef9d…. - VM: Ghidra has it analysed (2,689 functions). x64dbg has it paused at the system breakpoint with no arguments: left alone, not run.
2026-10-13 10:40 - Static comparison: same key generation as build 1
- No CSPRNG import. The QPC wrapper
FUN_14007fc6cfeeds the per-value seedFUN_140082c90: QPC×100 → decimal string → new Yarrow, seed, draw. - Per-file key set
FUN_140036730: key1 32 B, iv1, key2 and iv2 16 B each; 91-byte blob → 512-byte RSA footer. - Same as build 1: the 2,000,000-byte Part threshold, the CLI strings, the note, and the extensions.
- What changed:
- the string-obfuscation key: shadow-copy decode
(0x32−b)·0x2A mod 0x7F(build 1(0x39−b)·0x0B); the command is the same; - the note chat code:
6729-HK-NIZN-WOPQ; - the operator RSA key (not compared).
- the string-obfuscation key: shadow-copy decode
- Gates: WMI executor
FUN_140078890; root queueFUN_14007ac00(rootstd::wstringinr8). - Harness frozen before any run:
- driver
fc5d69fd…; - collector and state probe identical to build 1 run 6;
- build 1 decryptor
870c6db9….
- driver
- Protocol:
04-dynamic/01-b2run1-protocol.md. Write-up:03-static/01-comparison-with-build1.md. - Next: the analyst copies the two scripts to the VM Desktop and places test files; then the detonation.
2026-10-13 10:30 - Build 2 run 1: detonation (protocol 04-dynamic/01-b2run1-protocol.md)
- Before the run: both scripts are on the VM Desktop: the right sizes (2,562 / 624 B), and the collector’s tail matches the frozen copy byte for byte. The analyst’s paused no-argument instance (PID 2952) was stopped before any of its code ran.
- samples\data (state probe), 10 files:
- six repeat run 6:
20358696.jpg, bothphoto_*.jpg, the DOCX and both PNGs; - new:
AnyDesk.exe8,375,224,Detection Lab Automated BAS-to-Splunk Detection Engineering Loop.pdf595,456,rule.yml981.
- six repeat run 6:
- Pre-listing:
pre_run6.txt(3,289 B) was taken and imported into Ghidra/b2run1before encryption. It has not been read. - Detonation:
- image base
0x7FF709530000; command line--encryption_path=...\samples\data -localonly; - the WMI executor
+0x78890was hit from+0x791AA(insideFUN_140078ff0) and forced to return; - the root queue
+0x7AC00: one root,...\samples\data(0x27 chars); - then all breakpoints were deleted, and the sample ran to exit. No exceptions and no hits.
- image base
- Operator log
Log-13-10-2026-10-28-58.txt: 2 threads, 36,814 ms. - Post-run
post_run6.txt(SHA-256b5af889e…):- QPC 10 MHz; offset
134363561561486661(spread 111 ticks); - 8
.akirafiles andakira_readme.txt; AnyDesk.exeis not encrypted (an.exeexclusion, as in build 1);- the sample exe, zip and stage2 files are unchanged.
- QPC 10 MHz; offset
- Next: the analyst copies the 8
.akirafiles andpre_run6.txtto04-dynamic/b2run1-blind/.
2026-10-13 10:50 - Build 2 run 1 result: 6 of 7 in-scope files hash-exact with build 1’s decryptor
- Transfer: the analyst moved the
.akirafiles with a Python HTTP server on the VM. My own attempt was blocked by auto mode, and I stopped my VM server. Every file matched the VM post-run SHA-256. - Driver
fc5d69fd…and decryptor870c6db9…ran as frozen. Log:artifacts/b2run1-blind-recovery-2026-10-13.txt. - MATCH on pass 1, 15–30 s each:
- 3 JPEGs (JFIF);
- the DOCX;
- 2 PNGs.
- Gaps: 3,896–5,380 ticks.
- PDF (595,456 B): KEYS FOUND, OUTPUT DIFFERS (the ChaCha stage 2 again found nothing).
rule.yml: out of scope. - Conclusion: build 2 is the same codebase, and build 1’s decryptor works on it unchanged.
- Open:
- compare
pre_run6.txtwith the Ghidra/b2run1copy; - VM revert;
- the ChaCha stage-2 check.
- compare
2026-10-13 11:00 - Pre-listing cross-check
- The host
pre_run6.txtmatches the Ghidra/b2run1copy imported before detonation: the same size, and all 13 per-file SHA-256 values are identical.
2026-10-13 11:10 - Blog updated with build 2 (v6, same URL)
- Key findings: new bullet on the second build (6 of 7 hash-exact, decryptor unchanged).
- Proof section: retitled “three runs across two builds”; new “A second build, same flaw” subsection (static match, protocol, 9-row table, verdict).
- Recovery section: iv2 anchor range now cites 18 files across both builds.
- Limitations: “This build only” became “Two builds tested”.
- IOCs: build-2 SHA-256 and MD5, and its victim code.
- v5 said “seventeen files”; v6 corrects it to 18 (16 hash-exact plus 2 PDFs with keys found).
2026-10-14 - Build-2 PDF recovered hash-exact (stage 2)
- Cause: same as the run-6 PDF. The seeds were in the default window, and the zeros/text test rejected the right key. Here, the bytes at 65,535 are the tail of object 24’s compressed stream.
- Test:
06-decryptor/stage2-investigation/pdf_xref_oracle.py.- Exact
N G objheaders at offsets taken from the plaintext classic xref tables: 968 of them inside the ChaCha chunks. - Each candidate costs one ChaCha8 block.
- Exact
- Search: 24,373,969 pairs in 89 s. 1 candidate, 968/968 headers.
- Seeds: 1219626222000, 1219626650700, 1219627041700, 1219627450300.
- Result: MATCH with
pre_run6.txt(adb6bafb…). Build 1’s decryptor, unchanged, gives the same hash withdecrypt --seeds. - Tally: 7 of 7 in scope with the targeted stage-2 rerun. The blind protocol result stays 6 of 7.
- Log:
artifacts/stage2-pdf-xref-oracle-b2run1-window-2026-10-14.txt.
2026-10-14 - Integrated decryptor run
- Recovered: build 1’s decryptor, with the new PDF stage-2 fallback, recovers this case’s PDF hash-exact with the default command line (xref test, 4 min 52 s).
- Cross-check:
06-decryptor/stage2-investigation/check_deflate_test.pyruns the deflate test alone on a 101 x 101 window and finds the same seeds (artifacts/stage2-deflate-test-crosscheck-2026-10-14.txt). - Docs: the addendum in
04-dynamic/01-b2run1-protocol.mdand the README updated.