01. Executive Summary
•
취약점 개요
◦
Delphos Labs과 V12 보안 팀의 Aaron Esau에 의해 2026년 5월 9일 DirtyDecrypt(또는 DirtyCBC, CVE-2026-31635)이 발견 및 보고되었으나, V12에서는 커널 관리자들로부터 이미 메인라인에 패치된 취약점의 중복 건이라고 답변받아 2026년 5월 17일 PoC 공개
▪
Zellic의 공동 창립자인 루나 통(Luna Tong)에 따르면 rxgk_decrypt_skb 내에 COW(Copy-On-Write, 쓰기 시 복사) 보호 장치가 누락되어 발생하는 rxgk 페이지 캐시 쓰기 오류라고 밝힘
▪
구체적인 결함은 수신 측에서 들어오는 sk_buff(소켓 버퍼)를 복호화하는 함수인 rxgk_decrypt_skb()에 존재
◦
DirtyDecrypt는 CopyFail(CVE-2026-31431), Dirty-Frag(CVE-2026-43284&CVE-2026-43500), Fragnesia(CVE-2026-46300)에 이은 변종 취약점으로 모두 취약한 시스템에서 루트 권한 획득이 가능
◦
DirtyDecrypt는 CVE-2026-31635로 명명되고 있으나 실제 CVE에서 언급된 버그 발생지점과 DirtyDecrypt의 버그 발생 지점이 상이
▪
DirtyDecrypt에 대한 공식적인 CVE ID는 없는 것으로 볼 수 있으나, Tharros의 수석 취약점 분석가인 Will Dormann(CERT/CC, 이후 Analygence)이 CVE-2026-31635와의 연관성을 제기하였고 NVD 레코드에 V12의 PoC 링크가 포함되면서 CVE에 포함
•
대응방안
◦
(보안업데이트가 가능한 경우) : 2026년 4월 25일자 패치 또는 그 이후 버전이 포함된 커널 업데이트를 적용
◦
(보안업데이트가 어려운 경우) : 메인라인 수정 사항인 aa54b1d27fe0은 2026년 5월 10일부터 제공되어 안정화 트리로 전파되기 때문에 업데이트 지연 등 보안패치가 어려운 경우에는 영향받는 모듈을 언로드 하고 블랙리스트로 등록
▪
패치가 불가능한 경우 : modprobe 블랙리스트를 통해 esp4, esp6, rxrpc 모듈을 언로드하고 캐시를 비워야 함
▪
단, 이 조치는 IPsec/VPN 및 AFS를 중단시킬 수 있음을 유의해야 하며 워크로드가 허용하는 한 컨테이너 호스트를 안전화 커널 라인으로 이동 필요
◦
(쿠버네티스를 위한 컨테이너 호스트 전략) : 롤링 릴리스(Rolling Release)배포판에서 쿠버네티스 워커를 실행 중이라면 개별 노드의 커널을 일일이 패치하는 것이 아니라 선언적 호스트 전략이 필요
▪
정상적인 쿠버네티스 운영 환경에서는 imagePullPolicy: Always, allowPrivilegeEscalation: false, readOnlyRootFilesystem: true, runAsNonRoot: true가 기본값으로 이를 강제하지 않은 경우에는 DirtyDecrypt보다 더 큰 보안 문제가 발생할 소지가 존재
02. Overview
2.1. 취약점 개요
•
Delphos Labs과 V12 보안 팀의 Aaron Esau에 의해 2026년 5월 9일 DirtyDecrypt(또는 DirtyCBC, CVE-2026-31635)이 발견 및 보고되었으나, V12에서는 커널 관리자들로부터 이미 메인라인에 패치된 취약점의 중복 건이라고 답변받아 2026년 5월 17일 PoC 공개
◦
Zellic의 공동 창립자인 루나 통(Luna Tong)에 따르면 rxgk_decrypt_skb 내에 COW(Copy-On-Write, 쓰기 시 복사) 보호 장치가 누락되어 발생하는 rxgk 페이지 캐시 쓰기 오류라고 밝힘
◦
구체적인 결함은 수신 측에서 들어오는 sk_buff(소켓 버퍼)를 복호화하는 함수인 rxgk_decrypt_skb()에 존재
◦
CVE-2026-31635는 NVD기준으로 CVSS 점수 7.5으로 페이지 캐시 오염(page-cache corruption)을 통한 루트(root)로의 로컬 권한 상승(LPE)
◦
공개된 PoC는 Fedora환경에서 검증된 것으로 컨테이너 환경에서는 파드(Pod) 탈출 경로(Linux LPE → 호스트 커널 → 컨테이너 경계 붕괴)로 작용하므로 매우 치명적
•
DirtyDecrypt는 CopyFail(CVE-2026-31431), Dirty-Frag(CVE-2026-43284&CVE-2026-43500), Fragnesia(CVE-2026-46300)에 이은 변종 취약점으로 모두 취약한 시스템에서 루트 권한 획득이 가능
◦
2026년 4월 29일, Theori연구진에 의해 AF_ALG 암호화 소켓 인터페이스의 로컬 권한 상승 취약점인 Copy Fail 공개
▪
◦
2026년 5월 7일, 김현우(@v4bel)연구원에 의해 ESP 취약점(CVE-2026-43284)과 RxRPC 변종(CVE-2026-43500)을 결합하여 Copy Fail을 확장한 Dirty Frag 공개
▪
당초 리눅스 관리자들과 김현우 연구원은 5월 12일까지 정보를 공개하지 않기로 합의를 하였으나, 5월 7일 제3자가 엠바고 기간을 알지 못한 상태에서 익스플로잇을 공개하면서 CVE가 부여되기 전에 무방비 상태로 취약점 공개
◦
•
DirtyDecrypt를 비롯해 Copy Fail, Dirty Frag, Fragnesia 등 Linux 커널의 메모리 관리 및 하위 시스템에서 권한 상승 취약점이 연쇄적으로 발생하고 있는 상황에서 Linux PackageKit 데몬의 LPE 결함(Pack2TheRoot, CVE-2026-41651,CVSS 8.8) 및 커널의 부적절한 권한 관리 결함(ssh-keysign-pwn, CVE-2026-46333, CVSS 5.5)의 연쇄적 취약점 발견은 리눅스 생태계 전반에 보안 위협이 발견되고 있다는 것을 의미
2.2. 영향받는 버전
•
DirtyDecrypt는 Fedora, Arch Linux, openSUSE Tumbleweed와 같이 CONFIG_RXGK가 활성화된 배포판에만 영향
•
NVD 레코드에 링크된 CVE-2026-31635의 안정화 패치(2026년 4월 말부터 안정화 브랜치에 적용됨) 이전, 또는 구조적으로 DirtyDecrypt PoC를 커버하는 2026년 5월 10일자 메인라인 커밋 aa54b1d27fe0이전의 CONFIG_RXGK=y(또는 모듈 형태인=m) 설정의 Linux 커널 → 2026년 4월 25일자 패치 또는 그 이후 버전이 포함된 커널 업데이트 미적용 버전
•
Fedora(Rawhide 포함), Arch Linux, openSUSE Tumbleweed, 그리고 이러한 커널이나 최첨단(bleeding-edge) 메인라인 빌드를 실행하는 모든 쿠버네티스 컨테이너 플랫폼의 워커 노드에서 영향
2.3. 타임라인
•
2026년 5월 8일 : 김현우에 의해 커밋 aa54b1d27fe0이 작성(Copy Fail)
•
2026년 5월 10일 : aa54b1d27fe0 커밋이 리눅스(Linus) 트리에 committed되었으며, 이 패치는 RxRPC DATA/RESPONSE 패킷의 공유 해제(unsharing) 범위를 skb_has_frag_list() 및 skb_has_shared_frag()까지 확장
•
2026년 5월 14일 : 데이비드 하우얼즈(David Howells)가 [PATCH net v3 0/4] rxrpc: Better fix for DATA/RESPONSE decrypt vs splice() 패치 시리즈를 게시하며, RESPONSE 측의 선형 버퍼(linear-buffer) 수정 사항과 DATA 측의 수신 버퍼(receive-buffer) 수정 사항이 포함
•
2026년 5월 15일 : 커널 보안 조정팀이 해당 문제가 해결되었으며 정보를 공개를 승인
03. Vulnerability Analysis
3.1. 취약점 설명
1) 주요 공격 타깃 아키텍처
•
DirtyDecrypt는 Linux 커널의 RxGK 하위 시스템에 존재하는 것으로 사용자 영역의 프로세스가 AFS 네트워크 기능을 호출하거나 로컬 사용자가 modprobe 명령어를 실행할 때만 RxGK의 커널모듈이 로드
◦
RxGK : 앤드루 파일 시스템(AFS, Andrew File System) 클라이언트(afs.ko) 및 몇 가지 관련 분산 파일 시스템에서 사용하는 네트워크 전송 프로토콜인 RxRPC를 위한 GSS-API 기반 보안 레이어로 CONFIG_RXGK는 모든 메인라인 Linux 빌드와 롤링 릴리스 배포판에 기본적으로 포함
◦
(영향을 받는 구성 요소) Linux 커널 net/rxrpc/ 내부 RxGK 보안 레이어 (rxgk_decrypt_skb 함수)
◦
(영향도) 로컬 권한 상승 (LPE, Local Privilege Escalation) 및 컨테이너 탈출 (Pod Escape)
◦
(취약점 원인) 인증 전 제자리 복호화 수행 및 복사 시 쓰기 보호 장치 누락 (Missing COW Guard + Decrypt-before-MAC)
•
기술적으로 정밀하게 분석하자면, Delphos Labs(Kamil Leoniak, 2026년 5월 15일)의 1차 분석에서는 연결 설정 중 RxGK RESPONSE 패킷 토큰 복호화 과정의 코드 경로에서 발생
◦
공격 체인 : rxgk_verify_response() → rxgk_extract_token() → rxgk_decrypt_skb() → skb_to_sgvec() → crypto_krb5_decrypt()
◦
여기서 실제 취약점 유발 요인은 단순한 COW 보호 장치 누락뿐만 아니라, MSG_SPLICE_PAGES를 통해 페이지 캐시 페이지와 별칭(alias)이 지정될 수 있는 skb 분산-수집 리스트(scatterlist) 페이지 위에서 'MAC 검증 전 복호화'가 수행된다는 점
◦
여기에 공격자가 제어하는 서버 키를 통한 AES-CBC 선택 평문 구조가 결합되어 작동(무차별 대입이나 COW 레이스 조건 불필요)
◦
업스트림의 실질적인 수정 사항은 제자리 복호화 전에 공유 프래그먼트가 포함된 패킷을 복사하는 커밋 aa54b1d27fe0(2026년 5월 8일 작성, 5월 10일 반영)이며, 이후 David Howells의 구조적 후속 패치 시리즈(2026년 5월 14일)를 통해 암호화 단계 이전에 RESPONSE 콘텐츠를 선형 버퍼로 추출하도록 변경
2) 취약점 발생 원인 : 미인증 제자리 변조 (Unauthenticated In-Place Mutation)
•
해당 취약점은 단순한 메모리 버퍼 오버플로우나 레이스 컨디션(Race Condition)이 아니라 커널 네트워크 하위 시스템인 sk_buff와 가상 메모리 관리자 Management, 암호화 드라이버 서브 시스템 crypto간의 인터페이스 설계 결함
•
신뢰할 수 없는 원격 입력을 처리하는 네트워크 소켓 버퍼 데이터 구조가 무결성 인증(MAC Verification)을 통과하기 전에 커널 가속 물리 메모리 분산-수집 리스트(SGL)로 직접 다이렉트 매핑되어 제자리 암호화 해독 연산으로 인입되는 논리적 결함이 발생
3) 커널 내부 서브시스템 결함 분석
소켓 버퍼(sk_buff) 프래그먼트 구조와 페이지 공유 메커니즘
•
리눅스 커널은 제로 카피(Zero-copy) 네트워크 I/O 및 고성능 IPC 가속을 위해 splice() 및 vmsplice() 시스템 콜을 제공
◦
이 과정에서 사용자 영역의 버퍼나 특정 파일 시스템의 페이지가 소켓 버퍼 구조체로 들어올 때, 실제 메모리 바이트를 복사하지 않고 소켓 버퍼의 하위 구조체인 skb_shared_info 내의 프래그먼트 배열(skb_frag_t frags[])에 해당 물리 페이지의 참조(Page Reference) 정보만 바인딩하는 최적화 기능이 작동
◦
공격자가 MSG_SPLICE_PAGES 플래그를 사용하여 파이프(Pipe)와 UDP 소켓 간의 전송 흐름을 유도하면, 커널 내부적으로 다음과 같은 물리 메모리 매핑 구조가 sk_buff 내에 형성
▪
공격자 제어 영역: 사용자가 수작업으로 가공한 익명 페이지(Anonymous Page) 참조 바인딩
▪
타깃 파일 시스템 영역: 읽기 권한이 존재하는 SUID-root 바이너리 등 시스템 공용 파일의 물리 페이지 캐시(Page Cache) 구조체(struct page)에 대한 다이렉트 포인터 참조 바인딩
rxgk_decrypt_skb()의 Missing COW Guard 구조
•
일반적인 리눅스 커널의 MM(Memory Management) 서브시스템 구조하에서는, 여러 프로세스나 커널 스레드가 공유하고 있는 공용 페이지 캐시 메모리 영역에 쓰기(Write) 연산을 시도할 때 반드시 복사 시 쓰기(COW, Copy-On-Write) 규칙이 강제로 적용
◦
커널은 타깃 페이지의 참조 카운트와 공유 플래그를 검사하여 공유 상태임이 판명되면, 물리 메모리 관리자로부터 새로운 독립된 페이지를 할당받아 원본 데이터를 복사한 후 개인적인 쓰기 작업을 격리 수행을 해야함
◦
그러나 결함이 발생한 rxgk_decrypt_skb() 및 하위 데이터 가공 함수부에는 이 COW 경계면을 검사하고 격리 조치하는 Guard 로직이 완전히 누락
▽ Vulnerable Kernel Flow Graph
rxrpc_process_connection()
└─ rxgk_verify_response()
└─ rxgk_extract_token()
└─ rxgk_decrypt_skb()
│
├── nr_sg = skb_to_sgvec(skb, sg, _offset, len);
│ └─ [CRITICAL DEFECT]: skb 내에 보존되어 있던 공용 페이지 캐시(struct page)의
│ 물리 주소를 암호화 엔진용 Scatterlist(SGL) 엔트리에 원본 그대로 다이렉트 매핑
│
└── crypto_krb5_decrypt(..., sg, nr_sg, ...)
└─ [EXPLOITATION]: 크립토 가속 엔진 구동. 복호화 드라이버는 소스(src)와 목적지(dst)가
동일한 제자리(In-place) SGL 모드로 암호 해독 바이트를 물리 메모리에 Direct WriteBack
JavaScript
복사
•
이 인터페이스 결함으로 인해, 암호화 엔진 하드웨어/드라이버 레벨에서 복호화된 데이터를 받아 적는 WriteBack 연산이 실행되는 순간, 커널 페이지 테이블의 쓰기 보호 필터링을 우회하여 메모리 상에 로드되어 있는 SUID-root 바이너리의 페이지 캐시 바이트가 직접 물리적으로 오염(Poisoning)
4) 암호학적인 인증 결함 과정
① 연산 순서의 결함
•
RxGK의 하부 암호화 골격인 Kerberos krb5enc 표준 아키텍처는 가용성 및 처리 효율성을 명분으로 암호화 패킷 수신 시 "선 복호화 후 무결성 태그 검증(Decrypt-Before-MAC)" 연산 파이프라인을 채택
◦
AES-CTS-CBC 알고리즘으로 암호문을 완전 해독하여 메모리에 저장한 뒤, 최종 물리 단계에서 패킷 후미에 부착된 HMAC-SHA1 무결성 인증 태그를 검증하는 방식
▽ Kernel Cryptographic Operation Timeline
T1: 수신된 암호문 패킷 로드 및 복호화 엔진 인입
T2: AES_CTS_CBC_DECRYPT 연산 수행
T3: 도출된 raw 평문 바이트를 SGL 목적지 메모리 주소에 WriteBack (★ 공용 페이지 캐시 직접 오염 완료)
T4: 패킷 전체의 무결성을 증명하는 HMAC-SHA1 검증 연산 시작
T5: 무결성 검증 실패(HMAC Mismatch) 판정 선언 -> 커널이 공격 패킷으로 인지하고 connection abort 수행
JavaScript
복사
•
대상 메모리가 커널 내부의 완전히 격리된 독립 프라이빗 버퍼 스택이었다면 T5 단계에서 연결을 끊고 버퍼를 해제(Free)하는 것으로 완벽히 방어가 성립
◦
하지만 SGL 엔트리를 통해 커널 가상 메모리의 공용 페이지 캐시가 직접 인라인 매핑되어 있는 본 결함 구조하에서는, T5에서 인증 실패가 선언되어 커널이 세션을 완전히 파괴하는 시점에 이미 T3 단계의 물리적 변조 연산이 메모리 캐시 상에 영구적으로 반영되어 완결된 상태
◦
공격자는 유효한 HMAC 값을 위조할 필요가 없으며, 단지 복호화 쓰기가 통과한 직후 무결성 실패가 떨어지도록 패킷을 구성하면 됨
② AES-CBC Chosen-Plaintext Algebra 유도
•
공격자는 키 공간을 탐색하는 무차별 대입(Brute Force)을 수행하지 않고, 로컬 서브시스템 세션 내에 본인이 직접 제어하는 공격용 가짜 AF_RXRPC 서비스 소켓을 개방하고 수작업으로 도출한 rxrpc_s 서버 키를 커널 키링에 등록
◦
이를 통해 사용자 공간(Userspace)에서 토큰 암호화 키인 $K_e$ 값을 완전히 파악한 상태로 공격을 개시
•
표준 암호 블록 체인 복호화(CBC Decrypt) 모드 하에서 임의의 해독 평문 블록 P[i]는 현재 블록의 AES 하드웨어 해독 값과 직전 단계 암호문 블록 C[i-1] 간의 배타적 논리합(XOR) 연산 결과물로 정의
•
공격자는 MSG_SPLICE_PAGES 인터리빙 구조를 설계하여, 본인이 임의의 값으로 조작 가능한 익명 페이지 버퍼를 짝수 번째 암호문 블록 C[2i] 자리에 위치시키고, 변조 대상인 타깃 파일의 공용 페이지 캐시 메모리 블록을 홀수 번째 암호문 블록 C[2i+1] 자리에 정밀하게 조립하여 인입
•
여기서 커널 내부 복호화 로직이 타깃 메모리에 최종적으로 받아 적게 만들고자 하는 최종 변조 데이터(공격자가 원하는 악성 셸코드 바이너리 평문)를 chosen_i라고 정의하고, 방정식을 공격자가 패킷에 실어서 전송해야 할 유저 버퍼 값 user_buf_i 기준으로 재정리하면 다음과 같은 대수학적 결정론적 유도 공식이 성립
•
마지막 최종 논리 블록의 경우, RFC 3962에 규정된 암호 텍스트 도둑질(CTS-CS3) 스와핑 및 패딩 생략 보정 효과를 역산하기 위해 순방향 AES 암호화 프리미티브 연산을 적용하여 공격 버퍼 페이로드를 생성
•
결과적으로 공격자는 사전에 유도된 Ke 키 세트를 기반으로, 주입하고자 하는 16바이트 악성 코드 블록당 단 1회의 로컬 암호화 연산만 수행하면 커널 암호화 드라이버를 원격 조종 기계(Oracle)로 변질시켜 원하는 평문 바이트를 타깃 파일 메모리 캐시에 정확히 주입 가능
◦
AES-256 알고리즘의 강력한 암호학적 복잡성은 이 논리적 역산 구조 앞에서 무력화
5) End-to-End Exploitation Framework
메모리 분산-수집 리스트(SGL) 레이아웃 아키텍처
•
리눅스 커널의 네트워크 아키텍처 프래그먼트 최대 예산 제약 구조인 MAX_SKB_FRAGS = 17 스펙 한도 내에서 정밀한 타이밍 공격을 성립시키기 위해, 단일 RESPONSE 패킷 내의 구조적 프레임 헤더 및 후미의 HMAC 인증 부호 공간을 제외하고 정확히 6개의 (공격자 익명 페이지 블록, 타깃 파일 페이지 블록) 인터리빙 페어를 구성
•
이로써 단일 패킷 공격 행위당 정확히 96바이트의 런타임 평문 선택 제어 프리미티브를 확보
▽ SGL 물리 메모리 프레임 매핑 레이아웃
┌───────────┬────────────────────────────────────────────────────────────────────────┐
│ SGL Entry │ 매핑된 물리 메모리 상태 및 발생 연산 │
├───────────┼────────────────────────────────────────────────────────────────────────┤
│ wire[0] │ 공격자 Userspace 제어 익명 페이지 (vmsplice 파이프 주입 영역) │
├───────────┼────────────────────────────────────────────────────────────────────────┤
│ wire[1] │ 타깃 SUID 바이너리의 공용 페이지 캐시 블록 (Direct Overwrite 대상 영역) │
├───────────┼────────────────────────────────────────────────────────────────────────┤
│ wire[2] │ 공격자 Userspace 제어 익명 페이지 │
├───────────┼────────────────────────────────────────────────────────────────────────┤
│ wire[3] │ 타깃 SUID 바이너리의 공용 페이지 캐시 블록 (Direct Overwrite 대상 영역) │
├───────────┼────────────────────────────────────────────────────────────────────────┤
│ ... │ ... │
├───────────┼────────────────────────────────────────────────────────────────────────┤
│ wire[tail]│ HMAC-SHA1 무결성 인증 태그 매핑 필드 (의도적으로 무작위 더미 데이터 주입)│
└───────────┴────────────────────────────────────────────────────────────────────────┘
JavaScript
복사
커널 가상 메모리 관리자(MM) 영구 포이즈닝 시나리오
•
공격자는 스토리지 장치의 블록 레이어(I/O Subsystem)를 건드리지 않고 가상 메모리 서브시스템의 페이지 상태 모델만 정밀 타격
공격자 공간 (LPE 시도) 가상 메모리 관리자 (MM) 소켓 & 암호화 서브시스템
│ │ │
├── 1. open SUID 바이너리 ───────>│ │
├── 2. 메모리 참조 매핑 (Read) ───>│ 3. Page Cache Resident │
│ │ (물리 메모리 캐시 예열 완료) │
│ │ │
├── 4. vmsplice() & splice() ────>│ 5. sk_buff 프래그먼트에 │
│ │ 대상 파일 물리 Page 주소 바인딩
│ │ (SKBFL_SHARED_FRAG 플래그 유도)
│ │ │
├── 6. MSG_SPLICE_PAGES 패킷 송신 ──────────────────────────────────>│
│ │ │
│ │ ├── 7. rxgk_decrypt_skb() 인입
│ │ │
│ │ 8. skb_to_sgvec() 인터페이스 버그 작동
│ │<────────────────────────────────┤
│ │ (공용 Page 주소를 검증 없이 │
│ │ 크립토용 SGL 엔트리로 다이렉트 이관)
│ │ │
│ │ 9. crypto_krb5_decrypt() 제자리 복호화
│ │<────────────────────────────────┤
│ │ [★ CRITICAL PHYSICAL POISONING] │
│ │ 암호 해독된 페일로드 바이트가 │
│ │ 공용 페이지 캐시에 직접 WriteBack│
│ │ │
│ │ ├── 10. HMAC 무결성 검증 수행
│ │ │ (태그 Mismatch 판정)
│ │ ├── 11. 커널 소켓 연결 강제 파괴
│ │ │ (Connection Abort)
│ │ │
├── 12. 변조 완료된 SUID exec() ──>│ │
│ ├── 13. 디스크 I/O 완전 우회 │
│ │ 오염된 메모리 페이지를 │
│ │ 런타임에 직접 로드 및 실행 │
│ │ │
▼ ▼ ▼
[호스트 최고 권한(Root) 탈취 완료] ─────────────────────────────────────────┘
JavaScript
복사
•
공격 단계별 매커니즘
◦
Step 1 ~ 3 (공격초기 단계): 공격자가 타깃 SUID 바이너리를 사전에 읽어 들여 커널 가상 메모리 시스템의 페이지 캐시(Page Cache) 상에 물리적으로 상주하도록 유도합니다.
◦
Step 4 ~ 6 (포인터 바인딩): 제로 카피 메커니즘을 악용하여, 복사본 생성 없이 소켓 버퍼(sk_buff)가 타깃 파일의 물리 페이지 주소를 직접 참조(별칭 지정)하게 만듭니다.
◦
Step 7 ~ 9 (메모리 포이즈닝): DirtyCBC의 핵심 결함 지점입니다. COW(복사 시 쓰기) 보호 가드가 누락되어, 암호화 엔진이 해독한 평문 데이터가 공용 페이지 캐시 메모리에 직접 덮어씌워집니다.
◦
Step 10 ~ 11 (연결 파괴): 복호화가 끝난 후 HMAC 검증이 실패하여 커널은 해킹 패킷으로 판단하고 세션을 끊어버리지만, 이미 페이지 캐시는 변조가 완료된 후입니다.
◦
Step 12 ~ 14 (권한 상승): 시스템의 디스크 저장소는 깨끗하지만, 메모리 캐시가 오염되었기 때문에 바이너리를 실행하는 순간 커널은 메모리에 있던 악성 코드(setuid(0); execve("/bin/sh");)를 그대로 실행시켜 루트 셸을 내어주게 됩니다.
•
메모리 지속성 메커니즘 (Runtime Persistence Model) : 디스크의 원본 파일 아키텍처는 완전한 무결성 상태를 유지하므로 Tripwire나 AIDE 같은 파일 시스템 무결성 해시 검증 도구, 혹은 Direct I/O 방식의 로우 파일 시스템 정적 스캔으로는 오염 징후를 식별할 수 없음
◦
그러나 리눅스 커널의 가상 메모리 런타임 구조상, 한 번 오염된 캐시 페이지는 가상 메모리 테이블에 상주(Resident)하게 되며, 일반적인 환경에서 이 바이너리를 다시 실행(exec)하면 커널은 디스크 성능 저하를 막기 위해 메모리에 이미 올라와 있는 오염된 페이지 캐시를 가공하여 바로 코드를 실행
◦
공격자는 단 2개의 RESPONSE 패킷을 활용하여 192바이트 규모의 정밀하게 설계된 고성능 setuid(0); execve("/bin/sh"); x86_64 ELF 패인 페이로드를 페이지 캐시 첫머리에 영구 적재시키는 데 성공
◦
이에 따라 이 공격은 시스템 물리 재부팅, inode 강제 무효화 연산, 혹은 시스템 커널 매개변수를 통한 수동 캐시 드롭(echo 3 > /proc/sys/vm/drop_caches)이 일어나기 전까지 메모리에 완전히 잔존
6) 보안패치 구조 및 완화 매커니즘
1차 패치: 상태 인프라 필터링 (Commit: aa54b1d27fe0)
•
사용자가 유도한 splice() 계열의 시스템 콜 흐름을 통해 생성된 커널 내부 소켓 버퍼 데이터 구조체는 반드시 SKBFL_SHARED_FRAG 구조 플래그를 가짐
◦
업스트림 커널 팀은 패킷이 디스패치되어 제자리 암호화 함수부로 분기하기 직전, 소켓 버퍼의 클론 상태 및 공유 프래그먼트 리스트 존재 여부를 검사하는 보안 필터링 레이어를 도입
// net/rxrpc/ 서브시스템 내의 디스패치 보안 경계 가드 로직
if (skb_cloned(skb) || skb_has_frag_list(skb) || skb_has_shared_frag(skb)) {
// [보안 조치]: 외부 하위 시스템과 메모리가 공유되어 오염될 소지가 있는 skb 포착 시,
// 제자리 복호화 엔진으로 전달하기 전에 프라이빗 커널 메모리 영역에 안전하게 복사본을 생성
nskb = skb_copy(skb, GFP_NOFS);
// 복사된 프라이빗 독립 버퍼를 암호화부로 전달하여 외부 오염 차단
ret = conn->security->verify_response(conn, nskb);
}
JavaScript
복사
•
사용자 공간의 프로그램은 커널 핵심 내부 통제 플래그인 MSG_NO_SHARED_FRAGS를 임의로 조작할 권한이 없으므로, 이 상태 검사 필터 만으로도 MSG_SPLICE_PAGES를 활용한 메모리 인터리빙 우회 경로는 완벽히 격리 차단
2차 패치: 아키텍처 불변성 확립
•
1차 패치가 위험 징후가 포착된 버퍼를 선별 조치하는 필터링 방식이었다면, 최종 아키텍처 개편 패치는 암호화 변환 서브시스템과 네트워크 입출력 소켓 버퍼 스토리지 간의 긴밀한 커플링을 근본적으로 단절하는 구조적 불변성을 확립
// RESPONSE 패킷 검증 아키텍처 전면 개편
buffer = kmalloc(len, GFP_NOFS);
if (!buffer) return -ENOMEM;
// [구조적 격리]: 네트워크 소켓 버퍼(skb) 내부의 로우 데이터를
// 안전한 커널 전용 선형 격리 메모리 공간(kmalloc flat buffer)으로 1차 선형 추출 복사
ret = skb_copy_bits(skb, sizeof(struct rxrpc_wire_header), buffer, len);
// 이제 소켓 버퍼의 메모리 포인터 구조를 참조하지 않고,
// 완전히 격리된 독립 플랫 버퍼 상에서 복호화 및 무결성 태그 검증을 안전하게 완결
ret = conn->security->verify_response(conn, skb, buffer, len);
JavaScript
복사
•
이 구조적 아키텍처 갱신으로 인해 과거 페이지 오염의 시발점이었던 소켓 버퍼 다이렉트 매핑 함수 skb_to_sgvec()가 복호화 경로에서 완전히 영구 영명
•
이로써 "인증되지 않은 불안정한 네트워크 로우 데이터는 프로토콜 엔진 외부에 공유되거나 별칭이 지정될 가능성이 있는 어떠한 커널 스토리지 구조물 위에서도 제자리(In-place) 복호화 연산을 수행하지 않는다"는 최상위 커널 보안 대원칙이 강제 통제
7) 영향도 분석
레이어 | 영향 받음 | 영향 받지 않음 | 조건 |
커널 빌드 | 2026년 4월 25일 커밋 이전의 커널 베이스라인이면서 CONFIG_RXGK=y 또는 =m인 경우 | RxGK가 비활성화된 커널(Debian Stable, RHEL, Ubuntu LTS 표준 빌드) 또는 4월 25일 패치가 포함된 커널 | zcat /proc/config.gz | grep RXGK 또는 grep RXGK /boot/config-$(uname -r) 명령어로 확인 |
배포판 | Fedora Rawhide, Fedora Workstation (패치 적용 전), Arch Linux, openSUSE Tumbleweed | 커널 업데이트 후의 Fedora Stable, pacman -Syu 이후의 Arch, 최신 스냅샷으로 zypper dup을 마친 Tumbleweed | 워크스테이션의 업데이트 주기가 중요함 — 14일 동안 업데이트하지 않았다면 취약할 가능성이 높음 |
배포판 (안정화 버전) | 최첨단 패키지 사용 환경 (Ubuntu의 mainline PPA, RHEL/CentOS Stream의 ELRepo kernel-ml) | 표준 벤더 커널을 사용하는 Debian Bookworm, RHEL 8/9, Ubuntu 22.04/24.04 LTS | 거의 영향 받지 않음; 그럼에도 모든 호스트를 전수조사하는 것은 가치가 있음 |
컨테이너 이미지 | 컨테이너 이미지 빌드는 호스트 커널에 영향을 주지 않음 — 컨테이너 내부에서 RxGK는 스스로 로드되지 않음 | — | 직접적인 컨테이너 이미지 패치는 필요 없으며, 패치는 반드시 호스트에 적용되어야 함 |
컨테이너 호스트 (Kubernetes 워커) | Fedora CoreOS Rawhide, Arch 기반 커스텀 빌드, 최첨단 Talos 나이틀리(nightly) 빌드를 실행하는 워커 노드 | Talos 안정판, Flatcar 안정판, Bottlerocket, Ubuntu LTS 워커, AWS Bottlerocket | 파드 탈출 경로: 침해된 컨테이너 + 커널 LPE = 호스트 root 권한 탈취 |
베어메탈 서버 (호스팅) | 커스텀 롤링 커널을 사용하는 호스팅 제공업체 (흔치 않음) | Hetzner 표준 Debian, Mittwald 호스팅(Debian 백포트 라인), STRATO/Plesk 스택 | 불확실한 경우 호스팅 제공업체에 문의 |
개발자 워크스테이션 | 플랫폼 엔지니어, SRE, 보안 팀의 Fedora/Arch/Tumbleweed 워크스테이션 | macOS, Windows, Debian Stable 워크스테이션 | 권한 있는 접근 권한(kubectl 컨텍스트, AWS 프로필, SSH 키 등)을 보유하고 있어 위험 프로필이 매우 높음 |
3.2. CVE-2026-31635와 DirtyDecrypt 관계
•
DirtyDecrypt는 CVE-2026-31635로 명명되고 있으나 실제 CVE에서 언급된 버그 발생지점과 DirtyDecrypt의 버그 발생 지점이 상이
◦
DirtyDecrypt에 대한 공식적인 CVE ID는 없는 것으로 볼 수 있으나, Tharros의 수석 취약점 분석가인 Will Dormann(CERT/CC, 이후 Analygence)이 CVE-2026-31635와의 연관성을 제기하였고 NVD 레코드에 V12의 PoC 링크가 포함되면서 CVE에 포함
◦
V12 팀은 5월 9일 커널 관리자들에게 이 사실을 보고했으나 해당 이슈가 이미 내부적으로 중복 건으로 식별되어 패치되었다는 답변을 받은 후 취약점 공개 시에 "rxgk_decrypt_skb 내 COW 보호 장치 누락으로 인한 rxgk 페이지 캐시 쓰기"라고 발표
구분 | [Bug A] NVD에 명시된 버그내용 | [Bug B] DirtyDecrypt |
핵심 결함 | rxgk_verify_response() 함수 내의 인증자 길이 검사 조건 반전 (Inverted)→ 부호가 뒤집혀 실제 패킷 잔여 크기보다 큰 auth_len를 통과시킴 | rxgk_decrypt_skb() 함수 내의 COW(Copy-On-Write) 보호 가드 누락 (Missing)→ 공유 파이프/페이지에 대한 보호 장치 없이 제자리 복호화 쓰기 수행 |
매커니즘 | Oversized RESPONSE 패킷이 차단되지 않고 내부 skb_to_sgvec()까지 흘러 들어가 커널이 처리 불가한 길이를 마주함 | MSG_SPLICE_PAGES로 인해 다른 프로세스와 별칭(alias) 지정된 공유 페이지 캐시에 복호화된 데이터를 직접 덮어씀 |
커널내부 실행흐름 | rxgk_verify_response()→ rxgk_decrypt_skb()→ skb_to_sgvec() | rxgk_verify_response() → rxgk_extract_token() → rxgk_decrypt_skb() → skb_to_sgvec() → crypto_krb5_decrypt() |
공격결과 및 위험성 | 서비스 거부 (DoS)→ 커널이 BUG_ON(len)을 히트하여 시스템이 강제로 다운되거나 기절함 (권한 탈취 불가) | 로컬 권한 상승 (LPE)→ /etc/shadow, /etc/sudoers, SUID 바이너리 등의 페이지 캐시를 조작하여 일반 사용자가 root 권한 획득 |
NVD CVSS | AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H→ 가용성(Availability)에만 영향을 주는 위협으로 매핑 | NVD내에서는 LPE
컨테이너 환경에서는 파드 탈출(Pod Escape) 경로로 작동 |
진짜 수정 커밋 | aa54b1d27fe0 (5월 10일 패치) |
3.3. Drity 패밀리의 공통점 : 버그 클래스
•
DirtyDecrypt는 미묘한 메모리 관리 취약점으로 인해 발생하는 최근 Linux 커널 LPE 취약점 목록에 포함
◦
Dirty Frag(CVE-2026-43284 / CVE-2026-43500), Fragnesia, Copy Fail(참조 페이지 UID 732, 현재 CISA KEV에 등재), PackageKit 데몬의 Pack2TheRoot가 이에 해당
•
취약점들의 공통점은 모듈이 아니라 버그 클래스에서 확인
◦
페이지 캐시 작업 시 발생하는 레이스 조건(race conditions)이나 동기화 보장 미비로 인해, 매우 정밀한 타이밍을 맞추었을 때 권한이 있는 쓰기 작업으로 이어지게 된다는 점
◦
DirtyDecrypt는 네트워크 하위 시스템과 페이지 캐시의 교차점에 위치하므로 취약점 트리거 조건은 Copy Fail보다 더 특수하지만, 익스플로이트 경로의 위험성을 보임
리눅스 커널 취약점 현황
04. 대응방안
•
대응방안 적용순서 : 가능하면 패치를 먼저 적용하고, 그다음 임시 우회책을 적용한 후, 컨테이너 호스트 전략을 구조적으로 정리
4.1. 커널 패치를 적용하는 경우(보안 업데이트)
•
2026년 4월 25일자 패치 또는 그 이후 버전이 포함된 커널 업데이트를 적용
# Fedora / Fedora CoreOS
sudo dnf upgrade --refresh kernel kernel-core kernel-modules
sudo systemctl reboot
uname -r
# 빌드 날짜가 2026년 4월 25일 이후이거나 패치 노트에 CVE-2026-31635가 명시된 커널
# Arch Linux / Arch 기반 호스트
sudo pacman -Syu linux linux-headers
sudo systemctl reboot
uname -r
# openSUSE Tumbleweed
sudo zypper dup
sudo systemctl reboot
# Ubuntu Mainline PPA (사용 중인 경우)
sudo apt update
sudo apt upgrade linux-image-generic linux-headers-generic
sudo systemctl reboot
JavaScript
복사
•
재부팅하기 전에 rxrpc 모듈이 활성화되어 있는지, 어떤 파일이 afs 커널 모듈 락을 잡고 있는지 확인
◦
그렇지 안는 경우 재부팅 후 마운트가 중단될 소지가 있음
lsmod | grep -E "(rxrpc|afs)"
fuser -m /afs 2>/dev/null
JavaScript
복사
•
안정화 배포판(Debian Stable, RHEL, Ubuntu LTS)은 보통 RxGK가 비활성화되어 있으나, zcat /proc/config.gz | grep RXGK 명령어를 통한 신속한 확인은 필수적
◦
컨테이너 환경에서 취약한 버전의 Linux를 실행하는 워커 노드는 Pod에서 탈출할 수 있는 경로를 제공
4.2. 패치가 어려운 경우
•
메인라인 수정 사항인 aa54b1d27fe0은 2026년 5월 10일부터 제공되어 안정화 트리로 전파되기 때문에 업데이트 지연 등 보안패치가 어려운 경우에는 영향받는 모듈을 언로드 하고 블랙리스트로 등록
◦
패치가 불가능한 경우 : modprobe 블랙리스트를 통해 esp4, esp6, rxrpc 모듈을 언로드하고 캐시를 비워야 함
◦
단, 이 조치는 IPsec/VPN 및 AFS를 중단시킬 수 있음을 유의해야 하며 워크로드가 허용하는 한 컨테이너 호스트를 안전화 커널 라인으로 이동 필요
# 1. 모듈 블랙리스트 파일 생성
sudo tee /etc/modprobe.d/dirtydecrypt-mitigation.conf > /dev/null <<'EOF'
# Temporary mitigation for DirtyDecrypt / CVE-2026-31635
# Remove this file after kernel patch is applied
blacklist esp4
blacklist esp6
blacklist rxrpc
install esp4 /bin/false
install esp6 /bin/false
install rxrpc /bin/false
EOF
# 2. 활성화된 모듈 언로드 (실행 중인 서비스가 이 모듈들에 의존하지 않는지 사전에 확인)
sudo modprobe -r esp4 esp6 rxrpc 2>&1 | tee /tmp/modprobe-remove.log
# 3. 모듈 캐시 및 페이지 캐시 플러시
sudo depmod -a
sudo sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
# 4. 재부팅 후 모듈이 로드되지 않았는지 검증
lsmod | grep -E "(esp4|esp6|rxrpc)" && echo "WARN: module still loaded" || echo "OK: blacklisted"
JavaScript
복사
•
이 우회책은 IPsec VPN 연결(StrongSwan, libreswan, Algo 등 — 단, 다른 경로를 사용하는 WireGuard는 제외)과 AFS 분산 파일 시스템을 중단
4.3. 쿠버네티스를 위한 컨테이너 호스트 전략
•
롤링 릴리스(Rolling Release)배포판에서 쿠버네티스 워커를 실행 중이라면 개별 노드의 커널을 일일이 패치하는 것이 아니라 선언적 호스트 전략이 필요
# Talos Linux 워커 풀 확인
talosctl --nodes worker-01 version
# 만약 커스텀 커널 빌드가 포함된 1.10.x 이전 버전의 Talos인 경우:
# `talosctl upgrade --image ghcr.io/siderolabs/installer:v1.10.x`를 통해 워커 업그레이드 수행
# Flatcar 워커 풀 확인
ssh worker-01 cat /etc/os-release | grep VERSION
# Flatcar는 자동화된 OS 업데이트를 통해 커널 패치를 가져옵니다;
# Kured 또는 Karpenter를 통해 재부팅 윈도우를 제어하십시오.
# Bottlerocket 워커 풀 확인
aws ssm send-command --instance-ids i-... \
--document-name "AWS-RunShellScript" \
--parameters 'commands=["uname -r"]'
JavaScript
복사
•
정상적인 쿠버네티스 운영 환경에서는 imagePullPolicy: Always, allowPrivilegeEscalation: false, readOnlyRootFilesystem: true, runAsNonRoot: true가 기본값으로 이를 강제하지 않은 경우에는 DirtyDecrypt보다 더 큰 보안 문제가 발생할 소지가 존재
•
파드 보안 표준(Pod Security Standards, 제한된 프로필)이 클러스터 전체에 활성화되어 있어야 함
4.4. 취약점 영향도 점검 방법
•
사용방법
python3 dirty_frag_detect.py
JavaScript
복사


