能力值:
(RANK:280 )
|
-
-
2 楼
忘记上传附件了,补上
|
能力值:
(RANK:280 )
|
-
-
3 楼
首先说明一下为什么虽然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来完成
|
能力值:
(RANK:280 )
|
-
-
4 楼
另外我是用OD+IDA分析这个漏洞的
先IDA看GDI32.DLL,弄明白为什么会出错,然后用OllyDbg attach到Explorer.exe进程上调试
|
能力值:
(RANK:170 )
|
-
-
5 楼
结果提交时间 31 小时 50 分钟
结果提交时间长度 = 1910 分钟
结果提交次数 = 1
结果提交为可以利用的BUG地点,并构造出PE文件
得分 = [(4320 - 1910)/4320]^1/10 x 1.0 x 100 - (1 -1 ) x 5 = 94.33
|
|
|