首页
社区
课程
招聘
[原创]MS08-046漏洞分析
发表于: 2008-12-15 17:42 7440

[原创]MS08-046漏洞分析

dge 活跃值
6
2008-12-15 17:42
7440

Author:dge

    通过阅读微软安全公告和CVE-2008-2245,我们可以知道这是个发生在MSCMS模块里的堆溢出,CVE甚至给出了漏洞函数InternalOpenColorProfile。这个漏洞也是跟EMF图片有关,POC地址在这里:http://milw0rm.com/sploits/2008-emf_MS08-046.rar。

    本来可以直接对InternalOpenColorProfile函数进行分析,并且对其进行设断的,不过我在IDA里没找到这个函数,用PAIMEI定位到溢出点后才知道,IDA识别出了这个符号,只不过没把它放到FUNCTIONS列表里面,我们可以在NAMES列表里找到它,不过没关系,用PAIMEI找它也很简单。

说下跟踪步骤:
    先用PAIMEI跟踪,在跟踪记录中从后望前找,既然是堆溢出,那肯定得有堆分配的函数,而且在其附近代码中很可能有指向输入数据的寄存器和拷贝函数,这样很容易可以定位到溢出点,下一步就是在OD中对发生溢出的函数设断,中断后查看调用栈就可以获得漏洞触发路径了,如果这样不行的话,那就只能继续向上翻看PAIMEI的跟踪记录了,因为它记录的内容超多,所以有点麻烦,当然也可以只对函数进行跟踪,不过IDA在识别函数上经常出现问题,所以PAIMEI也会跟着倒霉。

漏洞产生路径:
PlayEnhMetaFileRecord
  |_MRSETICMPROFILE::bPlay
        |_SetICMProfileInternalA
              |_IcmSetDestinationColorSpace
                   |_IcmCreateColorSpaceByName
                        |_IcmCreateColorSpaceByColorSpace
                             |_IcmRealizeColorProfile
                                  |_OpenColorProfileW
                                        |_lstrcatW

POC截图:

蓝框就是RECORD的内容,当程序把它拷贝到小的堆中导致了溢出。

下边就仔细分析下这个漏洞:

.text:77EFEF66 __stdcall PlayEnhMetaFileRecord(x, x, x, x) proc near
.text:77EFEF66                                         ; CODE XREF: bInternalPlayEMF(x,x,x,x,x)+6A2 p
.text:77EFEF66                                         ; bInternalPlayEMF(x,x,x,x,x)+13B2 p ...
.text:77EFEF66
.text:77EFEF66 var_58          = dword ptr -58h
.text:77EFEF66 var_54          = dword ptr -54h
.text:77EFEF66 var_50          = dword ptr -50h
.text:77EFEF66 var_4C          = dword ptr -4Ch
.text:77EFEF66 var_48          = dword ptr -48h
.text:77EFEF66 var_44          = dword ptr -44h
.text:77EFEF66 var_40          = dword ptr -40h
.text:77EFEF66 var_3C          = dword ptr -3Ch
.text:77EFEF66 var_38          = dword ptr -38h
.text:77EFEF66 var_34          = dword ptr -34h
.text:77EFEF66 var_30          = dword ptr -30h
.text:77EFEF66 var_2C          = dword ptr -2Ch
.text:77EFEF66 var_28          = dword ptr -28h
.text:77EFEF66 var_24          = dword ptr -24h
.text:77EFEF66 var_20          = dword ptr -20h
.text:77EFEF66 var_1C          = dword ptr -1Ch
.text:77EFEF66 var_18          = dword ptr -18h
.text:77EFEF66 var_14          = dword ptr -14h
.text:77EFEF66 var_10          = dword ptr -10h
.text:77EFEF66 var_C           = dword ptr -0Ch
.text:77EFEF66 var_8           = dword ptr -8
.text:77EFEF66 var_4           = dword ptr -4
.text:77EFEF66 arg_0           = dword ptr  8
.text:77EFEF66 arg_4           = dword ptr  0Ch
.text:77EFEF66 arg_8           = dword ptr  10h
.text:77EFEF66 arg_C           = dword ptr  14h
.text:77EFEF66
.text:77EFEF66 ; FUNCTION CHUNK AT .text:77F18A61 SIZE 0000028A BYTES
.text:77EFEF66
.text:77EFEF66                 mov     edi, edi
.text:77EFEF68                 push    ebp
.text:77EFEF69                 mov     ebp, esp
.text:77EFEF6B                 sub     esp, 58h
.text:77EFEF6E                 push    ebx
.text:77EFEF6F                 mov     ebx, [ebp+arg_8]
.text:77EFEF72                 mov     eax, [ebx]
.text:77EFEF74                 cmp     eax, 1
.text:77EFEF77                 push    esi
.text:77EFEF78                 push    edi
.text:77EFEF79                 jb      short loc_77EFEF99
.text:77EFEF7B                 cmp     eax, 7Ah
.text:77EFEF7E                 ja      short loc_77EFEF99
.text:77EFEF80                 push    [ebp+arg_C]
.text:77EFEF83                 mov     ecx, ebx
.text:77EFEF85                 push    [ebp+arg_4]
.text:77EFEF88                 push    [ebp+arg_0]
.text:77EFEF8B                 call    _fpStartDocDlgW[eax*4] ; eax必须是70
.text:77EFEF92
.text:77EFEF92 loc_77EFEF92:                           ; CODE XREF: PlayEnhMetaFileRecord(x,x,x,x)+19D72 j
.text:77EFEF92                                         ; PlayEnhMetaFileRecord(x,x,x,x)+19D80 j
.text:77EFEF92                 pop     edi
.text:77EFEF93                 pop     esi
.text:77EFEF94                 pop     ebx
.text:77EFEF95                 leave
.text:77EFEF96                 retn    10h
.text:77EFEF99 ; ---------------------------------------------------------------------------

上图中的红线上边必须是0x70,这样才可以让数据流到达MRSETICMPROFILE::bPlay。

.text:77F2EA1B public: int __thiscall MRSETICMPROFILE::bPlay(void *, struct tagHANDLETABLE *, unsigned int) proc near
.text:77F2EA1B                                         ; DATA XREF: .data:77F3279C o
.text:77F2EA1B                                         ; .data:77F327A0 o
.text:77F2EA1B
.text:77F2EA1B var_46C         = dword ptr -46Ch
.text:77F2EA1B var_468         = dword ptr -468h
.text:77F2EA1B var_464         = dword ptr -464h
.text:77F2EA1B var_460         = dword ptr -460h
.text:77F2EA1B var_45C         = dword ptr -45Ch
.text:77F2EA1B var_458         = dword ptr -458h
.text:77F2EA1B var_454         = dword ptr -454h
.text:77F2EA1B var_450         = dword ptr -450h
.text:77F2EA1B var_44C         = dword ptr -44Ch
.text:77F2EA1B var_448         = dword ptr -448h
.text:77F2EA1B var_414         = dword ptr -414h
.text:77F2EA1B var_20C         = byte ptr -20Ch
.text:77F2EA1B var_4           = dword ptr -4
.text:77F2EA1B arg_0           = dword ptr  8
.text:77F2EA1B arg_4           = dword ptr  0Ch
.text:77F2EA1B
.text:77F2EA1B                 mov     edi, edi
.text:77F2EA1D                 push    ebp
.text:77F2EA1E                 mov     ebp, esp
.text:77F2EA20                 sub     esp, 46Ch
.text:77F2EA26                 mov     eax, ___security_cookie
.text:77F2EA2B                 push    esi
.text:77F2EA2C                 mov     [ebp+var_4], eax
.text:77F2EA2F                 mov     eax, [ebp+arg_4]
.text:77F2EA32                 push    edi
.text:77F2EA33                 mov     edi, [ebp+arg_0]
.text:77F2EA36                 push    eax
.text:77F2EA37                 mov     esi, ecx
.text:77F2EA39                 mov     [ebp+var_460], edi
.text:77F2EA3F                 call    MRNAMEDESCAPE::bCheckRecord(tagHANDLETABLE *) ;  这里必须符合[esi+10h]+[esi+c]&0FFFFFFFCh==[esi+4h]
.text:77F2EA44                 test    eax, eax
.text:77F2EA46                 jz      loc_77F2EBA2
.text:77F2EA4C                 push    ebx
.text:77F2EA4D                 xor     ebx, ebx
.text:77F2EA4F                 test    byte ptr [esi+8], 1 ; [esi+8h]必须等于0
.text:77F2EA53                 mov     [ebp+var_45C], ebx
.text:77F2EA59                 jz      loc_77F2EB74

当esi指向上图蓝色的位置时,[esi+10h]+[esi+c]&0FFFFFFFCh==[esi+4h],[esi+8h]必须等于0。

.text:77F2EB74 loc_77F2EB74:                           ; CODE XREF: MRSETICMPROFILE::bPlay(void *,tagHANDLETABLE *,uint)+3E j
.text:77F2EB74                 cmp     dword ptr [esi], 70h
.text:77F2EB77                 push    10002h          ; int
.text:77F2EB7C                 push    ebx             ; int
.text:77F2EB7D                 jnz     short loc_77F2EB8B
.text:77F2EB7F                 add     esi, 14h
.text:77F2EB82                 push    esi             ; lpString
.text:77F2EB83                 push    edi             ; HDC
.text:77F2EB84                 call    SetICMProfileInternalA(x,x,x,x)
.text:77F2EB89                 jmp     short loc_77F2EB95
.text:77F2EB8B ; ---------------------------------------------------------------------------

.text:77F20F7F __stdcall SetICMProfileInternalA(x, x, x, x) proc near
.text:77F20F7F                                         ; CODE XREF: SetICMProfileA(x,x)+F p
.text:77F20F7F                                         ; MRSETICMPROFILE::bPlay(void *,tagHANDLETABLE *,uint)+169 p
.text:77F20F7F
.text:77F20F7F var_210         = dword ptr -210h
.text:77F20F7F u_string        = byte ptr -20Ch
.text:77F20F7F var_4           = dword ptr -4
.text:77F20F7F hdc             = dword ptr  8
.text:77F20F7F lpString        = dword ptr  0Ch
.text:77F20F7F const_0         = dword ptr  10h
.text:77F20F7F const_10002     = dword ptr  14h
.text:77F20F7F
.text:77F20F7F                 mov     edi, edi
.text:77F20F81                 push    ebp
.text:77F20F82                 mov     ebp, esp
.text:77F20F84                 sub     esp, 210h
.text:77F20F8A                 mov     eax, ___security_cookie
.text:77F20F8F                 and     [ebp+var_210], 0
.text:77F20F96                 push    ebx
.text:77F20F97                 mov     ebx, [ebp+const_0]
.text:77F20F9A                 test    ebx, ebx
.text:77F20F9C                 push    esi
.text:77F20F9D                 mov     esi, [ebp+hdc]
.text:77F20FA0                 push    edi
.text:77F20FA1                 mov     edi, [ebp+lpString]
.text:77F20FA4                 mov     [ebp+var_4], eax
.text:77F20FA7                 jnz     short loc_77F20FB1
.text:77F20FA9                 test    edi, edi
.text:77F20FAB                 jz      loc_77F2104E

……

.text:77F21004                 test    edi, edi
.text:77F21006                 jz      short loc_77F21046
.text:77F21008                 push    edi             ; lpString
.text:77F21009                 call    ds:lstrlenA(x)
.text:77F2100F                 test    eax, eax
.text:77F21011                 jz      short loc_77F2103F
.text:77F21013                 cmp     eax, 104h       ; 如果RECORD的长度大于等于0x104就失败,所以最长是103字节
.text:77F21018                 jnb     short loc_77F2103F
.text:77F2101A                 inc     eax             ; 加上\0,最大长度为104字节
.text:77F2101B                 push    eax
.text:77F2101C                 push    edi
.text:77F2101D                 push    0
.text:77F2101F                 push    208h
.text:77F21024                 lea     eax, [ebp+u_string]
.text:77F2102A                 push    eax
.text:77F2102B                 call    ds:RtlMultiByteToUnicodeN(x,x,x,x,x) ; 把字符串转换成Unicode编码格式
.text:77F21031                 push    [ebp+const_10002]
.text:77F21034                 lea     eax, [ebp+u_string]
.text:77F2103A                 push    0
.text:77F2103C                 push    eax
.text:77F2103D                 jmp     short loc_77F20FF2

……

.text:77F20FF2 loc_77F20FF2:                           ; CODE XREF: SetICMProfileInternalA(x,x,x,x)+BE j
.text:77F20FF2                 push    esi             ; hdc
.text:77F20FF3                 call    IcmSetDestinationColorSpace(x,x,x,x)
.text:77F20FF8 ; ---------------------------------------------------------------------------

由上边的分析可知字符串最大长度为0x103字节。

.text:77F20CD3 __stdcall IcmSetDestinationColorSpace(x, x, x, x) proc near
.text:77F20CD3                                         ; CODE XREF: SetICMProfileInternalA(x,x,x,x)+74 p
.text:77F20CD3                                         ; SetICMProfileInternalW(x,x,x,x)+56 p ...
.text:77F20CD3
.text:77F20CD3 var_4           = dword ptr -4
.text:77F20CD3 hdc             = dword ptr  8
.text:77F20CD3 lpString2       = dword ptr  0Ch
.text:77F20CD3 const_0         = dword ptr  10h
.text:77F20CD3 const_10002     = dword ptr  14h
.text:77F20CD3
.text:77F20CD3                 mov     edi, edi
.text:77F20CD5                 push    ebp
.text:77F20CD6                 mov     ebp, esp
.text:77F20CD8                 push    ecx
.text:77F20CD9                 push    ebx
.text:77F20CDA                 push    esi
.text:77F20CDB                 xor     esi, esi
.text:77F20CDD                 cmp     [ebp+const_0], esi
.text:77F20CE0                 push    edi
.text:77F20CE1                 jnz     short loc_77F20D08
.text:77F20CE3                 cmp     [ebp+lpString2], esi
.text:77F20CE6                 jz      loc_77F20F71
.text:77F20CEC                 push    [ebp+lpString2] ; lpString
.text:77F20CEF                 call    ds:lstrlenW(x)
.text:77F20CF5                 cmp     eax, esi
.text:77F20CF7                 jz      loc_77F20F71
.text:77F20CFD                 cmp     eax, 104h
.text:77F20D02                 ja      loc_77F20F71

…….

.text:77F20D97 loc_77F20D97:                           ; CODE XREF: IcmSetDestinationColorSpace(x,x,x,x)+B5 j
.text:77F20D97                 cmp     [ebp+const_0], 0
.text:77F20D9B                 jnz     short loc_77F20DC4
.text:77F20D9D                 push    [ebp+const_10002] ; int
.text:77F20DA0                 push    dword ptr [esi+30h] ; int
.text:77F20DA3                 push    [ebp+lpString2] ; wchar_t *
.text:77F20DA6                 push    ebx             ; int
.text:77F20DA7                 call    IcmGetColorSpaceByName(x,x,x,x)
.text:77F20DAC                 test    eax, eax
.text:77F20DAE                 mov     [ebp+const_0], eax
.text:77F20DB1                 jnz     short loc_77F20DEE
.text:77F20DB3                 push    [ebp+const_10002] ; int
.text:77F20DB6                 push    dword ptr [esi+30h] ; int
.text:77F20DB9                 push    [ebp+lpString2] ; lpString2
.text:77F20DBC                 push    ebx             ; hdc
.text:77F20DBD                 call    IcmCreateColorSpaceByName(x,x,x,x)
.text:77F20DC2                 jmp     short loc_77F20DE3
.text:77F20DC4 ; ---------------------------------------------------------------------------

.text:77F0335B __stdcall IcmCreateColorSpaceByName(x, x, x, x) proc near
.text:77F0335B                                         ; CODE XREF: IcmUpdateLocalDCColorSpace(x,x)+1043 p
.text:77F0335B                                         ; IcmUpdateLocalDCColorSpace(x,x)+150B7 p ...
.text:77F0335B
.text:77F0335B struct_         = byte ptr -250h
.text:77F0335B var_4           = dword ptr -4
.text:77F0335B hdc             = dword ptr  8
.text:77F0335B lpString2       = dword ptr  0Ch
.text:77F0335B arg_8           = dword ptr  10h
.text:77F0335B const_10002     = dword ptr  14h
.text:77F0335B
.text:77F0335B                 mov     edi, edi
.text:77F0335D                 push    ebp
.text:77F0335E                 mov     ebp, esp
.text:77F03360                 sub     esp, 250h
.text:77F03366                 mov     eax, ___security_cookie
.text:77F0336B                 mov     edx, [ebp+lpString2]
.text:77F0336E                 push    esi
.text:77F0336F                 mov     esi, [ebp+hdc]
.text:77F03372                 mov     [ebp+var_4], eax
.text:77F03375                 push    edi
.text:77F03376                 xor     eax, eax
.text:77F03378                 mov     ecx, 93h
.text:77F0337D                 lea     edi, [ebp+struct_]
.text:77F03383                 rep stosd
.text:77F03385                 and     dword ptr [ebp+struct_+0Ch], eax
.text:77F0338B                 mov     eax, [ebp+arg_8]
.text:77F0338E                 mov     dword ptr [ebp+struct_+10h], eax
.text:77F03394                 push    edx             ; lpString2
.text:77F03395                 lea     eax, [ebp+struct_+44h]
.text:77F0339B                 push    eax             ; lpString1
.text:77F0339C                 mov     dword ptr [ebp+struct_], 50534F43h ;装填结构变量
.text:77F033A6                 mov     dword ptr [ebp+struct_+4], 400h
.text:77F033B0                 mov     dword ptr [ebp+struct_+8], 24Ch
.text:77F033BA                 call    ds:lstrcpyW(x,x) ; 把字符串拷贝到struct_+0x44
.text:77F033C0                 push    [ebp+const_10002]
.text:77F033C3                 lea     eax, [ebp+struct_]
.text:77F033C9                 push    0
.text:77F033CB                 push    eax             ; 结构指针
.text:77F033CC                 push    esi             ; hdc
.text:77F033CD                 call    IcmCreateColorSpaceByColorSpace(x,x,x,x)
.text:77F033D2                 mov     ecx, [ebp+var_4]
.text:77F033D5                 pop     edi
.text:77F033D6                 pop     esi
.text:77F033D7                 call    __security_check_cookie(x)
.text:77F033DC                 leave
.text:77F033DD                 retn    10h
.text:77F033DD __stdcall IcmCreateColorSpaceByName(x, x, x, x) endp
.text:77F033DD
.text:77F033DD ; ---------------------------------------------------------------------------

构造一个结构体变量做为参数传入,在这个结构体0x44偏移处包含RECORD的字符串。

.text:77F033E5 __stdcall IcmCreateColorSpaceByColorSpace(x, x, x, x) proc near
.text:77F033E5                                         ; CODE XREF: IcmCreateColorSpaceByName(x,x,x,x)+72 p
.text:77F033E5                                         ; IcmCreateColorTransform(x,x,x,x)+DDD p ...
.text:77F033E5
.text:77F033E5 hdc             = dword ptr  8
.text:77F033E5 lp_struct         = dword ptr  0Ch
.text:77F033E5 const_0         = dword ptr  10h
.text:77F033E5 const_10002     = dword ptr  14h
.text:77F033E5
.text:77F033E5 ; FUNCTION CHUNK AT .text:77F037FC SIZE 00000039 BYTES
.text:77F033E5 ; FUNCTION CHUNK AT .text:77F1684C SIZE 00000126 BYTES
.text:77F033E5
.text:77F033E5                 mov     edi, edi
.text:77F033E7                 push    ebp
.text:77F033E8                 mov     ebp, esp
.text:77F033EA                 push    ebx
.text:77F033EB                 push    esi
.text:77F033EC                 mov     esi, [ebp+lp_struct]
.text:77F033EF                 xor     ebx, ebx
.text:77F033F1                 test    esi, esi
.text:77F033F3                 push    edi
.text:77F033F4                 jz      loc_77F03529
.text:77F033FA                 cmp     _ghICM, ebx
.text:77F03400                 jz      loc_77F1684C

……

.text:77F03493                                         ; IcmCreateColorSpaceByColorSpace(x,x,x,x)+134B7 j ...
.text:77F03493                 mov     eax, [ebp+lp_struct]
.text:77F03496                 cmp     [eax+44h], cx   ; 检查RECORD的第一个字节内容是否为0
.text:77F0349A                 jz      loc_77F1690E
.text:77F034A0                 push    edi             ; size_t
.text:77F034A1                 lea     esi, [ebx+70h]
.text:77F034A4                 push    esi             ; int
.text:77F034A5                 push    esi             ; wchar_t *
.text:77F034A6                 call    BuildIcmProfilePath(x,x,x)
.text:77F034AB                 push    offset aSrgbColorSpace ; "sRGB Color Space Profile.icm"
.text:77F034B0                 push    eax             ; wchar_t *
.text:77F034B1                 call    ds:__imp___wcsicmp
.text:77F034B7                 test    eax, eax
.text:77F034B9                 pop     ecx
.text:77F034BA                 pop     ecx
.text:77F034BB                 jnz     short loc_77F034C1
.text:77F034BD                 or      dword ptr [ebx+0Ch], 1
.text:77F034C1
.text:77F034C1 loc_77F034C1:                           ; CODE XREF: IcmCreateColorSpaceByColorSpace(x,x,x,x)+D6 j
.text:77F034C1                 mov     dword ptr [ebx+20h], 1
.text:77F034C8                 mov     [ebx+24h], esi
.text:77F034CB                 mov     dword ptr [ebx+28h], 208h
.text:77F034D2
.text:77F034D2 loc_77F034D2:                           ; CODE XREF: IcmCreateColorSpaceByColorSpace(x,x,x,x)+13514 j
.text:77F034D2                                         ; IcmCreateColorSpaceByColorSpace(x,x,x,x)+13524 j ...
.text:77F034D2                 push    0               
.text:77F034D4                 push    ebx             ; ebx指向新的堆
.text:77F034D5                 call    IcmRealizeColorProfile(x,x)
.text:77F034DA ; ---------------------------------------------------------------------------

程序新建了个堆,并把前边构造的结构体变量复制到其中。

.text:77F032DD __stdcall IcmRealizeColorProfile(x, x) proc near
.text:77F032DD                                         ; CODE XREF: IcmCreateColorSpaceByColorSpace(x,x,x,x)+F0 p
.text:77F032DD                                         ; IcmCreateColorTransform(x,x,x,x)+E4D p ...
.text:77F032DD
.text:77F032DD lp_st           = dword ptr  8
.text:77F032DD const_0         = dword ptr  0Ch
.text:77F032DD
.text:77F032DD ; FUNCTION CHUNK AT .text:77F037E0 SIZE 0000001C BYTES
.text:77F032DD ; FUNCTION CHUNK AT .text:77F162CE SIZE 0000000C BYTES
.text:77F032DD
.text:77F032DD                 mov     edi, edi
.text:77F032DF                 push    ebp
.text:77F032E0                 mov     ebp, esp
.text:77F032E2                 push    esi
.text:77F032E3                 mov     esi, [ebp+lp_st]
.text:77F032E6                 test    esi, esi
.text:77F032E8                 jz      loc_77F037F4
.text:77F032EE                 cmp     dword ptr [esi+14h], 0
.text:77F032F2                 jnz     short loc_77F0331F
.text:77F032F4                 cmp     dword ptr [esi+24h], 0
.text:77F032F8                 jz      short loc_77F0331F
.text:77F032FA                 push    edi
.text:77F032FB                 push    3
.text:77F032FD                 push    3
.text:77F032FF                 push    1
.text:77F03301                 lea     eax, [esi+20h]
.text:77F03304                 push    eax
.text:77F03305                 call    _fpOpenColorProfileW ; 这里调用mscms模块里的OpenColorProfileW函数
.text:77F0330B                 mov     edi, eax
.text:77F0330D                 test    edi, edi
.text:77F0330F                 jz      short loc_77F0331E
.text:77F03311                 cmp     [ebp+const_0], 0
.text:77F03315                 jnz     loc_77F037E0
.text:77F0331B
.text:77F0331B loc_77F0331B:                           ; CODE XREF: IcmRealizeColorProfile(x,x)+50C j
.text:77F0331B                 mov     [esi+14h], edi
.text:77F0331E
.text:77F0331E loc_77F0331E:                           ; CODE XREF: IcmRealizeColorProfile(x,x)+32 j
.text:77F0331E                                         ; IcmRealizeColorProfile(x,x)+12FF8 j
.text:77F0331E                 pop     edi
.text:77F0331F
.text:77F0331F loc_77F0331F:                           ; CODE XREF: IcmRealizeColorProfile(x,x)+15 j
.text:77F0331F                                         ; IcmRealizeColorProfile(x,x)+1B j
.text:77F0331F                 xor     eax, eax
.text:77F03321                 cmp     [esi+14h], eax
.text:77F03324                 setnz   al
.text:77F03327
.text:77F03327 loc_77F03327:                           ; CODE XREF: IcmRealizeColorProfile(x,x)+51A j
.text:77F03327                 pop     esi
.text:77F03328                 pop     ebp
.text:77F03329                 retn    8
.text:77F03329 __stdcall IcmRealizeColorProfile(x, x) endp

上边调用MSCMS模块里的函数OpenColorProfileW。

.text:73AA1D96 __stdcall OpenColorProfileW(x, x, x, x) proc near
.text:73AA1D96                                         ; CODE XREF: DoesProfileMatchEnumRecord(x,x)+49 p
.text:73AA1D96                                         ; GetProfileClassString(x,x,x)+58 p
.text:73AA1D96
.text:73AA1D96 SecurityAttributes= _SECURITY_ATTRIBUTES ptr -18h
.text:73AA1D96 var_C           = dword ptr -0Ch
.text:73AA1D96 var_8           = dword ptr -8
.text:73AA1D96 var_4           = dword ptr -4
.text:73AA1D96 lpString1       = dword ptr  8
.text:73AA1D96 const_1         = dword ptr  0Ch
.text:73AA1D96 dwShareMode     = dword ptr  10h
.text:73AA1D96 dwCreationDisposition= dword ptr  14h
.text:73AA1D96
.text:73AA1D96 ; FUNCTION CHUNK AT .text:73AA2559 SIZE 00000051 BYTES
.text:73AA1D96 ; FUNCTION CHUNK AT .text:73AA3A77 SIZE 00000163 BYTES
.text:73AA1D96
.text:73AA1D96                 mov     edi, edi
.text:73AA1D98                 push    ebp
.text:73AA1D99                 mov     ebp, esp
.text:73AA1D9B                 pop     ebp
.text:73AA1D9C                 nop
.text:73AA1D9D                 nop
.text:73AA1D9E                 nop
.text:73AA1D9F                 nop
.text:73AA1DA0                 nop
.text:73AA1DA1
.text:73AA1DA1 __stdcall InternalOpenColorProfile(x, x, x, x):
.text:73AA1DA1                                         ; CODE XREF: OpenColorProfileA(x,x,x,x)+70 p
.text:73AA1DA1                 mov     edi, edi
.text:73AA1DA3                 push    ebp
.text:73AA1DA4                 mov     ebp, esp
.text:73AA1DA6                 sub     esp, 18h
.text:73AA1DA9                 push    ebx
.text:73AA1DAA                 push    esi
.text:73AA1DAB                 mov     esi, [ebp+lpString1]
.text:73AA1DAE                 xor     ebx, ebx
.text:73AA1DB0                 cmp     esi, ebx
.text:73AA1DB2                 push    edi
.text:73AA1DB3                 mov     [ebp+var_8], ebx
.text:73AA1DB6                 jz      loc_73AA2577
.text:73AA1DBC                 mov     edi, ds:IsBadReadPtr(x,x)

……

.text:73AA1E67                 mov     eax, [edi+4]    ; 指向输入串
.text:73AA1E6A                 test    eax, eax
.text:73AA1E6C                 jz      loc_73AA2563
.text:73AA1E72                 cmp     dword ptr [edi+8], 0
.text:73AA1E76                 jz      loc_73AA2563
.text:73AA1E7C                 push    eax             ; lpString
.text:73AA1E7D                 call    ds:lstrlenW(x)
.text:73AA1E83                 mov     esi, 104h
.text:73AA1E88                 cmp     eax, esi
.text:73AA1E8A                 jg      loc_73AA2563    ; 串长度必须小于等于208字节
.text:73AA1E90                 cmp     dword ptr [edi+8], 208h
.text:73AA1E97                 ja      loc_73AA2563
.text:73AA1E9D                 push    dword ptr [ebx+0Ch] ; lpszStart
.text:73AA1EA0                 call    GetFilenameFromPath(x)
.text:73AA1EA5                 cmp     eax, [ebx+0Ch]
.text:73AA1EA8                 jz      loc_73AA3AA2

…….

.text:73AA3AA2 loc_73AA3AA2:                           ; CODE XREF: OpenColorProfileW(x,x,x,x)+112 j
.text:73AA3AA2                 push    esi             ; dwBytes
.text:73AA3AA3                 mov     [ebp+var_C], esi
.text:73AA3AA6                 call    MemAlloc(x)     ; 分配固定长度0x104字节的堆
.text:73AA3AAB                 mov     edi, eax
.text:73AA3AAD                 test    edi, edi
.text:73AA3AAF                 mov     [ebp+lpString1], edi
.text:73AA3AB2                 jz      short loc_73AA3A9B
.text:73AA3AB4                 lea     eax, [ebp+var_C]
.text:73AA3AB7                 push    eax             ; PDWORD
.text:73AA3AB8                 push    edi             ; PWSTR
.text:73AA3AB9                 push    0               ; PCWSTR
.text:73AA3ABB                 call    GetColorDirectoryW(x,x,x) ; 获取路径
.text:73AA3AC0                 push    offset _gszBackslash ; "\\"
.text:73AA3AC5                 push    edi             ; lpString1
.text:73AA3AC6                 mov     edi, ds:lstrcatW(x,x)
.text:73AA3ACC                 call    edi ; lstrcatW(x,x)
.text:73AA3ACE                 push    dword ptr [ebx+0Ch] ; 这里就是蓝框中的字符串,只不过变成了UNICODE格式,所以长度成了原来的2倍。
.text:73AA3AD1                 push    [ebp+lpString1] ; lpString1
.text:73AA3AD4                 call    edi ; lstrcatW(x,x) ;这里可以溢出堆
.text:73AA3AD6                 push    dword ptr [ebx+0Ch] ; pMem
.text:73AA3AD9                 call    MemFree(x)
.text:73AA3ADE                 mov     eax, [ebp+lpString1]
.text:73AA3AE1                 mov     [ebx+0Ch], eax
.text:73AA3AE4                 mov     [ebx+10h], esi
.text:73AA3AE7                 jmp     loc_73AA1EAE
.text:73AA3AEC ; ------------------------------------------------------------------------

上边的拷贝函数可以把0x208字节的字符串拷贝到0x104字节的堆中,因此可以覆盖下一个堆块的管理结构。

总结下:这个漏洞产生的根本原因是程序员对Unicode字符串长度进行了错误的理解,这让我想起了MS06-040。

本人菜鸟一只,请指教,谢谢。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (8)
雪    币: 443
活跃值: (200)
能力值: ( LV9,RANK:1140 )
在线值:
发帖
回帖
粉丝
2
这次终于坐上沙发了!!!!!!!!!!!!!
2008-12-15 21:11
0
雪    币: 2056
活跃值: (13)
能力值: ( LV13,RANK:250 )
在线值:
发帖
回帖
粉丝
3
学习。
不过感觉LZ的分析还不完整,没有说明Exploit细节,即如何得到控制权执行Shellcode的?
2008-12-16 10:13
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
把那些细节发上来就好了。
2008-12-16 11:27
0
雪    币: 622
活跃值: (65)
能力值: ( LV13,RANK:290 )
在线值:
发帖
回帖
粉丝
5
首先我认为已经很详细了,我已经详细分析了这个漏洞的产生原因。
关于执行shellcode,因为是堆溢出,我无法饶过堆保护去实现能执行shellcode的攻击,不是不写,实在是能力有限,并且网上的POC也只是能拒绝服务而已,如果你有什么有效的方法,还请指教,谢谢你的回复。
2008-12-16 14:09
0
雪    币: 622
活跃值: (65)
能力值: ( LV13,RANK:290 )
在线值:
发帖
回帖
粉丝
6
你说骗就是骗老,呵呵,快乐就好。
2008-12-16 14:14
0
雪    币: 2056
活跃值: (13)
能力值: ( LV13,RANK:250 )
在线值:
发帖
回帖
粉丝
7
我想说的是这个意思,漏洞原因的确是说的很详细了,只是我个人觉得一篇完整的漏洞分析应该包含了漏洞原因和利用思路(如果能被利用的话)。
从微软的公告上看到MS08-046的级别是严重,可远程执行代码,既然微软都这样说了,理论上应该是能利用的,POC作者可能是有所保留。我这段时间比较忙,不想分心来弄这东西,有空时我再试试看吧,到时再一起讨论。
2008-12-17 10:34
0
雪    币: 622
活跃值: (65)
能力值: ( LV13,RANK:290 )
在线值:
发帖
回帖
粉丝
8
恩,有时间一起进步。
我从事的工作和漏洞也沾不上边,爱好而已,偶尔出来YY一下。
2008-12-17 14:34
0
雪    币: 232
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
还不错,支持下.
2008-12-18 13:16
0
游客
登录 | 注册 方可回帖
返回
//