首页
社区
课程
招聘
[原创][第一阶段◇第四题答案]看雪论坛.腾讯公司2008软件安全竞赛
2008-10-12 19:49 2790

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

2008-10-12 19:49
2790
收藏
点赞0
打赏
分享
最新回复 (4)
雪    币: 503
活跃值: (80)
能力值: (RANK:280 )
在线值:
发帖
回帖
粉丝
mstwugui 6 2008-10-12 19:50
2
0
忘记上传附件了,补上
上传的附件:
雪    币: 503
活跃值: (80)
能力值: (RANK:280 )
在线值:
发帖
回帖
粉丝
mstwugui 6 2008-10-12 20:33
3
0
首先说明一下为什么虽然Explorer.exe本身并没有直接调用StretchDIBits但还是会因为这个BUG受到影响。
Explorer.exe在显示目录时会调用到shell32.dll中的代码,并间接调用到user32.dll中的代码,在user32.dll区间内会设置SEH处理异常,这也是虽然StretchDIBits出错了,但系统并不会直接显示错误消息的原因

StretchDIBits是通过LookupIconIdFromDirectoryEx被调用到的。当参数lpBits的最低两位不都为0时,会跳转到77F2C6BE执行一段额外的处理


.text:77F1B0A6 test byte ptr [ebp+lpBits], 3
.text:77F1B0AA mov [eax+6D0h], edi
.text:77F1B0B0 jnz StretchDIBits_RtlAllocateHeap_77F2C6BE


77F26BE处的代码如下,这段代码的作用是从堆当中分配一块内存,然后将长度为bitmap_file_size,lpBits指向的数据复制到新分配的内存中,虽然目标地址是安全的,但是这里有个问题是lpBits指向的数据未必有bitmap_file_size个字节,也就是说有可能读到非法地址


.text:77F2C6BE StretchDIBits_RtlAllocateHeap_77F2C6BE: ; CODE XREF: StretchDIBits+71
.text:77F2C6BE mov eax, large fs:18h
.text:77F2C6C4 push [ebp+bitmap_file_size]
.text:77F2C6C7 mov eax, [eax+30h]
.text:77F2C6CA push edi
.text:77F2C6CB push dword ptr [eax+18h]
.text:77F2C6CE call ds:RtlAllocateHeap
.text:77F2C6D4 cmp eax, edi
.text:77F2C6D6 mov [ebp+heap_handle], eax
.text:77F2C6D9 jz loc_77F1B0B6
.text:77F2C6DF mov ecx, [ebp+bitmap_file_size]
.text:77F2C6E2 mov esi, [ebp+lpBits]
.text:77F2C6E5 mov edx, ecx
.text:77F2C6E7 shr ecx, 2
.text:77F2C6EA mov edi, eax
.text:77F2C6EC rep movsd
.text:77F2C6EE mov ecx, edx
.text:77F2C6F0 and ecx, 3
.text:77F2C6F3 rep movsb
.text:77F2C6F5 mov esi, [ebp+bmi]
.text:77F2C6F8 mov [ebp+lpBits], eax
.text:77F2C6FB xor edi, edi
.text:77F2C6FD jmp loc_77F1B0B6


现在回过头来在看看bitmap_file_size是怎么计算出来的


.text:77F1B094 mov esi, [ebp+bmi]
.text:77F1B097 push esi
.text:77F1B098 call calc_bitmap_size_77F1ABD7
.text:77F1B09D mov [ebp+bitmap_file_size], eax

...

.text:77F1ABD7 mov edi, edi
.text:77F1ABD9 push ebp
.text:77F1ABDA mov ebp, esp
.text:77F1ABDC mov ecx, [ebp+arg_bmi]
.text:77F1ABDF cmp [ecx+BITMAPINFO.bmiHeader.biSize], 0Ch
.text:77F1ABE2 push esi
.text:77F1ABE3 jz loc_77F32330
.text:77F1ABE9 mov eax, [ecx+BITMAPINFO.bmiHeader.biCompression]
.text:77F1ABEC test eax, eax
.text:77F1ABEE jnz loc_77F1B23D
.text:77F1ABF4 mov eax, [ecx+BITMAPINFO.bmiHeader.biHeight]
.text:77F1ABF7 test eax, eax
.text:77F1ABF9 jl loc_77F3235A
.text:77F1ABFF movzx edx, [ecx+BITMAPINFO.bmiHeader.biPlanes]
.text:77F1AC03 mov esi, eax
.text:77F1AC05 movzx eax, [ecx+BITMAPINFO.bmiHeader.biBitCount]
.text:77F1AC09 imul eax, edx
.text:77F1AC0C imul eax, [ecx+BITMAPINFO.bmiHeader.biWidth]
.text:77F1AC10 add eax, 1Fh
.text:77F1AC13 and eax, 0FFFFFFE0h
.text:77F1AC16 cdq
.text:77F1AC17 push 8
.text:77F1AC19 pop ecx
.text:77F1AC1A idiv ecx
.text:77F1AC1C imul eax, esi
.text:77F1AC1F pop esi
.text:77F1AC20 pop ebp
.text:77F1AC21 retn 4


很明显bitmap_file_size的计算公式是
((((BITMAPINFO.bmiHeader.biBitCount * BITMAPINFO.bmiHeader.biPlanes * BITMAPINFO.bmiHeader.biWidth) + 0x1F) & 0xFFFFFFE0) / 8) * BITMAPINFO.bmiHeader.biHeight

所以要利用这个BUG需要满足两个条件:
1. 参数lpBits的最低两位不都为0。这一点可以通过修改可执行文件图标资源的指针来实现,缺省情况下,资源起始地址被排列对齐过,最低两位是0。这里的处理方法是修改指针+1并将图标头及数据相应的向后移1位
2. bitmap_file_size足够大,这一点可以通过调整BITMAPINFO.bmiHeader.biHeight来完成
雪    币: 503
活跃值: (80)
能力值: (RANK:280 )
在线值:
发帖
回帖
粉丝
mstwugui 6 2008-10-12 20:42
4
0
另外我是用OD+IDA分析这个漏洞的
先IDA看GDI32.DLL,弄明白为什么会出错,然后用OllyDbg attach到Explorer.exe进程上调试
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
Aker 4 2008-11-13 12:16
5
0
结果提交时间 31 小时 50 分钟
结果提交时间长度 = 1910 分钟
结果提交次数 = 1
结果提交为可以利用的BUG地点,并构造出PE文件
得分 = [(4320 - 1910)/4320]^1/10 x 1.0 x 100 - (1 -1 ) x 5 = 94.33
游客
登录 | 注册 方可回帖
返回