cd C:\:$i30:$bitmap导致的NTFS错误漏洞分析

对于近期cd C:\:$i30$bitmap可以导致驱动器损坏,并导致重启后执行磁盘检查。这里也进行了一次复现,同时发现在windows日志中记录了此错误,描述为MFT中包含损坏的文件记录。

随后对该漏洞进行分析查找漏洞触发点,但由于作者对ntfs文件系统的了解不多。因此本文章更多的是描述跟踪查找此漏洞触发点的步骤。

首先通过procmon 对cmd 的cd 命令进行监控。发现以下文件操作:

发现是CreateFile操作导致的漏洞产生。随后写一段代码证实。

#include <stdio.h>
#include <windows.h>
int main()
{
	HANDLE hFile = ::CreateFile( 
		"c:\\:$i30:$bitmap", 
		FILE_READ_ATTRIBUTES, 
		FILE_SHARE_READ | FILE_SHARE_WRITE, 
		NULL, 
		OPEN_EXISTING, 
		FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_NORMAL, 
		NULL
	);
	printf("%d\n", GetLastError());
	return 0;
}

接下来使用写好的程序进行对漏洞的进一步跟踪。

通过断点跟踪到了此次NtCreateFile所发起的IRP

中断两次后跟到ntfs驱动的IRP_MJ_CREATE函数Ntfs!NtfsFsdCreate函数

但是发现函数很大且子函数很多,很难摸清楚哪行出了问题。

随后换了一种思路,此错误会在windows日志中产生错误日志。因此选择跟踪Etw事件或许是个不错的选择。

随后在EtwWrite处下断点,成功中断此次事件。但是发现是个子线程,说明NTFS对于错误处理有着一个队列,所有的错误都会被传递到这里进行处理。

随后查找NtfsProcessRepairQueue函数的引用来查看拉起该线程的究竟是何处。

随后在NtfsPostRepairRequest函数中查找到,由于函数名和代码大致逻辑猜测,如果ntfs没有出现错误,此线程应该不会出现,只有第一次出现错误时,此线程才会创建并处理错误。

因此随后在NtfsPostRepairRequest下断,跟踪到NtfsFsdCreate+0x2d6附近。

但是在IDA反汇编中并没有查找到错误处理代码的调用源,猜测是ntfs使用了SEH的原因,这部分代码实际上应该是__except内的语句块。

单步跟踪证实了这点,并且发现这个异常触发在NtfsCommonCreate中

但是NtfsCommonCreate函数仍然巨大无比。但在阅读代码的时候发现ntfs有个Debug功能,但是在默认情况下是不打开的,很多的代码都有以下逻辑,并且最终都会调用

NtfsStatusTraceAndDebugInternal函数

由此尝试使用以下方法将ntfs的调试功能打开

NtfsStatusDebugFlags = 0xff

NtfsStatusDisplayStatus = 1

 

并在NtfsStatusTraceAndDebugInternal处下断,随后成功中断,可以看到出错的整个调用栈。

由此看出此次导致的错误可能是在更新Scb操作中出现了Bad or orphan FRS错误。

以下是抛出异常部分代码。

猜你喜欢

转载自blog.csdn.net/xuandao_ahfengren/article/details/113062033
cd