Files
Valak/README.md
T

2.6 KiB

Valak

Valak

Zig DLL for Sliver implants. ChaCha20 encrypted sleep via indirect syscalls with synthetic callstack frames. HWBP AMSI/ETW bypass, no memory touched. FreshyCalls syscall extraction immune to inline hooks. CRT-free.

For initial delivery use Kage, minimal syscall-based shellcode loader.

Why Zig over C

No CRT linked, smaller binary, fewer imports for AV to flag. Comptime guarantees struct layouts match the PE spec without padding bugs. All the Win32 types, inline assembly, and raw pointer math of C but the compiler refuses to build if you get a struct offset wrong.

Valak replaces time.Sleep() in your implant's beacon loop with ChaCha20-encrypted sleep via indirect syscalls. During sleep your implant's .text is PAGE_NOACCESS, scanners get access violation. On wake, it restores and decrypts.

How it works

Every time Sliver would normally call time.Sleep(interval), Valak runs this instead:

1. ChaCha20 encrypts Sliver's .text section in memory (SystemFunction040)
2. Protects .text to PAGE_NOACCESS — read, write, and execute all blocked
3. NtDelayExecution(interval) via indirect syscall with random gadget
4. EDR scanner sees encrypted garbage or access violation, not Go runtime
5. On wake: protects back to PAGE_EXECUTE_READ, ChaCha20 decrypts
6. Returns to Sliver, which continues normal beacon operations

The callstack during sleep shows kernel32!BaseThreadInitThunk → ntdll!RtlUserThreadStart — what every legitimate Windows thread looks like. No gap, no zeroed return address.

Evasion stack

Technique How
ChaCha20 encrypted .text sleep SystemFunction040/041 → NtDelayExecution + PAGE_NOACCESS
Synthetic callstack frames kernel32!BaseThreadInitThunk → ntdll!RtlUserThreadStart
HWBP AMSI bypass DR0 + VEH, no memory modified
HWBP ETW bypass DR0 + VEH, no memory modified
FreshyCalls syscall extraction ntdll export table sorted by RVA, immune to inline hooks
Indirect syscalls Random gadget pool (64+ syscall;ret from ntdll .text)
CRT-free No libc import, minimal IAT footprint

Build

cd evasion && zig build -Doptimize=ReleaseFast
# → zig-out/bin/valak.dll

Sliver integration

See docs/sliver-integration.md. TL;DR:

  1. Embed valak.dll bytes into go-bridge/embed_dll.go
  2. Drop go-bridge/ into Sliver's implant/sliver/evasion/valak/
  3. Replace time.Sleep(d) with valak.EvasionSleep(d) in runner.go
  4. Build: garble -tiny -literals -seed=random build -tags evasion -ldflags="-s -w -H windowsgui"