When dealing with HTML injections there’s an interesting trick to make a XSS attack work. To illustrate this technique we will make use of the following, tweeted as a mini-challenge:

The code is short and very simple but built with key elements of a real world scenario:

brutelogic.com.br/tests/newsletter.php

Contrary to the obvious input, in this code we have a PHP_SELF flaw which makes us able to inject into the URL without providing any parameter:

As our injection lands on a tag attribute, we try to break out of it with no success because the greater than sign (>), needed to close the tag and start a new one, is replaced by a minus sign (-):

So we will try to use an inline injection, using an event handler:

Again without success, but this time because the javascript block (lines 11 to 17) sanitizes every string that has “on” followed or not by a spacer character (%09, %0A, %0C, %0D or %20) and an equal sign (=) in the document.location.href (line 15), the property that handles the URL.

The javascript function eventFilter(), called when the body of document loads (line 3), manipulates the page built at runtime (see DOM), so the injection does not work although it gets correctly reflected on source.

But if we create an arbitrary attribute and simply keep its value open, all the code after injection will be changed into its value:

That way, the “1” attribute will be closed only when the browser’s HTML parser finds the next single quote (‘), which is on the “Don’t be evil.” phrase. The form tag, the one we injected into, will be closed in the next greater than sign (>), which is in the </h6> tag.

The input field disappeared along with the submit button and the javascript function was completely disabled (all from line 8 to 18). Because there’s no more elements to interact in the page, “style” attribute is also replaced by a “-” and we can’t inject anything after our target tag, we have no way to trigger the event handler we provided (and none of the agnostic event handlers).

So here comes the last trick. In current Firefox browser, we have the following handlers that only need a script block after it in source to make them trigger:

onafterscriptexecute onbeforescriptexecute

But to reach the very end of the challenge (in the congrats.js script of the page),

if (brute)

alert(“Congratz, buddy!”);

else

alert(“Almost there, try again.”);

we can only use the latter:

#hack2learn

P.S.: in my private twitter account @brutalsecrets there’s another useful example of this technique.

P.S.2: Michal Špaček (@spazef0rze) came with a very interesting solution, check it out here. Thanks, Michal!