1. 개요
CVE-2025-59516은 Windows Storage Virtualization Service Provider 드라이버(storvsp.sys)에서 발견된 로컬 권한 상승 취약점이다. VSMB(Virtual SMB) 인터페이스를 통해 파일시스템 접근을 중개하는 과정에서 요청 경로 및 요청자 권한을 검증하지 않아 발생한다.
storvsp.sys는 가상 스토리지 서비스를 제공하는 커널 드라이버로 \Device\STORVSP\VSMB 경로를 통해 파일시스템 접근을 중개한다. 공격자는 일반 사용자 권한으로 이 경로를 통해 \Device 네임스페이스의 보호된 디바이스 객체에 무단 접근할 수 있으며 획득한 핸들을 활용해 임의 파일 생성·쓰기 및 추가 권한 상승 공격으로 이어질 수 있다.
2. 취약점 근본 원인 분석
항목 | 내용 |
CVE ID | CVE-2025-59516 |
취약 구성요소 | storvsp.sys (Windows Storage VSP Driver) |
취약점 유형 | Elevation of Privilege |
CWE 분류 | CWE-306 (Missing Authentication for Critical Function), CWE-73 (External Control of File Name or Path) |
CVSS v3.1 Score | 7.8 (High) |
CVSS Vector | AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
공개일 | 2025년 12월 9일 |
2.1. CWE 분류
본 취약점은 두 가지 CWE가 복합적으로 작용한다.
CWE-306: Missing Authentication for Critical Function
CWE-306 요소 | 취약점에서의 발현 |
중요 기능 | 커널 디바이스 객체 핸들 획득 |
인증 부재 | 요청자가 관리자 또는 SYSTEM인지 검증하지 않음 |
검증 우회 | 사용자 제어 Flags 필드로 VspVsmbGetStatInfo 검증 스킵 |
비정상 결과 | 일반 사용자가 보호된 디바이스 핸들 획득 |
CWE-73: External Control of File Name or Path
CWE-73 요소 | 취약점에서의 발현 |
외부 입력 | 사용자가 제공하는 VSMB 경로 |
경로 검증 부재 | \Device 등 임의 경로에 대한 필터링 없음 |
예기치 않은 접근 | 파일시스템 외 커널 오브젝트 네임스페이스 접근 |
비정상 결과 | 보호된 디바이스 객체에 대한 핸들 획득 |
2.2. 취약한 환경 조건
storvsp.sys는 기본 상태에서는 로드되지 않으며 다음 기능이 활성화된 경우에 한해 커널에 로드된다.
•
Hyper-V 역할 활성화
•
Windows Sandbox 활성화
•
WSL2 (Windows Subsystem for Linux 2) 사용
•
가상화 기반 보안(VBS) 활성화
2.3. 관련 함수 호출 구조
VspVsmbFileCreate ← [1] 경로 검증 없이 \Device 핸들 획득
│
├──► IoCreateFileEx ← STATUS_OBJECT_TYPE_MISMATCH
│
└──► ZwOpenDirectoryObject ← [2] 임의 디렉토리 객체 핸들 반환
│
▼
VspVsmbCommonRelativeCreate ← [3] Flags로 검증 우회
│
├──► IoCreateFileEx ← \Device 핸들 기반 상대 경로 열기
│
└──► VspVsmbGetStatInfo ← [4] 호출되지 않음 (검증 스킵)
│
▼
디바이스 객체 핸들 반환
Plain Text
복사
[그림 1] 취약한 함수 호출 흐름
2.4 취약점 패치 비교 분석
2.4.1. VspVsmbFileCreate - 패치 전 (취약)
__int64 __fastcall VspVsmbFileCreate(
struct WDFREQUEST__ *a1,
struct _UNICODE_STRING *a2,
__int64 a3,
struct _FILE_OBJECT *a4)
{
// ...
// 요청자 권한 검증 없이 RootIdentity 플래그만 설정
if ( (*(_DWORD *)(v10 + 16) & 2) != 0 )
*((_BYTE *)Pool2 + 41) = 1;
// ObjectAttributes: OBJ_KERNEL_EXCLUSIVE 미포함 (0x240)
ObjectAttributes.Attributes = v15 & 0x40 | 0x200;
ObjectAttributes.ObjectName = a2; // 사용자 제공 경로 검증 없이 사용
// IoCreateFileEx 실패 시 경로 검증 없이 ZwOpenDirectoryObject 호출
if ( Status == -1073741788 ) // STATUS_OBJECT_TYPE_MISMATCH
{
Status = ZwOpenDirectoryObject((PHANDLE)Pool2 + 4, 2u, &ObjectAttributes);
}
// ...
}
C
복사
[코드 1] 취약한 VspVsmbFileCreate 함수 내부
2.4.2 VspVsmbFileCreate - 패치 후 (완화)
__int64 __fastcall VspVsmbFileCreate(
struct WDFREQUEST__ *a1,
struct _UNICODE_STRING *a2,
__int64 a3,
struct _FILE_OBJECT *a4)
{
// ...
// [패치] Feature Flag 확인 후 요청자 권한 검증
// VspVsmbIsUserTrusted: 요청자가 관리자 또는 SYSTEM인지 확인
if ( (unsigned int)Feature_3553664313__private_IsEnabledDeviceUsage() )
{
if ( (SecurityContext->DesiredAccess & 2) == 0 )
{
if ( !VspVsmbIsUserTrusted(v33) )
{
Status = STATUS_ACCESS_DENIED; // 0xC0000022
goto LABEL_73;
}
}
}
// [패치] OBJ_KERNEL_EXCLUSIVE(0x400) 추가 → 0x640
if ( (unsigned int)Feature_3553664313__private_IsEnabledDeviceUsage() )
v21 = 1536; // 0x600
ObjectAttributes.Attributes = v21 | 0x40; // 결과: 0x640
// [패치] ZwOpenDirectoryObject 호출 시 \??\ 경로만 허용
if ( (unsigned int)Feature_3553664313__private_IsEnabledDeviceUsage() )
{
if ( Status == -1073741788 )
{
if ( RtlEqualUnicodeString(a2, &v35, 1u) ) // v35 = L"\??\"
{
Status = ZwOpenDirectoryObject((PHANDLE)Pool2 + 4, 2u, &ObjectAttributes);
}
// \Device 등 다른 경로는 차단됨
}
}
// ...
}
C
복사
[코드 2] 패치된 VspVsmbFileCreate 함수 내부
2.4.3 VspVsmbCommonRelativeCreate - 패치 전 (취약)
__int64 __fastcall VspVsmbCommonRelativeCreate(
__int64 a1, // VSMB 컨텍스트 (VspVsmbFileCreate에서 생성)
// ...
__int64 a9) // CreateOptions
{
// ...
// ObjectAttributes: 0x240 고정
ObjectAttributes.Attributes = 576; // 0x240
// IoCreateFileEx로 상대 경로 파일/디바이스 열기
Status = IoCreateFileEx(&FileHandle, DesiredAccess, &ObjectAttributes, ...);
// Flags & 2가 non-zero이면 검증 블록 전체 스킵
if (!v48 && !v51) {
// ...
Parameter = VspVsmbGetStatInfo(FileHandle, FileInformation);
if (Parameter < 0) goto Cleanup;
}
// v48 != 0이면 위 검증 블록을 건너뛰어 여기에 도달
// 핸들을 IOCTL 응답에 기록하여 사용자에게 반환
*((_QWORD *)v56 + 1) = FileHandle; // 응답 버퍼에 핸들 저장
*v56 = 2; // 응답 타입: 성공
*((_DWORD *)v56 + 1) = 0; // 상태: STATUS_SUCCESS
// ...
}
C
복사
[코드 3] 취약한 VspVsmbCommonRelativeCreate 함수 내부
2.4.4 VspVsmbCommonRelativeCreate - 패치 후 (완화)
__int64 __fastcall VspVsmbCommonRelativeCreate(
__int64 a1, // VSMB 컨텍스트
// ...
__int64 a9) // CreateOptions
{
// ...
// [패치] RootIdentity 플래그 기반 ObjectAttributes 조건부 강화
if ( Feature_3553664313__private_IsEnabledDeviceUsage() )
// RootIdentity(a1+41) 설정 시 0x640, 미설정 시 0x240
ObjectAttributes.Attributes = *((_BYTE *)a1 + 41) != 0 ? 1600 : 576;
else
ObjectAttributes.Attributes = 576;
Status = IoCreateFileEx(&FileHandle, DesiredAccess, &ObjectAttributes, ...);
// Flags 우회 로직 자체는 동일하나,
// 1단계(VspVsmbFileCreate)에서 \Device 핸들 획득이 차단되므로 도달 불가
// ...
}
C
복사
[코드 4] 패치된 VspVsmbCommonRelativeCreate 함수 내부
Microsoft는 Feature_3553664313__private_IsEnabledDeviceUsage Feature Flag를 도입하여 다중 계층 방어를 적용했다. VspVsmbFileCreate에서 VspVsmbIsUserTrusted 함수로 요청자가 관리자 또는 SYSTEM인지 검증하고 일반 사용자의 요청을 STATUS_ACCESS_DENIED로 거부한다. OBJ_KERNEL_EXCLUSIVE(0x400) 플래그를 추가하여 커널 모드 전용 핸들로 강화하고 RtlEqualUnicodeString으로 \??\ 경로만 허용하는 화이트리스트를 적용했다. VspVsmbCommonRelativeCreate에서는 RootIdentity 플래그 기반으로 ObjectAttributes를 조건부 강화했으며 근본적으로는 1단계 경로 차단을 통해 Flags 우회 공격 자체를 불가능하게 만들었다.
2.5. VspVsmbFileCreate - 경로 검증 없는 디렉토리 객체 접근
이 함수는 사용자가 \Device\STORVSP\VSMB\* 경로로 NtCreateFile을 호출할 때 실행되며 CWE-73 취약점이 발생하는 지점이다.
__int64 __fastcall VspVsmbFileCreate(
struct WDFREQUEST__ *a1,
struct _UNICODE_STRING *a2, // 사용자 제공 경로
__int64 a3,
struct _FILE_OBJECT *a4)
{
// ...
// 요청자 권한 검증 없음 - 일반 사용자의 요청도 처리됨
// ObjectAttributes 설정 - 사용자 경로를 검증 없이 사용
ObjectAttributes.RootDirectory = 0;
ObjectAttributes.Length = 48;
ObjectAttributes.Attributes = v15 & 0x40 | 0x200; // 0x240
ObjectAttributes.ObjectName = a2;
// IoCreateFileEx로 파일 열기 시도
Status = IoCreateFileEx(
(PHANDLE)Pool2 + 4,
0x100020u, // SYNCHRONIZE | FILE_READ_ATTRIBUTES
&ObjectAttributes,
&IoStatusBlock,
// ...
);
// \Device는 파일이 아닌 디렉토리 객체 → STATUS_OBJECT_TYPE_MISMATCH
if ( Status == -1073741788 ) // 0xC0000024
{
// [취약점] 경로 검증 없이 ZwOpenDirectoryObject 호출
Status = ZwOpenDirectoryObject((PHANDLE)Pool2 + 4, 2u, &ObjectAttributes);
}
// 성공 시 FileObject에 컨텍스트 저장
Status = 0;
a4->FsContext = (PVOID)Pool2;
// ...
}
C
복사
[코드 5] 취약한 VspVsmbFileCreate 함수 내부
ObjectAttributes.Attributes에 설정되는 0x240은 OBJ_CASE_INSENSITIVE(0x40)과 OBJ_KERNEL_HANDLE(0x200)의 조합이다. OBJ_KERNEL_EXCLUSIVE(0x400)가 포함되지 않아 해당 핸들이 커널 모드 전용으로 보호되지 않는다.
사용자가 파일시스템 경로(예: \??\C:\Windows\System32)를 요청하면 IoCreateFileEx가 성공하여 해당 경로에 대한 핸들을 반환한다. \Device와 같은 오브젝트 네임스페이스 경로를 요청하면 IoCreateFileEx가 STATUS_OBJECT_TYPE_MISMATCH를 반환하고, 취약한 코드는 이 실패를 처리하는 과정에서 경로를 검증하지 않고 ZwOpenDirectoryObject를 호출하여 디렉토리 객체에 대한 핸들을 반환한다. 즉, 파일시스템 경로와 오브젝트 네임스페이스 경로 모두에 대해 무단 접근이 가능하다.
2.6 VspVsmbCommonRelativeCreate - Flags에 의한 검증 우회
이 함수는 IOCTL을 통해 호출되며, VspVsmbFileCreate에서 획득한 핸들을 RootDirectory로 사용하여 상대 경로의 파일이나 디바이스를 연다. CWE-306 취약점이 발생하는 지점이다.
__int64 __fastcall VspVsmbCommonRelativeCreate(
__int64 a1, // VSMB 컨텍스트 (VspVsmbFileCreate에서 생성)
// ...
__int64 a9) // CreateOptions
{
// ...
v48 = v55 & 2; // 사용자 입력 Flags 필드에서 bit 1 추출
// ObjectAttributes 설정 - VspVsmbFileCreate에서 획득한 핸들을 RootDirectory로 사용
ObjectAttributes.RootDirectory = *(HANDLE *)(a1 + 32);
ObjectAttributes.Attributes = 576; // 0x240 고정
ObjectAttributes.ObjectName = PathUnicodeString; // 사용자 제공 상대 경로
// IoCreateFileEx로 상대 경로 파일/디바이스 열기
Status = IoCreateFileEx(&FileHandle, DesiredAccess, &ObjectAttributes, ...);
// [핵심 취약점] v48(Flags & 2)이 non-zero이면 검증 블록 전체 스킵
if (!v48 && !v51) {
// ...
// VspVsmbGetStatInfo - 대상이 파일시스템 객체인지 검증
// 디바이스 객체에서는 STATUS_NOT_IMPLEMENTED 반환 → 핸들 획득 실패
Parameter = VspVsmbGetStatInfo(FileHandle, FileInformation);
if (Parameter < 0) goto Cleanup;
}
// v48 != 0이면 위 검증 블록을 건너뛰어 여기에 도달
// 핸들을 IOCTL 응답에 기록하여 사용자에게 반환
*((_QWORD *)v56 + 1) = FileHandle; // 응답 버퍼에 핸들 저장
*v56 = 2; // 응답 타입: 성공
*((_DWORD *)v56 + 1) = 0; // 상태: STATUS_SUCCESS
// ...
}
C
복사
[코드 6] 취약한 VspVsmbCommonRelativeCreate 함수 내부
정상적인 흐름에서는 VspVsmbGetStatInfo가 호출되어 대상이 파일시스템 객체인지 검증한다. 디바이스 객체에 대해서는 이 함수가 STATUS_NOT_IMPLEMENTED를 반환하여 핸들 획득이 실패해야 한다.
그러나 사용자 입력의 Flags 필드에 bit 1이 설정되면 v48이 non-zero가 되어 if (!v48 && !v51) 조건이 FALSE로 평가된다. 검증 블록 전체가 스킵되어 VspVsmbGetStatInfo가 호출되지 않으며 IoCreateFileEx에서 열린 핸들이 응답 버퍼에 기록되어 사용자에게 그대로 반환된다.
이 취약점의 근본적인 패치는 2.2.2에서 분석한 VspVsmbFileCreate의 경로 검증이다. \Device 경로에 대한 ZwOpenDirectoryObject 호출이 차단되면 2단계에서 사용할 RootDirectory 핸들 자체를 획득할 수 없으므로 Flags 우회 공격이 불가능해진다.
2.7 최종 결과
항목 | 값 |
1단계 | VspVsmbFileCreate에서 \Device 디렉토리 핸들 획득 |
2단계 | VspVsmbCommonRelativeCreate에서 검증 우회 후 디바이스 객체 핸들 반환 |
검증 우회 | 사용자 제어 Flags 필드로 VspVsmbGetStatInfo 스킵 |
권한 수준 | 일반 사용자 → 커널 디바이스 객체 접근 |
3. 시연 영상
본 PoC는 CVE-2025-59516 취약점을 통해 일반 사용자 권한으로 \Device 네임스페이스의 보호된 디바이스 객체에 무단 접근하는 과정을 시연한다.
[동영상 1] CVE-2025-59516 시연 영상
시연 환경: Windows 11 (Hyper-V 활성화, 패치 미적용)
시연 내용:
1.
VSMB 인터페이스를 통한 \Device 네임스페이스 핸들 획득
2.
획득한 핸들을 기반으로 디바이스 객체 핸들 획득
3.
획득한 핸들의 권한 확인
시연에서 확인된 바와 같이 공격자는 일반 사용자 권한만으로 \Device 네임스페이스의 보호된 디바이스 객체에 대한 핸들을 획득할 수 있다. 이는 추가적인 커널 취약점 연계 및 보안 기능 우회로 이어질 잠재적 위협이 있다.
4. 탐지 및 검증
4.1 행위 기반 탐지
다음 조건을 만족하는 이벤트를 모니터링한다.
•
파일 접근: \Device\STORVSP\VSMB 경로에 대한 비정상적인 NtCreateFile 호출
•
IOCTL 패턴: storvsp.sys에 대한 비정상적인 IOCTL 호출 빈도 및 패턴
•
핸들 이상: 일반 사용자 프로세스에서 커널 디바이스 객체 핸들 보유
4.2 PurpleHound 솔루션을 통한 검증
본 취약점과 같은 권한 상승 공격에 대해 조직의 보안 인프라가 효과적으로 대응할 수 있는지 사전에 검증하는 것이 중요하다.
PurpleHound는 78ResearchLab에서 개발한 BAS(Breach and Attack Simulation) 솔루션으로, 실전 기반 공격 시나리오를 재구성하여 기업이 보유한 보안 장비와 시스템이 실제 공격에 얼마나 효과적으로 대응 가능한지 검증할 수 있도록 지원한다. 북한 등 실제 위협 그룹이 사용하는 최신 공격 기술을 반영하며, 모든 공격 시나리오는 실증 검증을 거쳐 탑재된다.
CVE-2025-59516 취약점 역시 PurpleHound에 공격 시나리오로 탑재되어, 조직 내 엔드포인트 보안 솔루션 및 EDR이 해당 공격을 탐지·차단하는지 검증할 수 있다.
5. 권장 조치
•
2025년 12월 Microsoft 보안 업데이트 즉시 적용
•
패치 불가 시: 불필요한 Hyper-V/WSL2/Windows Sandbox 비활성화 검토 및 엔드포인트 모니터링 강화
6. 결론
CVE-2025-59516은 storvsp.sys의 두 함수(VspVsmbFileCreate, VspVsmbCommonRelativeCreate) 간 상호작용에서 발생하는 권한 상승 취약점이다.
VspVsmbFileCreate에서 IoCreateFileEx 실패 시 경로 검증 없이 ZwOpenDirectoryObject를 호출하여 \Device 네임스페이스 접근을 허용한다. VspVsmbCommonRelativeCreate에서는 사용자 제어 가능한 Flags 필드를 통해 VspVsmbGetStatInfo 검증을 우회하여 디바이스 객체 핸들을 획득할 수 있다.
공격자는 이 두 취약점을 조합하여 일반 사용자 권한으로 보호된 커널 디바이스 객체에 무단 접근할 수 있으며 이는 임의 파일 생성·쓰기, 추가 권한 상승, 보안 기능 우회로 이어질 잠재적 위협이 존재한다.
7. 참고 자료
•
CWE-306: https://cwe.mitre.org/data/definitions/306.html
•
CWE-73: https://cwe.mitre.org/data/definitions/73.html


