漏洞概述
腾讯TT(QQ Traveler)是一款多页面浏览器,具有亲切、友好的用户界面,提供多种皮肤供用户根据个人喜好使用,另外TT更是新增了多项人性化的特色功能,使上网冲浪变的更加轻松自如、省时省力。智能屏蔽一键开通, 最近浏览一键找回,多页面一键打开,浏览记录一键清除,多种皮肤随心变换,多线程高速旋风下载。
腾讯TT在处理地址栏输入的URL时,存在栈溢出漏洞。虽然其处理过程中对URL进行了Unicode编码,但是经过精心的构造,还是可以构造出可见的 Unicode字符串,来控制EIP指令寄存器,并构造支持Unicode的shellcode。这一点已经得到我们的证实!
漏洞分析
构造的URL如下:
其中蠀緑是7DD1 8800这个十六进制的unicode码,这个地址指向Window XP的shell32.dll中的某个JMP ESP指令的地址;
剩下的蓝色部分是一段支持unicode的shellcode,这段shellcode是failwest大侠所作,可以自动加载user32.dll动态链接库,并弹出对话框,显示"failwest"。
因此,如果把上面的url填入腾讯TT的地址栏,并执行了shellcode,即弹出了对话框,那么就可以说明这个漏洞的存在,下面是实验结果的截图:
javascript:resizepic(this) border=0>
因此可以证明这个漏洞的存在,下面我们用ollyDBG来跟踪分析一下:
javascript:resizepic(this) border=0>
0053AE1D |. 8B35 30825600 MOV ESI,DWORD PTR DS:[] ; msvcrt.wcslen
0053AE23 |. 55 PUSH EBP ; /s 指向URL的堆地址
0053AE24 |. FFD6 CALL ESI ; \wcslen 进行长度URL的计算
0053AE26 |. 83C4 04 ADD ESP,4
0053AE29 |. 85C0 TEST EAX,EAX ;EAX此时是URL的长度
0053AE2B |. 0F84 3B010000 JE TTravele.0053AF6C ;如果URL的长度为0,则退出
0053AE31 |. 68 D0CA5A00 PUSH TTravele.005ACAD0 ; /wstr2 = "about:blank"
0053AE36 |. 55 PUSH EBP ; |wstr1
0053AE37 |. FF15 38825600 CALL DWORD PTR DS:[] ; \_wcsicmp 让URL与"about:blank"比较
0053AE3D |. 83C4 08 ADD ESP,8
0053AE40 |. 85C0 TEST EAX,EAX ;如果URL和"about:blank"相同
0053AE42 |. 0F84 24010000 JE TTravele.0053AF6C ;就退出
0053AE48 |. A1 E4125C00 MOV EAX,DWORD PTR DS:[5C12E4]
0053AE4D |. 33DB XOR EBX,EBX
0053AE4F |. 85C0 TEST EAX,EAX
0053AE51 |. 76 32 JBE SHORT TTravele.0053AE85 ;跳0053AE85
0053AE53 |. BF 00705B00 MOV EDI,TTravele.005B7000
0053AE58 |> 55 /PUSH EBP ; /wstr2
0053AE59 |. 57 |PUSH EDI ; |wstr1
0053AE5A |. FF15 38825600 |CALL DWORD PTR DS:[] ; \_wcsicmp
0053AE60 |. 83C4 08 |ADD ESP,8
0053AE63 |. 85C0 |TEST EAX,EAX
0053AE65 |. 74 12 |JE SHORT TTravele.0053AE79
0053AE67 |. A1 E4125C00 |MOV EAX,DWORD PTR DS:[5C12E4]
0053AE6C |. 43 |INC EBX
0053AE6D |. 81C7 4A100000 |ADD EDI,104A
0053AE73 |. 3BD8 |CMP EBX,EAX
0053AE75 |.^72 E1 \JB SHORT TTravele.0053AE58
0053AE77 |. EB 0C JMP SHORT TTravele.0053AE85
0053AE79 |> 3B1D E4125C00 CMP EBX,DWORD PTR DS:[5C12E4]
0053AE7F |. 0F82 E7000000 JB TTravele.0053AF6C
0053AE85 |> 8B1D 2C825600 MOV EBX,DWORD PTR DS:[] ; msvcrt.wcscpy
0053AE8B |. 8D4424 10 LEA EAX,DWORD PTR SS:[ESP+10]
0053AE8F |. 55 PUSH EBP ; /src指向URL的堆地址
0053AE90 |. 50 PUSH EAX ; |dest指向栈帧中的一个栈地址
0053AE91 |. FFD3 CALL EBX ; \wcscpy 复制URL到栈中
0053AE93 |. 8D4C24 18 LEA ECX,DWORD PTR SS:[ESP+18]
0053AE97 |. 51 PUSH ECX
0053AE98 |. FFD6 CALL ESI
通过上面的分析,可以看出程序仅判断了地址栏输入的URL的长度是否为0,但是没有对URL长度的上限进行判断。这是导致最后栈溢出的根本原因!
那么我们只要算好地址,正好淹没了函数的返回地址即可,并在返回地址后紧跟着我们编制好的支持unicode的shellcode,也就是说我们玩的是JMP ESP这种经典的栈溢