KRIe は、eBPF を用いて Linux カーネルのエクスプロイトを検出することを目的とした研究プロジェクトです。KRIe は決して完全無欠な戦略ではありません。eBPF に関連する制限や、侵害されたカーネルに依存してセキュリティイベントを出力する可能性のあるポストエクスプロイト検出など、意図を持った攻撃者があれば最終的には回避できることは明らかです。とはいえ、このプロジェクトの目標は、攻撃者の活動を困難にし、最終的には既存のエクスプロイトが脆弱なカーネル上で動作するのを防ぐことです。
KRIe は CO-RE (Compile Once - Run Everywhere) を使用して開発されており、幅広いカーネルバージョンと互換性があります。カーネルが BTF デバッグ情報をエクスポートしていない場合、KRIe は BTFHub から自動的にダウンロードを試みます。カーネルが BTFHub に存在しない場合でも、手動でカーネルの BTF データを生成できた場合は、設定ファイルで指定することができます(以下参照)。
このプロジェクトは Ubuntu Focal 20.04(Linux カーネル 5.15)で開発され、Ubuntu Bionic 18.04(Linux カーネル 4.15)までの古いリリースでテストされています。
lib/modules/$(uname -r) にインストールされていることを想定しています。それ以外の場所にある場合は、Makefile の場所を更新してください。オプションフィールドは、eBPF プログラムを再コンパイルするために必要です。
# ~ make build-ebpf
# ~ make build
# ~ make install
KRIe は root 権限で実行する必要があります。ヘルプを表示するには sudo krie -h を実行してください。
# ~ krie -h
Usage:
krie [flags]
Flags:
--config string KRIe config file (default "./cmd/krie/run/config/default_config.yaml")
-h, --help help for krie
## ログレベル。オプション: panic, fatal, error, warn, info, debug, trace
log_level: debug
## JSON 出力ファイル。空のままにすると JSON 出力は無効になります。
output: "/tmp/krie.json"
## 現在のカーネルの BTF 情報(.tar.xz 形式)。KRIE が自動的に特定できない場合にのみ必要です。
vmlinux: ""
## イベント設定
events:
## init_module イベントが検出されたときのアクション
init_module: log
## delete_module イベントが検出されたときのアクション
delete_module: log
## bpf イベントが検出されたときのアクション
bpf: log
## bpf_filter イベントが検出されたときのアクション
bpf_filter: log
## ptrace イベントが検出されたときのアクション
ptrace: log
## kprobe イベントが検出されたときのアクション
kprobe: log
## sysctl イベントが検出されたときのアクション
sysctl:
action: log
## sysctl プログラムのデフォルト設定(カーネル 5.2 以降のみ)
sysctl_default:
block_read_access: false
block_write_access: false
## sysctl プログラムのカスタム設定(カーネル 5.2 以降のみ)
sysctl_parameters:
kernel/yama/ptrace_scope:
block_write_access: true
kernel/ftrace_enabled:
override_input_value_with: "1\n"
## hooked_syscall_table イベントが検出されたときのアクション
hooked_syscall_table: log
## hooked_syscall イベントが検出されたときのアクション
hooked_syscall: log
## kernel_parameter イベント設定
kernel_parameter:
action: log
periodic_action: log
ticker: 1 # 1秒間に最大1回イベントを送信
list:
- symbol: system/kprobes_all_disarmed
expected_value: 0
size: 4
# - symbol: system/selinux_state
# expected_value: 256
# size: 2
# sysctl
- symbol: system/ftrace_dump_on_oops
expected_value: 0
size: 4
- symbol: system/kptr_restrict
expected_value: 0
size: 4
- symbol: system/randomize_va_space
expected_value: 2
size: 4
- symbol: system/stack_tracer_enabled
expected_value: 0
size: 4
- symbol: system/unprivileged_userns_clone
expected_value: 0
size: 4
- symbol: system/unprivileged_userns_apparmor_policy
expected_value: 1
size: 4
- symbol: system/sysctl_unprivileged_bpf_disabled
expected_value: 1
size: 4
- symbol: system/ptrace_scope
expected_value: 2
size: 4
- symbol: system/sysctl_perf_event_paranoid
expected_value: 2
size: 4
- symbol: system/kexec_load_disabled
expected_value: 1
size: 4
- symbol: system/dmesg_restrict
expected_value: 1
size: 4
- symbol: system/modules_disabled
expected_value: 0
size: 4
- symbol: system/ftrace_enabled
expected_value: 1
size: 4
- symbol: system/ftrace_disabled
expected_value: 0
size: 4
- symbol: system/sysctl_protected_fifos
expected_value: 1
size: 4
- symbol: system/sysctl_protected_hardlinks
expected_value: 1
size: 4
- symbol: system/sysctl_protected_regular
expected_value: 2
size: 4
- symbol: system/sysctl_protected_symlinks
expected_value: 1
size: 4
- symbol: system/sysctl_unprivileged_userfaultfd
expected_value: 0
size: 4
## 機密カーネル空間フックポイントで register_check が失敗した場合のアクション
register_check: log