• Stars
    star
    346
  • Rank 118,463 (Top 3 %)
  • Language
    C
  • License
    GNU General Publi...
  • Created over 5 years ago
  • Updated 8 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A kernelspace syscall interceptor and randomized faulter

KRF

CI

KRF is a Kernelspace Randomized Faulter.

It currently supports the Linux and FreeBSD kernels.

What?

Fault injection is a software testing technique that involves inducing failures ("faults") in the functions called by a program. If the callee has failed to perform proper error checking and handling, these faults can result in unreliable application behavior or exploitable vulnerabilities.

Unlike the many userspace fault injection systems out there, KRF runs in kernelspace via a loaded module. This has several advantages:

  • It works on static binaries, as it does not rely on LD_PRELOAD for injection.
  • Because it intercepts raw syscalls and not their libc wrappers, it can inject faults into calls made by syscall(3) or inline assembly.
  • It's probably faster and less error-prone than futzing with dlsym.

There are also several disadvantages:

  • You'll probably need to build it yourself.
  • It probably only works on x86(_64), since it twiddles cr0 manually. There is probably an architecture-independent way to do that in Linux, somewhere.
  • It's essentially a rootkit. You should definitely never, ever run it on a non-testing system.
  • It probably doesn't cover everything that the Linux kernel expects of syscalls, and may destabilize its host in weird and difficult to reproduce ways.

How does it work?

KRF rewrites the Linux or FreeBSD system call table: when configured via krfctl, KRF replaces faultable syscalls with thin wrappers.

Each wrapper then performs a check to see whether the call should be faulted using a configurable targeting system capable of targeting a specific personality(2), PID, UID, and/or GID. If the process shouldn't be faulted, the original syscall is invoked.

Finally, the targeted call is faulted via a random failure function. For example, a read(2) call might receive one of EBADF, EINTR, EIO, and so on.

You can read more about KRF's implementation in our blog post.

Setup

Compatibility

NOTE: If you have Vagrant, just use the Vagrantfile and jump to the build steps.

KRF should work on any recent-ish (4.15+) Linux kernel with CONFIG_KALLSYMS=1.

This includes the default kernel on Ubuntu 18.04 and probably many other recent distros.

Dependencies

NOTE: Ignore this if you're using Vagrant.

Apart from a C toolchain (GCC is probably necessary for Linux), KRF's only dependencies should be libelf, the kernel headers, and Ruby (>=2.4, for code generation).

GNU Make is required on all platforms; FreeBSD additionally requires BSD Make.

For systems with apt:

sudo apt install gcc make libelf-dev ruby linux-headers-$(uname -r)

Building

git clone https://github.com/trailofbits/krf && cd krf
make -j$(nproc)
sudo make install # Installs module to /lib/modules and utils to /usr/local/bin
sudo make insmod # Loads module

or, if you're using Vagrant:

git clone https://github.com/trailofbits/krf && cd krf
vagrant up linux && vagrant ssh linux
# inside the VM
cd /vagrant
make -j$(nproc)
sudo make install # Installs module to /lib/modules and utils to /usr/local/bin
sudo make insmod # Loads module

or, for FreeBSD:

git clone https://github.com/trailofbits/krf && cd krf
cd vagrant up freebsd && vagrant ssh freebsd
# inside the VM
cd /vagrant
gmake # NOT make!
gmake install-module # Installs module to /boot/modules/
sudo gmake install-utils # Installs utils to /usr/local/bin
gmake insmod # Loads module

Usage

KRF has three components:

  • A kernel module (krfx)
  • An execution utility (krfexec)
  • A control utility (krfctl)
  • A kernel module logger (krfmesg)

To load the kernel module, run make insmod. To unload it, run make rmmod.

For first time use it might be useful to launch sudo krfmesg on a separate terminal to see messages logged from krfx.

KRF begins in a neutral state: no syscalls will be intercepted or faulted until the user specifies some behavior via krfctl:

# no induced faults, even with KRF loaded
ls

# tell krf to fault read(2) and write(2) calls
# note that krfctl requires root privileges
sudo krfctl -F 'read,write'

# tell krf to fault any program started by
# krfexec, meaning a personality of 28
sudo krfctl -T personality=28

# may fault!
krfexec ls

# tell krf to fault with a 1/100 (or 1%) probability
# note that this value is represented as a reciprocal
# so e.g. 1 means all faultable syscalls will fault
# and 500 means that on average every 500 syscalls will fault (1/500 or 0.2%)
sudo krfctl -p 100

# tell krf to fault `io` profile (and so i/o related syscalls)
sudo krfctl -P io

# krfexec will pass options correctly as well
krfexec echo -n 'no newline'

# clear the fault specification
sudo krfctl -c

# clear the targeting specification
sudo krfctl -C

# no induced faults, since no syscalls are being faulted
krfexec firefox

Configuration

NOTE: Most users should use krfctl instead of manipulating these files by hand. In FreeBSD, these same values are accessible through sysctl krf.whatever instead of procfs.

/proc/krf/rng_state

This file allows a user to read and modify the internal state of KRF's PRNG.

For example, each of the following will correctly update the state:

echo "1234" | sudo tee /proc/krf/rng_state
echo "0777" | sudo tee /proc/krf/rng_state
echo "0xFF" | sudo tee /proc/krf/rng_state

The state is a 32-bit unsigned integer; attempting to change it beyond that will fail.

/proc/krf/targeting

This file allows a user set the values used by KRF for syscall targeting.

NOTE: KRF uses a default personality not currently used by the Linux kernel by default. If you change this, you should be careful to avoid making it something that Linux cares about. man 2 personality has the details.

echo "0 28" | sudo tee /proc/krf/targeting

A personality of 28 is hardcoded into krfexec, and must be set in order for things executed by krfexec to be faulted.

/proc/krf/probability

This file allows a user to read and write the probability of inducing fault for a given (faultable) syscall.

The probability is represented as a reciprocal, e.g. 1000 means that, on average, 0.1% of faultable syscalls will be faulted.

echo "100000" | sudo tee /proc/krf/probability

/proc/krf/control

This file controls the syscalls that KRF faults.

NOTE: Most users should use krfctl instead of interacting with this file directly — the former will perform syscall name-to-number translation automatically and will provide clearer error messages when things go wrong.

# replace the syscall in slot 0 (usually SYS_read) with its faulty wrapper
echo "0" | sudo tee /proc/krf/control

Passing any number greater than KRF_NR_SYSCALLS will cause KRF to flush the entire syscall table, returning it to the neutral state. Since KRF_NR_SYSCALLS isn't necessarily predictable for arbitrary versions of the Linux kernel, choosing a large number (like 65535) is fine.

Passing a valid syscall number that lacks a fault injection wrapper will cause the write(2) to the file to fail with EOPNOTSUPP.

/proc/krf/log_faults

This file controls whether or not KRF emits kernel logs on faulty syscalls. By default, no logging messages are emitted.

NOTE: Most users should use krfctl instead of interacting with this file directly.

# enable fault logging
echo "1" | sudo tee /proc/krf/log_faults
# disable fault logging
echo "0" | sudo tee /proc/krf/log_faults
# read the logging state
cat /proc/krf/log_faults

TODO

  • Allow users to specify a particular class of faults, e.g. memory pressure (ENOMEM).
    • This should be do-able by adding some more bits to the personality(2) value.

Thanks

Many thanks go to Andrew Reiter for the initial port of KRF to FreeBSD. Andrew's work was performed on behalf of the Applied Research Group at Veracode.

Licensing

KRF is licensed under the terms of the GNU GPLv3.

See the LICENSE file for the exact terms.

More Repositories

1

algo

Set up a personal VPN in the cloud
Jinja
27,779
star
2

manticore

Symbolic execution tool
Python
3,536
star
3

graphtage

A semantic diff utility and library for tree-like files such as JSON, JSON5, XML, HTML, YAML, and CSV.
Python
2,300
star
4

ctf

CTF Field Guide
C
1,273
star
5

publications

Publications from Trail of Bits
Python
1,232
star
6

deepstate

A unit test-like interface for fuzzing and symbolic execution
Python
806
star
7

pe-parse

Principled, lightweight C/C++ PE parser
C++
691
star
8

eth-security-toolbox

A Docker container preconfigured with all of the Trail of Bits Ethereum security tools.
Dockerfile
648
star
9

maat

Open-source symbolic execution framework: https://maat.re
C++
606
star
10

twa

A tiny web auditor with strong opinions.
Shell
579
star
11

winchecksec

Checksec, but for Windows: static detection of security mitigations in executables
C++
523
star
12

cb-multios

DARPA Challenges Sets for Linux, Windows, and macOS
C
498
star
13

polytracker

An LLVM-based instrumentation tool for universal taint tracking, dataflow analysis, and tracing.
C++
487
star
14

onesixtyone

Fast SNMP Scanner
C
411
star
15

tubertc

Peer-to-Peer Video Chat for Corporate LANs
JavaScript
361
star
16

vast

VAST is an experimental compiler pipeline designed for program analysis of C and C++. It provides a tower of IRs as MLIR dialects to choose the best fit representations for a program analysis or further program abstraction.
C++
340
star
17

fickling

A Python pickling decompiler and static analyzer
Python
330
star
18

polyfile

A pure Python cleanroom implementation of libmagic, with instrumented parsing from Kaitai struct and an interactive hex viewer
Python
322
star
19

it-depends

A tool to automatically build a dependency graph and Software Bill of Materials (SBOM) for packages and arbitrary source code repositories.
Python
313
star
20

sinter

A user-mode application authorization system for MacOS written in Swift
Swift
302
star
21

SecureEnclaveCrypto

Demonstration library for using the Secure Enclave on iOS
Swift
276
star
22

protofuzz

Google Protocol Buffers message generator
Python
262
star
23

dylint

A tool for running Rust lints from dynamic libraries
Rust
259
star
24

osquery-extensions

osquery extensions by Trail of Bits
C
256
star
25

constexpr-everything

Rewrite C++ code to automatically apply `constexpr` where possible
C++
245
star
26

binjascripts

Scripts for Binary Ninja
Python
241
star
27

RpcInvestigator

Exploring RPC interfaces on Windows
C#
236
star
28

audit-kubernetes

k8s audit repo
Go
226
star
29

mishegos

A differential fuzzer for x86 decoders
C++
219
star
30

semgrep-rules

Semgrep queries developed by Trail of Bits.
Go
197
star
31

circomspect

A static analyzer and linter for the Circom zero-knowledge DSL
Rust
186
star
32

PrivacyRaven

Privacy Testing for Deep Learning
Python
178
star
33

llvm-sanitizer-tutorial

An LLVM sanitizer tutorial
C++
177
star
34

siderophile

Find the ideal fuzz targets in a Rust codebase
Rust
171
star
35

flying-sandbox-monster

Sandboxed, Rust-based, Windows Defender Client
Rust
170
star
36

not-going-anywhere

A set of vulnerable Golang programs
Go
163
star
37

AppJailLauncher

CTF Challenge Framework for Windows 8 and above
C++
141
star
38

zkdocs

Interactive documentation on zero-knowledge proof systems and related primitives.
HTML
133
star
39

sienna-locomotive

A user-friendly fuzzing and crash triage tool for Windows
C++
132
star
40

uthenticode

A cross-platform library for verifying Authenticode signatures
C++
131
star
41

ObjCGraphView

A graph view plugin for Binary Ninja to visualize Objective-C
Python
127
star
42

Honeybee

An experimental high performance, fuzzing oriented Intel Processor Trace capture and analysis suite
C
124
star
43

sqlite_wrapper

An easy-to-use, extensible and lightweight C++17 wrapper for SQLite
C++
117
star
44

ctf-challenges

CTF Challenges
Python
112
star
45

ebpfpub

ebpfpub is a generic function tracing library for Linux that supports tracepoints, kprobes and uprobes.
C++
110
star
46

pasta

Peter's Amazing Syntax Tree Analyzer
C++
109
star
47

appjaillauncher-rs

AppJailLauncher in Rust
Rust
103
star
48

vscode-weaudit

Create code bookmarks and code highlights with a click.
TypeScript
103
star
49

test-fuzz

To make fuzzing Rust easy
Rust
100
star
50

on-edge

A library for detecting certain improper uses of the "Defer, Panic, and Recover" pattern in Go programs
Go
97
star
51

ios-integrity-validator

Integrity validator for iOS devices
Shell
97
star
52

abi3audit

Scans Python packages for abi3 violations and inconsistencies
Python
94
star
53

ebpfault

A BPF-based syscall fault injector
C++
93
star
54

binrec-tob

BinRec: Dynamic Binary Lifting and Recompilation
C++
92
star
55

clang-cfi-showcase

Sample programs that illustrate how to use control flow integrity with the clang compiler
C++
92
star
56

BTIGhidra

Binary Type Inference Ghidra Plugin
Java
88
star
57

blight

A framework for instrumenting build tools
Python
83
star
58

ManticoreUI

The Manticore User Interface with plugins for Binary Ninja and Ghidra
Python
71
star
59

bisc

Borrowed Instructions Synthetic Computation
Ruby
70
star
60

manticore-examples

Example Manticore scripts
Python
69
star
61

algo-ng

Experimental version of Algo built on Terraform
HCL
68
star
62

differ

Detecting Inconsistencies in Feature or Function Evaluations of Requirements
Python
64
star
63

deceptiveidn

Use computer vision to determine if an IDN can be interpreted as something it's not
Python
63
star
64

necessist

A tool for finding bugs in tests
Rust
59
star
65

reverie

An efficient and generalized implementation of the IKOS-style KKW proof system (https://eprint.iacr.org/2018/475) for arbitrary rings.
Rust
57
star
66

magnifier

C++
56
star
67

ruzzy

A coverage-guided fuzzer for pure Ruby code and Ruby C extensions
Ruby
53
star
68

awesome-ml-security

52
star
69

sixtyfour

How fast can we brute force a 64-bit comparison?
C
52
star
70

LeftoverLocalsRelease

The public release of LeftoverLocals code
C++
51
star
71

Codex-Decompiler

Python
50
star
72

DomTreSat

Dominator Tree LLVM Pass to Test Satisfiability
C++
47
star
73

nyc-infosec

Mapping the NYC Infosec Community
CSS
43
star
74

cfg-showcase

Sample programs that illustrate how to use Control Flow Guard, VS2015's control flow integrity implementation
C++
40
star
75

tsc_freq_khz

Linux kernel driver to export the TSC frequency via sysfs
C
40
star
76

HVCI-loldrivers-check

PowerShell
40
star
77

rubysec

RubySec Field Guide
Ruby
40
star
78

indurative

Easily create authenticated data structures
Haskell
37
star
79

http-security

Parse HTTP Security Headers
Ruby
36
star
80

trailofphish

Phishing e-mail repository
Ruby
36
star
81

KRFAnalysis

Collection of LLVM passes and triage tools for use with the KRF fuzzer
LLVM
34
star
82

spf-query

Ruby SPF Parser
Ruby
30
star
83

ebpf-verifier

Harness for the Linux kernel eBPF verifier
C
30
star
84

umberto

poststructural fuzzing
Haskell
30
star
85

ebpf-common

Various utilities useful for developers writing BPF tools
C++
28
star
86

clang-tidy-audit

Rewrite C/C++/Obj-C to Annotate Points of Interest
C++
27
star
87

macroni

C and C++ compiler frontend using PASTA to parse code, and VAST to represent the code as MLIR.
C
27
star
88

eatmynetwork

A small script for running programs with (minimal) network sandboxing
Shell
26
star
89

anselm

Detect patterns of bad behavior in function calls
C++
25
star
90

dmarc

Ruby DMARC Parser
Ruby
25
star
91

testing-handbook

Trail of Bits Testing Handbook
C++
25
star
92

btfparse

A C++ library that parses debug information encoded in BTF format
C++
22
star
93

linuxevents

A sample PoC for container-aware exec events for osquery
C++
22
star
94

mpc-learning

Perform multi-party computation on machine learning applications
Python
21
star
95

go-mutexasserts

A small library that allows to check if Go mutexes are locked
Go
21
star
96

screen

Measure branching along code paths
C
20
star
97

tacklebox

Phishing Toolkit
Ruby
20
star
98

itergator

CodeQL library and queries for iterator invalidation
CodeQL
19
star
99

WinDbg-JS

JavaScript
19
star
100

dkim-query

Ruby DKIM Parser
Ruby
18
star