
Windows CLFS 타입 혼동(CVE-2022-24481)에 대한 심층 분석으로, 근본 원인 설명, 익스플로잇 흐름, 커널 가젯 세부 정보 및 동작하는 로컬 권한 상승 PoC를 포함합니다.
타입 혼동
clfs.sys
rgContainers[0]에 대한 검증 로직이 엄격하지 않기 때문에, rgContainers[0]를 위조한 후 ClientContext가 ContainerContext 구조체와 겹치게 된다. 위조된 데이터가 수락되면, CloseHandle 이후 CClfsLogFcbPhysical::FlushMetadata가 ClientContext 데이터를 복원한다.
rgContainers[0]를 위조한 후, ClientContext가 ContainerContext 구조체와 겹치게 된다. 위조된 데이터가 수락되면, CloseHandle 이후 CClfsLogFcbPhysical::FlushMetadata가 ClientContext 데이터를 복원한다. 구조체가 겹치기 때문에 이 과정에서 ContainerContext->pContainer가 위조된 데이터로 변경된다. 마지막으로 CClfsBaseFilePersisted::RemoveContainer가 호출되면 간접 멤버 함수 호출이 트리거되어 특정 가젯이 실행되고 권한 상승으로 이어진다.
createlog가 새 로그 파일을 생성한다.
Container 항목을 추가한다.
현재 디렉터리를 가리키는 심볼릭 링크 X:\를 생성한다.
cbSymbolName_start -> cbSymbolName_end 범위를 지운다.
cbSymbolName_start를 X:\N으로 설정한다.
ContainerContext_start -> New_cbSymbolName_end의 데이터를 ClientContext에 복사한다.
rgContainers[0]가 새 ContainerContext_start 위치를 가리키도록 업데이트한다.
새 ContainerContext->pContainer 값을 업데이트한다.
체크섬을 다시 계산한다.
커널 메모리에서 가젯 주소를 찾는다.
가짜 가상 테이블을 구성한다.
나머지 메모리 설정을 수행한다.
CClfsLogFcbPhysical::Initialize
00000001C0002EDB에 ClientContext 데이터가 저장된다.
CloseHandle 이후 CClfsRequest::Cleanup->CClfsLogFcbPhysical::FlushMetadata가 실행된다.
위조된 데이터를 ClientContext에 다시 복사한다. ClientContext가 ContainerContext와 겹치므로 ContainerContext->pContainer는 위조된 데이터로 덮어쓰여진다.
그런 다음 CClfsBaseFilePersisted::RemoveContainer가 우리의 가젯을 실행하여 임의 주소에 16바이트를 쓰는 결과를 낳는다.
https://zhuanlan.zhihu.com/p/645490730
https://github.com/fr4nkxixi/CVE-2022-24481-POC
https://securelist.com/windows-clfs-exploits-ransomware-cve-2022-24521/111580/
https://starmap.dbappsecurity.com.cn/blog/articles/2022/05/10/cve-2022-24481/
https://www.4awl.net/9646.html
win10_21H2_19044.1620
파일 열기를 위한 CClfsLogFcbPhysical::Initialize(0x??7c) 초기화 루틴
bp clfs!CClfsLogFcbPhysical::Initialize + 0x45F
이 코드는 ClientContext 메모리를 저장한다.

CloseHandle 이후 CClfsRequest::Cleanup->CClfsLogFcbPhysical::FlushMetadata가 실행된다.
bp clfs!CClfsLogFcbPhysical::FlushMetadata + 0x46
이 코드는 ClientContext 데이터를 복원한다.

CClfsBaseFilePersisted::RemoveContainer
bp clfs!CClfsBaseFilePersisted::RemoveContainer + 0x10F
위조된 가상 테이블 포인터를 사용하여 가젯에 도달한다.

위조된 파일이 실패하면 파일 열기가 실패하고 GetLastError가 이유를 알려준다. 이 경우 익스플로잇 흐름을 계속할 수 없다.
CClfsBaseFilePersisted::RemoveContainer

CLFS!ClfsEarlierLsn
nt!SeSetAccessStateGenericMapping

nt!SeSetAccessStateGenericMapping

movdqu xmmword ptr [rax+8], xmm0는 [rax+8](XMMWORD, 128비트)에 16바이트를 쓴다.
순차적으로 실행한 결과, poi(rdx) 0xFFFFFFFF의 16바이트 데이터가 poi(poi(rcx+0x48)+0x8)에 쓰여진다.
rcx는 가상 테이블 포인터 위치이며, 이 위치는 우리가 제어한다.
https://github.com/uname1able/CVE-2022-24481.git
winver
win10_21H2_19044.1620

bp clfs!CClfsBaseFilePersisted::RemoveContainer + 0x10F
winver
win11_21H2_22000.593

bp clfs!CClfsBaseFilePersisted::RemoveContainer + 0x183