To find XSS flaws we need to know where to look for it and how we can detect it. Where to look for it is as simple as complicated: all we need is to probe every input the application has.
We will do it using a probe string: a set of characters that we can look for it in source code in order to know if we can go further to inject a payload.
So let’s think about it: which is the most important single character for a XSS payload? As we are dealing with HTML, the most important is the identifier of a tag: the less than sign “<”.
Although there are injections which don’t need it, like an injection inside a tag without breaking it or one into the javascript section of the code, the tag based payloads work on all situations.
If we inject a “<” sign into any application input and we see it in the response of the web server, there’s a great chance to inject a payload. But it will be hard to spot only that char in source code (it’s everywhere), so we need something to help us to identify it. So we will use just another char after it:
<1
In fact, we can use any char that does not form a true tag like “<a” or a pseudo one like “<x”. But why? Because most filters will not recognize it as dangerous (not a tag), it might allow us to know if the “<” is being reflected without being caught. In some .NET applications, for example, we may be able to bypass the language native filter with “% u003C” (unicode) instead of the “<” character.
But when dealing with multiple inputs, we also need to be able to track which one get reflected. This can be achieved simply by adding a tracker before it:
n<1
where “n” is a number for each input we try, like the following:
param1=1<1¶m2=2<1¶m3=3<1
Usually this is not enough to be sure if there’s a real XSS hole in the server side script but it’s a great clue about it: if the application is allowing the reflection of a “<”, probably is also allowing the reflection of a single or double quote needed to break out of an existing tag.
Using our example above, if we see this in source after trying to inject into URL parameters:
Probe
http://domain/page?param1=1<1¶m2=2<1
Source code
<input type=“text” value=“2<1”>
We can quickly move to a full working payload like:
Injection
http://domain/page?param1=1¶m2=”><svg+onload=“alert(1)
Source code
<input type=“text” value=“”><svg onload=“alert(1)”>
And if there’s no filter in place, we got a XSS.
We could have tested for a XSS flaw in several ways but our discussed probe string has the following advantages:
1) it’s short and simple;
2) very suitable for manual tests;
3) flies under the radar of most filters;
4) may go unnoticed in server logs.
In my private twitter account @brutalsecrets, there’s a video showing this technique in an advanced way to find a XSS in a real world scenario.
#hack2learn
I often start by injecting an integer, to see what contexts I can inject into. Then I figure out what sequences will escape from that context to execute. Yet to meet a filter that rejects my integer, and it allows me to count which injection points are well-filtered in addition to which ones are susceptible.
[…] http://brutelogic.com.br/blog/probing-to-find-xss/ […]