I was asked to figure out what exactly this Java Script was doing, so I figured I’d put it all down here. I’m no expert in Java Scripts though, so it was a lot of trial and error before I got through it all. As for this type of scripts, they’ve been around at least since the first half of 2008.
1. The original script had a frame pointing to a legal site and then a javascript at the end.
2. After unescaping the ‘$‘ variable, we see 15 new variables and a function named ‘sc‘. The sc function will create a cookie named ‘rf5f6ds‘ and set the value of this to ‘2‘ and the expire time to 7 days. The script will check for this cookie and if it’s not found it will call sc and then do an eval on the unescaped versions of the variables ‘dz‘,’cz‘,’op‘ and ‘st‘ concatenated with the string ‘dw(dz+cz($+st));‘. As we don’t have any functions named ‘dw‘ or ‘cz‘ yet, we can assume that the unescaped variables will contain these functions.
3. Looking at the unescaped and concatenated string, we’ll see the dw and the cz functions. The function cz will just return a concatenated string of variables ‘ca‘,’cb‘,’cc‘,’cd‘,’ce‘ and the given parameter which in this case is the concatenated string ‘$+st‘. I felt it better to just concatenate $ and st into one variable and thus rewrite all this to
$=”dw(dcs(cu,14));$=st;dcs(da+db+dc+dd+de,10);dw(st);st=$;”;
dw(dz+ca+cb+cc+cd+ce+$);
4. After this call to dw, it’s used all the variables that became code by using one unescape. Some of the variables have had their contents overwritten and therefore I listed the changed variables once more before going on to look at what the eval inside the dw function will do. After this first call, any call to dw is basically the same as ‘eval(unescpe(parameter))’.
5. The eval inside the first call to dw will have a new function named ‘dcs‘. This new function is a simple XOR decryptor used to decrypt the string ‘cu‘ (XOR with 10) and the concatenated strings ‘da‘,’db‘,’dc‘,’dd‘ and ‘de‘ (XOR with 14) . The first parameter to dcs is the encrypted string, the second parameter is the value each character should be XORed with. The result from the decryption will be stored in the variable st.
6. After cu has been decrypted it is stored in st. The decrypt function does not return anything, so calling dw with the decrypt function as parameter will do an eval on nothing. Therefore this dw call is useless, but the decrypting still does its job. The result in st is then saved to $ before the next decryption. The next decryption then saves it’s results to st and then dw is called with st as parameter which basically means eval(unescape(st)).
7. Looking at the code given to eval this time, we see some date functions and operations and then it replaces ’fbcmfir.com‘ in $ with something else and adding ‘.com‘ to the end. Remember that $ is where the result from the first decryption was stored, so the $ probably contains this URL which will be replaced based on these date-related operations. The generated URL is based on dates, so it’s possible to generate the URL for any given date, but it’s hard to give a description of the URL here. The only thing I can do is to show the general structure of it and to point out that the last 5 characters before the .com is easy to find as it’s just based on the current month:
[a-j][a-y][a-z][1-9|a|d|g|j|m|p|s|v|y][m9[month-1]].com
8. As I wrote, I’m not an expert in Java Script and therefore I stumbled upon my first little problem when I tried to see what was in the first decrypted string. For some reason my test script didn’t want to write the decrypted string to a file! I went into the decryptor loop and found out that one of the decrypted chars was not inside the ASCII value range, and therefore I couldn’t write this as ASCII to a file. I Switched out this one character with a little text of my own though to see where in the code this character actually was placed.
9. Looking at the first string again, we’re finally done with all the evals and unescapes and can see the real code. The whole script is enclosed in JavaScript tags for HTML. After the opening tag, we’ll see ‘if (navigator.cookieEnabled){‘, so this code is only executed if cookies are enabled. After this we get three global variables.
The script contains 5 functions: pop_init(), pop_show(), pop_setCookie (name, value), pop_getCookie(name), pop_cookie_enabled() and it calls the pop_init function at the end. pop_init is a function that will check for MS user agent and if found we copy all onclick handlers on links to onclick_copy and then register show_pop as the onclick handler. This is because IE is the only browser (?) that have a bubbling event order, that means inner layers get triggered before the outer layers in IE. It also sets the default onmouseup handler to show_pop and store the onclick handler in onclick_copy.
The pop_cookie_enabled function will just check if it’s possible to set a cookie or not and then return a boolean value. The pop_setCookie will create a cookie with the given name and value. We’ll see later that the value will be the time when the last popup was shown. The pop_getCookie function will search for the cookie with the given name and return the value if found. If it’s not found it will return null.
The last function, show_pop, contains a URL ( Remember that the domain in this URL will be changed into something else by the date functions mentioned earlier. ) and will first run the original onclick handler if it exists, and then open a new window under the current one based on a few criteria. If another popup window already exists it will not open a new one. If the value of the cookie named ‘advmaker_komap‘ is under the timeout, it will not open a new window. If it does open a new window, it will also create a cookie with the current time as value.
10. Now we’ve gone through all the evals and should end up back in the original document where we can see a ‘document.write($)‘ after the ‘eval(z($))’ function. This will write this last script to the browser and show the pop-up.
Ps. Through all this I’ve been replacing the eval functions one by one with a function to write to file instead. After the write, I’ve cut and pasted the needed parts to get to the next eval and then replaced this and so on. This is a pretty slow process, but it does give a very good understanding of where you are in the code at all times, and it’s easy to spot where in the code there are errors or traps. For those not really interested in all the manual work, I’d recommend you look at a program named ‘Malzilla‘. Just be aware that opening any malicious file in any program might be a security risk!