
CVE-2026-31431(Linux 커널 LPE)에 대한 Seccomp 기반 완화 조치입니다. PAM 모듈과 독립 실행형 래퍼를 통해 AF_ALG 소켓을 차단하며, 패치된 커널을 자동으로 감지합니다.
CVE-2026-31431을 위한 가볍고 되돌릴 수 있는 seccomp 기반 완화 도구입니다. 이 취약점은 Linux 커널의 algif_aead / authencesn 암호화 서브시스템에서 발생하는 로컬 권한 상승 취약점입니다.
유형: 로컬 권한 상승(LPE)
영향을 받는 구성 요소: Linux 커널 crypto/algif_aead.c - 제자리(in-place) AEAD 연산
공격 원리: authencesn AEAD 알고리즘의 스크래치 쓰기 경로를 통해 읽기 가능한 모든 파일의 페이지 캐시에 4바이트 제어 가능한 쓰기를 수행합니다. /etc/passwd를 대상으로 공격자는 자신의 UID를 0(root)으로 변경하고 su를 통해 루트 셸을 얻을 수 있습니다.
영향을 받는 커널: 커널 6.12+, 6.17+, 6.18+에서 확인되었으며, RHEL/CentOS 4.18/5.14 커널에서도 재현되었습니다.
검증된 환경: Rocky Linux 8(커널 4.18) 및 Rocky Linux 9(커널 5.14) - 악용이 완전히 차단되었으며, 안전한 제거가 확인되었습니다.
근본 원인: 커밋 72548b093ee3이 제자리(in-place) AEAD 연산을 도입했습니다. 스플라이스된 페이지 캐시 페이지가 대상 scatterlist로 사용될 때, AAD seqno_lo 필드가 AEAD 복호화 중 페이지 캐시에 잘못 다시 쓰여집니다.
업스트림 수정: 제자리(out-of-place) AEAD 연산으로 되돌리기.
이 솔루션은 두 가지 구성 요소로 이루어져 있습니다:
PAM 모듈(pam_block_afalg.so) - 기본 방어 수단입니다. PAM이 세션 시작 시(pam_sm_open_session) 로드하며, 사용자 코드가 실행되기 전에 socket(AF_ALG, ...)을 차단하는 seccomp BPF 필터를 적용합니다. 이는 모든 PAM 인증 세션을 포괄합니다: su -c, su -, SSH, TTY 로그인 등.
독립 실행 바이너리(block_afalg) - 선택 사항입니다. 비-PAM 시나리오(예: cron 작업, systemd 서비스, 수동 호출)에서 특정 프로그램을 감쌀 수 있습니다.
seccomp 필터:
socket(AF_ALG, ...)만 차단합니다(EACCES 반환)setuid, su, sudo 포함)에는 영향이 없습니다PAM 세션 시작 (su, ssh, login 등)
|
v
pam_block_afalg.so (pam_sm_open_session)
|
+-- 확인: 커널이 취약한가? (socket(AF_ALG) 시도)
| |
| +-- 아니오 --> PAM_SUCCESS 반환 (no-op)
| |
| +-- 예 --> prctl(PR_SET_SECCOMP, BPF 필터)
| |
| +-- seccomp 필터가 sshd 자식 프로세스에 적용됨
| +-- 사용자 셸과 모든 자식 프로세스에 상속됨
| +-- socket(AF_ALG, ...)이 EACCES 반환
v
사용자 셸 / 명령이 seccomp 보호와 함께 실행됨
|
+-- su, sudo 및 기타 모든 시스템 콜은 정상 작동
+-- AF_ALG 소켓만 차단됨
| 파일 | 용도 |
|---|---|
pam_block_afalg.c | PAM 모듈 소스. 세션 시작 시 seccomp 필터를 적용합니다. |
pam_minimal.h | 최소 PAM 타입 정의(pam-devel 없이 컴파일 가능). |
gcc(컴파일용)libpam(런타임, 일반적으로 사전 설치됨)# 1. PAM 모듈 컴파일
gcc -Wall -O2 -fPIC -shared -o pam_block_afalg.so pam_block_afalg.c \
/usr/lib64/libpam.so.0
# 2. 설치 (su, sshd, login에 PAM 구성 자동 추가)
sudo ./deploy.sh install
# 3. 확인 (새 세션이어야 함)
cat /proc/self/status | grep Seccomp
# 표시되어야 함: Seccomp: 2
python3 -c "
import socket
try:
s = socket.socket(38,2,0); s.close()
print('VULNERABLE')
except OSError:
print('BLOCKED')
"
# 표시되어야 함: BLOCKED
# 4. 제거
sudo ./deploy.sh remove
| 명령 | 설명 |
|---|---|
deploy.sh install | PAM 모듈 컴파일, /lib64/security/에 설치, PAM 구성 자동 추가 |
deploy.sh remove | 전체 제거: 모듈 제거, PAM 구성 정리, 파일 삭제 |
deploy.sh status | 설치 상태, PAM 구성, 커널 상태 표시 |
비-PAM 시나리오의 경우 block_afalg를 직접 사용하세요:
# 컴파일
gcc -Wall -O2 -o block_afalg block_afalg.c
# AF_ALG가 차단된 상태로 명령 실행
./block_afalg python3 your_script.py
./block_afalg bash
python3 -c "
import socket
try:
s = socket.socket(38, socket.SOCK_SEQPACKET, 0)
s.close()
print('VULNERABLE: AF_ALG socket available')
except:
print('SAFE: AF_ALG socket blocked or unavailable')
"
# seccomp 상태 확인
cat /proc/self/status | grep Seccomp
# Seccomp: 0 = 보호되지 않음
# Seccomp: 2 = 보호됨
# AF_ALG 소켓 테스트
python3 -c "
import socket
try:
s = socket.socket(38,2,0)
s.close()
print('AF_ALG available - NOT protected')
except OSError:
print('AF_ALG blocked - PROTECTED')
"
# PAM 로그 확인
grep pam_block_afalg /var/log/secure
# 표시되어야 함: seccomp filter applied, AF_ALG blocked
x86_64의 __NR_socket)을 하드코딩합니다. 다른 아키텍처는 시스템 콜 번호를 업데이트해야 합니다.exec() 호출하는 경우는 포함되지 않습니다(이 경우 block_afalg 사용).remove로 정리할 수 있습니다.yum update kernel 후 모듈을 제거하세요.이 도구는 공인된 보안 테스트 및 방어 목적으로만 제공됩니다. 소유한 시스템 또는 명시적으로 평가 권한이 부여된 시스템에서만 사용하세요.
block_afalg.c | 독립 실행 seccomp 래퍼 바이너리. 비-PAM 용도. |
deploy.sh | 배포 스크립트. PAM 모듈을 컴파일, 설치 및 관리합니다. |