M11 배우기 모드 — 왜 LSM bprm 훅인가¶
M11 README를 먼저. 핵심 한 줄: exec 허용목록은 적재되는 이미지의 신원을 봐야 하는데, 그건 syscall 표면(arg0·caller)엔 없고 LSM
bprm_check_security에만 있다.
1단계 — 세 후보를 손에 익힌다 (무엇을 보나)¶
| 훅 | 보는 것 | exec 허용목록에서 |
|---|---|---|
sys_execve + matchArgs arg0 (M4) |
argv[0] 문자열 |
rename으로 우회(/tmp/x sh) — 이름은 신원이 아님 |
matchBinaries (어느 훅이든) |
exec를 호출한 바이너리(caller) | 거꾸로 — nginx -v는 죽고 nginx-RCE 셸은 통과(ADR 0001) |
LSM bprm_check_security |
적재될 linux_binprm->file |
실제 inode/path — 정직한 허용목록의 유일한 훅 |
2단계 — 한 칸 채우기 (정책에서 무엇이 load-bearing인가)¶
tracingpolicy-lsm-exec-allowlist.yaml에서:
lsmhooks:
- hook: "bprm_check_security"
args: [{ index: 0, type: "linux_binprm" }] # 적재 이미지
selectors:
- matchArgs: [{ index: 0, operator: "NotPrefix", values: ["/usr/sbin/nginx", ...] }]
matchActions: [{ action: Sigkill }]
왜 matchBinaries가 아니라 matchArgs인가?
matchBinaries는 caller(exec를 호출한 바이너리)를 매칭한다 — exec 허용목록엔 거꾸로다. 우리가 알아야 할 건 적재될 바이너리이고, 그건 bprm 훅의linux_binprm->file = 이 정책에선 matchArgs index 0이다. matchArgs(적재-이미지) ✓ / matchBinaries(caller) ✗.왜 Sigkill이고, 진짜 방지는?
Sigkill은 적재 직전 프로세스를 죽인다(detection-then-kill). prevention-grade는action: Override로 exec syscall에 -EPERM을 반환해 exec 자체를 거부하는 것. 룰 헤더 주석 참고.3단계 — 예측 후 측정 (BPF-LSM 커널에서)¶
bash labs/m11/grade.sh 전에 예측하라:
1. nginx -v → ? (적재 이미지 = nginx, 허용목록 안 → 생존)
2. /bin/sh → ? (적재 이미지 = sh, 허용목록 밖 → 137)
3. cp busybox /tmp/x; /tmp/x sh → ? (적재 이미지 = busybox, 137 — LSM은 path/inode를 보므로 rename이 안 통함. M4 arg0는 여기서 뚫렸다.)
kind에서 SKIP이 떠도 실패가 아니다 — lsm=에 bpf가 없으면 이 통제는 증명 불가이고, 그래서 ED3는 NOT_COVERED·헤드라인 불변이다. 그 정직한 경계를 설명할 수 있으면 졸업이다.