This post is based on the blog post by FireEye located Here.
I was given a private .saz to look at by someone else that gave me the entire infection chain.
In this post I will only be doing 2 levels of decoding..
While looking at this saz file, FireEye published the post above. This gave me a better idea of what to expect as I was pulling these files apart.
What I will be showing here is a more lower level on how the script is decoding the first 2 levels. After that it requires that the server for the second level that it calls out to, to still be online and available to get the next level to download.
This sample is after it has already fingerprinted the system and sent the encoded data to the server.
At the end of the FireEye post there is a list of several hashes of files. We will be using “229f69a0b21740c91bfd0174e63cc0b7be3a7f5f9d6819cc3bdf3cf117ada9ff” which can be found on Hybrid Analysis Here , Virus Total Here , (I re-uploaded to) VirusBay Here in case those that want to follow along only have an account there.
Now that we have our sample lets take a look.
That is pretty dense so lets make a copy and then make it “Pretty”
That is a little better but it is still highly obfuscated. It appears to have a hex string at the bottom that gets reassembled and is using a crazy method of string replacement / rebuilding. The clean won’t get output if you just walk thru the code in the debugger. So we have to figure out what each section decodes to and then do the string replacements by hand for our first script..
For some reason which I don’t fully understand yet it will always choose the last char in that array. So the next value to tack on is “i”. Now this would be a pain to go thru by hand so what else can we do ?
If we look close, they are in brackets and we can decode each section using some simple html code.
First part looks like this.
Second part of the line.
So now it goes from the long crazy string to this decoded version.
So lets use this method and decode the rest of the lines and see what we have.
When using the above decoding method to extract the decoded string be sure to mind the matching pairs for the square brackets. If you add any extra code including the string like highlighted in the green you may end up with other results.
Also note that this would most probably not run after we do the replacements but does help to understand what it is doing.
Lets take a closer look at the decoding function. By the time we get here the hex string at the bottom has already been reassembled and converted to a byte array and assigned to the the array variable of “ kijuqmoha”
So what is this thing actually doing ?
It starts with the last char of the key then
Xor’s the byte array with that value. Next it adds 1 more char to the left then Xor’s the bytes from the last output by these to Chars.
It will continue on until is uses all of the chars for the key.
I wrote a tool to help visualize the output. This came about from a conversation between Lee Holmes and myself. He has a post Here
In this tool I started with the full key then reduced to the last char. The decode starts with 1 char and increases to the full key. That is the way I made this decoder.
In this test we can see we can start with the full key or the last char as long as we add/remove the same direction.
Next I wrote another tool to test the same idea but reducing to first char instead of the last.
As you can imagine, changing sides using the same data and key will give different output.
Back to decoding the first level hex values.
We input the cleaned up hex string and the key of “c~J=e~~kk” we get get back this.
We can also step thru the code in the web browser debugger until it outputs the decoded value in a anonymous function then extracting it from there.
If we look at the bottom of the code after we pretty it up we see this.
This second level will use the same decoding function to decode the hex array at the bottom but with a twist. It will input the original function code as a string and the current running code as a string and a “Seed Key” as a decimal array thru the function “encKey” to to generate a new Key to finally decode the hex array at the bottom.
If we look at this part of the code we see if is sending the 2 pieces of code into the key builder .
One other thing we notice here is in the caller function it is tacking on something else to the Caller code.
If we step thru the code in IE debugger we end up with this “MozillacallerFunctionText” getting tacked onto the original code that gets run.
After messing with this for a few days and not getting anywhere I started to wonder if this was supposed to fail with the catch block.
If we look at this comment in the code below it appears as if this code is supposed to be run by Windows script host rather than the browser scripting engine.
I developed this tool to try and generate the key needed for the decoding tool.
Stepping thru the code in the browser debugger can give us an idea of what needs to be run thru the function to output the proper decoding key.
Our first try using the added string will produce this.
Testing that key in the decoder failed to properly decode the hex string at the end.
Back to the drawing board on what to input. After failing several more times I started to look for a way to brute force the key. If I understand the math correctly it would be 256 to the 10th power possible combinations to find a key. That is way to many to try them all.
The way this is set up you can not do a normal plain text search to find the Xor Key.
I wrote another tool to test brute forcing a 10 Char key using a know plaintext search which worked very well on a normal 1 level Xored data.
Do to the nature of the way the function works in this case the key would be thoroughly diffused and you can not look for a string the same way as a normal 1 level Xor.
The decoding is tied to the way the key gets cut up and used in the rounds. So even if you had a know plain text and know encoded text I have not found a way to run it backwards to get the key.(yet)
So that leaves us with figuring out what has to go into the key builder.
This code is similar to a hashing function in that if you change 1 item it can drastically change the output.
After lots of trial and error and dumping what gets output by the debugger we end up with this for the original calling input.
And for the current running code we use this.
You may notice that both inputs do not have the hex arrays in the strings.
We also need the Seed Key “var key = [181, 205, 244, 42, 206, 126, 77, 88, 31, 20];”
We are finally able to generate a proper key and use that to decode to the next level.
There is nothing like seeing the proper output after so many hours of researching.
Here is what it looks like pretty.
If we take a closer look at the top there are 2 values that are encoded and use the function “geturl” to decode.
All this function does is go thru the string and if the index mod 2 = 1 then that char gets saved to the output. After that it is a simple reverse string to get the final string.
In the original saz file I was looking at, the early scripts were using this same function for decoding some values.
Since the server was down for this URL that was as far as I could go on decoding the levels and have not gotten anymore recent samples to try and go further.
That’s it for this one. I hope you learned something like I did.
If I left any questions unanswered catch me on Twitter @Ledtech3
Thanks for reading.