I saw this blog post by the smart guys over at Sucuri and thought that it was just another URL redirection script hding behind escaped characters but it turned out to be better than that.
Here's what the script looks like in its original form:
When you unescape it, it looks like this. Notice that there's two sections. The self-executing function at the top and another at the bottom. The function at the top deobfuscates the blob of characters in the middle and makes an array out of it. The bottom function takes values from a resulting array to redirect the user to the drive-by site.
In the screenshot above I put an arrow where the main deobfuscation takes place. It reads in the blob of characters, two at a time, and does a base30 decode then subtracts a value from an array. The array is made up of four characters which is the length of the script itself, 1,867 characters. The algorithm subtracts the ASCII representation of those four numbers.
What this means is that if you change anything in the script, the script will break and won't properly decode the blob.
Let's deobfuscate this script dynamically and statically.
There are several ways to deob this dynamically but here's the most straightforward and easiest I think. In this screenshot I add an "alert(LCWEHH);" so I can see the result of the deobfuscation.
When I run it, I get garbage because I modified the length of the script.
Let me try this again. Since the deobfuscation routine is based on the length of the script I need to subtract what I'm adding in. So "alert(LCWEHH);" is 14 characters.
I need to find a place in the script, after it's done with the deobfuscation, where I can subtract 14 characters to keep the length the same. Here's something I can replace (highlighted in red). I can remove the "(LCWEHH[2-4+1+3])" without causing an error.
If you notice this string is 17 characters so I need to add 3 characters back to the script. So I just pad my alert call with three spaces. Here's the final script:
When I run it, I get the deobfuscated results:
Now I can build the redirection function using the values from this array so it looks like this:
Now let's do the same thing statically. For this I'll use Converter.
Fire it up and paste in the blob of characters from the middle of the script.
Click on Tools > Convert Base
Make the following selections then click on Convert. I click on "Send Data to Main Form" to send the result to the main screen.
I need to change this to comma delimited so I just click on Search/Replace Text and replace spaces with commas.
Next, I click on the "Copy Output to Input" button then on Tools > Key Search/Convert.
Finally I make these selections and click on Convert.
What I did was use Converter's built-in expression engine which takes the decimal val(ue), subtract the previous res(ult) then subtract the ASCII value of the first digit of the script's length which is 49 (remember the total length of the script is 1,867). I add a comma then repeat the expression using the second digit of the script's length which is 56 and so on. Since I selected the Consecutive action, it will loop through these four expressions across the entire decimal value input.
So basically, Converter is doing this calculation for me:
164 - 49 - 0 = 115 = s
270 - 56 - 115 = 99 = c
267 - 54 - 99 = 114 = r
274 - 55 - 114 = 105 = i
By the way, if you need help with the expression engine, click on Extras > Expressions Help