확인과 사용 사이의 찰나 — 커널이 유저 메모리를 두 번 읽은 대가

확인과 사용 사이의 찰나 — 커널이 유저 메모리를 두 번 읽은 대가

분류: CVE · 커널·OS · 권한상승(LPE) [정보성] · CVE-2023-28218

덱. 보안 연구팀 Theori는 Windows 커널의 네트워크 드라이버(afd.sys)에서 힙 오버플로우 결함을 찾아 CVE-2023-28218로 이어지는 연구를 2023년 Hexacon 컨퍼런스에서 발표했습니다. 취약점 자체는 흔한 정수 오버플로우형 버그지만, 연구팀이 주목받은 지점은 이 버그를 “우연이 아니라 매번” 터뜨리는 방법이었습니다. 사용자 메모리를 다루는 커널 코드 특유의 타이밍 문제를 이용해 신뢰도 높은 커널 권한 상승 경로를 완성했습니다.

리드

취약점 연구에서 “코드에 버그가 있다”는 사실 자체보다 자주 어려운 건 “그 버그를 원할 때 원하는 방식으로 재현시키는 것”입니다. 값을 확인하는 시점과 그 값을 실제로 쓰는 시점 사이에 아주 짧은 틈이라도 있으면, 공격자는 그 틈을 파고들어 검사를 통과한 값과 실제로 쓰이는 값을 다르게 만들 수 있습니다. 이런 확인-사용 시차형(time-of-check to time-of-use) 결함은 오래된 클래스지만, 커널처럼 사용자 메모리를 직접 참조하는 코드에서는 지금도 재현성 있는 공격의 핵심 재료로 쓰입니다. 이번 사례는 그 교과서적인 예입니다.

핵심 사실 요약

  • 대상은 Windows 커널의 afd.sys(Ancillary Function Driver, 소켓 통신을 처리하는 드라이버)이며, 그중에서도 일반적인 입출력 요청(IRP) 경로가 아니라 더 빠른 처리를 위해 별도로 존재하는 Fast I/O라는 경로에서 발견됐습니다. 연구팀은 상대적으로 덜 조사된 영역이라는 점에서 이 경로를 분석 대상으로 골랐다고 밝혔습니다.
  • 취약점은 사용자가 넘긴 데이터 구조체의 크기를 계산하는 함수와, 그 크기만큼 실제로 커널 메모리에 복사하는 함수가 분리돼 있다는 점에서 시작합니다. 크기 계산 과정에 정수 연산 오류가 있어, 특정 값을 넣으면 계산된 정렬(alignment) 크기가 0이 되면서 뒤이은 크기 검사를 무의미하게 만듭니다. 이런 식으로 검사를 무력화한 뒤 발생하는, 길이를 사실상 통제할 수 없는 복사를 원문은 “wild copy”라 부릅니다.
  • 이 버그를 신뢰성 있게 재현하려면 두 가지가 더 필요했다고 연구팀은 설명합니다. 하나는 크기를 계산하는 시점과 실제로 복사하는 시점 사이에 사용자 메모리의 값을 다시 바꿔치기하는 것(같은 값을 두 번 읽는 이른바 “더블 페치” 패턴을 경쟁 조건으로 악용)이고, 다른 하나는 커널이 사용자 메모리 접근 중 발생하는 페이지 폴트를 예외로 처리하는 메커니즘을 역이용해, 통제 불가능해 보이는 “무한 복사”를 원하는 지점에서 멈추도록 유도하는 것입니다(원문 제목의 “User Fault Handling”이 가리키는 부분). 구체적인 절차는 이 글에서 다루지 않습니다.
  • 확보한 메모리 손상 능력은 커널 객체 하나를 표적으로 삼아 “임의 주소의 값을 1 감소시키는” 원시 동작(primitive)으로 이어졌고, 이를 통해 현재 스레드의 권한 모드를 커널 모드로 바꾸는 방식으로 최종 권한 상승에 이르렀다고 원문은 설명합니다. 스프레이 가능한 커널 객체를 이용한 이런 방식은 앞선 Synacktiv 등의 Windows 커널 익스플로잇 연구 계보를 잇는다고 연구팀 스스로 언급했습니다.
  • 벤더 패치는 문제가 된 정수 연산 부분을, 오버플로우 여부를 미리 검사하는 안전한 산술 래퍼 함수들(RtlULongSub, RtlSizeTAdd 등 계열)로 교체하는 형태였다고 원문은 서술합니다.
  • 공식 CVSS 3.1 기본점수는 **7.0(HIGH, AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H)**이며, CWE-122(힙 기반 버퍼 오버플로우)로 분류됩니다. 영향 범위는 Windows 10(150722H2)·Windows 11(21H2·22H2)과 Windows Server 2008 SP22022 전반이고, 2023년 4월 정기 보안 업데이트(패치 화요일, 4월 11일 공개)로 수정됐습니다. (출처: NVD)
  • 연구는 2023년 10월 프랑스 파리의 Hexacon 컨퍼런스에서 발표됐고, 발표 영상도 공개돼 있다고 원문에 명시돼 있습니다.

짧은 논평

이 사례가 흥미로운 이유는 버그 자체보다 “재현성을 어떻게 확보했는가”에 있습니다. 취약점 연구에서 코드 한 줄의 정수 연산 실수를 찾는 일은 상대적으로 기계적인 작업에 가깝지만, 그걸 매번 같은 방식으로 터뜨리는 일은 다릅니다. 여기서는 (1) 검사와 사용 사이의 시차를 경쟁 조건으로 메우고 (2) 커널의 예외 처리 메커니즘을 이용해 통제 불가능한 복사를 통제 가능한 복사로 바꾸는, 서로 다른 층위의 기법 두 개를 겹쳐 썼습니다. 저희가 필터 우회 사례들에서 반복해서 보는 원칙과 같은 결입니다 — 하나의 신뢰할 수 없는 신호(사용자 메모리 값)를 두 번 이상 참조하는 코드는, 그 사이의 시간을 공격 표면으로 내어준다는 것입니다. 방어 관점에서는 이런 구조가 왜 까다로운지도 짚을 만합니다. 크기 검사 로직 자체는 정적으로 봤을 때 “존재는 하는” 코드라서 일반적인 코드 리뷰나 정적 분석으로는 놓치기 쉽고, 정수 연산의 경계값(overflow 지점)까지 정확히 시뮬레이션해야 문제가 드러납니다. 완화 기법(mitigation) 다수가 “검사가 있는가”를 전제로 설계되는데, 검사 자체가 산술 오류로 무력화되는 경우엔 그 전제가 깨진다는 점이 이런 부류의 커널 버그가 계속 나오는 이유 중 하나로 보입니다.

References / 참고자료

  1. Theori (Frontier Squad), “Exploiting Windows Kernel Wild Copy With User Fault Handling (CVE-2023–28218)” — 이 글이 재구성한 원 분석. afd.sys 취약점 발견 과정과 익스플로잇 기법, 패치 내용을 다룸. https://blog.theori.io/exploiting-windows-kernel-wild-copy-with-user-fault-handling-cve-2023-28218-89f5189d0926

이 글은 위 원 분석을 우리 관점에서 다시 쓰고 짧은 논평을 더한 정보성 초안입니다. 특정 문장·코드·완성형 익스플로잇 절차를 그대로 옮기지 않았으며, 기법은 개념 수준으로만 서술했습니다. ⚠️미확인 표시 항목은 발행 전 독립 팩트체크에서 확증·정정되어야 합니다.