Intro
TOOR 팀 활동을 하며 분석하게된 윈도우 커널 스트리밍 서비스 원데이 취약점에 관한 글입니다.

이번에 알아볼 취약점은 2023년 6월 13일에 공개된 윈도우 커널 스트리밍 서비스 드라이버에서 발생하는 LPE 취약점 입니다.
mskssrv.sys에서 MDL을 처리하는 과정의 잘못된 인자 설정으로 인해 임의의 커널 영역을 유저 영역에서 덮어쓸 수 있게하는 취약점입니다. 이를 통해 공격자는 권한 상승을 하여 관리자 권한의 쉘을 획득하는 것이 가능해집니다.
본 글은 선행 연구를 진행하신 다른 연구원분들의 글들을 읽고 제 나름 분석을 진행하며 취약점을 공부하며 이해하고 정리해본 결과로 작성하게된 글입니다. 나름의 분석을 해봤지만 맞지 않는 부분이 있을 수 있으며, 만약 이를 발견하셨을 시 피드백해주시면 적극 반영하도록 하겠습니다. 취약점 및 PoC 분석에 많은 도움이된 자료는 다음과 같습니다.
Vuln
- CVE-ID : CVE-2023-29360
- CWE-822: Untrusted Pointer Dereference
RCA
취약점은 mskssrv.sys의 FsAllocAndLockMdl 함수에서 발생합니다.
FsAllocAndLockMdl은 다음과 같은 흐름으로 호출됩니다.

패치전의 FsAllocAndLockMdl 함수에서는 MmProbeAndLockPages를 다음과 같은 형태로 호출합니다.

이때 MmProbeAndLockPages의 첫 번째, 두 번째 인자는 매핑할 가상주소 및 크기이며 유저 영역의 데이터를 통해 값을 설정할 수 있습니다. 세 번째 인자는 AccessMode로 MmProbeAndLockPages로 잠글 MDL이 유저 모드인지 커널모드인지에 따라 주소 검증을 진행합니다.
__int64 __fastcall MiProbeAndLockPrepare( __int64 a1, __int64 a2, unsigned __int64 a3, unsigned int a4, char a5, int a6, int a7){ ... if ( a5 && (v10 > 0x7FFFFFFF0000i64 || a3 >= v10) ) JUMPOUT(0x140499F86i64); ...}1일 경우 UserMode로 커널 영역의 가상 주소를 매핑할 수 없게 만듭니다. 하지만 패치 전의 코드에서는 커널 모드로 주소 검증이 생략됩니다.
이를 통해 유저 영역에서 임의의 커널 주소 공간으로 MDL을 잠그는 것이 가능합니다. 이를 어떻게 악용할까요?
Exploit
IoControlCode == 0x2F0420일 경우에 호출되는 ConsumeTx는 FSFrameMdl::MapPages를 호출하게되는데, 이를 통해 사용자 영역의 주소를 앞서 잠근 커널 주소의 물리 메모리와 매핑 시킬 수 있습니다.
__int64 __fastcall FSStreamReg::ConsumeTx(FSStreamReg *this, struct FSFrameInfo *a2){ ... v11 = FSFrameMdl::MapPages( (FSFrameMdl *)v9, *((struct _EPROCESS **)this + 7), *((struct _EPROCESS **)this + 8), (struct FSFrameInfo *)((char *)a2 + 136 * v10 + 40)); ...}이렇게 매핑된 현재 프로세스의 권한 정보를 가진 물리 메모리 영역을 덮어씀으로써 권한 상승을 할 수 있습니다.
PoC
PoC는 여기에서 확인할 수 있습니다.
PoC의 일부를 확인해보면 다음과 같습니다.
int main(){ ... tokenAddress = GetTokenAddress();
uint64_t privaddr = tokenAddress + OFFSET_OF_TOKEN_PRIVILEGES;
...
success = PublishTx(DeviceH3, privaddr); // 토큰 권한 영역
uint8_t *mappedAddress = NULL;
success = ConsumeTx(DeviceH3, &mappedAddress); // 유저 영역에 토큰 권한 영역 매핑
...
if(mappedAddress != NULL) { // Enable all privileges memset(mappedAddress, 0xFF, 0x10); spawnShell(); }
...}앞서 살펴본 취약점으로 사용자 영역에 커널 영역의 물리주소를 매핑하고 이를 덮어쓴 후, 쉘을 실행시키는 것을 볼 수 있습니다.
Video
Patch
이번에 알아본 취약점은 FsAllocAndLockMdl에서 다음과 같은 패치가 이루어졌습니다.
MmProbeAndLockPages(Mdl, 0, IoWriteAccess);MmProbeAndLockPages(Mdl, 1, IoWriteAccess);이로써 검증 코드가 실행되어 DeviceIoControl을 통해 커널 영역을 MDL로 잠글 수 없게되었습니다.
Mitigation
해당 취약점에 대한 보안 업데이트를 통해 취약점을 완화시킬 수 있습니다.
References
- https://big5-sec.github.io/posts/CVE-2023-29360-analysis/
- https://github.com/Nero22k/cve-2023-29360
- https://blog.theori.io/chaining-n-days-to-compromise-all-part-3-windows-driver-lpe-medium-to-system-12f7821d97bb
- http://bsodtutorials.blogspot.com/2013/12/understanding-mdls-memory-descriptor.html
- https://msrc.microsoft.com/update-guide/vulnerability/CVE-2023-29360