Skip to content

Commit 17d67b4

Browse files
committed
feat(evasion): Evasion scanner
This changeset establishes the architecture for the evasion scanner. Evasion scanner piggybacks on top of different evasion detectors such as direct syscall (being the first evasion behaviour implemented). When the evasion behaviour is detected, the event is decorated with such evasion in its metadata.
1 parent 2bc6165 commit 17d67b4

26 files changed

Lines changed: 2000 additions & 7 deletions

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@
6868
6969
> /area deps
7070
71+
> /area evasion
72+
7173
> /area other
7274
7375

.github/workflows/pr.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ jobs:
151151
run: |
152152
cd yara
153153
make install
154+
- name: Setup test fixtures
155+
run: |
156+
choco install -y go-task
157+
task --taskfile internal/etw/_fixtures/Taskfile.yml all
154158
- name: Test
155159
shell: bash
156160
run: |

configs/fibratus.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,22 @@ handle:
156156
# Indicates if process handles are collected during startup or when a new process is spawn.
157157
enumerate-handles: false
158158

159+
# =============================== Evasion ====================================================
160+
161+
# Tweaks for controlling evasion scanner behaviours. Evasion behaviours can represent strong
162+
# IoC (Indicators of Compromise) such as direct syscall or require a combination of fine-tune
163+
# exceptions to reduce the alert fatigue.
164+
evasion:
165+
# Indicates if evasion detections are enabled global-wise. If disabled, evasion scanner will
166+
# not try to classify ad-hoc evasion techniques.
167+
#enabled: true
168+
169+
# Indicates if direct syscall evasion detection is enabled. A direct syscall bypasses Windows
170+
# API functions and calls the underlying system call directly using the syscall instruction,
171+
# skipping the NTDLL stub that normally performs the transition to kernel mode.
172+
#enable-direct-syscall: true
173+
174+
159175
# =============================== Event ===============================================
160176

161177
# The following settings control the state of the event.

internal/bootstrap/bootstrap.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ package bootstrap
2121
import (
2222
"context"
2323
"errors"
24+
"github.com/rabbitstack/fibratus/internal/evasion"
2425
"github.com/rabbitstack/fibratus/pkg/aggregator"
2526
"github.com/rabbitstack/fibratus/pkg/alertsender"
2627
"github.com/rabbitstack/fibratus/pkg/api"
@@ -138,7 +139,7 @@ func NewApp(cfg *config.Config, options ...Option) (*App, error) {
138139
var engine *rules.Engine
139140
var rs *config.RulesCompileResult
140141

141-
if cfg.Filters.Rules.Enabled && !cfg.ForwardMode && !cfg.IsCaptureSet() {
142+
if cfg.Filters.Rules.Enabled && !cfg.ForwardMode && !cfg.IsCaptureSet() && !cfg.IsFilamentSet() {
142143
engine = rules.NewEngine(psnap, cfg)
143144
var err error
144145
rs, err = engine.Compile()
@@ -203,9 +204,8 @@ func (f *App) Run(args []string) error {
203204
// In case of a regular run, we additionally set up the aggregator.
204205
// The aggregator will grab the events from the queue, assemble them
205206
// into batches and hand over to output sinks.
206-
filamentName := cfg.Filament.Name
207-
if filamentName != "" {
208-
f.filament, err = filament.New(filamentName, f.psnap, f.hsnap, cfg)
207+
if cfg.IsFilamentSet() {
208+
f.filament, err = filament.New(cfg.Filament.Name, f.psnap, f.hsnap, cfg)
209209
if err != nil {
210210
return err
211211
}
@@ -234,6 +234,10 @@ func (f *App) Run(args []string) error {
234234
f.symbolizer = symbolize.NewSymbolizer(symbolize.NewDebugHelpResolver(cfg), f.psnap, cfg, false)
235235
f.evs.RegisterEventListener(f.symbolizer)
236236
}
237+
// register evasion scanner
238+
if cfg.Evasion.Enabled {
239+
f.evs.RegisterEventListener(evasion.NewScanner(cfg.Evasion))
240+
}
237241
// register rule engine
238242
if f.engine != nil {
239243
f.evs.RegisterEventListener(f.engine)
@@ -314,9 +318,9 @@ func (f *App) ReadCapture(ctx context.Context, args []string) error {
314318
if err != nil {
315319
return err
316320
}
317-
filamentName := f.config.Filament.Name
318-
if filamentName != "" {
319-
f.filament, err = filament.New(filamentName, f.psnap, f.hsnap, f.config)
321+
322+
if f.config.IsFilamentSet() {
323+
f.filament, err = filament.New(f.config.Filament.Name, f.psnap, f.hsnap, f.config)
320324
if err != nil {
321325
return err
322326
}
@@ -355,6 +359,7 @@ func (f *App) ReadCapture(ctx context.Context, args []string) error {
355359
return err
356360
}
357361
}
362+
358363
return api.StartServer(f.config)
359364
}
360365

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
version: '3'
2+
3+
vars:
4+
SYSWHISPERS3_REPO: https://github.com/klezVirus/SysWhispers3.git
5+
VISUAL_STUDIO_EDITION: Enterprise
6+
VISUAL_STUDIO_VERSION: 2022
7+
8+
tasks:
9+
direct-syscall:
10+
desc: Builds the binary to perform direct syscalls via Syswhispers generated stubs
11+
dir: direct-syscall
12+
cmds:
13+
- git clone {{ .SYSWHISPERS3_REPO }}
14+
- python SysWhispers3/syswhispers.py -a x64 -c msvc -p common -o syscalls
15+
- cmd.exe /c 'C:\"Program Files"\"Microsoft Visual Studio"\{{ .VISUAL_STUDIO_VERSION }}\{{ .VISUAL_STUDIO_EDITION }}\VC\Auxiliary\Build\vcvars64.bat && nmake -f Makefile.msvc'
16+
silent: true
17+
18+
all:
19+
deps:
20+
- direct-syscall
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
OPTIONS = -Zp8 -c -nologo -Gy -Os -O1 -GR- -EHa -Oi -GS-
2+
LIBS = libvcruntime.lib libcmt.lib ucrt.lib kernel32.lib
3+
4+
main:
5+
ML64 /c syscalls-asm.x64.asm /link /NODEFAULTLIB /RELEASE /MACHINE:X64
6+
cl.exe $(OPTIONS) syscalls.c main.c
7+
link.exe /OUT:direct-syscall.exe -nologo $(LIBS) /MACHINE:X64 -subsystem:console -nodefaultlib syscalls-asm.x64.obj syscalls.obj main.obj
23.5 KB
Binary file not shown.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include "syscalls.h"
2+
3+
#include <Windows.h>
4+
5+
int main(int argc, char* argv[])
6+
{
7+
Sw3NtSetContextThread(-1, NULL);
8+
return 0;
9+
}
1.02 KB
Binary file not shown.

0 commit comments

Comments
 (0)