원문 캡처 · calif.io
원문 캡처 · calif.io

보안 연구업체 Calif의 앤드루 그리피스(Andrew Griffiths)는 OpenBSD 커널에서 약 37년 전 BSD 원본 코드까지 거슬러 올라가는 공유 메모리 카운터 취약점을 이용해 로컬에서 루트 권한을 얻는 익스플로잇을 공개했다. 해당 취약점은 OpenBSD의 정오표 026과 018에서 각각 수정됐다.

공유 메모리 연결 횟수를 저장하는 값은 부호 있는 16비트 정수였다. 프로세스를 반복해서 분기하면 횟수가 최댓값인 32,767을 넘어서 음수로 돌아갈 수 있고, 경쟁 조건과 커널의 별도 범위 밖 쓰기 취약점이 결합되면 해제 후 사용(Use-after-free)을 거쳐 로컬 권한 상승으로 이어질 수 있다.

공개된 공격 경로는 KARL, SMAP, SMEP가 활성화된 상태에서도 정보 노출 취약점을 사용하지 않고 커널 코드 실행에 도달한다. 공유 메모리 세그먼트와 프로세스를 만들어 카운터를 음수로 돌린 뒤, 메모리 할당 상태를 추적하고 경쟁 조건을 유도해 커널 메모리를 덮어쓴다. 연구팀은 이를 통해 루트 셸을 얻었다고 설명했다. 상세한 코드와 개념 증명은 공개 저장소에서 볼 수 있다.

Calif는 OpenBSD의 KARL이 커널 함수와 데이터 주소를 무작위화하지만, 커널 메모리 할당자는 결정적이어서 같은 하드웨어에서 부팅 초기 구조체가 예측 가능한 위치에 놓일 수 있다고 지적했다. 연구팀은 이 특성이 함수 포인터를 공격 대상으로 삼는 데 이용됐다고 설명하며, 안전한 연결 해제 검사, 자기 참조 페이지 테이블(PTE) 맵 주소 무작위화, 할당기 주소와 실행 중 할당 순서의 무작위화 등을 완화책으로 제시했다.

문서에는 배열 범위 검사기와 포인터를 포함한 할당을 분리하는 컴파일러 기능 Alloc Tokens도 잠재적 방어책으로 언급됐다. Calif는 취약점 종류 자체를 줄이는 방어 기법과 익스플로잇 비용을 높이는 조치를 함께 적용하는 것이 중요하다고 주장했다.