
copyfail(CVE-2026-31431)의 Bash 구현
레이스 없음. 오프셋 없음. 맹목적으로 신뢰할 사전 빌드 바이너리 없음.
CVE-2026-31431(Copy Fail)의 bash 구현입니다. 이 스크립트는 런타임에 최소한의 C 헬퍼를 인라인으로 컴파일합니다. bash 레이어는 아키텍처 탐지, 페이로드 압축 해제, 대상 선택을 처리하고, C 레이어는 bash만으로는 닿을 수 없는 실제 커널 상호작용(AF_ALG 소켓, splice, sendmsg)을 수행합니다.
전체 기술 분석은 copy.fail에서 확인하세요.
버그는 커널의 AF_ALG AEAD 소켓 인터페이스인 algif_aead에 있습니다. 2017년의 in-place 최적화로 인해 페이지 캐시 페이지가 authencesn 복호화 작업의 쓰기 가능한 대상 scatterlist에 포함될 수 있습니다. splice()를 통해 올바른 입력을 전달하면 소유하지 않은 setuid 바이너리를 포함한 읽기 가능한 모든 파일의 페이지 캐시에 결정적인 4바이트 쓰기가 발생합니다.
/usr/bin/su를 셸코드로 4바이트씩 덮어쓴 다음 실행하면 루트 셸을 얻습니다. 레이스 윈도우도, 커널별 심볼도, 재시도도 필요 없습니다.
chmod +x copyfail.sh
# Check if the system is vulnerable before doing anything
./copyfail.sh -c
# Run the exploit (must be non-root)
./copyfail.sh
# Specify a different setuid target
./copyfail.sh -t /usr/bin/passwd
# List all setuid-root candidates on the system
./copyfail.sh -s
이 익스플로잇은 메모리의 페이지 캐시만 덮어쓸 뿐 디스크의 파일은 건드리지 않습니다. 재부팅하면 모든 것이 복원됩니다. 즉시 정리하려면:
# Inside your root shell
/usr/bin/su --version # still works from disk if page cache is evicted
# Or just reboot
su가 아닌 다른 대상을 -t로 지정했다면 마찬가지입니다. 페이지 캐시만 해당되며 디스크는 깨끗합니다.
gccpython3(한 줄이면 되며 패키지가 필요 없습니다)algif_aead, authencesn, hmac, cbc알고리즘을 사용할 수 없는 경우:
sudo modprobe algif_aead authencesn hmac cbc
일부 배포판은 임시 해결책으로 /etc/modprobe.d/에 차단 설정을 포함합니다. 있다면 제거하세요:
sudo rm /etc/modprobe.d/disable-algif{_,-}aead.conf 2>/dev/null
floor: torvalds/linux 72548b093ee3 August 2017, v4.14
(AF_ALG iov_iter rework that introduced
the file-page write primitive via splice
into the AEAD scatterlist)
ceiling: torvalds/linux a664bf3d603d April 2026, mainline
(reverts the 2017 in-place optimization;
source and destination scatterlists are
now separate, page-cache pages can no
longer end up as writable crypto output)
이 두 커밋 사이에 있는, 수정 사항을 백포트하지 않은 모든 주요 배포판이 영향을 받습니다. Ubuntu, RHEL, SUSE, Amazon Linux, Debian은 모두 공개 시점에 취약한 것으로 확인되었습니다. 배포판 백포트는 2026-04-29경부터 배포되기 시작했습니다. 특정 커널을 확인하려면 변경 로그에서 a664bf3d603d(또는 해당 배포판의 백포트)를 찾아보세요.
| 아키텍처 | 상태 |
|---|---|
| x86_64 | ✓ |
| aarch64 | ✓ |
| i386 / i686 | ✓ |
| armv7l | ✓ |
영구 조치: 커널을 업데이트하세요.
임시 조치(AF_ALG 소켓을 차단하며, 커널 암호화 API를 직접 사용하는 IPsec/XFRM에는 영향을 주지 않습니다):
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf
sudo rmmod algif_aead 2>/dev/null
컨테이너: AF_ALG 소켓 생성을 차단하는 seccomp 프로필을 추가하고, 포드 보안 컨텍스트에서 allowPrivilegeEscalation: false로 설정하세요. 이렇게 하면 no_new_privs가 활성화되어 커널이 execve()에서 setuid 비트를 적용하지 않게 됩니다.
bash 버전은 의존성 측면에서 우위를 점하지는 못하지만, 실행 전에 처음부터 끝까지 읽을 수 있는 단일 스크립트입니다. C 헬퍼는 런타임에 heredoc에서 생성·컴파일되므로 별도로 감사할 바이너리 블롭이 없습니다.
승인된 보안 테스트 및 연구 목적으로만 사용하세요. 소유하지 않았거나 명시적인 서면 허가를 받지 않은 시스템에서 실행하지 마세요.
| Python | Go | Bash |
|---|
| 의존성 | python3 | 없음(정적 바이너리) | gcc + python3 |
| 사전 빌드 바이너리 | 아니요 | 예 | 아니요 |
| 단일 파일 | 예 | 아니요 | 예 |
| 컴파일 단계 | 아니요 | 아니요 | 예(인라인, 자동) |