Nytro Posted December 8, 2016 Report Posted December 8, 2016 woumn December 7, 2016 ROP & Heap Spray for a Reverse Shell in IE8 Introduction/Motivation This exploit is aimed at Internet Explorer 8 running on Windows 7. We are chiefly concerned with the use of a plugin which uses the Java Network Launch Protocol, which has an overflow vulnerability. In order to do this, we will be using Heaplib.js alongside developing our own ROP chain to disable DEP, and hopefully gaining control of the victim machine. Did it Work? My exploit does not currently work. I know that I hit the LEAVE; instruction: Which I further confirmed with disassembly. The error looks like I don’t have the rights to access this DLL (which is wrong), or perhaps that there is a violation of the page’s read-write/execute privileges. I investigated further, and sure enough after running !vprot 7c3411a4 which shows the privileges I’m interested in: Sure enough! I should be able to execute this… This is where I called it quits. I hope that this write-up is as accurate as I can pretend to be. I’m actually pretty interested to see where I went wrong–I know there will be a lot of places. Please continue reading down below at “Unanswered Questions” for more discussion. Developing the Exploit Structuring the Malicious Inputs The Java Network Launch Protocol (JNLP) enables applications to be launched on a client desktop using resources which are hosted on a remote server. It turns out the JNLP has a buffer overflow vulnerability (doesn’t everything now a days). The structure of the request sent doesn’t matter too much to us, although, we’re mainly concerned with overflowing the docbase parameter passed to JNLP. Additionally, we’ll be using Javascript to enable this exploit for a couple reasons. First, we have use Javascript to directly influence the DOM. The DOM is a Document Object Model which is fancy words for the page that is shown on the screen. It renders the HTML + CSS and Javascript, and also has access to Browser “Syscalls” like QuickTime, Flash, etc. This makes it very convenient to just practice the exploit within the confines of the Browser. This exploit uses a lot of techniques we’ve seen already with over overflow vulnerabilities, so I won’t go into detail about those. But recognize that when we’ve an overflow vulnerability, that means we can control EIP and the memory at ESP. Yet, we’re left with the problem of DEP–the stack is unable to execute.Because of the DEP protection, we are forced to use ROP (Return Oriented Programming) to get around that. We’ve briefly used ROP techniques in other exploits before–namely, when we found the addresses of say jump 4 or other things. We find places that do have execution privileges, and then just call the address of the OP codes we want. The challenge here is that we need more than just one or two instructions. In general, ROP chains can get to be very large, and on top of that, we have shellcode we also want to insert. The worry is that the stack may not have enough space for all of our payload, which leaves us with the heap–and the challenges that come along with that. The first challenge with the heap is locating anything we stick in there. Luckily, this problem is alleviated with the help of the Heaplib.js, which handles spraying the heap and can guarantee aligned addresses. Heap spray is the notion of putting a bunch of blocks of memory into the heap, so that we have a chance of jumping into the part we need. It looks something like: It turns out that the Heaplib.js library provides very accurate heap spraying, and the shellcode is present at every 2000 bytes (i.e. 0020, 2020, 4020, etc.) The second problem we face is converting the heap into the stack. This is somewhat counter intuitive at first, but trust me–after this and the next problem, you’ll understand why we need to do this. Many call this problem the “Stack Flip [Pivot]” because we will see that in order to convince the stack that it is the heap, we simply need to swap ESP with a value that is pointing to our heap (hopefully where we placed the shellcode with the heap spray). This is usually achieved by flipping EAX with the command XCHNG EAX, ESP; RET which is in itself ROP gadget. However, we don’t control EAX, but we do control EBP, which is also able to do the stack flip with the instructions LEAVE; RET. I learned this after passing A’s through, and observing which registers were overwritten–EIP and EBP were the only two. The primary reason we go through this trouble is because all the RET statements will try to return to ESP, so we need ESP to be pointing to our data located on the heap. The next issue we have to tackle is how to execute the shellcode that we placed in the heap. Well, remember, after executing the stack flip, the heap is now the “stack”, or at least it appears that way to a process. How can we execute the shellcode? Well, unfortunately, Windows uses DEP (Data Execution Prevention), which says that certain memory locations are either read/writable or just executable. This is in place to prevent exactly what we want to do–execute these instructions that are stored on the stack. It turns out that there is a way around this. In Windows, there is a function located in the Kernel32.dll called VirtualProtect, which is used to change the protection of a region in memory. This is perfect for us because if we can call this function on the memory space of our shellcode, then we can change the protection from read/write to executable and then continue on executing the shellcode. It turns out that Kernel32.dll is ASLR’ed, but we can handle this later in the “Determining the Parameters Used” section. Just realize that we have a means of changing our privileges–and of course this will be achieved with another ROP-chain. Determining the Parameters Used The first thing I deciding to do was figure out what parameters we will pass into the VirtualProtect function call. This was straight forward, because Alex gave us parameters we can use that will work because of the nature of the heap spray: These values will be what we place on the stack to be passed into the VirtualProtect function call. Pretty straight forward. Next, I went after the address to VirtualProtect. To do this, I used WINdbg to explore the MSVCR71.DLL that was not ASLR’d. We can run the commands: dh msvcr71 to dumb the header which gives us an address table for the VirtualProtect function. Next, we call: dps msvcr71+3a000 which is given in the table prior to find the VirtualProtect stub (you may need to type dps more than once). And finally, that gives us an address, which we confirm with u poi(7c37a140) to be the address we’re after. Incidentally, this address is listed on the web, and was also given to us on the slides. The next thing we’re concerned about is ensuring the stack pivot goes as planned. I mentioned that it depends on which register you have access to in that process. Simply use the WINdbg to attach to the IE process, pass it enough A’s to overflow the buffer (200 in our case) and observe which register is overflowed. After doing this, EIP and EBP are both overflowed with A’s, and EAX is left untouched. That means we need to use the LEAVE; RET gadget. It’s also important to mention that all ROP gadget searching was done on the MSVCR71.dll because not only is it unprotected by ASLR, but Alex also said to use this one specifically. Generating the Malicious Input So though out this section, I will be referring to the following diagram for which specific ROP-gadget we’re searching for: Briefly, a ROP gadget is simply a memory address in some shared memory (in our case the MSVCR71.DLL) that we can reference to do some action, and return. There are different tools that can be used to search for these addresses, because we need granularity over what exact instructions we want to issue. Alex suggested two different options; the first is something called Skyrack and the second was msfpescan with a regex. Both of these tools are bad for what we want to do–at least I had a very bad time with them. Skyrack is a pain to even get started, and then you can only search for individual instructions, and we’re basically only concerned with compound instructions (i.e. POP EAX; RET in one address). I fumbled with these for far too long before turning to Google and finding an open source tool called Ropper. So, I used ropper. It was very easy to install (follow the github) and also very easy to search for compound instructions–incidentally it also returns all instances matching your query, instead of just one. The command to use is: ropper --file ~/path/to/msvcr71.dll --search "INSTRUCTION; ret" where INSTRUCTION is the instruction you want to search for. Here is the list of instructions we need to set up the stack I have shown above: 1. POP EAX, RET; 2. MOV EAX, DWORD PTR [EAX]; RET; 3. CALL EAX; RET; 4. POP EAX; POP EDI; POP ESI; POP EBX; POP EBP; RET; The first three can be easy found with Ropper. The final instruction is a bit more difficult. For this one, I found a source called Fuzzysecurity which does a similar exploit using a ROP-chain for IE8. So naturally, I tried to follow his example, but he decided to use a well-known and published generic ROP-chain that I decided against using (published by corelanc0d3r ). However, I did notice that he had the pop’s and return I was looking for–additionally, he had listed a text file of ROP gadgets hosted here, that one could search through. The only caveat here is that the gadget used contains five POP instructions, and we only need four considering the call to VirtualProtect only has four parameters. Well, that’s no problem, I can just add a dummy value to the end that will be popped off later! Next, that leaves the ROP-gadget for the stack pivot. As I explained above, we don’t have access to EAX–we know that after checking WINdbg after overflowing the buffer, and noticing that only EIP and EBP were overwritten. That leaves us with the ROP-gadget for pivoting the stack when we control EBP which is just LEAVE; RET. I was actually able to use Skyrack for this if only because when searching for the LEAVE instruction, there’s a very high chance it’s immediately followed by a RET. I verified this using WINdbg and disassembling the memory at the address. The reason we have the POP (x5); RET included is because of the nature of ROP-chains. Consider the following: Basically, we’re faking a stack frame, and when we return from the call to VirtualProtect. That means we need to POP all of the parameters to VirtualProtect and then after those POP’s we return to the address next listed on the stack, which is our pop’s. That means when we return from VirtualProtect, we return to the address of the POP(x5); RET;, which removes the parameters, and returns to shellcode. I should mention that originally, I had intended to use my own hand generated ROP-chain to demonstrate my “understanding” of what should be happening, but it didn’t work (big surprise!). So I decided to take Chandan’s advice and use the auto-generated ROP-chain by Mona.py–incidentally this is the same ROP-chain I linked to earlier. Here, I will also address some “phantom” addresses that have been suggested to me. During class, Alex gave us some “hints” regarding the structure of our exploit. Firstly, he said that our buffer overflow should contain the stack pivot (later I decided it also needs the address of our ROP-chain/shellcode stuff because of the nature of the LEAVE; command). Next, we received an ambiguous hint that there should be an address placed before our ROP-chain for either: 1) byte alignment or 2) it may be something else–I decided to just try the address of the shellcode promised with Heaplib.js because why not? I have no idea what else should be there! And the final hint was that after our ROP-chain and before the shellcode, we should include the “hard coded” address of our shellcode. This one especially doesn’t make sense to me because if it is proceeding the ROP-chain, we should be able to just plop the shellcode right there, and after our call to VirtualProtect finishes, then we can just immediately begin executing the shell. So basically, for every time I needed the “address of the shellcode” I used 0x0a0a2020 . Finally, we’re left with the shellcode. This is old news by now, but I used Metasploit to generate my shellcode. The command is: generate -t js_be which gives us shellcode that can be pasted into a Javscript function. An important note is to ensure that the shellcode is divisible by 4 so that it lines up correctly. Mine was 324 bytes long, which is divisible by 4, so there wasn’t anything I needed to do with it. Unanswered Questions There are multiple questions I had regarding this assignment that I wasn’t quiet able to figure out. Below, I’ll detail my concerns and the conclusions I came to in an attempt to convince those reading that at least some thought was put into this. I’m not entirely sure what address to overwrite EIP with during the initial buffer overflow. I know in the slides and in class, we discussed just any aligned address on the heap because we would either hit NOPs or our shellcode. But, I’m not sure how that works because the entire point of this exploit was to get the code we have on the heap to execute. That means that if we hit something like the NOPs or the beginning of our shellcode (basically everything excluding the pivot), we get stuck because we haven’t moved ESP to where we are or changed the protections. After having another class with Alex, he said to overwrite EIP with our stack pivot, so that’s what I wound up doing. I considered moving the stack pivot address to be what we initially overflow into EIP, but that doesn’t make sense to me because the op codes that happen for the stack pivot (LEAVE; RET) simply move the ESP into EBP, but if we’re still on the stack, we won’t be replacing it with an address on the heap. So I ended up addressing this by overflowing the initial buffer with the address of the shellcode and also the address of the stack pivot (as pairs), because I knew that the pivot would be landing in EIP. This was later confirmed after looking through WINdbg. Alex basically told us to insert an address before our ROP-chain and immediately following it. The first one was ambiguous as to what its purpose was–I still don’t really know. Nothing I’ve read indicates this is necessary. Perhaps it is only for alignment? The second address after the ROP-chain is supposed to be the “hard coded” address to our shellcode. Again, I don’t understand why this is necessary instead of just placing the shellcode immediately following, but at this point, I’m blindly taking Alex’s suggestions. Why am I unable to execute the LEAVE; instruction? My primary thought is there there is an issue with EBP or something not pointing to memory I should be. I’m not entire sure if that’s what is happening, nor how I could fix it! That’s all I can think of immediately. Anyway, I’m happy with what I’ve learned with this project, even if I wasn’t able to get a reverse shell. Besides, everyone I talked to couldn’t either. I wish I knew more answers to these questions–it’s very unsatisfying being so confused! Unfortunately, I ended my quest at this error. Due to time constraints, a final, and simply other classes–even with a day extension–I reached my wit’s end, and without simply asking for a code review with Chandan, I’m not sure I could figure this out on my own. And I think that’s okay–we learn from our failures, and just because it’s called a failure, that doesn’t mean I should quit! Sursa: https://woumn.wordpress.com/2016/12/07/rop-heap-spray-for-a-reverse-shell-in-ie8/ Quote