
dirtyfrag의 Go 구현 (CVE-2026-43284 / CVE-2026-43500)
두 개의 버그. 하나의 셸. 디스크 쓰기 없음.
Go 포팅 dirtyfrag (CVE-2026-43284 / CVE-2026-43500).
버그 클래스는 Linux 커널 XFRM 서브시스템에 있습니다. 파일 페이지가 splice()로 파이프로 이동되고 ESP로 암호화된 소켓으로 이동될 때, 커널은 ESP 페이로드를 소스 파일의 페이지 캐시 페이지에 직접 제자리에서 복호화합니다. 파일은 읽기 전용입니다. 페이지 캐시는 그렇지 않습니다.
dirtyfrag는 이 프리미티브를 활용하는 두 개의 독립적인 버그를 연결합니다.
CVE-2026-43284 - ESP/XFRM 경로
NETLINK_XFRM를 통해 48개의 XFRM 전송 모드 SA를 설치합니다. 각 SA는 ESN 재생 상태의 seq_hi 필드에 4바이트의 셸코드 페이로드를 인코딩합니다. vmsplice + splice 체인이 각 SA에 대해 ESP 제자리 복호화를 트리거하여 해당 4바이트를 /usr/bin/su 페이지 캐시 엔트리에 씁니다. 48개의 트리거, 192바이트 기록, 경쟁 조건 없음.
CVE-2026-43500 - RxRPC/rxkad 경로
오프라인으로 복호화 시 대상 바이트 시퀀스를 생성하는 3개의 PCBC(fcrypt) 세션 키를 브루트 포스합니다. 각 키에 대해 AF_RXRPC 소켓 트리거를 발생시켜 /etc/passwd의 루트 엔트리를 root::0:0 (nullok)로 패치합니다. 그러면 su -가 빈 비밀번호를 허용합니다.
두 경로 모두 사용자 + 네트워크 네임스페이스 (CLONE_NEWUSER | CLONE_NEWNET)에서 실행되어 호스트에서 CAP_NET_ADMIN이 필요하지 않도록 합니다.
go build -o dirtyfrag-go .
./dirtyfrag-go
# Force a specific path
./dirtyfrag-go --force-esp
./dirtyfrag-go --force-rxrpc
# Verbose output
./dirtyfrag-go -v
바이너리는 먼저 ESP 경로를 시도합니다. 이후 /usr/bin/su가 패치되지 않으면 RxRPC 경로로 폴백합니다 (최대 3회 재시도). 성공하면 새 PTY를 통해 루트 셸로 진입합니다.
익스플로잇은 페이지 캐시만 건드립니다. 디스크 상의 바이너리와 /etc/passwd는 건드리지 않습니다. 재부팅하면 모든 것이 복원됩니다. 재부팅 없이 즉시 제거하려면:
echo 1 | tee /proc/sys/vm/drop_caches
esp4, esp6 (ESP 경로) 및/또는 rxrpc (RxRPC 경로)패치 이전의 모든 커널:
rmmod esp4 esp6 rxrpc
printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' \
> /etc/modprobe.d/dirtyfrag.conf
| C (원본) | Go | |
|---|---|---|
| 외부 종속성 | 없음 | 없음 |
| 단일 파일 | 아니오 | 아니오 |
| 정적 바이너리 | 예 | 예 |
| RxRPC 경로 | 예 | 예 |
| ESP 경로 | 예 | 예 |
| 네임스페이스 격리 | unshare() | Cloneflags로 재실행 |
Go의 런타임은 처음부터 멀티스레드이므로 unshare(CLONE_NEWUSER)가 허용되지 않습니다. Go 포트는 SysProcAttr.Cloneflags가 설정된 자식 프로세스로 자신을 재실행하며, 이는 Go 런타임이 초기화되기 전에 clone()을 호출합니다.