类别:堆溢出shell
描述:此漏洞存在于KingView6.53软件的HistorySvr.exe进程中,这个软件服务程序在TCP 777端口监听时收到一个超长请求,致使堆缓冲区溢出从而执行任何代码。windows
参考资料:《Metasploit魔鬼训练营》p225-p232安全
下载此漏洞的利用代码:http://downloads.securityfocus.com/vulnerabilities/exploits/45727.rb网络
发现这个利用代码中没有针对windows 2003的target,因此直接攻击不能成功数据结构
可是查看靶机,会发现HistorySvr.exe这个进程已经消失了(若是没消失,多试几回exploit)。这说明应该是成功溢出了,只是没有顺利执行Shellcode。ide
为了解决这个问题,咱们能够经过OllyDbg在系统默认的异常处理函数运行前,进入程序异常时的现场。函数
在OllyDbg中开启”Just-in-time debugging“spa
重启HistorySvr.exe后,再次攻击,OllyDbg截获异常。发现此时eax寄存器的值正式源代码中对应target的Ret值!操作系统
再观察中断处的代码插件
经过view->log能够看到中断的地址和缘由
这说明异常发生时这一块内存空间并无被分配使用,所以触发了异常。
总的来讲,此次攻击咱们成功地用Ret值覆盖了eax寄存器,可是须要将Ret值改成针对windows 2003的值才能成功将程序劫持到Shellcode处。因此接下来应该寻找Shellcode在内存中的位置。
咱们在攻击模块代码中增长一个target,Ret值先随便设一个:
52 [ 'Windows 2003 SP0 EN', {'Ret' => 0x00A1FB84} ], #New target
--snip--
85 elsif target.name =~ /2003 SP0/ 86 87 #sploit << make_nops(1024) 88 sploit << make_nops(1020) 89 sploit << "ABAC" #做为查找Shellcode的特殊标记 90 sploit << payload.encoded 91 sploit << "\x44"*(31752-payload.encoded.length) 92 sploit << [target.ret].pack('V')
在msfconsole中reload这个模块,靶机开启HistorySvr.exe,设置target为2后,再次攻击。
靶机OllyDbg截获异常,经过在内存中查找ASCII字符“ABAC”,成功找到咱们Shellcode的地址。
可知shellcode地址位于0x00CD04C4
Ret地址改成0x00CD04B4(0x00CD04C0-0xC)
而在0x00CD04C0地址上的内存应是Shellcode的地址,代码中"ABAC"的位置相应改成"\xC4\x04\xCD\x00"。
修改源代码后,从新载入模块并exploit,试了3次,终于成功!
****************************************************************************************************************************
KingView堆溢出安全漏洞原理分析
因为操做系统对堆内存的管理在调试态和非调试态存在区别,因此不一样于前面的攻击,此次先用OllyDbg附加HistorySvr.exe,同时启用HideOD插件,而后让程序运行起来,并在WSOCK32.dll模块的接收数据recv函数处下断点。
为了方便调试,将攻击模块代码中的 sploit << "\xC4\x04\xCD\x00" 改成“ABCC”。
而后进行攻击。
OllyDbg加载程序在接受网络数据时就会中断,用“ctrl+f9”执行到返回,来到nettrans.dll模块。
这段代码的做用至关于 memcpy(destbuf, sourcebuf, size)。
就是将接收到的网络数据保存在buf中,而后按接收的长度,将buf 的数据复制到另一段缓冲区中。
因此咱们要获得的是这3个参数,destbuf, sourcebuf, size。
在0x00322A9E和0x00332AB9处下断点,从攻击机进行exploit
(可是从metasploit攻击后,在靶机OllyDbg上须要迅速按f9才能屡次在nettrans.dll模块和wsock32.dll模块中跳转。慢的话按两三次f9就不动了。这样就不够时间观察了。.我猜多是没被接收的数据包超时就被丢弃了吧。。个人解决办法就是经过录像软件来分析)
①攻击后程序会停在wsock32.recv函数的入口处,此时观察栈能够获得sourcebuf为0X00CCC0C4:
②按f9后程序来到nettrans模块的0x00332A9E处,此时eax寄存器为复制长度size。
前两次是,最后一次是
。
③停在0x00322AB9时edi的值为destbuf的地址
第一次为;第二次为
;第三次次为
程序分3次一共接收了0x800C字节数据。
找到源缓冲区起始地址以前的内容
这里块首的0x180B是堆空间大小。
结合这些咱们能够算出目的缓冲区的最大大小为0x8000
也就是说而第三次的起始地址0x00CD80C4以后已是超出目的缓冲区的边界,形成了溢出!
最后一次复制前时内存0x00CD80C4地址处的内容为
咱们覆盖掉的函数地址是本来为 18 84 33 00 那里。意味着原来应该执行的是[0x00338418+C]处的代码。
这里有几个疑问:
一、不知道怎么肯定堆块块首。块首与buffer地址相隔0x2c,不知道这0x2c怎么算的;
二、按书上说的,从蓝色的地方开始是堆块的数据部分起始地址,其中的数据和书上类似但不彻底同样。我不清除这些蓝色部分的数据表明的是什么。
最后用书上的话来总结吧:
KingView堆溢出漏洞能够被成功利用的缘由,是程序在分配堆块后在块尾维持了一个数据结构,而其中包括一个函数指针地址(也就是“ABCC”所在的位置),程序以后会根据这个地址去执行相应的函数,渗透利用代码经过堆溢出漏洞覆盖这个函数指针,使Shellcode得以执行。
调试的时候用ABCC去覆盖了函数指针地址,因此最后会显示错误: