In this post I will be going thru the multiple ways that they use to encode 3 pages in the pcap. I will use the pacp available from Zerophage @Zerophage1337 located here https://zerophagemalware.com/2017/04/20/magnitude-ek-urls-from-14-20-april/
We will start with the initial get request at packet 178.
Notice anything strange about the “Full request URI: “ It is doubled up. Make note because we will need this later.
Next we get our first encoded page in packet 180.
When we first see this it looks like a jumbled mess.
After formatting by hand it is a little more clear on what it is doing.
In an older version they had “toString” set as a variable but here they are using Unicode encoding “toS\u0074r\u0069\u006e\u0067” so lets fix that.
Next lets take a closer look at the first function.
So what does this do? A quick look would make it appear that it is using the value left of the comma on each side of the operator to get a Boolean result and the larger number right of the comma gets used in the “toString” function. In other scripts I’ve looked at if the result is true then it will use the left value, if false then it will use the right value.
In the “toString” function it really only accepts 1 parameter so the second value appears to be ignored.
When we see a function like this “ (1294399205).toString(36) “ this would be converting Base 10 to Base 36.
I’ve noticed that so far that the number on the right is always used so I don’t bother to do the math. It is still only 2 possibilities anyway. So the result of decoding this is.
So lets go thru and do all of the decoding and replacements.
Now that is a little better but we still have some encoded parameters.
So how does this work ? This is where that note comes into play from above. We take the full path “ http://fx4you%5B.%5Dnet/” (not including the brackets.) and tack on the string “m6t35”.
So the numbers in the parentheses is the index value from the combined string.
So lets do the replacements on those.
Now that we have that complete, that just leaves the parameter of “dgaO0”. The values generated from this is a form of a Checksum calculated by adding the char code values of each letter for the screen property and then Xor’ing that result by a number and tacking on “y” and then the real value of the property and tacking on a “t”. It will continue for all of the property values.
In each of the pcaps I’ve looked at the Xor value has been different. So that number will change.
When all of that is combined we end up with the full get request in packet 182.
So now we are at packet 184 lets take a closer look at the formatted page.
This decoding is similar to the last one but as you can see something strange is going on here. They are using a value from the screen info and adding something else.
After decoding the first part now we have this.
Now if we look closer at the function “n57TV13J” we will see that it takes as input 2 number values and the left will add the value of screen height to it and the right will subtract the value of “systemXDPI” from it.
We can reverse calculate what these values are or pull them from the last get request.
If we set it up like a chart then we can see what we need.
The indexed values are the values from the get request. The bottom list is the calculated parameter values. We can just look and see that for “Height” we get a value of 632 for the checksum and 1024 for the real screen height. We get 987 for the checksum and 96 for the real value.
And to calculate the result.
Now lets go thru and do the rest of them. Here is what we end up with.
Now it looks like we still have several Index values to replace using the URL that led us here.
Now lets do the index replacements and see what we end up with.
As we can see here it is checking for Kaspersky Virtual keyboard and if not found it will make the call to the next Url. I assume it will just quit if it does or throw an error, I can not find a reference to the value in the catch statement.
In packet 186 we see the get request and in packet 200 we see the obfuscated page we will work with.
This is a very busy page. It used the base decoding like in the first section, but it also uses Hex, Integer, and Octal Char codes to build strings.
I’ll save everyone the step by step on this one as it is a long drawn out process to do it by hand.
After decoding and formatting the first section and decoding the variable array for “lW” we get this.
All of the “lW” items highlighted get replaced by the index value, so lets do that. (Note: commented section with the decoded array.)
Even after decoding and doing the replacements we still have some math functions and other encoding to tend with. We have multiple layers to hide what is going on but we can still get and idea of what is happening even with the bad formatting that yet needs to be cleaned up.
The highlighted section shows a call to download a scriptlet file.
Here further down we can see 2 possible execute calls.
There is still a lot of formatting and possible junk/unused code that could be removed but we should have enough to tell what this is doing and it most likely would not run in this state either.
The web request from above is found in packet 329 and the response in in packet 340.
After formatting this packet here is what we have for the downloaded scriptlet file.
Even with the slight obfuscation here we can see that it will make a call out to that URL download and run the file.
And if we look up that Class ID we find this.
What do you know borrowed malware.
Well that’s as far as we are going on this one.
Thanks for reading if you got this far.