Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
LID — LID — Linux Integrity Drift: eBPFパス名書き換えによるAppArmorのバイパス。監査フットプリントゼロのLSM前syscall引数操作。「Linuxは死につつある」 | Kitploit
ツール/GitHubGitHub/azqzazq1/lid
特権昇格脆弱性分析エクスプロイトIDS/IPS回避ペネトレーションテストバイナリ解析論文と研究学習と教育レッドチーミング
GitHubazqzazq1/lid

LID

LID — Linux Integrity Drift: eBPFパス名書き換えによるAppArmorのバイパス。監査フットプリントゼロのLSM前syscall引数操作。「Linuxは死につつある」

2012ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
リポジトリを見る


``` ██╗ ██╗██████╗ ██║ ██║██╔══██╗ ██║ ██║██║ ██║ ██║ ██║██║ ██║ ███████╗██║██████╔╝ ╚══════╝╚═╝╚═════╝ ```

Linux Integrity Drift

— 「Linuxは死にかけている」 —


LSMのセキュリティ保証を迂回するカーネルコードパスの体系的な発見
門は破られたのではない。迂回されたのだ。



LIDとは何か?

Linux Security Moduleフレームワークには、20年以上にわたって維持されてきた中核的な保証が1つあります:

セキュリティモジュールは制限を追加することしかできない。制限を削除することは決してできない。

この保証は正しい。LIDはそれを破らない。

LIDはLSMフックを完全に迂回するカーネルコードパスを発見する — LSMフレームワークに相談せずにセキュリティ上重要な操作を実行するサブシステム。セキュリティチェック自体は正しい。問題は、カーネルがそもそも問い合わせないことにある。


LIDが何であるか(そして何でないか)を理解する

各発見には、混同すべきではない2つの異なる側面があります:

A) ポリシー可視性ギャップ

アーキテクチャ上の盲点。「攻撃者はこれを悪用できるか?」という問いではなく:

  • AppArmor/SELinuxは実際に何を見ているのか?
  • 監査ログは何を記録するのか?
  • あなたのSIEM/EDRは何を観測するのか?
  • ポリシーエンジンは何が起こったと認識するのか?

セキュリティ上重要な操作が発生し、強制レイヤーがそれを評価すらしない場合、攻撃者が今日実際に悪用できるかどうかに関係なく、可視性ギャップが存在します。これはコンプライアンス、フォレンジック、多層防御の前提にとって重要です。

B) 実用的な権限昇格経路

現実世界での悪用可能性に関する問い:

  • 特権境界を越えるか?
  • 攻撃者はトリガーするのに既存のroot/CAP_BPFを必要とするか?
  • エクスプロイトチェーンが必要か、それとも単独で成立するか?
  • 実際の影響は何か — データアクセス、権限昇格、ポリシー回避?

これら2つは別物です。 ある発見が重大な可視性ギャップ(あなたの監視が盲目である)であっても、実用的な権限昇格(攻撃者がすでにrootを必要とする)であるとは限りません。逆に、ある発見が最小限の前提条件で直接的な昇格経路になることもあります。


再現性マトリクス

各発見には特定のカーネル/設定/特権要件があります。環境が一致しない場合、その発見は再現しません。

LID-001: eBPFパス名書き換え

LID-002: io_uring MSG_RING

LID-004: BPFトークンのAppArmor盲目化

LID-003: 新しいマウントAPI

LID-005: AF_XDP tc Egress迂回

クイックリファレンス: 各発見をブロックするもの


発見結果


パターン

すべての発見は同じパターンに従います:``` ┌─────────────────────────────────────────────────────────────┐ │ THE LID PATTERN │ │ │ │ Kernel Subsystem A LSM Framework │ │ (eBPF / io_uring / mount API) (AppArmor / SELinux) │ │ │ │ ┌───────────────────┐ │ │ │ Performs operation │──── should call ──── security_*() │ │ │ or manipulates │ but │ │ │ security input │ DOESN'T ██ │ │ └───────────────────┘ │ │ │ │ The LSM framework is correct. │ │ The kernel just doesn't always use it. │ └─────────────────────────────────────────────────────────────┘

root@kitploit:~
二つのカーネルサブシステム。相容れない信頼の前提。一つのギャップ。

<br>

---

## LID-001: eBPF パス名書き換え

**最重要の発見。** `do_sys_openat2` 上の BPF kprobe は、カーネルがコピーする前にユーザーメモリ内のファイル名を書き換える。AppArmor は書き換えられたパスをチェックし、アクセスを許可する。監査トレースはゼロ。```
  process: open("/tmp/secret.txt")
       │
       ▼
  do_sys_openat2()
       │
    ★ LID kprobe fires here
    │  bpf_probe_write_user()
    │  rewrites "/tmp/secret.txt" → "/tmp/.bypass_link"
       │
       ▼
  getname_flags()          ← kernel copies the (rewritten) path
       │
       ▼
  security_file_open()     ← LSM hooks check "/tmp/.bypass_link"
       │                      AppArmor: ALLOW ✓
       ▼
  VFS opens inode          ← same file content (hard link)
       │
       ▼
  return fd to process     ← success, zero audit trace

クイックスタート```bash

sudo ./scripts/check_prerequisites.sh sudo ./scripts/setup_env.sh make sudo ./scripts/setup_demo.sh sudo ./scripts/run_demo.sh

root@kitploit:~
### デモ出力```
╔══════════════════════════════════════════════════════════╗
║  Phase 1: AppArmor ENFORCING — access should be DENIED   ║
╚══════════════════════════════════════════════════════════╝

  $ /tmp/test_reader
  [-] DENIED: open() failed: Permission denied (errno=13)

╔══════════════════════════════════════════════════════════╗
║  Phase 2: Loading LID — BPF kprobe pathname rewrite       ║
╚══════════════════════════════════════════════════════════╝

  [*] BPF kprobe attached to do_sys_openat2

╔══════════════════════════════════════════════════════════╗
║  Phase 3: With LID active — access should be GRANTED      ║
╚══════════════════════════════════════════════════════════╝

  $ /tmp/test_reader
  [+] SUCCESS: Read 44 bytes: SECRET_DATA=this_is_protected_content_12345

╔══════════════════════════════════════════════════════════╗
║  Phase 4: Stealth check — audit log inspection             ║
╚══════════════════════════════════════════════════════════╝

  $ dmesg | grep apparmor | grep DENIED
  (empty — no denial was ever generated)


LID-002: io_uring MSG_RING における LSM フック欠落

IORING_OP_MSG_RING と IORING_MSG_SEND_FD を組み合わせると、io_uring リング間でファイルディスクリプタが転送されますが、security_file_receive() が呼び出されません。他のすべての fd 転送機構ではこの関数が呼び出されます。``` MSG_RING SEND_FD: __io_fixed_fd_install() ← NO security_file_receive() FIXED_FD_INSTALL: receive_fd() ← security_file_receive() ✓ SCM_RIGHTS: receive_fd() ← security_file_receive() ✓ binder: security_binder_transfer_file() ✓

root@kitploit:~
**バグ箇所:** `io_uring/msg_ring.c` の `io_msg_install_complete()` — `__io_fixed_fd_install()` を直接呼び出し、LSMフックをスキップします。

**ftraceで検証済み:** `security_file_receive` は SCM_RIGHTS では発火するが、MSG_RING では発火しない。

**影響を受けるバージョン:** Linux 5.18+ から v7.1-rc3 まで(2026-05-17 時点では未修正)。

**PoC:** [`findings/lid-002-iouring-msgring/msg_ring_bypass.c`](https://github.com/azqzazq1/lid/blob/HEAD/findings/lid-002-iouring-msgring/)

<br>

---

## LID-003: 新しいマウント API が AppArmor をバイパスする

新しいマウント API(`fsopen` + `fsconfig` + `fsmount` + `move_mount`)は **決して `security_sb_mount()` を呼び出しません** — これは AppArmor が実装している唯一のマウントフックです。```
  OLD API:  mount("proc", "/mnt", "proc", 0, NULL)
            → security_sb_mount()  → AppArmor: DENY ✗

  NEW API:  fsopen("proc") → fsconfig(CMD_CREATE) → fsmount() → move_mount()
            → security_sb_kern_mount()  → AppArmor: (not implemented) → ALLOW ✓

AppArmor は 4 個のマウントフックを登録しています。SELinux は 14 個を登録しています。新しいマウント API は、SELinux だけが実装しているフックを使用します。

追加で見つかったギャップ:

  • open_tree(OPEN_TREE_CLONE): セキュリティフックがゼロ — バインドマウントポリシーをバイパスします
  • mount_setattr(): カーネルには LSM フックが一切存在しません
  • move_mount() (デタッチされたマウント): AppArmor は NULL ソースパスを認識します

詳細: findings/lid-003-mount-api/



LID-004: BPF トークン — AppArmor カバレッジゼロ

BPF トークンサブシステム (Linux 6.9+) は、BPF ケーパビリティをユーザー名前空間内の非特権プロセスに委任します。カーネルは 9 個の BPF LSM フックを定義しています。SELinux は実際の avc_has_perm() による強制で 9 個すべてを実装しています。AppArmor は ゼロ を実装しています。``` Kernel defines 9 BPF LSM hooks: ┌─────────────────────────────────────────────────────────────────┐ │ bpf, bpf_map, bpf_prog, bpf_map_create, bpf_prog_load, │ │ bpf_token_create, bpf_token_free, bpf_token_cmd, │ │ bpf_token_capable │ └─────────────────────────────────────────────────────────────────┘

SELinux: ████████████████████████████ 9/9 implemented AppArmor: 0/9 implemented Smack: 0/9 implemented

root@kitploit:~
Ubuntu/Debian では、bpffs の委任を持つコンテナは次のことが可能です:
- BPF トークンを作成 → AppArmor は何も検知しない
- トークンを使ってトレーシングプログラムをロード → AppArmor は何も検知しない
- CAP_PERFMON を委任 → Spectre 緩和策を無効化 → AppArmor は何も検知しない

**詳細:** [`findings/lid-004-bpf-token/`](https://github.com/azqzazq1/lid/blob/HEAD/findings/lid-004-bpf-token/)

<br>

---

## LID-005: デフォルト Docker コンテナからの AF_XDP tc Egress バイパス

AF_XDP のコピーモード送信パス(`xsk_generic_xmit` → `__dev_direct_xmit`)は、コンテナのインターフェース上で **tc egress classifier をバイパスします**。tc u32 の DROP-ALL で検証済み — AF_PACKET はブロックされ、AF_XDP は通過します。

**ただし:** Cilium v1.19(kind クラスタ、全て拒否の egress NetworkPolicy)でテスト済み — **Cilium はバイパスされませんでした。** Cilium はノード側の veth ピア ingress で強制し(`cil_from_container` を tcx/ingress 経由で)、さらに送信元 IP 検証を行います。AF_XDP パケットは `bpf_lxc.c:1603` で「Invalid source ip」としてドロップされました。影響は、ネットワークポリシーを tc egress classifier のみに依存する環境(プレーンな Docker + tc ルール、CNI なし)に限定されます。```
  Normal TX path:
  socket → dev_queue_xmit() → sch_handle_egress() → tc classifiers → driver
                                     ↑
                                  ENFORCED (Cilium eBPF, Calico, tc u32)

  AF_XDP copy-mode TX:
  xsk_sendmsg() → xsk_generic_xmit() → __dev_direct_xmit() → driver
                                              ↑
                                           SKIPPED (tc never runs)

カーネル 6.8.0 上の Docker デフォルトコンテナで動的に検証済み:``` tc egress DROP-ALL on container eth0:

AF_PACKET sendto → ENOBUFS (BLOCKED by tc) AF_XDP sendto → 0 (BYPASS — 3 spoofed packets reached docker0 bridge)

root@kitploit:~
パケットは攻撃者が制御するEthernetヘッダー — 偽装されたMAC、偽装されたIP — を運び、有効なDROPポリシーにもかかわらずDockerブリッジに到達します。

**PoC + 詳細:** [`findings/lid-005-afxdp-tc-bypass/`](https://github.com/azqzazq1/lid/blob/HEAD/findings/lid-005-afxdp-tc-bypass/)

<br>

---

## アーキテクチャ: BPF LSMがこれを修正できない理由```
  LSM Hook Chain: call_int_hook(file_open, ...)

  ┌─────────────┐   ┌─────────────┐   ┌─────────────┐   ┌─────────────┐
  │  Lockdown    │──>│  Capability  │──>│   AppArmor   │──>│  BPF LSM    │
  │  return 0    │   │  return 0    │   │  return -13  │   │  (never     │
  │  (allow)     │   │  (allow)     │   │  (DENY) ██   │   │   reached)  │
  └─────────────┘   └─────────────┘   └──────┬───────┘   └─────────────┘
                                              │
                                         loop breaks
                                         RC = -EACCES

  ★ The LSM framework is correct. No module can undo another's denial.
  ★ LID operates OUTSIDE the framework — before hooks run, or where hooks don't exist.

コンパニオン: SunnyDayBPF```

root@kitploit:~
               ┌───────────────────────────────────────┐
               │          THE ATTACK TIMELINE           │
               │                                       │

Syscall Entry │ ★ LID ─── manipulates input │ │ │ (security check sees wrong data) │ ▼ │ │ LSM Check │ LSM allows (or never runs) ✓ │ │ │ │ ▼ │ │ Syscall Exit │ ★ SunnyDayBPF ─── rewrites telemetry │ │ │ (monitoring sees wrong data) │ ▼ │ │ Audit/Log │ SIEM sees nothing ✓ │ │ │ │ Combined: ghost access │ └───────────────────────────────────────┘

root@kitploit:~
<br>

## プロジェクト構造```
LID/
├── src/
│   ├── bpf/
│   │   └── lid.bpf.c              # BPF kprobe — pathname rewriter (LID-001)
│   └── loader/
│       └── lid_loader.c           # Userspace loader + event monitor
├── findings/
│   ├── lid-001-ebpf-pathname/     # eBPF pathname rewriting bypass
│   ├── lid-002-iouring-msgring/   # io_uring MSG_RING missing LSM hook
│   │   ├── msg_ring_bypass.c      # PoC with ftrace verification
│   │   └── ADVISORY.md            # Technical advisory
│   ├── lid-003-mount-api/         # New mount API AppArmor bypass
│   ├── lid-004-bpf-token/        # BPF token AppArmor/Smack zero coverage
│   └── lid-005-afxdp-tc-bypass/  # AF_XDP tc egress bypass from container
├── tests/
│   └── test_reader.c              # Victim binary for LID-001 demo
├── scripts/
│   ├── check_prerequisites.sh     # Verify system requirements
│   ├── setup_env.sh               # Install build dependencies
│   ├── setup_demo.sh              # Create demo environment
│   ├── run_demo.sh                # Run full LID-001 demonstration
│   └── teardown.sh                # Clean up everything
├── docs/
│   └── RESEARCH.md                # Full technical research paper
├── publish/                       # Articles for Medium, dev.to, etc.
├── Makefile
├── LICENSE
├── SECURITY.md
└── README.md

ステルスプロファイル (LID-001)


緩和策

緩和策の詳細なガイダンスについては、docs/RESEARCH.md を参照してください。


要件

各検証結果の完全な詳細については、再現性マトリックス を参照してください。概要:


作者

Azizcan Daştan
Milenium Security

  • GitHub: @azqzazq1

免責事項

このツールは、認可されたセキュリティテスト、研究、教育目的のみで公開されています。所有していない、または明示的な書面によるテスト許可を得ていないシステムに対して使用しないでください。


LID — なぜなら、整合性は決してロックされていなかったからです。

ツールをダウンロード
FindingVisibility GapPractical Escalation
LID-001重大 — AppArmorは何も見ず、監査ログは空、フォレンジックの痕跡ゼロ限定的 — rootまたはCAP_BPF+CAP_PERFMONを必要とする(すでに特権あり)。権限昇格ではない。影響:ポリシー回避+監査の盲目化。
LID-002高 — security_file_receive()が発火せず、fd転送がすべてのLSMから不可視高 — io_uring経由で非特権ユーザースペースから動作。いかなる特権もなしにLSM強制境界を越える。
LID-003高 — security_sb_mount()が迂回され、AppArmorのマウントポリシーはデッドコード中 — マウント名前空間へのアクセスを必要とする(ユーザー名前空間内のCAP_SYS_ADMIN)。多くのコンテナ設定で利用可能。
LID-004重大 — AppArmorは何も見ず、BPFフックはゼロ(0/9)、BPFトークン操作の監査トレースなし中 — ホストによるbpffs委任+ユーザー名前空間内のCAP_BPFを必要とする。BPF委任を備えたコンテナランタイム(LXD/Incus)で利用可能。
LID-005中 — コンテナインターフェース上のtc egress分類子がAF_XDPトラフィックを評価しない限定的 — コンテナeth0上のtc egressを迂回(検証済み)。Ciliumは迂回されない — ノード側veth ingressで強制+送信元IP検証(テスト済み)。影響はtc専用egressフィルタリングの素のDocker構成に限定。
ConditionRequiredNotes
カーネルバージョン5.x+5.15、6.1、6.6、6.8でテスト済み
CONFIG_BPF_SYSCALL=y主要な全ディストロでデフォルト
CONFIG_BPF_KPROBE_OVERRIDE=yUbuntu/Debianは有効、RHELは無効
CONFIG_SECURITY_APPARMOR=y対象LSMはAppArmorである必要あり
AppArmorプロファイルEnforcing、対象パスへのdenyルール任意のパスベースdenyルールで動作
特権rootまたはCAP_BPF+CAP_PERFMON非特権では実行不可
kernel.lockdownnoneまたはintegrityconfidentialityモードはkprobeアタッチをブロック
kernel.unprivileged_bpf_disabled無関係いずれにせよCAP_BPFが必要
fs.protected_hardlinksクロスユーザーリンクでは01(デフォルト)でも同ユーザーのハードリンクは許可
SELinuxをAppArmorの代わりに使用動作しないSELinuxはinodeベースであり、パス名ベースではない
ConditionRequiredNotes
カーネルバージョン6.0+IORING_MSG_SEND_FDは6.0で追加
CONFIG_IO_URING=y主要な全ディストロでデフォルト
特権不要非特権ユーザースペースから動作
io_uring_disabled sysctl0(デフォルト)2は非特権をブロック、1はすべてをブロック
対象LSM任意(SELinux、AppArmor、Smack)security_file_receive()は汎用LSMフック
kernel.lockdown無関係BPFは関与しない
ConditionRequiredNotes
カーネルバージョン6.9+BPFトークンは6.9で導入
CONFIG_BPF_SYSCALL=y主要な全ディストロでデフォルト
CONFIG_SECURITY_APPARMOR=yUbuntu/Debianのデフォルト
委任付きbpffsありホストがdelegate_*オプションでマウントする必要あり
特権ユーザー名前空間内のCAP_BPFuserns rootには簡単に利用可能
SELinuxをAppArmorの代わりに使用影響なしSELinuxは9個すべてのBPFフックを実装
ConditionRequiredNotes
カーネルバージョン5.2+fsopen/fsmountは5.2で導入
CONFIG_SECURITY_APPARMOR=y影響を受けるのはAppArmorのみ
特権ユーザー名前空間内のCAP_SYS_ADMINunshare -mで利用可能
SELinuxをAppArmorの代わりに使用動作しないSELinuxはsecurity_sb_kern_mount()を実装
コンテナランタイムseccompフィルタに依存Dockerデフォルトのseccompはfsopenをブロック — Podman/LXCはブロックしない場合あり
ConditionRequiredNotes
カーネルバージョン4.18+AF_XDPは4.18で導入
CONFIG_XDP_SOCKETS=y主要な全ディストロでデフォルト
特権CAP_NET_RAWのみDocker、Kubernetesポッドでデフォルト
コンテナランタイムDocker、K8s、LXCデフォルトのケーパビリティセット
tcベースのネットワークポリシーありCilium eBPF、Calico、tc u32/flower
EnvironmentLID-001LID-002LID-003LID-004LID-005
Ubuntu 22.04+(AppArmor、デフォルト)動作動作動作動作(6.9+)動作
Debian 12+(AppArmor)動作動作動作動作(6.9+)動作
RHEL/Fedora(SELinux)不可動作不可不可動作
lockdown=confidentiality不可動作動作部分的動作
非特権ユーザー不可動作ユーザーns次第bpffs委任次第不可
コンテナ(CAP_BPFなし)不可io_uring次第seccomp次第不可動作
コンテナ(CAP_NET_RAW削除)不可次第次第不可不可
IDVectorTargetWhat Happens
LID-001eBPF kprobeパス名書き換えAppArmorkprobeがcopy_from_userの前にファイル名を書き換える → AppArmorは誤ったパスをチェック
LID-002io_uring MSG_RING SEND_FDSELinux、AppArmor、Smackfd転送がsecurity_file_receive()をスキップ — 他のすべてのfd転送はそれを呼ぶ
LID-003新しいマウントAPI(fsopen/fsmount)AppArmorsecurity_sb_mount()が呼ばれない — AppArmorの唯一のマウントフックが迂回される
LID-004BPFトークン委任AppArmor、SmackBPFフックがゼロ — トークン作成、使用、ケーパビリティ委任が完全に不可視
LID-005AF_XDP __dev_direct_xmittc egress、Cilium、CalicoデフォルトDockerからのコピーモードTXがtc分類子を迂回 — 偽造パケットがブリッジに到達
指標可視性備考
AppArmor監査ログなし拒否は発生しない
auditd / journaldなしセキュリティイベントは生成されない
dmesg一度きりの警告一般的な bpf_probe_write_user メッセージ
bpftool prog list表示されるアタッチされたkprobeを表示する(確認した場合)
ディスク上のハードリンク検出可能find -samefile (遅い、ノイズが多い)
緩和策効果トレードオフ
kernel.lockdown=confidentialityBPFを完全にブロック正当なモニタリングを無効化
bpf_probe_write_user を無効化LID-001のパス書き換えを防止カーネルの再ビルドが必要
fs.protected_hardlinks=1ハードリンクの作成を制限最近のカーネルではデフォルト
bpftool prog list を監視アタッチされたプローブを検出能動的なポーリングが必要
SELinuxへの移行inodeベースで、パス書き換えを無効化複雑な移行
io_uringを制限LID-002をブロックアプリケーションを壊す可能性がある
検証結果最小カーネル権限対象
LID-0015.x+root / CAP_BPF+CAP_PERFMONAppArmorのみ
LID-0026.0+なしすべて (SELinux、AppArmor、Smack)
LID-0035.2+CAP_SYS_ADMIN (ユーザー名前空間OK)AppArmorのみ
LID-0046.9+CAP_BPF (ユーザー名前空間OK)AppArmor、Smack
LID-0054.18+CAP_NET_RAW (Dockerデフォルト)tc egress (Cilium、Calicoなど)