首页
社区
课程
招聘
[原创][第一阶段◇第四题]看雪论坛.腾讯公司2008软件安全技术竞赛
发表于: 2008-10-13 07:46 3530

[原创][第一阶段◇第四题]看雪论坛.腾讯公司2008软件安全技术竞赛

2008-10-13 07:46
3530
简单说下崩溃的原因:StretchDIBits对位图长,宽,面验证不够,通过修改位图结构,构造一个很大的数(当然这个大小也有限度,太大申请堆空间会失败的),可以让它在执行堆拷贝的时候,由于拷贝,发生内存访问错误,导致explorer崩溃,只想到崩溃,不知道能否溢出 ,大牛来哈
1.找崩溃点
  用ida看了下gdi32的StretchDIBits里面能产生崩溃的函数只有执行到77F0C624:
77F0C624 >  64:A1 18000000  mov     eax, dword ptr fs:[18]
77F0C62A    FF75 D4         push    dword ptr [ebp-2C]
77F0C62D    8B40 30         mov     eax, dword ptr [eax+30]
77F0C630    57              push    edi
77F0C631    FF70 18         push    dword ptr [eax+18]
77F0C634    FF15 AC11EF77   call    dword ptr [<&ntdll.RtlAllocateHe>; ntdll.RtlAllocateHeap               //申请堆
77F0C63A    3BC7            cmp     eax, edi
77F0C63C    8945 C4         mov     dword ptr [ebp-3C], eax
77F0C63F  ^ 0F84 99EAFEFF   je      <loc_77EFB0DE>
77F0C645    8B4D D4         mov     ecx, dword ptr [ebp-2C]
77F0C648    8B75 2C         mov     esi, dword ptr [ebp+2C]
77F0C64B    8BD1            mov     edx, ecx
77F0C64D    C1E9 02         shr     ecx, 2
77F0C650    8BF8            mov     edi, eax
77F0C652    F3:A5           rep     movs dword ptr es:[edi], dword p>     //然后拷贝
77F0C654    8BCA            mov     ecx, edx
77F0C656    83E1 03         and     ecx, 3
77F0C659    F3:A4           rep     movs byte ptr es:[edi], byte ptr>    //少于4字节的拷贝
为什么这里可能会产生崩溃,因为这里是对位图数据的拷贝,如果[esi]空间不够,就会出现内存访问错误
2.崩溃前的程序流程:
   explorer执行到崩溃点之前的代码:
77EFB067 >  8BFF            mov     edi, edi
77EFB069    55              push    ebp
77EFB06A    8BEC            mov     ebp, esp
77EFB06C    83EC 68         sub     esp, 68
77EFB06F    8B45 08         mov     eax, dword ptr [ebp+8]
77EFB072    53              push    ebx
77EFB073    56              push    esi
77EFB074    8B75 30         mov     esi, dword ptr [ebp+30]
77EFB077    57              push    edi
77EFB078    33FF            xor     edi, edi
77EFB07A    25 00007F00     and     eax, 7F0000
77EFB07F    BB 00000100     mov     ebx, 10000                       ; UNICODE "=::=::\"
77EFB084    3BC3            cmp     eax, ebx
77EFB086    897D C4         mov     dword ptr [ebp-3C], edi
77EFB089    897D F0         mov     dword ptr [ebp-10], edi
77EFB08C    897D F4         mov     dword ptr [ebp-C], edi
77EFB08F    897D FC         mov     dword ptr [ebp-4], edi
77EFB092    897D B8         mov     dword ptr [ebp-48], edi
77EFB095    0F85 4A220100   jnz     <loc_77F0D2E5>
77EFB09B >  3BF7            cmp     esi, edi
77EFB09D    0F84 E7150100   je      <loc_77F0C68A>
77EFB0A3    57              push    edi
77EFB0A4    8D45 D8         lea     eax, dword ptr [ebp-28]
77EFB0A7    50              push    eax
77EFB0A8    FF75 34         push    dword ptr [ebp+34]
77EFB0AB    56              push    esi
77EFB0AC    E8 2FE6FFFF     call    <pbmiConvertInfo(x,x,x,x)>   //关键点1
77EFB0B1    3BC7            cmp     eax, edi
77EFB0B3    8945 F0         mov     dword ptr [ebp-10], eax
77EFB0B6    0F84 C7150100   je      <loc_77F0C683>
77EFB0BC    8B75 F0         mov     esi, dword ptr [ebp-10]
77EFB0BF    56              push    esi
77EFB0C0    E8 3AFBFFFF     call    <cjBitmapBitsSize(x)>         //关键点2
77EFB0C5    8945 D4         mov     dword ptr [ebp-2C], eax
77EFB0C8 >  64:A1 18000000  mov     eax, dword ptr fs:[18]
77EFB0CE    F645 2C 03      test    byte ptr [ebp+2C], 3              //关键点3,
77EFB0D2    89B8 D0060000   mov     dword ptr [eax+6D0], edi
77EFB0D8    0F85 46150100   jnz     <loc_77F0C624>                 //跳到崩溃点

关键点1:应该是通过一些验证,得到一个合法的 位图信息结构,经过跟踪发现,这里可以为两种格式,但系统默认的是BITMAPINFOHEADER 28大小的结构,
typedef struct tagBITMAPCOREHEADER {
        DWORD   bcSize;                 /* used to get to color table */
        WORD    bcWidth;
        WORD    bcHeight;
        WORD    bcPlanes;
        WORD    bcBitCount;
} BITMAPCOREHEADER, FAR *LPBITMAPCOREHEADER, *PBITMAPCOREHEADER;

typedef struct tagBITMAPINFOHEADER{
        DWORD      biSize;
        LONG       biWidth;
        LONG       biHeight;
        WORD       biPlanes;
        WORD       biBitCount;
        DWORD      biCompression;
        DWORD      biSizeImage;
        LONG       biXPelsPerMeter;
        LONG       biYPelsPerMeter;
        DWORD      biClrUsed;
        DWORD      biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;

关键点2:是计算位图需要内存的大小,跟踪发现,这个大小就是简单biWidth,biHeight,biPlanes之间的运行,并且没有对结构进行检查,如果构造一个比实际大很多的biWidth,biHeight,biPlanes值,这会导致后面的申请堆,拷贝位图数据时,由于长度太大,而产生内存访问错误,这里应该是产生bug的根本原因

关键点3:判断是否4字节对齐,不是则跳崩溃点,重新申请堆,然后拷贝

3.构造产生崩溃的条件
  通过上面3个关键点的分析,可以有两个方案实现崩溃
  一个是构造一个合法0x28大小BITMAPINFOHEADER结构, 然后将iWidth,biHeight,biPlanes
   该成一个很大数,然后把pe里的ico位图向后移一个字节单位,这样可以造成不是4字节的条件
  二个是构造一个合法0xC大小的BITMAPCOREHEADER结构,因为用了这个结构不是4字节对齐的,不需要把pe里的ico位图向后移一个字节单位,然后iWidth,biHeight,biPlanes也改成很大
4.我的pe构造
  这里我选择第一个方案,BITMAPINFOHEADER 的内容如下:
28000000212100002121000001000100000000008002000000000000000000000000000000000000
说明一个下
28000000         //长度 这个固定的
21210000         //iWidth  宽
21210000         //biHeight 高
0100                 //biPlanes 面
0100
00000000
80020000
00000000
00000000
0000
0000
00000000
然后把 pe里的ico位图向后移一个字节单位 就ok了

4. 结果 打开修改的pe文件,explorer崩溃,半天无反应

5.附件说明
  修改了两个文件,一个是exe的(第一种方案),一个ico的文件(第二种方案)

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
2
结果提交时间 43 小时 46 分钟
结果提交时间长度 = 2626 分钟
结果提交次数 = 1
结果提交为可以利用的BUG地点,并构造出PE文件
得分 = [(4320 - 2626)/4320]^1/10 x 1.0 x 100 - (1 -1 ) x 5 = 91.06
2008-11-13 13:55
0
游客
登录 | 注册 方可回帖
返回
//