Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
工具/GitHubGitHub/azqzazq1/lid
Privilege EscalationVulnerability AnalysisExploitationIDS/IPS EvasionPenetration TestingBinary AnalysisPapers & ResearchLearning & EducationRed Teaming
GitHubazqzazq1/lid

LID

LID — Linux Integrity Drift: Bypassing AppArmor via eBPF pathname rewriting. Pre-LSM syscall argument manipulation with zero audit footprint. "Linux is Dying"

查看仓库
2012个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享


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

Linux 完整性漂移

— "Linux 正在消亡" —


系统发现绕过 LSM 安全保证的内核代码路径
大门从未被攻破,只是被绕过了。



什么是 LID?

Linux 安全模块框架有一个核心保证,已经保持了 20 多年:

安全模块只能增加限制。它们永远不能移除限制。

这个保证是正确的。LID 并没有打破它。

LID 发现了完全绕过 LSM 钩子的内核代码路径——执行安全敏感操作而不咨询 LSM 框架的子系统。安全检查是正确的。问题是内核从未询问过。


理解 LID 是什么(以及不是什么)

每个发现有两个不同的维度,不应混为一谈:

A) 策略可见性差距

架构上的盲点。问题不是“攻击者能否利用这个?”而是:

  • AppArmor/SELinux 实际看到了什么?
  • 审计日志记录了什么?
  • 你的 SIEM/EDR 观察到了什么?
  • 策略引擎认为发生了什么?

如果发生了一个安全敏感操作,而执行层甚至从未对其进行评估,那么你就存在一个可见性差距——无论攻击者今天是否能够实际利用它。这对合规性、取证和纵深防御假设很重要。

B) 实际提权路径

现实世界中的可利用性问题:

  • 这是否跨越了权限边界?
  • 攻击者是否需要现有的 root/CAP_BPF 才能触发它?
  • 是需要利用链,还是独立存在?
  • 实际影响是什么——数据访问、权限提升、策略规避?

这两者是不同的。 一个发现可以是关键的可见性差距(你的监控是盲目的),而不一定是一个实际的权限提升(攻击者已经需要 root)。相反,一个发现可以是一个直接提权路径,具有最低的先决条件。

发现可见性差距实际提权
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 出站分类器永远不评估 AF_XDP 流量有限 — 绕过容器 eth0 上的 tc 出站(已验证)。Cilium 未被绕过——在节点侧 veth 入站加强并验证源 IP(已测试)。影响限于仅使用 tc 出站过滤的普通 Docker 设置。

可复现性矩阵

每个发现都有特定的内核/配置/权限要求。如果你的环境不匹配,该发现将无法复现。

LID-001:eBPF 路径名重写

条件要求注释
内核版本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 配置文件强制模式,目标路径上有拒绝规则适用于任何基于路径的拒绝规则
权限root 或 CAP_BPF + CAP_PERFMON不能以无特权方式运行
kernel.lockdownnone 或 integrityconfidentiality 模式阻止 kprobe 附加
kernel.unprivileged_bpf_disabled无关无论如何都需要 CAP_BPF
fs.protected_hardlinks跨用户链接需为 01(默认)仍允许同用户硬链接
SELinux 代替 AppArmor不工作SELinux 基于 inode,而不是基于路径名

LID-002:io_uring MSG_RING

条件要求注释
内核版本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

LID-004:BPF 令牌 AppArmor 盲区

条件要求注释
内核版本6.9+BPF 令牌在 6.9 中引入
CONFIG_BPF_SYSCALL=y所有主要发行版默认开启
CONFIG_SECURITY_APPARMOR=yUbuntu/Debian 默认
bpffs 启用了委托是主机必须使用 delegate_* 选项挂载
权限用户命名空间中的 CAP_BPF用户命名空间 root 可轻易获得
SELinux 代替 AppArmor不受影响SELinux 实现了所有 9 个 BPF 钩子

LID-003:新挂载 API

条件要求注释
内核版本5.2+fsopen/fsmount 在 5.2 中引入
CONFIG_SECURITY_APPARMOR=y仅影响 AppArmor
权限用户命名空间中的 CAP_SYS_ADMIN可通过 unshare -m 获取
SELinux 代替 AppArmor不工作SELinux 实现了 security_sb_kern_mount()
容器运行时取决于 seccomp 过滤器Docker 默认 seccomp 阻止 fsopen — Podman/LXC 可能不阻止

LID-005:AF_XDP tc 出站绕过

条件要求注释
内核版本4.18+AF_XDP 在 4.18 中引入
CONFIG_XDP_SOCKETS=y所有主要发行版默认开启
权限仅 CAP_NET_RAWDocker、Kubernetes Pod 默认具备
容器运行时Docker、K8s、LXC默认权限集
基于 tc 的网络策略是Cilium eBPF、Calico、tc u32/flower

速查表:哪些因素阻止每个发现

环境LID-001LID-002LID-003LID-004LID-005
Ubuntu 22.04+(AppArmor,默认)有效有效有效有效(6.9+)有效
Debian 12+(AppArmor)有效有效有效有效(6.9+)有效
RHEL/Fedora(SELinux)否有效否否有效
lockdown=confidentiality否有效有效部分有效
无特权用户否有效取决于用户命名空间取决于 bpffs 委托否
容器(无 CAP_BPF)否取决于 io_uring取决于 seccomp否有效
容器(已丢弃 CAP_NET_RAW)否取决于取决于否否

发现

ID向量目标发生了什么
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、Smack零 BPF 钩子 — 令牌创建、使用、能力委托完全不可见
LID-005AF_XDP __dev_direct_xmittc 出站、Cilium、Calico从默认 Docker 的复制模式 TX 绕过 tc 分类器 — 伪造的数据包到达网桥

模式

每个发现都遵循相同的模式:``` ┌─────────────────────────────────────────────────────────────┐ │ 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()。所有其他文件描述符传输机制都会调用它:``` 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 实现了所有 9 个,并带有真实的 avc_has_perm() 强制。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出口绕过

AF_XDP的拷贝模式传输路径(`xsk_generic_xmit` → `__dev_direct_xmit`)**绕过容器接口上的tc出口分类器**。已使用tc u32 DROP-ALL验证——AF_PACKET被阻止,AF_XDP通过。

**然而:** 使用Cilium v1.19(kind集群,拒绝所有出口NetworkPolicy)进行测试——**Cilium未被绕过。** Cilium在节点侧veth对端入口(通过tcx/ingress的`cil_from_container`)实施强制,并具有源IP验证。AF_XDP数据包在`bpf_lxc.c:1603`处作为"Invalid source ip"被丢弃。影响仅限于仅依赖tc出口分类器进行网络策略的环境(纯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)

在 Docker 默认容器上动态验证于内核 6.8.0:``` 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:~
数据包携带攻击者控制的以太网头部——伪造的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)

指标可见性备注
AppArmor 审计日志无拒绝从未发生
auditd / journald无未生成安全事件
dmesg一次性警告通用 bpf_probe_write_user 消息
bpftool prog list可见显示已附加的 kprobe(如果检查)
磁盘上的硬链接可检测find -samefile(缓慢、嘈杂)

缓解措施

缓解措施有效性权衡
kernel.lockdown=confidentiality完全阻止 BPF导致合法监控失效
禁用 bpf_probe_write_user阻止 LID-001 路径重写需要重新编译内核
fs.protected_hardlinks=1限制硬链接创建现代内核默认启用
监控 bpftool prog list检测已附加的探针需要主动轮询
迁移到 SELinux基于 inode,阻止路径重写迁移复杂
限制 io_uring阻止 LID-002可能破坏应用程序

有关详细缓解指导,请参阅 docs/RESEARCH.md。


要求

查看可重现性矩阵获取每项发现的完整详细信息。摘要:

发现最低内核权限目标
LID-0015.x+root / CAP_BPF+CAP_PERFMON仅限 AppArmor
LID-0026.0+无任何 (SELinux, AppArmor, Smack)
LID-0035.2+CAP_SYS_ADMIN (用户命名空间可行)仅限 AppArmor
LID-0046.9+CAP_BPF (用户命名空间可行)AppArmor, Smack
LID-0054.18+CAP_NET_RAW (Docker 默认)tc egress (Cilium, Calico, 等)

作者

Azizcan Daştan
Milenium Security

  • GitHub: @azqzazq1

免责声明

本工具仅发布用于授权的安全测试、研究和教育目的。不得用于您不拥有或未获得明确书面许可的系统。


LID — 因为完整性从未被锁定。

下载工具