Friday, April 30, 2010

Cloning jQuery UI datepicker

In case you were having problems with cloning fields with jQuery UI datepicker attached to them - solutions mentioned in the interwebs are similar to this one:
$('.cloned-input').removeClass('hasDatepicker').datepicker(); 
However, that did not work for me. If you happen to have a set of similar symptoms:
  • new datepicker is not instantiated at all
  • JS errors occur while instantiating new datepicker
  • even if datepicker is cloned, it refers to the old field
the issue is that there are remaining (cloned) events (if you're using .clone(true) like me) on the field AND there is a still attached cloned datepicker object.

Solution

Either imitate datepicker('destroy') manually:
$input = $('.cloned-input'); 
// remove still present related DOM objects
$input.siblings('.ui-datepicker-trigger,.ui-datepicker-apply').remove();
// remove datepicker object and detach events 
$input
  .removeClass('hasDatepicker')
  .removeData('datepicker')
  .unbind()
  .datepicker();
or implement a different procedure:
  1. before cloning destroy the datepicker on the base input
  2. clone(true)
  3. recreate the datepicker on base input
  4. use unbind() and recreate datepicker on cloned input

Friday, April 16, 2010

When overloading eval() fails

Today I encountered a small issue when decoding yet another 'crackme' challenge from Paweł Goleń. This time it turned out to be just a little bit more difficult, as Paweł:
  • used some onerror handlers to run the code
  • tried (unsuccessfully) to beat my function overloading
  • used multi-level obfuscation
But obviously, this could only slow down any determined programmer. So there I was, happily decrypting the code bit by bit, restarting Firefox from time to time (heavy debugging session in Firebug always ends up like this for me ;) ) when suddenly the code stopped working.

And all I did was to replace eval('code') with code. To be more specific, that is the actual code:
<img onerror="eval('code;') // ok" src="http://i.dont.exist" />
<img onerror="code; //gives errors" src="http://i.dont.exist" />

Such operation usually has no side effects - after all, eval is meant to immediately evaluate the passed code. But my eval was overloaded (check my previous post to see how I achieved this) and this caused problems. What's even worse - it turned out overloaded eval will not always work as expected and you cannot avoid it!

Eval() is special

The 'original' eval turned out to be a very special function (just like arguments being a very special array)  - it has its own execution context and you cannot emulate it with any other function. See the below example:

<html>
<head>
<script type="text/javascript">
var y = 'Klaatu barada nikto';
var eval2 = eval;
console.log('in global: ',y,this);
</script>
<body>
<img src="about:blank" onerror="console.log('in event handler:',y,this)">
<img src="about:blank" onerror="eval(&quot;console.log('in eval:',y,this)&quot;)">
<img src="about:blank" onerror="eval2(&quot;console.log('in eval2:',y,this)&quot;)">
</body>
</html>

Here we define a global variable y and we try to read the value of y from
  1. global context (<script> element)
  2. an event handler
  3. eval() function inside an event handler
  4. eval2() which is just a reference to 'original' eval (let's call it dummy overload ;))
What is important, this inside event handler points to <img> element, and images have their y property - so y should not be our 'Klaatu barada nikto', but a number. But running the above code in Firebug gives some unexpected results:


1st case works as expected (this is window, and global y is accessed), so is the 2nd (this is img, y is local), eval() does not change the scope nor variable visibility. But eval2()suddenly sees our global variable, even though it's in the context of <img>! WTF??

So there is a slight difference between original and overloaded eval() - although the context stays the same (thanks to Function.apply I used in original overloading), variable visibility is different - so one could potentially detect that eval() is overloaded.

We're doomed?

I tried to overcome this using various known techniques (wrapping in anonymous function, playing with scopes etc.) but to no avail. I cannot emulate eval without getting this strange behaviour.

Luckily, malware authors are is the same position - they usually obfuscate eval call by using some intermediate function (in other words, there is eval2 = eval equivalent somewhere in their code). But still, I'd rather have a perfect emulation... Is there any?

Wednesday, April 14, 2010

Beating JavaScript obfuscators with Firebug

Today I encountered a very pleasant 'crackme' challenge from Paweł Goleń. The purpose is to find out what is the purpose of demo page set up by Paweł.

Visiting this page with e.g. Firebug enabled (or with any HTTP proxy) quickly shows that a POST request is sent upon visiting. You didn't submit any form manually so it must be JavaScript sending it. So, you just need to view the source of the page to find the JS code. And this is where the fun starts. The code looks like this:


Obfuscation

Not really readable... This code is obfuscated - modifed to make its analysis difficult. This is the technique widely used with malware software.
The encoded software usually tries to hack into the machine, so it can:
  • download even more code from a remote URL
  • send some data to a remote (attacker) server
  • exploit a browser vulnerability to execute a code on the machine
  • scan the internal network
  • hack into your router and convert it to a spam server
Obfuscating code sometimes prevents the software from being detected by antivirus/malware scans, but it is mainly used to make it harder to determine what the script actually does (and e.g. prepare antivirus signature for it).
In JavaScript obfuscation is usually based on heavy usage of unescape, String.fromCharCode and eval functions.

Luckily, JavaScript itself, with the help of Firebug, has tools that enable you to decode such obfuscated script, so it is only a matter of time to reverse engineer it.

Function overloading

JavaScript is a functional language, so - in plain words - the function itself can be written to variable, passed as an argument etc. And - as a variable - it can be reassigned. So it is possible to change the behaviour of any JavaScript function. Example:

<html><head>
</head>
<body><div id="alert"></div>
<script type="text/javascript">
window.alert = function() { 
  document.getElementById('alert').innerHTML = arguments[0] 
};
alert('hello world');
</script>
</body></html>

Here we overload widely used alert function - instead of a message box it will insert a given message to a <div id="alert"> element. Two things to note:
  • alert is in fact window.alert because JS in browsers has a global object named window
  • arguments is an array-like object containing parameters passed to the function, so in this case it's ['hello world']

Let's decode

Analysing any obfuscated script will be much easier if you overloaded the key functions: unescape, String.fromCharCode and eval. But, for the script to actually work, our overloaded functions must call the original ones:

var oldunescape = window.unescape;
window.unescape = function() {
  var u = oldunescape.apply(this,arguments); // this calls the old function
  console.log('unescape ', arguments, u);
  return u;
}

var oldCharCode = String.fromCharCode;

String.fromCharCode = function() {
  var u = oldCharCode.apply(this,arguments);
  console.log('charcode ', arguments, u);
  return u;
}

var oldeval = window.eval;
window.eval = function() {
  var args = arguments;
  console.log('eval ', arguments, u);
  var u = oldeval.apply(this,arguments);
  debugger; // here the debugger (e.g. Firebug) will kick in 
  return u;
}

With this code you may start decoding the script, consistently replacing obfuscated code in HTML with decoded one coming from Firebug console. You can also insert the debugger; line anywhere in a JS to add a breakpoint.

One thing to note - when debugging malware, be sure to make it in a safe environment (e.g. a separate virtual machine, some sort of sandbox), because otherwise there is a risk you'll become its victim.

We're finished...?

Unfortunately, that's only the first part of analyzing the software. After getting the plaintext version we need to understand what it actually does (and that's usually intentionally hidden in many functions, variables, exceptions, browser differences and strange program flow). It is hard and requires both patience and a bit of JavaScript knowledge, but it is, I think, one of the fastest and most exciting ways to learn. So, go grab your Firebugs and try for yourself - what does this page do?