
# CVE-2026-31431 종합 분석 Linux 커널 LPE(로컬 권한 상승) 취약점인 CVE-2026-31431에 대한 종합 분석으로, 익스플로잇 방법론, 탐지 스크립트, YARA 규칙, auditd 및 Falco 구성, 그리고 대응 가이드를 포함합니다.
algif_aead 로컬 권한 상승CISA KEV | CVSS 7.8 HIGH | Linux 커널 4.14 ~ 2026년 초반 영향 (~9년)
CVE-2026-31431은 **"Copy Fail"**이라는 별칭으로 불리는, Linux 커널의 암호화 하위 시스템에서 발생하는 높은 심각도의 로컬 권한 상승(LPE) 취약점입니다. 낮은 권한의 로컬 사용자는 패치되지 않은 모든 시스템에서 수 초 내에 root로 권한을 상승할 수 있습니다.
| 속성 | 값 |
|---|---|
| CVE | CVE-2026-31431 |
| 별칭 | Copy Fail |
| CVSS v3.1 | 7.8 HIGH |
| 공격 벡터 | 로컬 |
| 필요한 권한 | 낮음 |
| 사용자 상호작용 | 없음 |
| 구성 요소 | crypto/algif_aead.c — authencesn 템플릿 |
| 도입 시점 | 2017년 (커밋 72548b093ee3) |
| 공개 시점 | 2026년 |
| 잠복 기간 | ~9년 |
| CISA KEV | 예 |
| 공개 PoC | 예 (732바이트 독립형 Python 스크립트) |
detection/check_vulnerable.sh를 실행합니다.CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
| Metric | Value | Rationale |
|--------|-------|-----------|
| Attack Vector | **Local** | 셸 액세스 필요(SSH, 컨테이너 exec, 물리적 액세스) |
| Attack Complexity | **Low** | 신뢰할 수 있고 완전 자동화 — 경쟁 조건 불필요 |
| Privileges Required | **Low** | 권한 없는 일반 사용자 계정 |
| User Interaction | **None** | 피해자 상호작용 불필요 |
| Confidentiality | **High** | 전체 시스템 장악 |
| Integrity | **High** | 전체 시스템 장악 |
| Availability | **High** | 전체 시스템 장악 |
### 위협 환경
| Factor | Assessment |
|--------|-----------|
| PoC Availability | 공개, 무기화됨, 732바이트 독립형 Python |
| Exploit Reliability | 높음 — 수정 없이 테스트된 배포판 전반에서 작동 |
| Detection Difficulty | 높음 — 디스크 쓰기 없음, 더티 페이지 없음 |
| Attacker Skill Required | 낮음 — 공개 PoC를 사용하는 스크립트 키디 |
| CISA KEV | 2026년 추가 — 적극적으로 모니터링됨 |
| Microsoft Defender | 활발한 조사 중으로 플래그 지정됨 |
### 영향받는 환경
| Environment | Risk |
|-------------|------|
| 베어메탈 Linux 서버 | Critical |
| Linux VM(클라우드 또는 온프레미스) | Critical |
| Kubernetes 노드 | Critical(컨테이너 탈출도 가능) |
| Docker 호스트 | Critical |
| 공유 호스팅 / 멀티 테넌트 | Critical |
| WSL2 / Windows의 Linux | 커널 버전별 평가 |
---
## 3. 기술 심층 분석
### 3.1 배경: AF_ALG 및 AEAD
Linux 커널은 **AF_ALG 소켓**(`AF_ALG = 38`)을 통해 사용자 공간에 암호화 작업을 노출합니다. 이 인터페이스(`algif_aead`)는 권한 없는 애플리케이션이 커널 모드 코드 없이 커널 암호화 하드웨어 가속기를 호출할 수 있게 합니다.
**AEAD**(연관 데이터 인증 암호화) 알고리즘인 AES-GCM 및 ChaCha20-Poly1305는 TLS, 디스크 암호화, VPN 프로토콜에 널리 사용됩니다. 취약한 템플릿은 `authencesn` — IPsec에서 일반적으로 사용되는 확장 시퀀스 번호(ESN) 지원과 함께 `hmac(sha256)` + `cbc(aes)`를 사용하는 AEAD 구성입니다.
### 3.2 근본 원인
2017년, 커밋 `72548b093ee3`은 성능 최적화로 `algif_aead`에 **제자리 AEAD 작업**을 도입했습니다 — 암호화 엔진이 동일한 버퍼를 읽고 쓸 수 있게 하는 것입니다. 이는 결함이 있었습니다:```
The bug chain:
1. Caller binds AF_ALG socket to:
authencesn(hmac(sha256),cbc(aes))
2. Caller sends a decryption request via sendmsg() with specific flags
3. Caller uses splice() to feed PAGE CACHE PAGES from an open file
descriptor directly into the socket's scatterlist
4. The authencesn template, during ESN header processing, uses the
OUTPUT BUFFER as scratch space — writing 4 bytes past the
expected output boundary
5. Because the scatterlist contains page cache pages (not private
copies), this scratch write lands DIRECTLY IN THE PAGE CACHE
6. Page cache is shared kernel-wide — all processes reading the
same file now see the modified bytes
Key insight: splice() is zero-copy — it hands page cache references
to the socket. The in-place "optimization" then writes INTO those
pages. No dirty bit is set because the write goes through the crypto
engine, not the normal write path.
이 취약점은 공격자가 읽기용으로 열 수 있는 모든 파일의 페이지 캐시에 대한 제어된 4바이트 쓰기를 제공합니다:
쓰기는 반복 가능합니다 — 익스플로잇은 더 큰 코드 시퀀스를 패치하기 위해 4바이트 쓰기를 반복합니다.
[1] Open /usr/bin/su (or any setuid-root binary) for reading ↓ [2] Map a copy to find target instruction bytes (e.g., UID check, execve path, security gate) ↓ [3] Compute exact page cache offset of target bytes ↓ [4] Set up AF_ALG socket → authencesn(hmac(sha256),cbc(aes)) ↓ [5] splice() the target binary's page cache into the socket ↓ [6] Trigger decryption → authencesn scratch write patches the target bytes in page cache (4 bytes per iteration) ↓ [7] Repeat for each 4-byte patch needed ↓ [8] Execute /usr/bin/su → runs root-owned setuid binary but now with attacker-controlled code in page cache ↓ [9] Root shell
### 3.5 표준 방어 체계가 무력화되는 이유
| 방어 체계 | 우회 가능? | 이유 |
|---------|-----------|--------|
| 파일 무결성 모니터링 (Tripwire/AIDE) | **예** | 디스크상 변경 없음 |
| IDS 파일 해시 검사 | **예** | 디스크 바이트 불변 |
| `inotify` 파일 감시 | **예** | VFS 쓰기 이벤트 없음 |
| SELinux / AppArmor | **부분적** | 프로세스를 제어하지만 암호화 엔진을 통한 페이지 캐시 쓰기는 제어하지 못함 |
| 읽기 전용 마운트 | **예** | 페이지 캐시가 마운트가 아닌 메모리 내에서 수정됨 |
| 바이너리 대상 `auditd` 감시 | **예** | Audit은 VFS 쓰기를 감시 — 이 기법은 VFS를 우회함 |
### 3.6 영향받는 커널 버전
| 브랜치 | 취약한 버전 | 수정된 버전 |
|--------|-------------------|------------|
| 4.14.x | 전체 (취약점 기원) | 업스트림 수정 없음 (EOL) |
| 5.4.x (LTS) | 전체 | 배포판 백포트 필요 |
| 5.10.x (LTS) | 전체 | 배포판 백포트 필요 |
| 5.15.x (LTS) | 전체 | 배포판 백포트 필요 |
| 6.1.x (LTS) | ≤ 6.1.129 | **6.1.130+** |
| 6.6.x (LTS) | ≤ 6.6.86 | **6.6.87+** |
| 6.12.x (LTS) | ≤ 6.12.22 | **6.12.23+** |
| 6.15-rc | rc에서 수정됨 | **6.15-rc+** |
> 배포판 커널은 서로 다른 버전 번호로 수정 사항을 백포트했을 수 있습니다. 항상 해당 배포판의 보안 권고를 확인하세요.
---
## 4. 공격 방법론 — 레드 팀
> **권한 필요.** 이 섹션은 방어자가 공격자의 관점을 이해하도록 돕기 위해 존재합니다. 소유한 시스템 또는 명시적인 서면 승인을 받은 시스템에서만 실행하세요.
### 4.1 사전 요구 사항
- 대상에서의 낮은 권한 셸 (SSH, 컨테이너 exec, RCE 체인)
- Python 3.10+ **또는** 컴파일된 C 바이너리
- `algif_aead`를 사용할 수 있는 패치되지 않은 커널
### 4.2 정찰```bash
# Check if vulnerable
uname -r
cat /proc/crypto | grep -A10 "authencesn"
lsmod | grep algif_aead
# Verify setuid target exists
ls -la /usr/bin/su /usr/bin/sudo /usr/bin/passwd
원래 연구자들(Theori)은 완전히 작동하는 732바이트 독립형 Python PoC를 공개했습니다:
python3 copy_fail_exp.py
python3 copy_fail_exp.py /usr/bin/passwd
로컬 복사본은 `exploit/poc.py`에서 확인할 수 있습니다. 기술적 분석은 `exploit/README.md`를 참조하세요.
### 4.4 컨테이너 탈출 시나리오
Linux 페이지 캐시는 동일한 호스트의 모든 프로세스(호스트와 컨테이너 포함) 간에 공유되므로:```
Attacker in container → patches /usr/bin/su in HOST page cache
Host user runs su → executes attacker code as root on host
This works even from non-privileged containers, as long as the host kernel is vulnerable.
이 저장소의 주요 초점입니다.
탐지 스크립트를 모든 Linux 시스템에서 실행하세요:```bash chmod +x detection/check_vulnerable.sh sudo ./detection/check_vulnerable.sh
**검사 항목:**
- 알려진 취약 버전 범위에 대한 커널 버전
- `algif_aead` 모듈 로드 상태 및 블랙리스트 상태
- `/proc/crypto`에서 `authencesn` 사용 가능 여부
- setuid 바이너리의 페이지 캐시 무결성 (root 권한 필요)
- 배포판별 패치 상태
- 활성 익스플로잇 징후에 대한 실행 중인 프로세스
타임스탬프가 포함된 보고서는 `/tmp/cve-2026-31431-report-*.txt`에 저장됩니다.
### 5.2 YARA 탐지
`detection/yara/`에 두 개의 YARA 규칙이 제공됩니다:
| 규칙 파일 | 용도 |
|-----------|---------|
| `cve_2026_31431_base.yar` | 알려진 공개 PoC와 정확히 일치 |
| `cve_2026_31431_enhanced.yar` | 난독화, 컴파일 및 변형 익스플로잇 탐지 |```bash
# Install YARA
apt-get install yara # Debian/Ubuntu
dnf install yara # RHEL/Fedora
apk add yara # Alpine
# Scan running process executables
sudo yara -r detection/yara/cve_2026_31431_enhanced.yar /proc/*/exe 2>/dev/null
# Scan common dropper locations
sudo yara -r detection/yara/cve_2026_31431_enhanced.yar /home /tmp /var/tmp /dev/shm
# Scan uploaded files / quarantine
yara detection/yara/cve_2026_31431_base.yar <suspect_file>
강화된 규칙이 중요한 이유: 공격자는 공개된 Python PoC를 난독화할 수 있습니다(base64 인코딩 문자열, XOR 인코딩 알고리즘 이름, C 바이너리로 컴파일, 심볼 제거). 강화된 규칙은 익스플로잇을 깨뜨리지 않고는 제거할 수 없는 불변 요소를 대상으로 하여 이러한 변형을 탐지합니다:
authesn을 수신해야 합니다splice()를 사용하여 제로카피 페이지 캐시 접근을 달성해야 합니다38)을 생성해야 합니다/etc/audit/rules.d/cve-2026-31431.rules에 배포합니다:```bash
-a always,exit -F arch=b64 -S socket -F a0=38 -k cve_2026_31431_afalg
-a always,exit -F arch=b64 -S splice -k cve_2026_31431_splice
-a always,exit -F arch=b64 -S init_module -S finit_module -k cve_2026_31431_modload
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -k cve_2026_31431_suid_exec
Reload:```bash
augenrules --load && service auditd restart
쿼리 기반 공격 시도 탐색:```bash
ausearch -k cve_2026_31431_afalg --start today
ausearch -k cve_2026_31431_afalg -k cve_2026_31431_splice --start today
### 5.4 Falco / eBPF 탐지
`/etc/falco/rules.d/cve-2026-31431.yaml`에 추가:```yaml
- rule: CVE-2026-31431 AF_ALG Socket Creation
desc: Detects unprivileged process creating AF_ALG socket (family 38) — required step for Copy Fail exploit
condition: >
syscall.type = socket and
evt.arg.domain = 38 and
not user.uid = 0 and
not proc.name in (known_crypto_daemons)
output: >
CVE-2026-31431 exploitation attempt - AF_ALG socket (user=%user.name
uid=%user.uid pid=%proc.pid cmd=%proc.cmdline)
priority: CRITICAL
tags: [cve-2026-31431, lpe, kernel, crypto]
- list: known_crypto_daemons
items: [strongswan, charon, pluto, openssl]
- rule: CVE-2026-31431 Splice After AF_ALG
desc: Detects splice() syscall shortly after AF_ALG socket creation — exploitation sequence
condition: >
syscall.type = splice and
not user.uid = 0 and
evt.elapsed < 5000000000
output: >
CVE-2026-31431 splice after AF_ALG socket (user=%user.name pid=%proc.pid)
priority: CRITICAL
tags: [cve-2026-31431, lpe]
익스플로잇이 디스크에 쓰지 않고 페이지 캐시를 수정하므로, 표준 FIM 도구는 이를 감지하지 못합니다. 이 검사는 활성 익스플로잇을 탐지합니다:```bash #!/bin/bash
SETUID_BINS=("/usr/bin/su" "/usr/bin/sudo" "/usr/bin/passwd")
for binary in "${SETUID_BINS[@]}"; do [[ -f "$binary" ]] || continue LIVE_HASH=$(sha256sum "$binary" | awk '{print $1}') echo 3 | sudo tee /proc/sys/vm/drop_caches > /dev/null # flush page cache DISK_HASH=$(sha256sum "$binary" | awk '{print $1}') if [[ "$LIVE_HASH" != "$DISK_HASH" ]]; then echo "CRITICAL: Page cache tampering detected on $binary" echo " Pre-flush: $LIVE_HASH" echo " Post-flush: $DISK_HASH" else echo "OK: $binary page cache matches disk" fi done
**운영 참고 사항:** `drop_caches`는 성능 저하를 유발합니다. 유지보수 시간대에 실행하거나 중요하지 않은 시스템에서 먼저 실행하세요.
### 5.6 침해 지표(IoC)
| IoC 유형 | 지표 | 신뢰도 |
|----------|-----------|-----------|
| 문자열(바이너리/스크립트) | `authencesn(hmac(sha256),cbc(aes))` | 높음 |
| 16진수 바이트 | `78 DA AB 77 F5 71 63 62 64 64` (zlib 페이로드 헤더) | 높음 |
| 시스템 콜 시퀀스 | `socket(38,5,0)` → `bind()` → `splice()` | 높음 |
| 네트워크 | 없음 — 순수 로컬 전용 | 해당 없음 |
| 파일 | 디스크 쓰기 없음(은닉) | — |
| 프로세스 | AF_ALG 소켓을 가진 수명이 짧은 Python/C 프로세스 | 중간 |
| 페이지 캐시 | setuid 바이너리 페이지 캐시 ≠ 디스크 해시 | 심각 |
### 5.7 SIEM 탐지 쿼리
**Splunk(auditd 소스):**```spl
index=linux_audit sourcetype=auditd action=SYSCALL syscall=socket a0="0x26"
| join pid [
search index=linux_audit sourcetype=auditd action=SYSCALL syscall=splice
]
| where (_time - join_time) < 30
| table _time host user pid cmd a0
| eval severity="CRITICAL"
Elastic KQL:```kql event.action: "SYSCALL" AND process.args: "socket" AND auditd.data.a0: "0x26" AND NOT user.id: "0"
**Microsoft Sentinel (KQL):**```kql
Syslog
| where Facility == "kern" or ProcessName == "audit"
| where SyslogMessage contains "socket" and SyslogMessage contains "a0=0x26"
| extend UserName = extract("uid=([0-9]+)", 1, SyslogMessage)
| where UserName != "0"
| project TimeGenerated, Computer, UserName, SyslogMessage
| order by TimeGenerated desc
자동 패치 스크립트를 실행합니다:```bash chmod +x patch/patch.sh sudo ./patch/patch.sh
### 6.1 즉시 완화 조치 (재부팅 불필요*)```bash
# Blacklist the module permanently
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf
echo "install authencesn /bin/false" | sudo tee -a /etc/modprobe.d/disable-algif-aead.conf
# Unload if currently loaded
sudo rmmod algif_aead 2>/dev/null || echo "Not loaded — mitigation active after config"
# Verify
lsmod | grep algif_aead && echo "WARNING: still loaded — reboot needed" || echo "OK: not loaded"
*algif_aead가 이미 로드된 경우, 블랙리스트가 완전히 적용되려면 재부팅이 필요합니다.
부작용: AF_ALG를 통해 커널 AEAD 인터페이스를 사용하는 애플리케이션(드물지만, 대부분 OpenSSL 사용자 공간을 사용)은 실패할 수 있습니다. 표준 TLS, 디스크 암호화, VPN 도구는 일반적으로 영향을 받지 않습니다.
kubectl get nodes -o wide
kubectl drain --ignore-daemonsets --delete-emptydir-data
kubectl uncordon
노드 자동 업그레이더(Karpenter, Managed Node Groups)를 사용하거나, 가능한 경우 클러스터 노드 풀 로테이션을 활용하세요.
### 6.4 패치 후 검증```bash
# Re-run detection script
sudo ./detection/check_vulnerable.sh
# Quick manual verification
uname -r # confirm new kernel version
lsmod | grep algif_aead # should be empty
cat /proc/crypto | grep authencesn # should return nothing (or still listed but module blacklisted)
탐지 도구를 안전하게 테스트하기 위한 최소한의 Alpine Docker 실험 환경이 제공됩니다.```bash cd lab/ docker compose up -d docker exec -it cve-2026-31431-lab /bin/sh
/cve-2026-31431/detection/check_vulnerable.sh
> **중요:** Docker 컨테이너는 호스트 커널을 공유합니다. 이 실습은 **호스트 커널의** 취약점 상태를 테스트합니다. 취약점 결과는 실제 호스트 시스템을 반영합니다 — 이는 현실적인 평가를 위한 의도된 동작입니다.
특정 취약한 커널 버전으로 격리된 테스트를 수행하려면 커널을 고정한 전용 VM을 사용하세요. VM 설정 지침은 `lab/README.md`를 참조하십시오.
---
## 8. 참고 자료
| 리소스 | 링크 |
|----------|------|
| NVD 권고 | https://nvd.nist.gov/vuln/detail/CVE-2026-31431 |
| 원본 연구 | https://copy.fail |
| 기술 분석 문서 | https://xint.io/blog/copy-fail-linux-distributions |
| 공개 PoC | https://github.com/theori-io/copy-fail-CVE-2026-31431 |
| CISA KEV 카탈로그 | https://www.cisa.gov/known-exploited-vulnerabilities-catalog |
| 커널 수정 — 커밋 되돌리기 | `a664bf3d603d` / `fafe0fa2995a` |
| 취약 커밋 | `72548b093ee3` |
| Microsoft Defender 권고 | Microsoft Defender 위협 인텔리전스 블로그 |
---
## 저장소 구조```
cve-2026-31431/
├── README.md ← This document
├── exploit/
│ ├── README.md ← Technical exploit breakdown
│ └── poc.py ← Public PoC (theori-io, for reference)
├── detection/
│ ├── README.md ← Detection guide
│ ├── check_vulnerable.sh ← Vulnerability & IoC detection script
│ └── yara/
│ ├── cve_2026_31431_base.yar ← Detects known public PoC
│ └── cve_2026_31431_enhanced.yar ← Detects obfuscated/compiled variants
├── patch/
│ ├── README.md ← Remediation guide
│ └── patch.sh ← Automated patch/mitigation script
└── lab/
├── README.md ← Lab setup guide
├── Dockerfile ← Alpine-based lab container
└── docker-compose.yml ← Lab orchestration
본 연구는 교육 및 방어적 보안 목적으로만 제공됩니다. 모든 도구는 방어자가 보호 권한을 가진 시스템에서 CVE-2026-31431을 탐지하고 수정하는 데 도움을 주기 위해 설계되었습니다.
저장소는 rippsec이(가) 유지 관리합니다.
| 속성 | 값 |
|---|
| 쓰기 크기 | 4바이트 |
| 오프셋 제어 | 가능 — splice 오프셋을 통한 공격자 제어 |
| 대상 | 읽기 가능한 모든 파일의 페이지 캐시 |
| 더티 페이지 표시 | 없음 |
| 디스크 수정 | 없음 |
| 타임스탬프 업데이트 | 없음 |
| 커널 로그 항목 | 없음 (auditd가 구성된 경우 제외) |
| Technique | ID | Notes |
|---|
| 권한 상승을 위한 악용 | T1068 | 핵심 기법 |
| 권한 상승 제어 메커니즘 남용: Setuid/Setgid | T1548.001 | Setuid 바이너리 하이재킹 |
| 실행 흐름 하이재킹 | T1574 | 인메모리 바이너리 패치 |
| 지표 제거: Timestomp | T1070.006 | 타임스탬프 미갱신 |
| 간접 명령 실행 | T1202 | 패치된 바이너리가 셸 실행 |
| 배포판 | 업데이트 명령 |
|---|
| Ubuntu / Debian | apt-get update && apt-get upgrade linux-image-generic && reboot |
| RHEL / CentOS / Rocky | dnf update kernel && reboot |
| Amazon Linux 2 | yum update kernel && reboot |
| Amazon Linux 2023 | dnf update kernel && reboot |
| SUSE / SLES | zypper update kernel-default && reboot |
| Arch Linux | pacman -Syu linux && reboot |
| Alpine Linux | apk update && apk upgrade linux-lts && reboot |
| Debian | apt-get update && apt-get upgrade linux-image-amd64 && reboot |