Poison Ivy string decryption

This is short and quick blog to share with you, as promised, the IDAPython script used to decrypt the strings in the Poison Ivy sample discussed in our previous blog post [1].

Before we can start decrypting the strings, we first need to locate the string decoding function. Looking through Poison Ivy’s code, we can see a function that appears to take three parameters as input; one being a key and another being an offset to some bytes.

If we look at Xrefs in IDA for this function we will see quite a few references.

Looking at some of these references, we can see the same type of arguments passed to the function each time it’s called. Moreover, by looking inside the function you can see what looks like a decryption loop.

This is looking more and more like our string decryption function.

To make sure, we can check using our debugger and breakpoint right after the loop. By checking the buffer that gets filled in the loop – in this case the pointer to the start of the buffer is in ‘rbx’ – we can see the string decrypted.

The string decryption function uses a double word key value in ‘r8d’ to decrypt the buffer supplied in ‘rdx’. The loop rotates through each byte in the key, xor-ing the least significant byte with a byte in the supplied buffer.

In each iteration, the key also gets the encrypted byte added to it so the key changes in each loop.

Using the IDAPython script [2] we can now see all the decrypted strings and add a comment next to each encrypted value. So, we get something like the below:

Looking at some of the decrypted strings, we can see it looking for pipes like \\.\RegMon\\.\FileMon\\.\ProcmonDebugLogger and \\.\NTICE.

You can probably guess what the first three are for. The last one is for SoftICE, a kernel debugger that used to be quite popular back in the day.

We can also see strings like Wireshark-is-running-{9CA78EEA-EA4D-4490-9240-FC01FCEF464B}WinDbgFrameClass and ACPUASM (Ollydbg window class name detection). These are all to check for debugging and analysis tools that would be running while the sample is. If they are, the sample exits. You can overcome any of these checks by patching the strings in memory so the checks would fail. 

There is also the string IsDebuggerPresent which you can bypass the check for by either patching the return value from the API or, if you are using Ollydbg, using an anti-anti-debugging plugin such as StrongOD.

Happy reversing!


[1] https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2017/august/analysing-a-recent-poison-ivy-sample/

[2] https://github.com/nccgroup/Cyber-Defence/blob/master/Scripts/poison_ivy_string_decrypt.py

First :  07 September 2017

Written by:  Ahmed Zaki