之前见到过一款系统,可以实现对U盘的访问控制,只有注册过的U盘才能正常使用,否则会提示
请将磁盘插入驱动器...
简单用IDA膜拜了一下它的一个驱动,貌似是从diskperf上修改的,就想着模仿一下它的功能,因为其工作比较复杂,不止一个驱动,所以打算简单实现功能即可。。。没加多少代码,高手飘过~~
曾经在一个群里问过怎么才能实现 弹出 请将磁盘插入驱动器 这个对话框,估计问题太2,没人摆我,于是就在IDA里翻啊翻,在其 ReadWriteDispatch 翻到这么一段代码:(感谢F5插件,要不我等水货肯定头大)
if ( pDeviceObject == DeviceObject ) // xxx的 FDO
{
status = 0xC0000010u; // STATUS_INVALID_DEVICE_REQUEST
LABEL_3:
Irp->IoStatus.Status = status;
returnValue = status;
LABEL_44:
Irp->IoStatus.Information = 0;
IofCompleteRequest(Irp, 0);
return returnValue;
}
想着也许就是这个 STATUS_INVALID_DEVICE_REQUEST 起了作用,该怎么测试呢?自己修改diskperf试试不就完了嘛,开工。
1、 尝试在 DiskPerfReadWrite 里面返回 STATUS_INVALID_DEVICE_REQUEST,直接返回肯定不行了,要不系统都起不来,仅仅在插入U盘时返回即可,怎么判断呢?
看看设备栈:
> 81fe2a30 \Driver\xxxxxx 81fe2ae8
81fe2c40 \Driver\PartMgr 81fe2cf8
82051ab8 \Driver\Disk 82051b70 DR4 U盘
81fd3d40 \Driver\USBSTOR 81fd3df8 00000087 USBSTOR
看来只要判断最下面的设备所属驱动是不是USBSTOR就行了,如下(XP SP3 硬编码):
//也可以在AddDevice里面保存最底层的设备
RealDevice=*(ULONG*)(*(ULONG*)((ULONG)DeviceObject+0xb0)+0x18); //AttachedTo XP SP3
RealDevice=*(ULONG*)(*(ULONG*)((ULONG)RealDevice+0xb0)+0x18); //AttachedTo
UsbStorDevice=*(ULONG*)(*(ULONG*)((ULONG)RealDevice+0xb0)+0x18); //AttachedTo
UsbStorDriverObj=UsbStorDevice->DriverObject;
ObQueryNameString(UsbStorDriverObj,pDeviceName,512,&uactLength);
//DbgPrint("驱动对象:%x 驱动名称:%wZ\n",UsbStorDriverObj,pDeviceName);
RtlInitUnicodeString(&CompareString,L"\\Driver\\USBSTOR");
if(RtlCompareUnicodeString(&CompareString,pDeviceName,FALSE))
{
;
}
else
{
DbgPrint("访问移动分区\n");
DbgPrint("禁止访问\n");
status=STATUS_DEVICE_NOT_READY;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IofCompleteRequest(Irp, 0);
return status;
}
这样就行啦,丢进虚拟机里试了一下,还真的可以,哈哈~~
2、
接下来就该考虑如何实现认证U盘的正常使用了,那个xxx系统制作的U盘丢在普通电脑上显示未格式化,应该是对MBR(DBR)动了手脚,那咱也试试呗
用WinHex修改U盘的DBR,对NTFS文件系统我修改的是 'NTFS' 标志为 0x1b 0x01 0x13 0x06 在DiskPerfReadWrite 调用 FltReadSectors 读取DBR,判断DBR的标志,如果是加密标志,
则调用 FltWriteSectors 改写DBR为正常,这样就能正常识别了,测试可行。
那么,标志还得改回去啊,要不插在普通电脑上也能识别了~~什么时候改呢?
一开始加了个计数器,每访问一次就加一,对NTFS文件系统测试发现,在识别文件系统后再修改DBR是可以的,不影响文件操作,但FAT32会将DBR修改回去。。。
结果发现不好使,不能精确确定计数器的值,使得在此之后修改DBR不影响文件访问~~~看了看diskperf,想到可以在U盘安全卸载的时候写入啊(作为测试,不考虑强制拔出的情况了)
于是在 DiskPerfRemoveDevice 加入了回写标志的代码,之后开始测试,然后就郁闷了,在盘符上点击弹出,FltWriteSectors会返回写入磁盘错误,因为磁盘无效,上群里问啊,各种没人摆啊
去看雪发帖问啊,感谢 ITSailor 作了回答和测试,虽然没解决原因~~~后来发现点击右下角的 安全弹出硬件却能正常,
可能是 两种弹出方式有一些差别,还望知道的给个解释,调试能力不行~~~搞不定啊
这是第一个版本,只要选择安全弹出,就能正常使用。。。
3、
既然第一个版本可以了,就该思考一下怎么在强制拔出的情况下也能正常使用的问题了,换个思路想想,
其实只要让文件系统识别器和文件系统看到的是正常的DBR数据就行了,那么可以在
在DiskPerfReadWrite上做手脚啊,考虑了一下,判断读请求的 偏移和大小,如果是读DBR,就设置一个完成函数,在完成函数里修改返回的数据为正常的DBR不就行了,经过测试,仅判断偏移
是否为0即可,这是第二个版本,个人认为功能比较健全了,呵呵(具体处理细节见代码。。。)
由于仅仅做个测试,修改DBR标志这种强度是远远不够的,有兴趣的可以在这上面增加功能,例如动态的标志,交互服务进程实现动态配置等。。。
马上工作了,工作以后估计很难摸到电脑,破事很多,就做到这个程度吧~~
附件里是两个版本的代码(IRP HOOK就是个鸡肋,在系统启动的时候被自动修复了貌似)和bin,还包含一个制作认证U盘的 控制台程序(要在不装这个驱动的电脑上运行)。
PS:原系统不是这么做的,貌似还有一个文件过滤驱动,还没研究。。。
欢迎交流,
羡慕每天有代码敲的................
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。