• 拒绝服务漏洞分析研究报告


    分析研究报告

    漏洞介绍:

    适用环境:

         全补丁 xp,  2003系统

     

    漏洞发现时间:2013-3-4

    漏洞起因:

             ImagePath 项读取的长度未做检查和限定,导致后面的复制有问题

    影响系统:xp, 2003

     

    危害
    本地拒绝服务

     

    攻击所需条件: 填充注册表ImagePath 修改成REG_MULTI_SZ, 填充数据 的长度

    Len(DWORD 类型) 满足:Len > = 65536

     

    一.漏洞poc的构造(poc.exe)

    创建一个服务:xxxx2, 删除原有的ImagePath 键值,新建 REG_MULTI_SZ类型的ImagePath,填充 Len = 65536 ,内容为:
    pBuffer[65536] = {‘\’,0,’A’.....后面全部是A};

     

    二.漏洞分析(xp sp3  英文版)

     

    05 f8af9bd8 8057e40e nt!KiTrap0E+0xd0

    06 f8af9c80 80580f31 nt!IopBuildFullDriverPath+0xf6

    07 f8af9d54 80581487 nt!IopLoadDriver+0x227

    08 f8af9d7c 8053876d nt!IopLoadUnloadDriver+0x45

    09 f8af9dac 805cff64 nt!ExpWorkerThread+0xef

    0a f8af9ddc 805460de nt!PspSystemThreadStartup+0x34

    0b 00000000 00000000 nt!KiThreadStartup+0x16

     

     

    蓝屏时候的堆栈,一步步跟踪后,重点从IopBuildFullDriverPath开始下断点,看实际的系统操作,最终会调用(从调用堆栈就可以看出)

     

    PAGE:805A5B8B                 lea     eax, [ebp+Destination]

    PAGE:805A5B8E                 push    eax             ; nDestLen

    PAGE:805A5B8F                 push    [ebp+BugCheckParameter1] ; KeyHandle

    PAGE:805A5B92                 lea     eax, [ebp+pusDriverName]

    PAGE:805A5B95                 push    eax             ; pusDriverName

    PAGE:805A5B96     call    _IopBuildFullDriverPath@12 ; IopBuildFullDriverPath(x,x,x)

     

    重点函数体在此:

     

    此函数声明:

    int __stdcall IopBuildFullDriverPath(PUNICODE_STRING pusDriverName, HANDLE KeyHandle, int nDestLen)

     

     

     

    进入此函数内部:

    直接调用IopGetRegistryValue  获取ImagePath 的KEY_VALUE_FULL_INFORMATION ,通过第三个参数返回结构体信息:

    此结构体如下:

    typedef struct _KEY_VALUE_FULL_INFORMATION

    {

    ULONG TitleIndex;

    ULONG Type;

    ULONG DataOffset;     

    ULONG DataLength;

    ULONG NameLength;

     WCHAR Name[1];

    } KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION;

     

    PAGE:004CF132                 mov     edi, edi

    PAGE:004CF134                 push    ebp

    PAGE:004CF135                 mov     ebp, esp

    PAGE:004CF137                 sub     esp, 10h

    PAGE:004CF13A                 push    ebx

    PAGE:004CF13B                 mov     ebx, [ebp+arg_8]

    PAGE:004CF13E                 push    esi

    PAGE:004CF13F                 push    edi

    PAGE:004CF140                 lea     eax, [ebp+pOutKeyFullInFormation]

    PAGE:004CF143                 push    eax             ; int

    PAGE:004CF144                 xor     esi, esi

    PAGE:004CF146                 push    offset word_4CF242 ; ImagePath:

    PAGE:004CF14B                 push    [ebp+ulLenWithoutNull] ; KeyHandle

    PAGE:004CF14E                 mov     [ebx+2], si

    PAGE:004CF152                 mov     [ebx], si

    PAGE:004CF155                 mov     [ebx+4], esi

    PAGE:004CF158                 mov     [ebp+arg_8], esi

    PAGE:004CF15B                 mov     [ebp+var_8], esi

    PAGE:004CF15E                 mov     [ebp+pOutKeyFullInFormation], esi

     

    PAGE:004CF161             call    IopGetRegistryValue@12 ; IopGetRegistryValue(x,x,x)

    PAGE:004CF166                 test    eax, eax

    PAGE:004CF168                 jl      loc_4DE606

    PAGE:004CF16E                 mov     ecx, [ebp+pOutKeyFullInFormation] ; ecx = pOutInformation  ;结构体输出 基地址0x81fbe00

    PAGE:004CF171     mov  eax, [ecx+_KEY_VALUE_FULL_INFORMATION.DataLength] ; eax = 0x10000 ,填充的Name 数组就是这么大

    PAGE:004CF174                 cmp     eax, esi

    PAGE:004CF176                 jz      loc_4DE606

    PAGE:004CF17C     mov     esi, [ecx+_KEY_VALUE_FULL_INFORMATION.DataOffset]

    PAGE:004CF17F                 add     esi, ecx        ; esi = 0x81d16028

    PAGE:004CF181                add     eax, 0FFFFFFFEh ; eax = eax - 2结果等于0xfffe

    PAGE:004CF184                 cmp     word ptr [esi], 5Ch ; pValue[0] = L’\’

    PAGE:004CF188                mov     [ebp+ulLenWithoutNull], eax ; 这是Name字段的长度 不加后面的空(宽字符原因)大小为0xfffe

    PAGE:004CF18B                 mov     [ebp+pValue], esi;指向Name起始地址

    PAGE:004CF18E                 jz      short go1    ;第一个字符为 L’\’ 直接跳走

     

    --- 

    /***

    执行查询ImagePath 的KEY_VALUE_FULL_INFORMATION 

    内存分布:

    kd> db 81fbe000  

    81fbe000  00 00 00 00 07 00 00 00-28 00 00 00 00 00 01 00  ........(.......

    81fbe010  12 00 00 00 49 00 6d 00-61 00 67 00 65 00 50 00  ....I.m.a.g.e.P.

    81fbe020  61 00 74 00 68 00 29 10-5c 00 41 41 41 41 41 41  a.t.h.)..AAAAAA

    81fbe030  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

    81fbe040  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

    81fbe050  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

    81fbe060  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

    81fbe070  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

     

    前面是 结构体各个字段的信息,后面是 我们在ImagePath 里面填充的字符 “ AAAAA....”

     

    Ebx 下面是一个局部结构体变量 ,逆向后其结构为:

    00000000 _MEM_INFOR      struc ; (sizeof=0x8)

    00000000 wDataLen        dw ?    //字符长度,不带null

    00000002 wLen            dw ?    // 整个mem 大小

    00000004 pDstMem         dd ?    // 指针 ,指向开辟的空间

    00000008 _MEM_INFOR      ends

    ***/

     

    PAGE:004CF19E go1:  

    PAGE:004CF19E                 mov     ecx, [ebp+ulLenWithoutNull] ;ecx 为Name字段的长度 - 2 

    PAGE:004CF1A1                 mov     eax, [ebp+var_8] ; eax = 0

    PAGE:004CF1A4                 mov     edi, [ebp+arg_8] ; edi = 0

    PAGE:004CF1A7                 add     eax, ecx        ;eax = ecx

    PAGE:004CF1A9                 lea     eax, [edi+eax+2] ; eax= eax +2,恢复整体长度 ,就是Name的totalLen = 0x10000

    PAGE:004CF1AD                 mov     [ebx+_MEM_INFOR.wLen], ax ; Loword(eax)  eax 为整体的长度,此时MemInfor.wLen  等于 原始Name长度的低位值,这里poc 调试LOWORD(eax) = 0

    PAGE:004CF1B1                 movzx   eax, ax

    PAGE:004CF1B4                 push    20206F49h       ; Tag

    PAGE:004CF1B9                 push    eax             ; NumberOfBytes ;size为0

    PAGE:004CF1BA                 push    1               ; PoolType

    PAGE:004CF1BC                 call    _ExAllocatePoolWithTag@12 ; ExAllocatePoolWithTag(x,x,x)   ;开辟的长度 为外部输入Name长度的低4位值,这里就明显没有根据了,可能没有他认为我们不可能输入这么长的字符数,这里取低位以后长度大小为 0

     

    PAGE:004CF1C1                 test    eax, eax

    PAGE:004CF1C3                 mov     [ebx+_MEM_INFOR.pDstMem], eax;存放指针

    0xe1a79708

    PAGE:004CF1C6                 jz      loc_519E9C

    PAGE:004CF1CC                 mov     cx, [ebx+_MEM_INFOR.wLen] ;为 0

    PAGE:004CF1D0                 sub     cx, 2   ;0 -2 = 0xfffe

    PAGE:004CF1D4                 test    edi, edi ;edi 一直为零

    PAGE:004CF1D6                 mov     [ebx+_MEM_INFOR.wDataLen], cx ; 实际能放的字符长度0xfffe ,这里已经错了

    PAGE:004CF1D9                 jz      short go2       ; 肯定跳转  edi = 0

     

    /******

    此时 pMemInforDst 的情况为:

    kd> dd ebx

    f8af9cf8  0000fffe e1a79708

    wDataLen        dw     0xfffe  //允许存放的空间大小

    wLen            dw     0x0   //开辟的长度 为0

    pDstMem         dd     0xe1a79708

     

    *******/

    PAGE:004CF1F3 go2:                                    ; CODE XREF: IopBuildFullDriverPath(x,x,x)+A7j

    PAGE:004CF1F3                 mov     ecx, [ebp+ulLenWithoutNull]

    PAGE:004CF1F6                 test    ecx, ecx

    PAGE:004CF1F8                 jz      short loc_4CF20E

    PAGE:004CF1FA                 mov     edi, [ebx+_MEM_INFOR.pDstMem]

    PAGE:004CF1FD                 add     edi, [ebp+arg_8] ; arg8 = 0

    PAGE:004CF200                 mov     eax, ecx

    PAGE:004CF202                 shr     ecx, 2          ; ecx = ecx /4 这里就使用有问题了,它使用的是esi的size = 0x10000,而此时复制的目的DstMem 的size = 0(他是取得低四位数值)

    PAGE:004CF205              rep movsd              

     ;esi : pNameValue  edi:pDstMem ,(ecx = 0x3ffff> (DstMem = 0) 开辟空间的大小 ,内存复制大小使用出错,导致蓝屏

     

    至此 ,分析完毕

     

     

     

     

     

     

     

  • 相关阅读:
    2021.07.11 【ABAP随笔】采购订单Message输出打印
    项目管理43210学习笔记
    Rails跳过回调方法
    树莓派接USB温湿度传感器(python)
    Visual Studio2019安装时报错Microsoft.Net.4.7.2.FullRedist的解决方法
    微信浏览器中H5使用wx-open-launch-app打开第三方APP
    Linux系统使用qq邮箱在线发送邮件
    LRU工程实现源码(一):Redis 内存淘汰策略
    Android Studio解决Build Log出现乱码问题
    git新拉取项目
  • 原文地址:https://www.cnblogs.com/microzone/p/3225554.html
Copyright © 2020-2023  润新知