Tuesday, January 06, 2009

Enumerating objects / methods in Javascript

I was reading the following post on the Metasploit blog: Fuzzing Flash For Fun (ASNative), which described how to use an undocumented feature of ActionScript to get the list of all functions and then fuzz them. I thought: surely, there is a simpler, documented way to do that.

Now, the following code was written in Javascript, but given that both Actionscript and Javascript are derivatives of the same ECMA standard, a similar technique may (should?) work with Actionscript also. The basic idea is that there exists a "Global Object", which all other objects are referenced from, so starting the walk there should give you all the objects.

Two remarks: you have to collect the results first and display it later, because writing to the DOM will create an infinite cycle (for each object you see a new DOM object is created, which in turn also needs to be parsed and so on). The try/catch clauses are necessary because accessing some protected properties/objects (I've tested it with FF - I'm not sure if other browsers have a similar concept) will trigger exceptions, prematurely terminating the enumeration if they aren't present.

<script>
seen = [];

function gatherObjects(obj, path) {  
  if (seen == obj) return;
  try {
    for (var i in obj) {
      var o;
      try { o = obj[i]; } 
      catch(err) { continue; }
      if ('object' != typeof o) continue;
      
      var wasSeen = 0;
      for (var j in seen)
        if (seen[j] == obj[i]) {
          wasSeen = 1;          
          break;
        }
        
      if (wasSeen) continue;
      
      seen[path] = obj;
      gatherObjects(obj[i], path + '/' + i);
    }
  } catch(err) {
    alert("Error: " + err);
  }
}
gatherObjects(this, '');

functions = 0;
objects = 0;
document.write('<ul>');
for (var j in seen) {
  document.write('<li>' + j + '</li>');
  document.write('<li>');
  document.write('<ul>');    
  ++objects;
  try {
    for (var i in seen[j]) {
      try {
        if ('function' != typeof seen[j][i]) continue;
        if (gatherObjects == seen[j][i]) continue;
        document.write('<li>' + i + '</li>');
        ++functions;
      } catch(err) { }
    }
  } catch(err) { }
  document.write('</ul>');
  document.write('</li>');  
}
document.write('</ul>');
document.write('<p>Seen ' + functions + ' functions in ' + objects + ' objects</p>');
</script>

From here you can start fuzzing (the same technique of sending feedback trough XMLHttpRequest should work) the same way as the Metasploit guys used it. Happy fuzzing!

1 comment:

  1. Anonymous8:00 PM

    Great writeup on object enumeration via reflection, but the are some constraints that limit its use in terms of fuzzing. The problem with function enumeration in Javascript is that it depends on the browser. Internet Explorer used to crash if you iterated a native object (for i in window.alert); now it just returns undefined. I don't believe this method works with ActionScript, since some of the ASnative functions are undocumented and not exported via the API or object space. The method above works great for fuzzing the native DOM of Firefox :-)

    ReplyDelete