64 lines
2.6 KiB
Markdown
64 lines
2.6 KiB
Markdown
<p align="center">
|
|
<img src="assets/Valak.png" alt="Valak">
|
|
</p>
|
|
|
|
# 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](https://github.com/Yenn503/Kage), minimal syscall-based shellcode loader.
|
|
|
|
## Why Zig over C
|
|
|
|
No CRT. C programs pull in the C Runtime Library which adds DLL imports to your IAT. Zig just calls the OS. Smaller binary, less for AV to see.
|
|
|
|
Detection engines mostly know C, C++, Rust, Go. Zig flies under the radar. Lower VirusTotal scores.
|
|
|
|
Ghidra struggles with Zig binaries (open bug). IDA doesn't properly support it either. Makes reverse engineering harder.
|
|
|
|
Comptime makes sure struct layouts match the PE spec. Same low level control as C.
|
|
|
|
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
|
|
|
|
```bash
|
|
./scripts/integrate.sh ~/projects/sliver
|
|
```
|
|
|
|
See [docs/sliver-integration.md](docs/sliver-integration.md) for prereqs and options.
|