Breaking Non-Existant Code

I recently ran into a fun problem that stumped me for about 1/2 hour.  I had found a value that I could control in the query string, which would put data inside a “onmouseover” attribute on an href tag.  So something like:

url:          ?myvalue=”xxxx
html:      <a href=”#” onmouseover=”par=window.parent;par.call_function(‘xxxx‘);”>test</a>

normally, one would escape this by setting the “myvalue” parameter to:

x’);alert(document.cookie);(‘x

which when injected would terminate the call to my_function and inserts my alert box*.

<a href=”#” onmouseover=”my_function(‘x’);alert(document.cookie);(‘x‘);”>test</a>

This is pretty straight forward, tried and true.  Except, in the case of this test, the my_function function doesn’t actually exist.  This particular page was expected to be called from an iframe, and it’d walk back up to the parent to call a library the parent has loaded**.  In short, this means that due to a bug in the actual page, my attack wouldn’t work because JS would stop processing after the failed call to my_function.  Suckage.

But not all is lost.  To get around this normally, we just need to inject ourselves earlier into the page’s process before the page can call the missing function.  One could try:

x’);”/><script>body.onload = function(){ alert(document.cookie); } </script><a href=”#” onmouseover=”(‘x

which results in:

<a href=”#” onmouseover=”my_function(‘x’);”/><script>body.onload = function(){ alert(document.cookie); } </script><a href=”#” onmouseover=”(‘x‘);”>test</a>

In this payload, we end the onmouseover and include our own script tag.  In this tag, we override the onload behavior of the body***, which would allow our alert box to execute before JS has a chance to later fail.  The Javascript after that is just a nicety to prevent the html from being malformed.

Except, yet again we were foiled.

In this case, the developers were actually encoding the ” character, so I couldn’t break out of the function call to do this.  Normally this might be end game; but never fear, order of operations prevails in the end.

q: In general programming theory– before a function can be called, it first has to what?
a: Process it’s arguments.

To get my payload to execute, despite the fact that my_function() doesn’t exist, I merely have to make my attack an argument to that function.  In other words, unless you pass a reference to a function (or a proc itself), the application will have to first process that call before it can call the function it’s being passed to.  The end payload is:

x’,alert(document.cookie),’x

which results in:

<a href=”#” onmouseover=”my_function(‘x’,alert(document.cookie),’x‘);”>test</a>

In this example the alert box’s results are to be passed to the non-existant function, which processes my payload.  If this was anything more than a POC, you’d do something far more nasty, such that the end user would never see the broken code.  Because, for all intent and purpose, you fixed it for them.  How nice of you.

This topic of fitting is something I will be talking more about in my BSidesDFW talk coming up in November.

-A
* for anything other than this post, you’d generally want to grab the session details and send them to a 3rd party host, and maybe even redirect the user to the login page so you could try and login as them shortly there-after.  But that code just makes this code less clear, so we went back to a trusty old alert box.

** the code itself calls into the parent window and loads it to make the function call.  But, because that’s more than needed I omitted for clarity sake.

*** you can override the body, document, or window depending on what you are after.

Advertisements
Post a comment or leave a trackback: Trackback URL.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: