블로그
home
Nation-State Cyber Actors Analysis Report
home

Fragnesia 변종 취약점 DirtyDecrypt 분석(CVE-2026-31635)

작성자
김미희
감수인
작성일
2026/05/27
배포일
2026/05/29
문서등급
TLP:CLEAR
Tags
DirtyDecrypt
CVE-2026-31635
문서유형
TechNote

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월 1일, KEV에 CVE-2026-31431 등록
2026년 5월 7일, 김현우(@v4bel)연구원에 의해 ESP 취약점(CVE-2026-43284)과 RxRPC 변종(CVE-2026-43500)을 결합하여 Copy Fail을 확장한 Dirty Frag 공개
당초 리눅스 관리자들과 김현우 연구원은 5월 12일까지 정보를 공개하지 않기로 합의를 하였으나, 5월 7일 제3자가 엠바고 기간을 알지 못한 상태에서 익스플로잇을 공개하면서 CVE가 부여되기 전에 무방비 상태로 취약점 공개
2026년 5월 15일, William Bowling과 V12 팀(Zellic)에 의해 Dirty Frag 취약점 클래스의 일종인 Fragnesia 공개
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$ 값을 완전히 파악한 상태로 공격을 개시
Ke=DK(K,RXGK_SERVER_ENC_TOKEN)(여기서 usage value=1036)K_{e} = \text{DK}(K, \text{RXGK\_SERVER\_ENC\_TOKEN}) \quad (\text{여기서 usage value} = 1036)
표준 암호 블록 체인 복호화(CBC Decrypt) 모드 하에서 임의의 해독 평문 블록 P[i]는 현재 블록의 AES 하드웨어 해독 값과 직전 단계 암호문 블록 C[i-1] 간의 배타적 논리합(XOR) 연산 결과물로 정의
P[i]=AES_DEC(Ke,C[i])C[i1]P[i] = \text{AES\_DEC}(K_{e}, C[i]) \oplus C[i-1]
공격자는 MSG_SPLICE_PAGES 인터리빙 구조를 설계하여, 본인이 임의의 값으로 조작 가능한 익명 페이지 버퍼를 짝수 번째 암호문 블록 C[2i] 자리에 위치시키고, 변조 대상인 타깃 파일의 공용 페이지 캐시 메모리 블록을 홀수 번째 암호문 블록 C[2i+1] 자리에 정밀하게 조립하여 인입
변조 목적지 평문 공식: P[2i+1]=AES_DEC(Ke,target_block_i)user_buf_i\text{변조 목적지 평문 공식: } P[2i+1] = \text{AES\_DEC}(K_{e}, \text{target\_block\_i}) \oplus \text{user\_buf\_i}
여기서 커널 내부 복호화 로직이 타깃 메모리에 최종적으로 받아 적게 만들고자 하는 최종 변조 데이터(공격자가 원하는 악성 셸코드 바이너리 평문)를 chosen_i라고 정의하고, 방정식을 공격자가 패킷에 실어서 전송해야 할 유저 버퍼 값 user_buf_i 기준으로 재정리하면 다음과 같은 대수학적 결정론적 유도 공식이 성립
user_buf_i=AES_DEC(Ke,target_block_i)chosen_i\text{user\_buf\_i} = \text{AES\_DEC}(K_{e}, \text{target\_block\_i}) \oplus \text{chosen\_i}
마지막 최종 논리 블록의 경우, RFC 3962에 규정된 암호 텍스트 도둑질(CTS-CS3) 스와핑 및 패딩 생략 보정 효과를 역산하기 위해 순방향 AES 암호화 프리미티브 연산을 적용하여 공격 버퍼 페이로드를 생성
user_buf_(N-1)=AES_ENC(Ke,chosen_(N-1)target_block_(N-1))\text{user\_buf\_(N-1)} = \text{AES\_ENC}(K_{e}, \text{chosen\_(N-1)} \oplus \text{target\_block\_(N-1)})
결과적으로 공격자는 사전에 유도된 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) : 디스크의 원본 파일 아키텍처는 완전한 무결성 상태를 유지하므로 TripwireAIDE 같은 파일 시스템 무결성 해시 검증 도구, 혹은 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) 경로로 작동
진짜 수정 커밋
a2567217ade97, beee051f259a, e2f1a80d8b1e등 (4월 24일 패치)
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보다 더 특수하지만, 익스플로이트 경로의 위험성을 보임
리눅스 커널 취약점 현황
Vulnerability Name
CVE
Subsystem
Modules
Introduced
Fixed (upstream)
벤더별 패치현황
CopyFail
CVE-2026-31431
AF_ALG (Crypto Socket)
af_alg, algif_skcipher
Aug 2017 (72548b093ee3)
Mar 31 2026 (a664bf3d603d)
DirtyFrag
CVE-2026-43284
IPsec ESP
esp4esp6
Jan 2017 (cac2661c53f3)
May 5 2026 (f4c50a4034e6)
Fragnesia
CVE-2026-46300
RxRPC
rxrpc
Jun 2023 (2dc334f1a63a)
May 10 2026 (aa54b1d27fe0)
DirtyDecrypt
CVE-2026-31635
RxGK
rxrpc, afs
2017년 이후 출시된 모든 버전(커널 7.0.4 포함)

04. 대응방안

대응방안 적용순서 : 가능하면 패치를 먼저 적용하고, 그다음 임시 우회책을 적용한 후, 컨테이너 호스트 전략을 구조적으로 정리

4.1. 커널 패치를 적용하는 경우(보안 업데이트)

2026년 4월 25일자 패치 또는 그 이후 버전이 포함된 커널 업데이트를 적용
# Fedora / Fedora CoreOS sudo dnf upgrade --refresh kernel kernel-core kernel-modules sudo systemctl reboot uname -r # 빌드 날짜가 2026425일 이후이거나 패치 노트에 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
복사
IGLOO Corp. 2026. All rights reserved.