[단독방어] 분석 — CVE-2025-71113
The Linux kernel af_alg zero‑initialization flaw can cause local denial‑of‑service via spurious -EBUSY errors, and the immediate mitigation is to blacklist/unload the af_alg module.
📋 요약
- 심각도 medium · CVSS 5.5 · EPSS 0.00123 · 악용난이도 hard
🔍 공격 기법
- 로컬 사용자가 AF_ALG 소켓을 생성하고 암호화 요청을 수행하면,
sock_kmalloc()으로 할당된 컨텍스트 구조체의inflight변수가 초기화되지 않아 임의의 값이 남습니다. - 커널은
if (ctx->inflight)로 값을 검사하므로, garbage 값이 true 로 해석될 경우af_alg_alloc_areq()가 무작위로‑EBUSY를 반환합니다. - 이 오류는 암호화 서비스가 비정상적으로 실패하도록 만들어 시스템·서비스 수준에서 가용성(Availability) 장애를 유발할 수 있습니다.
악용 가능성: 이 취약점은 AV:L(Local)이며 로컬 시스템에 접근 가능한 사용자가 직접 sock_kmalloc()을 호출해 af_alg 소켓 인터페이스를 이용해야만 발현됩니다. 따라서 원격 네트워크에서 바로 공격할 수 없고, 로컬 쉘이나 컨테이너 탈출 등 사전 권한 상승 단계가 전제되어 난이도는 높게(Hard) 평가되었습니다. AC:L·PR:L·UI:N 조합은 코드 실행 자체는 복잡하지 않지만, 공격자가 반드시 af_alg 사용자 API(예: algif_kpp.c, algif_akcipher.c)에 접근해 비정규화된 컨텍스트 구조를 생성하고 오류 경로 혹은 향후 추가될 필드를 트리거해야 함을 의미합니다. EPSS = 0.00123이라는 매우 낮은 실측 위험 점수와 KEV 미등재는 현재까지 실제 악용 사례가 거의 없음을 보여 주지만, **‘uninitialized memory’**가 커널 레벨에서 암호화 연산에 사용될 경우 메모리 내용이 노출되거나 비정상적인 동작을 유발할 가능성이 존재합니다. 공격 표면은 af_alg 소켓(AF_ALG)을 통해 제공되는 로컬 IPC(Unix domain socket)와 해당 인터페이스에 전달되는 구조체 필드(inflight 등)이며, 이들 파라미터가 제대로 초기화되지 않은 경우만이 취약점을 이용할 수 있는 유일한 경로입니다. 따라서 공격 성공은 **‘특정 오류 경로를 강제로 호출하거나 신규 필드를 조작하는 로컬 프로세스’**에 한정되며, 일반 사용자나 원격 공격자는 직접적인 활용이 거의 불가능합니다.
💥 영향 분석
- 공격자는 일반 사용자 권한(Low privilege)만으로도 영향을 받을 수 있으며, 반복적인 요청을 통해 특정 서비스(예: TLS 오프로드, IPsec 등)의 암호화 작업을 지속적으로 실패하게 만들어 서비스 거부 상태를 초래합니다.
- 데이터 무결성·기밀성은 직접 손상되지 않지만, 연속된 장애가 운영 환경 전반에 걸쳐 가용성을 크게 저하시킬 수 있습니다.
🔗 관련 취약점·체이닝
- 동일한 AF_ALG 소켓을 이용하는 다른 커널 취약점(예: CVE‑2024‑XXXXX)과 결합하면 권한 상승이나 메모리 손상으로 이어질 가능성이 있으나, 현재 확인된 직접적인 체인 사례는 없습니다.
🔎 탐지
-
로그 지표
kernel로그(dmesg,/var/log/kern.log)에af_alg_alloc_areq가-EBUSY를 반환한 메시지가 기록됩니다.auditd이벤트에서socket(AF_ALG, ...)시스템 콜이 발생하고, 이후errno=16 (EBUSY)로 종료되는 경우.
-
SIEM 쿼리 예시 (Splunk/Elastic 등)
text1index=kernel sourcetype=kern.log "af_alg_alloc_areq" "-EBUSY"2| stats count by host, _timetext1{2 "query": {3 "bool": {4 "must": [5 { "match_phrase": { "message": "af_alg_alloc_areq" } },6 { "wildcard": { "message": "*-EBUSY*" } }7 ]8 }9 }10}text1-w /dev/null -p x -k afalg_ebusy -
오탐 튜닝
- 정상적인 서비스 초기화 단계에서 드물게
‑EBUSY가 발생할 수 있으므로, 일정 시간(예: 5 분) 내 동일 호스트·프로세스에서 다중 건이 감지될 때만 알림을 발생하도록 임계값을 설정합니다.
- 정상적인 서비스 초기화 단계에서 드물게
🛡️ 완화 방안
- 즉시(긴급 차단)
af_alg모듈을 즉시 언로드하고 블랙리스트에 추가합니다.
1modprobe -r af_alg # 현재 로드된 경우 제거 2echo "blacklist af_alg" > /etc/modprobe.d/af_alg.conf-
적용 후
lsmod | grep af_alg로 모듈이 로드되지 않았는지 확인합니다. -
난이도: 낮음 → 단일 명령 실행만 필요, 가용성 영향은 AF_ALG 기반 암호화 기능(예: IPsec offload) 사용 중인 서비스에 제한적 영향을 줄 수 있습니다.
-
단기(완화)
- SELinux/AppArmor 정책을 강화하여 비특권 사용자에게
socket(AF_ALG)생성 권한을 차단합니다. 예시(AppArmor):
- SELinux/AppArmor 정책을 강화하여 비특권 사용자에게
1/usr/bin/* r, 2network socket af_alg deny,-
시스템 호출 감시(
auditd)를 통해 AF_ALG 소켓 생성을 모니터링하고, 비정상적인 빈도 발생 시 자동으로systemctl stop <service>로 서비스 차단하는 스크립트를 배포합니다. -
난이도: 중간 → 정책 작성·배포 필요, 기존 서비스에 대한 권한 검토가 요구됩니다.
-
근본(해결)
- 커널을 최신 패치 레벨로 업데이트합니다. 해당 취약점은
crypto/af_alg.c에서 컨텍스트를memset()로 초기화하도록 수정된 커밋이 포함된 버전부터 적용됩니다.- 지원되는 최소 버전: 6.7.x 이후(패치가 backport 된 경우 5.16 이상에서도 적용 가능).
- 업데이트 절차:
- 현재 배포판에 맞는 최신 커널 패키지 설치 (
yum update kernel또는apt-get install linux-image-<ver>). - 시스템 재부팅 후
uname -r로 버전 확인. dmesg | grep af_alg로 모듈 로드 여부 및 오류 유무 검증.
- 현재 배포판에 맞는 최신 커널 패키지 설치 (
- 난이도: 높음 → 커널 교체·재부팅 필요, 서비스 중단 시간이 발생할 수 있습니다.
- 커널을 최신 패치 레벨로 업데이트합니다. 해당 취약점은
-
잔여 리스크
- 패치를 적용해도 동일한 메모리 초기화 로직을 사용하는 다른 암호 API가 존재한다면 유사한 오류가 재발할 가능성이 있습니다. 따라서 장기적으로는 커널 전체의 메모리 할당 후
memset정책 검토와 정적 분석 도구를 통한 코드 리뷰가 필요합니다.
- 패치를 적용해도 동일한 메모리 초기화 로직을 사용하는 다른 암호 API가 존재한다면 유사한 오류가 재발할 가능성이 있습니다. 따라서 장기적으로는 커널 전체의 메모리 할당 후
-
인시던트 대응 플레이북
- 알림 수신 → 해당 호스트에서
dmesg | grep -i "af_alg_alloc_areq"실행,‑EBUSY발생 시점 파악. - 즉시 차단 조치 확인:
lsmod | grep af_alg; 로드돼 있으면 위 즉시 절차대로 언로드·블랙리스트 적용. - 서비스 영향도 평가 → AF_ALG 기반 암호화 기능을 사용하는 서비스가 있다면 일시 중지 또는 대체 경로 전환.
- 단기 정책 적용 여부 검증 → SELinux/AppArmor 로그(
audit.log)에 차단 이벤트 기록 확인. - 패치 적용 계획 수립 및 실행 → 커널 업데이트 후 정상 동작 테스트.
- 알림 수신 → 해당 호스트에서
위 방안들을 순차적으로 적용하면 현재 보고된 가용성 위협을 빠르게 차단하고, 장기적인 코드 수준의 결함 해결까지 이어질 수 있습니다.
⚖️ 위험도 / 우선순위
- 조치: monitor (모니터링)
- 근거: CVSS=5.5 · non-KEV · EPSS=0.00123 · exploit=hard · in_scope=None