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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-31431-cleaned — CVE-2026-31431에 대한 개념 증명 익스플로잇으로, splice()와 조작된 소켓 옵션을 통한 Linux 커널 로컬 권한 상승을 이용해 임의의 커널 메모리 쓰기를 가능하게 하여 setuid 바이너리를 덮어씁니다. | Kitploit
도구/GitHubGitHub/galoryber/cve-2026-31431-cleaned
Privilege EscalationExploit FrameworksVulnerability AnalysisExploitationBinary Exploitation
GitHubgaloryber/cve-2026-31431-cleaned

CVE-2026-31431-cleaned

CVE-2026-31431에 대한 개념 증명 익스플로잇으로, splice()와 조작된 소켓 옵션을 통한 Linux 커널 로컬 권한 상승을 이용해 임의의 커널 메모리 쓰기를 가능하게 하여 setuid 바이너리를 덮어씁니다.

저장소 보기

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

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

copyFail.py — CVE 익스플로잇 분석 보고서

요약

copyFail.py는 Linux 커널의 로컬 권한 상승 취약점을 입증하는 개념 증명(PoC) 익스플로잇입니다. splice() 시스템 콜을 조작된 소켓 옵션과 결합하여 악용함으로써, 익스플로잇은 임의의 커널 메모리를 손상시킬 수 있는 능력을 얻습니다. 이 기능을 사용하여 디스크에 있는 임의의 setuid 바이너리를 사용자 정의 ELF 실행 파일로 덮어쓴 다음, 변조된 바이너리를 실행하여 상승된 권한을 획득합니다.

공격 유형: 로컬 권한 상승(LPE) 영향: 전체 루트 셸 접근(setuid-루트 바이너리를 대상으로 할 때) 복잡도: 낮음(단일 스크립트, 외부 종속성 없음)

사용법:

root@kitploit:~
./copyFail_cleaned.py [대상_바이너리]   # 기본값: /usr/bin/su

원본 PoC는 /usr/bin/su를 하드코딩했지만, 기본 커널 취약점은 모든 파일에 적용됩니다 — 공격자는 선택한 모든 setuid 바이너리를 덮어쓸 수 있습니다. 정리된 버전은 대상을 지정하기 위한 선택적 명령줄 인수를 허용하여 이 동작을 명시적으로 만듭니다.


취약점이란 무엇인가

Linux 커널은 두 파일 디스크립터 간에 데이터를 커널 내부에서 완전히 복사하는 splice() 시스템 콜을 제공합니다 — 먼저 사용자 공간으로 데이터를 복사하지 않습니다. 이를 "제로-카피 I/O"라고 하며 웹 서버 및 리버스 프록시와 같은 고처리량 애플리케이션의 성능을 위해 사용됩니다.

이 취약점은 커널이 지원되지 않는 프로토콜 수준 소켓 옵션으로 구성된 PACKET 소켓에 splice()가 사용될 때 특정 소켓 구조의 내부 상태를 제대로 검증하지 않기 때문에 발생합니다. 이러한 옵션을 신중하게 구성함으로써 공격자는 커널 포인터를 손상시킬 수 있으며, 그런 다음 splice()를 사용하여 커널 메모리 쓰기를 임의의 위치로 리디렉션할 수 있습니다.

간단히 말하면: 커널에는 내부적으로 데이터를 이동시키는 지름길이 있으며, 이 익스플로잇은 그 지름길을 속여 잘못된 위치 — 구체적으로 시스템 바이너리의 메모리 내 복사본 — 에 데이터를 쓰게 합니다.


익스플로잇 작동 방식(높은 수준)

익스플로잇은 명확한 일련의 단계를 따릅니다:

1. 잘못된 소켓 설정

익스플로잇은 원시 PACKET 소켓(AF_PACKET / SOCK_RAW)을 생성하고 의도적으로 잘못된 주소에 바인딩합니다. 그런 다음 Linux가 인식하지 못하는 Solaris 수준 상수인 SOL_PNIO(프로토콜 수준 279)를 사용하여 setsockopt()를 호출합니다.

이것이 중요한 이유: 커널이 setsockopt()에서 지원되지 않는 프로토콜 수준을 만나면 데이터를 제대로 검증하지 않는 일반 처리기로 폴백합니다. 이로 인해 커널 메모리가 일관되지 않고 악용 가능한 상태로 남게 됩니다.

2. sendmsg()로 커널 포인터 손상

accept()를 통해 소켓 연결을 설정한 후, 익스플로잇은 sendmsg()를 사용하여 조작된 보조(제어) 메시지를 전송합니다. 이러한 메시지는 의도적으로 불일치하는 길이 헤더를 가지고 있습니다 — 일부는 실제보다 짧다고 주장하고, 다른 일부는 더 길다고 주장합니다.

이것이 중요한 이유: 커널의 제어 메시지 파서는 이러한 길이를 포인터 산술에 사용합니다. 불일치하는 길이는 파서가 의도된 경계를 넘어 읽거나 쓰게 하여 인접한 커널 구조 — 특히 splice()가 나중에 따를 포인터 — 를 손상시킵니다.

3. splice()를 리디렉션하여 임의 메모리 덮어쓰기

익스플로잇은 파이프를 생성하고 splice()를 두 번 호출합니다:

  • 먼저 /usr/bin/su에서 파이프로 데이터를 스플라이스합니다.
  • 그런 다음 파이프에서 손상된 소켓으로 스플라이스합니다.

이것이 중요한 이유: splice() 호출은 2단계에서 심어진 손상된 커널 포인터를 따르므로 소켓 버퍼 대신 공격자가 선택한 커널 메모리 주소에 데이터를 쓰게 됩니다. 이는 익스플로잇에 임의 커널 메모리 쓰기 프리미티브를 제공합니다.

4. 각 셸코드 청크에 대해 반복

익스플로잇의 페이로드는 160바이트 ELF 실행 파일입니다(아래 참조). 익스플로잇 함수에 대한 각 호출은 정확히 4바이트를 씁니다. 따라서 메인 루프는 40회 실행됩니다(160 / 4 = 40), 매회:

  • 새 소켓 생성
  • 커널 상태 손상
  • 4바이트 셸코드 쓰기
  • 정리

모든 40회 반복 후, /usr/bin/su의 처음 160바이트가 덮어써집니다.

5. 변조된 바이너리 실행

마지막으로 익스플로잇은 os.system("su")를 실행합니다. 커널은 페이지 캐시(이제 실제 su 바이너리 대신 공격자의 셸코드를 포함하는)에서 수정된 /usr/bin/su를 로드하고, 셸코드가 실행됩니다.


셸코드 페이로드

내장된 페이로드는 다음 셸코드를 포함하는 160바이트 x86-64 ELF 실행 파일로 압축 해제됩니다:

root@kitploit:~
; syscall 105(execveat) 시도 — 이전 커널에서는 사용하지 못할 수 있음
xor  eax, eax
xor  edi, edi
mov  al, 0x69          ; syscall 105
syscall

; 폴백: syscall 59(execve) — 신뢰할 수 있는 경로
lea  rdi, [rip+0xf]    ; RDI = "/bin/sh" 포인터
xor  esi, esi           ; RSI = NULL (envp)
push 0x3b               ; syscall 59 번호
pop  eax
cdq                     ; RDX = NULL (argv)
syscall

; 깨끗하게 종료
xor  edi, edi
push 0x3c               ; syscall 60 (exit)
pop  eax
syscall

; 데이터 섹션: "/bin/sh\0\0\0"

기능: 인수 없이 /bin/sh를 생성하여 su를 실행한 프로세스의 권한을 상속합니다. 익스플로잇이 루트로 실행되면(또는 su에 루트 접근을 부여하는 기능으로), 결과 셸은 루트 셸입니다.

하지 않는 것:

  • 리버스 셸 또는 네트워크 콜백 없음
  • 지속성 메커니즘 없음(cron, systemd, SSH 키 등)
  • 자격 증명 도용 또는 데이터 유출 없음
  • 프로세스 숨김 또는 안티-포렌식 없음

이는 연구 PoC와 일치하는 단순한 일회성 권한 상승입니다.


기술적 세부 사항

사용된 주요 Linux 상수

파일 구조

root@kitploit:~
copyFail.py
├── hex_to_bytes()         — 16진수 문자열 디코더
├── exploit_splice()       — 핵심 익스플로잇(소켓 설정 + 손상 + splice)
│   ├── 1단계: PACKET 소켓 생성, 바인딩, setsockopt (SOL_PNIO)
│   ├── 2단계: accept() 연결
│   ├── 3단계: 조작된 보조 메시지로 sendmsg()
│   ├── 4단계: pipe() + splice()로 커널 메모리 손상
│   └── 5단계: recv() 시도(손상 강화)
└── 메인 루프:
    ├── /usr/bin/su 열기(읽기 전용)
    ├── 내장 페이로드 압축 해제(zlib → 160바이트 ELF)
    ├── 루프: 반복당 4바이트 주입(총 40회 반복)
    └── 변조된 su 실행 → 루트 셸

왜 읽기 전용인가?

익스플로잇은 /usr/bin/su를 O_RDONLY(읽기 전용)로 엽니다. 쓰기 접근이 필요하지 않은 이유는 손상이 커널 페이지 캐시 — 커널이 변경 사항을 디스크에 플러시하기 전에 사용하는 파일의 메모리 내 복사본 — 를 통해 발생하기 때문입니다. splice() 기반 쓰기는 일반 파일 권한을 완전히 우회하여 커널 메모리로 직접 이동합니다.


탐지 및 완화

손상 지표

  • 수정된 /usr/bin/su 바이너리(패키지 관리자와 해시 비교)
  • 비루트 프로세스에 의한 비정상적인 PACKET 소켓 생성
  • 알 수 없는 프로토콜 수준을 사용한 예기치 않은 setsockopt() 호출
  • 일반 파일이 아닌 파일 디스크립터에 대한 splice() 시스템 콜

완화 조치

  • 사용 가능할 때 이 CVE에 대한 커널 패치 적용
  • sysctl을 사용하여 권한 없는 사용자의 AF_PACKET 소켓 생성 제한
  • 커널 하드닝 옵션 활성화(CONFIG_FORTIFY_SOURCE, CONFIG_STACKPROTECTOR)
  • 중요 바이너리의 파일 무결성 모니터링(AIDE, OSSEC, Tripwire)

참고 자료

  • 원본 PoC: copyFail.py(배포된 대로)
  • 주석 버전: copyFail_cleaned.py(같은 디렉토리)
  • 관련 커널 서브시스템: net/packet/, fs/splice.c, net/core/sock.c

이 보고서는 보안 연구 및 방어 분석 목적으로만 제공됩니다.

도구 다운로드
상수값익스플로잇에서의 용도
AF_PACKET17원시 패킷 소켓 패밀리
SOCK_RAW3원시 소켓 유형
SOL_PNIO279지원되지 않는 프로토콜 수준(Solaris)
MSG_DONTWAIT0x400비차단 sendmsg 플래그