首页
社区
课程
招聘
[原创]QQProtect驱动调用者签名校验漏洞分析
发表于: 2013-10-15 07:39 10144

[原创]QQProtect驱动调用者签名校验漏洞分析

2013-10-15 07:39
10144
NTSTATUS
QQPDispatchCreateClose( PDEVICE_OBJECT DeviceObject,PIRP Irp )
{
    NTSTATUS            status = STATUS_SUCCESS;
    PIO_STACK_LOCATION  IrpSp = NULL;
 
    KdPrint(("------------------------QQPDispatchCreateClose-------------------\n"));
    if( !DeviceObject || !Irp )
    {
        status = STATUS_UNSUCCESSFUL;
        goto exit;
    }
    
    IrpSp = IoGetCurrentIrpStackLocation( Irp );
    if( IRP_MJ_CREATE == IrpSp->MajorFunction )
    {
        if( IsCallerAppImageAllowed() )
        {
            if( !InterlockedCompareExchange( &g_bHookMonThreadBusy,TRUE,FALSE))
            {
                MakeSureHookOk();
                MakeSureLoadImageNotifyOk( &NotifyRoutine_LoadImage);
                MakeSureCreateThreadNotifyOk(&NotifyRoutine_CreateThread);
                MakeSureCreateProcessNotifyOk(&NotifyRoutine_CreateProcess);
                InterlockedExchange( &g_bHookMonThreadBusy,FALSE );
            }
        }
        else
        {
            status = STATUS_ACCESS_DENIED;
        }
    }
    else if ( IRP_MJ_CLOSE == IrpSp->MajorFunction )
    {
        CloseR3Object();
        FreeList_0_1_2_3();
    }
 
    Irp->IoStatus.Information = 0;
    Irp->IoStatus.Status = status;
    IoCompleteRequest( Irp,IO_NO_INCREMENT );
 
exit:
    KdPrint(("Ret value:%x\n",status ));
    KdPrint(("----------------------------------------------------------\n\n\n"));
 
    return status;
}
BOOLEAN
NTAPI
IsCallerAppImageAllowed()
/*++
function description:
    Check whether current process is allowed to control driver
Parameters:
    None
return value:
    if allowed,return true,otherwise return false
comment:
    this function is called in DispatchCreate Routine
--*/
{
    WCHAR   DosDeviceName[MAX_UNICODE_STRING_CHARS + 1] = {0};
    WCHAR   FileDosName[MAX_UNICODE_STRING_CHARS + 1] ={0};
 
  //获取调用者可执行文件名称
    GetProcessDevicePathName( (ULONG)PsGetCurrentProcessId(),DosDeviceName,0x100 );
    GetFileDosName( DosDeviceName,FileDosName,0x100,FALSE );
    wcsupr( FileDosName );  //统一为大写
    if( wcsstr( FileDosName,L"\\QQPROTECT.EXE"))  //判断文件全路径中是否含有QQPROTECT.EXE的字样
    {
        BOOLEAN bResult = FALSE;
        __try{
        bResult = IsFileDigitalSignatureOk( FileDosName );  //校验数字签名
        }__except(EXCEPTION_EXECUTE_HANDLER )
        {
            KdPrint(("exception occurred in IsCallerAppImageAllowed\n"));
        }
        return bResult;
    }
 
    return FALSE;
}
BOOLEAN
NTAPI
IsFileDigitalSignatureOk( PCWSTR    FileName )
/*++
function description:
    Check whether the digital signature( Tencent) in file is ok
Parameters:
    FileName:the specific file name
return value:
    if signature is ok,then return ture ,otherwise return false
--*/
{
    BOOLEAN     bResult = FALSE;
    PVOID       FileData = NULL;
    ULONG       FileSize = 0;
    struct _SIG_INFOR        //签名信息的结构体
    {
        ULONG   StartFileOffset;
        ULONG   Length;
        UCHAR   MD5Value[0x10];
    }sig_infor = {0},sig_infor_tmp = {0};
    ULONG       retBytes = 0;
    ULONG       SigDataOffset = 0;
 
    FileData = GetFileData_6MB( FileName,&FileSize );// 从文件头提取不多于6MB的数据
    if( !FileData )
        goto exit;
    if( FileSize <= 0x40 )
        goto exit;
    if( !IsValidPeImage( FileData )) //检查PE文件格式,对于版本2.6.0.4并不重要
        goto exit;
    
    SigDataOffset = *(PULONG)((ULONG_PTR)FileData + 0x28);//获取RSA密文的文件偏移
    if( !SigDataOffset || SigDataOffset > FileSize - 0x80 )
        goto exit;
 
retBytes = sizeof( sig_infor );
    //RSA解密数据,此函数中包含TX的公钥。后边我会展开该函数。
    if( !RSA_Encode( (unsigned char *)((ULONG_PTR)FileData + SigDataOffset),
                     0x80,
                     (unsigned char *)&sig_infor,//解密后的数据存到sig_infor中
                     &retBytes ))
        goto exit;
 
  //验证签名数据是否有效。
    sig_infor_tmp = sig_infor;
    if( sig_infor.Length && 
        sig_infor.Length <= FileSize && 
        sig_infor.StartFileOffset + sig_infor.Length <= FileSize )
    {
        MD5Data( (unsigned char*)((ULONG_PTR)FileData + sig_infor.StartFileOffset),
                 sig_infor.Length,
                 sig_infor.MD5Value );
    //对比文件从指定位置,指定长度的数据进行MD5运算,并和签名信息中的原始数据进行对比
        if( RtlCompareMemory( sig_infor.MD5Value,sig_infor_tmp.MD5Value,0x10 ) == 0x10 )
            bResult = TRUE;
    }
 
exit:
    if( FileData )
        ExFreePool( FileData );
    
    return bResult;
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 5
支持
分享
最新回复 (41)
雪    币: 2887
活跃值: (3919)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
沙发,顶起
2013-10-15 08:06
0
雪    币: 94
活跃值: (465)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
怎么没有源码和BIN啊?
2013-10-15 08:10
0
雪    币: 1689
活跃值: (379)
能力值: ( LV15,RANK:440 )
在线值:
发帖
回帖
粉丝
4
操作失误,现在有了。注意你的安装版本,然后再play.
2013-10-15 08:40
0
雪    币: 623
活跃值: (40)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
mark
2013-10-15 09:11
0
雪    币: 859
活跃值: (309)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
6
wonderful!
2013-10-15 09:15
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
感觉很有收获,赞一个
2013-10-15 09:29
0
雪    币: 1491
活跃值: (985)
能力值: (RANK:860 )
在线值:
发帖
回帖
粉丝
8
非常的非常详细,感谢楼主的文章
2013-10-15 09:38
0
雪    币: 35
活跃值: (96)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
思路说的很清晰
2013-10-15 09:53
0
雪    币: 1753
活跃值: (2187)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
果断下载留念,丝毫不敢怠慢
2013-10-15 09:54
0
雪    币: 3116
活跃值: (1269)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
11
V5,看到数学公式就知道有含金量了
2013-10-15 10:02
0
雪    币: 200
活跃值: (38)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
不理解tx为什么不用win自带的校验数字签名的api呢?还请大神解答
2013-10-15 10:11
0
雪    币: 433
活跃值: (1870)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
13
非常感谢 hackerlzc 同学之前的反馈,目前修复版本已发布,欢迎广大基友测试使用。
2013-10-15 10:14
0
雪    币: 27
活跃值: (127)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
14
对驱动有所了解的朋友都知道,Ring3打开驱动的方式首先是CreateFile,然后是DeviceIoControl或者Read/Write File一类的操作。而要校验调用者的合法性,方法无非是在IRP_MJ_CREATE 的派遣例程中进行验证,HOOK住ZwCreateFile对来自CreateFile的调用进行验证,或者是对来自DeviceIoControl,Read/WriteFile 的调用进行合法性验证等


我的观点
在产品设计时,对于调用者验证这个问题,考虑通过驱动和应用之间的通信协议来保证调用者的合法性,会更好一些
2013-10-15 11:40
0
雪    币: 680
活跃值: (68)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
15
upup
2013-10-15 12:45
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
16
话说,我还以为是TX用的N被分解成3个质数了~~
2013-10-15 12:53
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
赞赞赞,回头分析下。
2013-10-15 13:21
0
雪    币: 46
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
关注学习
2013-10-15 14:04
0
雪    币: 234
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
学习!
还有洞,包括Q管
2013-10-15 15:01
0
雪    币: 11075
活跃值: (17602)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
楼主很厉害,还能找到漏洞,支持分享
2013-10-15 20:33
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
支持下啊 写的很好
2013-10-16 17:37
0
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
谢谢分享,来看看
2013-10-16 22:59
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
好文,4个
2013-10-17 09:22
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
在你这个文章启发下,我发现又有其它的逻辑漏洞要吧利用!
过会去测试一下.
2013-10-17 10:29
0
雪    币: 1491
活跃值: (985)
能力值: (RANK:860 )
在线值:
发帖
回帖
粉丝
25
期待你能给论坛的朋友们共享下
2013-10-17 14:59
0
游客
登录 | 注册 方可回帖
返回
//