The Damn Vulnerable Web App – Part 3

I recently attended the absolutely fantastic SecurityFest in Gothenberg, and saw talks on several areas of information security that were really very interesting. One of the talks I was looking forwards to especially, was that of Frans Rosén, on the secret life of a bug bounty hunter. Having found and reported some bugs, I thought it would be excellent for advancing my interest (and fortunes) in bug bounties.

There were many very good points brought up, but the main one by far was “Read The Code”. It is the single most likely manner in which you are able to find bugs. If you can see from the javascript that user input is not properly escaped, then you can be pretty sure that there are going to be some XSS opportunities around.

Frans’ talk was great, and has really spurred me on to study this injection class of attack more (hence this post), but I also wanted to say that the other talks were also just as great, and it has rekindled my drive, which has been somewhat lacking now that the sun is finally arrived in Sweden.

I thought I would up the challenge rating for myself too, so I made a goal of being able to XSS the DVWA at a security level that was either medium or high. The low level is pretty good at demonstrating that XSS exists,  but I figured one of the higher levels would simulate an actual web app somewhat better.

Taking a note out of Frans’ book, I started off by reading the code. I am not really very well versed in PHP, which the DVWA is written in, but I gave it a try none the less. I reloaded the DVWA and started reading. As you can see, the code is “pretty” straight forwards, even for someone like me, who has only ever read one book on PHP.

I find when I am looking at code like this, it is much more easy to understand if I go through and comment it myself in a text editor, line by line. I could tell that the str_replace function was taking 3 parameters, one value it should be looking for (called the ‘needle’), one it would replace that string with (in this case an empty string), and a body of text in which to search for it (called the ‘haystack’). They are in that order too, so it was essentially stripping out <script> tags and replacing them with empty strings.

The code above it, was pretty much just checking that there was a body of text to display in the first place, and that it was neither empty, or had a NULL value. After a minute or two looking up some of the syntax ( is || a boolean or a bitwise?!) I ended up with the following.

So now I knew how to attack the form field. I would have to make sure that after my input had <script> removed from it, that it would still contain <script>. This is actually pretty easy, as there is only one round of replacement performed, so <scr<script>ipt> should evaluate to <script>.

Sadly, nothing happened. I checked my code, checked the code for the DVWA again and again. I was pretty sure that it should execute the javascript, until I realised that I use the NoScript plugin by default! Turning it off, gave me exactly the error I expected to have.


Huge success!

So now that we have the medium security XSS under our belts, let’s try for the high security. The code for the high security page looks like this.

The first part is identical, just checking that there is actually a name parameter in the URL to be shown. The next part though has a new function in it, “htmlspecialchars”, which I am guessing escapes all the html tags, or strips them out. A quick visit to the PHP manual pages should enlighten us further.

I found the following as the second paragraph

“””If the input string passed to this function and the final document share the same character set, this function is sufficient to prepare input for inclusion in most contexts of an HTML document. If, however, the input can represent characters that are not coded in the final document character set and you wish to retain those characters (as numeric or named entities), both this function and htmlentities() (which only encodes substrings that have named entity equivalents) may be insufficient. You may have to use mb_encode_numericentity() instead. “””

That sounds to me like I could use some other encoding schema to bypass the filter, perhaps UTF8 or something.

Sadly, I was completely unable to solve this part, although I am pretty happy that I managed the medium security setting for XSS, as perhaps I may not be such a newbie anymore. Perhaps. I also looked around on Google for any one who had solved the high security XSS challenge, but no dice either.

I thought perhaps that it could be left there as an example of how to properly treat user defined strings in PHP, but I see other solves for non-XSS challenges at high security levels, so maybe my Google Fu just needs some brushing up.

If you know of a way to defeat the htmlspecialchars, then please let me know in the comments!

I hope you have a seriously awesome week!


Leave a Reply

Your email address will not be published. Required fields are marked *