Unpacking RIG EK shellcode using ESIL

Nick Rafter
3 min readApr 23, 2017

--

I was taking a look at the Silverlight 2016–0034 exploit used last year in the RIG exploit kit to get an idea of how these guys were using variables in the Silverlight object (sample from Kaffeine). In the fiddler archive you got the xap file and the landing page, but it’s a little obfuscated, so I pretty printed the page up in Chrome and hit a breakpoint on what looked like a reasonable return value and it happened to be the decrypted function that loads the application object to the page.

Gist to the the decoded variable included here

The variable has a param called shell32 probably containing the shellcode, so I dropped it into https://defuse.ca/online-x86-assembler.htm to take a look at the disassembly real quick.

Looks like a decoder for an encoded shellcode based on the initial bytes and the jump/call move, specifically a countdown xor decoder. I could have done a couple things but I’ve looking at radare2 and ESIL and a couple articles that came out covering it for unpacking (https://blog.xpnsec.com/radare2-using-emulation-to-unpack-metasploit-encoders/ and http://radare.today/posts/unpacking-shikata-ga-nai-by-scripting-radare2/) so I figured it’d be a good time to learn how to use it to automate some of the stuff I want to do.

Just to cover what it looks like the decoder is doing, the first instruction pushes all registers onto the stack to save the current state of the CPU (probably for restoring execution), it jumps to 0x4 and then calls back to 0x3 to gain the current instruction pointer making this position independent code, it stores 0x4d1 as a counter in ecx and starts counting down, xoring every byte starting at the end with 0x19 and counting down. When ecx equals 0, test ecx, ecx sets the zero flag which allows you to continue past the jne, and jmps to the start of the freshly decoded shellcode.

Because of the way I ripped the shellcode out of the variable and dump it into a binary I know exactly where the decoded stuff is, I could easily just load it into r2pipe and say continue to that offset using aecu. 0x19 is 25 so aecu 25 should get us there. There does seem to be something worth investigating in what exactly is going on with the decoded, because it’s 1564 bytes in length but the decoder only operates on 1233 bytes.

node.js script to unpack this sample

While doing some research into getting ESIL working I found this script that uses unicorn emulator instead (https://github.com/mothran/unicorn-decoder) and it runs but it doesn’t seem to unpack my sample correctly. Maybe someone else’ll have some luck with it.

--

--