Pages

Apr 10, 2010

Referencing yourself with arguments.callee()

Obfuscation using arguments.callee() in java scripts is widely seen in browser exploitation and malicious PDF attacks. This kind of obfuscation could be a bit tricky to handle for security analyst.

The arguments.callee() call is used normally to prevent security analyst from modifying the malicious function. The variable that holds the arguments.callee will be validated in order to detect whether code has be altered or not. If yes, then the code will generate a false result or no result at all.

Based on the JavaScript reference, the variable that is assigned with arguments.callee() will store the function’s content where the call is residing. The example below is a simple JavaScript code that validates the length of the characters in the function’s content. If the function is altered and the length is increased, the false result will be called.

function malicious_fn(arg1, arg2) {
 var validate = arguments.callee.toString();
 if (validate.length <= 198) {
   eval(unescape(arg1));
 }
 else {
   eval(unescape(arg2));
 }
}

malicious_fn("%54%68%69%73%20%69%73%20%6d%61%6c%69%63%69%6f%75%73%21","%54%68%69%73%20%69%73%20%6e%6f%74%20%6d%61%6c%69%63%69%6f%75%73%21");

In order to bypass this kind of obfuscation trick, we can circumvent the trap by replacing the variable ‘validate’ with the original malicious_fn function.

function malicious_fn(arg1, arg2) {
 var validate = unescape("%66%75%6e%63%74%69%6f%6e%20%6d%61%6c%69%63%69%6f%75%73%5f%66%6e%28%61%72%67%31%2c%20%61%72%67%32%29%20%7b%0d%0a%09%76%61%72%20%76%61%6c%69%64%61%74%65%20%3d%20%61%72%67%75%6d%65%6e%74%73%2e%63%61%6c%6c%65%65%2e%74%6f%53%74%72%69%6e%67%28%29%3b%0d%0a%0d%0a%09%69%66%20%28%76%61%6c%69%64%61%74%65%2e%6c%65%6e%67%74%68%20%3c%3d%20%31%39%38%29%20%7b%0d%0a%09%09%65%76%61%6c%28%75%6e%65%73%63%61%70%65%28%61%72%67%31%29%29%3b%0d%0a%09%7d%0d%0a%09%65%6c%73%65%20%7b%0d%0a%09%09%65%76%61%6c%28%75%6e%65%73%63%61%70%65%28%61%72%67%32%29%29%3b%0d%0a%09%7d%0d%0a%7d");

 if (validate.length <= 198) {
   eval(unescape(arg1));
 }
 else {
   eval(unescape(arg2));
 }
}

malicious_fn("%54%68%69%73%20%69%73%20%6d%61%6c%69%63%69%6f%75%73%21","%54%68%69%73%20%69%73%20%6e%6f%74%20%6d%61%6c%69%63%69%6f%75%73%21");

This example code is just a basic demonstration of how arguments.callee() is practically being used in real malicious code. Bear in mind that there are hundreds of ways arguments.callee() can be used to make your life miserable as an analyst. The is only way for us to handle this annoyance is by understanding how the code works.