Linux 커널 익스플로잇 입문: LPE의 세계
커널 익스플로잇은 해킹의 정점이라 불린다. 일반 유저 권한에서 root를 탈취하는 LPE(Local Privilege Escalation) — CTF의 pwn 카테고리에서도 종종 등장하고, 실제 APT 공격에서도 핵심 단계다.
왜 커널인가?
유저스페이스 취약점으로 코드 실행에 성공해도, 결국 권한은 그 프로세스의 uid를 못 벗어난다. 하지만 커널 레벨에서 코드를 실행하면 얘기가 달라진다 — commit_creds(prepare_kernel_cred(NULL))로 root 크레덴셜을 통째로 교체할 수 있다.
주요 공격 표면
드라이버 취약점이 가장 흔하다. /dev/ 아래 존재하는 커스텀 디바이스 드라이버들은 코드 품질이 들쭉날쭉해서 heap overflow, UAF, race condition이 자주 터진다.
Syscall 인터페이스 — ioctl, mmap, read/write 핸들러에서 잘못된 사용자 입력 검증이 트리거가 된다.
핵심 기법: ret2usr
과거엔 가장 단순한 방법이었다.
- 유저스페이스에 shellcode 준비 (
commit_creds(prepare_kernel_cred(0))+iretq) - 커널 EIP/RIP를 shellcode 주소로 덮어씌움
- 커널이 유저스페이스 주소로 점프 → root 획득
현재는 SMEP(Supervisor Mode Execution Prevention) 으로 막혀있지만, CTF에서는 SMEP disabled 환경이 자주 등장한다.
SMEP 우회: ROP in Kernel Space
SMEP이 활성화되면 커널이 유저 페이지를 실행하지 못한다. 이때는 커널 내부의 ROP 가젯을 이용한다.
커널 텍스트 영역 가젯 체인
→ prepare_kernel_cred(0)
→ commit_creds()
→ swapgs; iretq
→ 유저스페이스 복귀
/proc/kallsyms로 심볼 주소를 읽고 (root 필요), CTF에서는 보통 /tmp/kallsyms 또는 환경 설정으로 제공된다.
실습 환경 세팅
# QEMU로 커널 디버깅 환경 구성
qemu-system-x86_64 \
-kernel bzImage \
-initrd rootfs.cpio.gz \
-append "console=ttyS0 nosmep nopti" \
-s -S # GDB 원격 디버깅
-s -S 옵션으로 GDB stub 활성화 후:
gdb vmlinux
target remote :1234
도구들
- syzkaller — 커널 퍼저, Google이 수백 개의 CVE를 이걸로 찾았다
- exploit-db kernel 섹션 — 실제 CVE PoC 참고용
- pwndbg + GDB — 커널 디버깅에도 유용
마치며
커널 익스플로잇은 진입 장벽이 높지만, 한 번 뚫리면 막을 방법이 없다. KASLR, SMEP, SMAP, KPTI 같은 미티게이션이 겹겹이 쌓여있지만, CTF와 실전 모두에서 우회 기법은 계속 진화 중이다. 기초 pwn부터 차근차근 올라와라 — 커널은 도망가지 않는다.