CVE-2023-28218 보고서
버그 개요
Windows 커널에서 권한 상승으로 이어지는 버그입니다. 버그는 Windows Ancrillary Function Driver for WinSock (AFD.sys) 드라이버에서 발생합니다. 이 버그는 2023년 4월 11일 패치에서 릴리스되었습니다. CVSS:3.1 7.0 / 6.1 점수를 가지며 Important로 평가됩니다.
버그 설명
- 버그 유형:
Double fetch 및 Integer overflow로 인한 pool overflow.
- 버그는
Afd!AfdComputeCMSGLength 및 Afd!AfdCopyCMSGBuffer 함수에서 발생합니다.

두 함수 모두 v82를 입력 매개변수로 받습니다. v82는 usermode가 제어하는 주소입니다. Afd!AfdComputeCMSGLength 함수에서 이 주소는 값을 가져오기 위해 직접 참조됩니다. 그런 다음 CMSG 버퍼의 길이 값을 계산하여 반환합니다. 이후 이 크기에 따라 풀이 할당됩니다. a1 및 a2라는 두 입력 매개변수를 제어하여 a3 매개변수에 반환될 크기를 제어할 수 있습니다.

Afd!AfdCopyCMSGBuffer 함수에서 v82 주소는 값을 가져오기 위해 직접 참조됩니다. 몇 가지 검사 단계를 거친 후 이 값은 memmove 작업의 크기로 사용됩니다.

이 함수에는 Integer overflow 오류가 있으며, 두 함수 모두 usermode 측 주소에서 직접 가져오기 때문에 실행 중에 해당 값을 변경할 수 있습니다. 이로 인해 memmove 시 매우 큰 크기 값이 생성됩니다. 액세스할 수 없는 메모리 영역에 복사하면 try catch가 발생합니다. 그러나 이전 메모리 영역의 복사는 이미 발생했습니다. 이를 통해 원하는 크기로 복사할 수 있습니다.

- POC를 트리거하려면 먼저
type 매개변수가 SOCK_DGRAM인 socket을 생성해야 합니다. 그런 다음 이 socket의 핸들을 사용하여 bind 함수를 호출합니다. 마지막으로 두 개의 스레드를 생성합니다. 하나의 스레드는 IOCTL이 0x120D3인 DeviceControl을 지속적으로 호출합니다. 몇 가지 검사를 우회하기 위해 적절한 userbuffer를 설정합니다. 나머지 하나의 스레드는 위의 두 함수에 대한 매개변수로 사용되는 usermode 주소에 저장된 값을 지속적으로 변경합니다.
익스플로잇
- 이 버그를 통해 크기와 데이터를 usermode에서 완전히 제어할 수 있는 non-paged NX 풀을 오버플로우할 수 있습니다.
- 공격 방법은 많은
Namedpipe 객체를 스프레이한 다음 일부 객체를 해제하여 힙에 구멍을 만드는 것입니다. 그런 다음 Afd!AfdComputeCMSGLength 함수에서 크기를 계산한 후 풀을 생성합니다. 이 크기는 Namedpipe 객체의 크기와 일치해야 합니다. 그러면 풀이 방금 해제된 객체에 할당됩니다. 버그를 사용하여 인접한 Namedpipe 객체를 오버플로우한 다음 Namedpipe 메커니즘을 사용하여 커널 메모리 읽기/쓰기 권한을 얻습니다. 시스템 프로세스의 토큰을 읽은 다음 현재 프로세스의 토큰에 씁니다.
영향을 받는 범위
- Windows Server 2012 R2 (Server Core 설치) 빌드 6.3.9600.20919 이전
- Windows Server 2012 R2 빌드 6.3.9600.20919 이전
- Windows Server 2012 (Server Core 설치) 빌드 6.2.9200.24216 이전
- Windows Server 2012 빌드 6.2.9200.24216 이전
- Windows Server 2008 R2 x64 기반 시스템 서비스 팩 1 (Server Core 설치) 빌드 6.1.7601.26466 이전
- Windows Server 2008 R2 x64 기반 시스템 서비스 팩 1 빌드 6.1.7601.26466 이전
- Windows Server 2008 x64 기반 시스템 서비스 팩 2 (Server Core 설치) 빌드 6.0.6003.22015 이전
- Windows Server 2008 x64 기반 시스템 서비스 팩 2 빌드 6.0.6003.22015 이전
- Windows Server 2008 32비트 시스템 서비스 팩 2 (Server Core 설치) 빌드 6.0.6003.22015 이전
- Windows Server 2008 32비트 시스템 서비스 팩 2 빌드 6.0.6003.22015 이전
- Windows Server 2016 (Server Core 설치) 빌드 10.0.14393.5850 이전
- Windows Server 2016 빌드 10.0.14393.5850 이전
- Windows 10 버전 1607 x64 기반 시스템 빌드 10.0.14393.5850 이전
- Windows 10 버전 1607 32비트 시스템 빌드 10.0.14393.5850 이전
- Windows 10 x64 기반 시스템 빌드 10.0.10240.19869 이전
- Windows 10 32비트 시스템 빌드 10.0.10240.19869 이전
- Windows 10 버전 22H2 32비트 시스템 빌드 10.0.19045.2846 이전
- Windows 10 버전 22H2 ARM64 기반 시스템 빌드 10.0.19045.2846 이전
- Windows 10 버전 22H2 x64 기반 시스템 빌드 10.0.19045.2846 이전
- Windows 11 버전 22H2 x64 기반 시스템 빌드 10.0.22621.1555 이전
- Windows 11 버전 22H2 ARM64 기반 시스템 빌드 10.0.22621.1555 이전
- Windows 10 버전 21H2 x64 기반 시스템 빌드 10.0.19044.2846 이전
- Windows 10 버전 21H2 ARM64 기반 시스템 빌드 10.0.19044.2846 이전
- Windows 10 버전 21H2 32비트 시스템 빌드 10.0.19044.2846 이전
- Windows 11 버전 21H2 ARM64 기반 시스템 빌드 10.0.22000.1817 이전
- Windows 11 버전 21H2 x64 기반 시스템 빌드 10.0.22000.1817 이전
- Windows 10 버전 20H2 ARM64 기반 시스템 빌드 10.0.19042.2846 이전
- Windows 10 버전 20H2 32비트 시스템 빌드 10.0.19042.2846 이전
- Windows 10 버전 20H2 x64 기반 시스템 빌드 10.0.19042.2846 이전
- Windows Server 2022 (Server Core 설치) 빌드 10.0.20348.1668 이전
- Windows Server 2022 빌드 10.0.20348.1668 이전
- Windows Server 2019 (Server Core 설치) 빌드 10.0.17763.4252 이전
- Windows Server 2019 빌드 10.0.17763.4252 이전
- Windows 10 버전 1809 ARM64 기반 시스템 빌드 10.0.17763.4252 이전
- Windows 10 버전 1809 x64 기반 시스템 빌드 10.0.17763.4252 이전
- Windows 10 버전 1809 32비트 시스템 빌드 10.0.17763.4252 이전
패치
- 버그는 두 개의 이전 함수를 새로운 함수로 교체하여 패치되었습니다. 이전 함수 이름 뒤에는
_old가 추가되었습니다. 새로운 함수에서는 여전히 double fetch가 있지만 가져온 값은 사용하기 전에 검사됩니다. Rtl 함수는 연산을 대체하고 Integer overflow를 방지하는 데 사용됩니다.
결론
- 버그의 영향 범위가 매우 넓어 많은 시스템을 위협합니다. 그러나 익스플로잇 페이로드를 실행할 때 힙 스프레이로 인해 Windows가 충돌하는 작은 실패 확률이 있습니다. 또한 cmd 프로세스의 권한을 System으로 상승시킨 후 이 프로세스를 종료하면 Windows가 충돌할 수 있습니다. 이는 익스플로잇 과정에서 Namedpipe 객체가 손상되었기 때문입니다.
첨부 파일
- 최소 POC

- 익스플로잇 POC
