In a previous post I talked a bit about NTOSpider, how it was “o.k.” with what it did, and how I was generally disappointed overall in the effectiveness of web app scanners in the market. As a matter of fact, Caleb Sima (founder and CTO of SPI Dynamics) actually had a couple of good points in a comment he left on that one.
I figured it was a bold statement when I said “I mean to build a web app scanner generally isn’t rocket science,” and I thought it might ruffle the feathers of some who have vested time into a really robust web app scanner project. Now, I’m sure that Caleb didn’t get too bothered by my post – but his response included the following “…at the surface it may seem like that but there is nothing farther from the truth. It is one of the most complicated pieces of technology I have ever had to deal with. Its not as simple as parsing out HREFs and sticking single quotes in params.”
He was referring to a scanner I referenced in sentence I wrote: “There’s actually a really good how-to write your own web app scanner in the O’Reilly book “Network Security Tools, Writing, Hacking, and Modifying Security Tools.” The code for that one is available here.” Which pretty much does – just what Caleb said it does – not too much. It’s simple and limited, but the right basic theory is there for a good and solid web app scanner.
Before I break all this down and go on – let me first say that I don’t think there’s an automated solution on the market (and there likely won’t ever be) that can find every vulnerability in your web application. There are things that scanners are good at picking up, input validation problems like xss and sql injection, directory listing stuff, CRLF injection, etc. And there are things that they aren’t too good at picking up, like logic based errors which grant you some sort of privilege escalation or give you access to something you shouldn’t have – like a sensitive file (the scanner might not know that you shouldn’t have access to that file) that is specific to that custom application.
Another metric that is typically used when judging the effectiveness of an automated web app scanner besides how well it finds vulnerabilities (and how many vulnerabilities it finds) is application coverage when crawling a site. For instance, when you are looking for vulnerabilities in an application you want to make sure that you’re looking at all of the pages and/or functionality of the application. If you (or the automated crawling functionality of a scanner) miss parts of the application and those parts of the application don’t get tested – then that’s a problem. Therefore, I always like to have a two-pronged approach when blackbox testing. I like to crawl the site manually and have a good crawler hit the application and feed the requests to a scanner, that way if one method misses something – hopefully the other method will have picked it up – this way we can be sure we’re maximizing application coverage to the best of our ability.
That being said – I don’t think that testing web apps should ever be an automated or manual kind of a process, but more of an automated and manual kind of a process (that is, if you really care about the overall security posture of your application). I don’t think there’s too many experienced web app pentesters out there who would disagree with me on that one.
However, let’s focus on some things that web app scanners are good at, like finding XSS and SQL injection vulnerabilities – and talk about possible tools (scanners) that one might use to accomplish this (for free). And with a little modification to these free tools, such as incorporating some of the concepts discussed below, one could possibly garnish better/more results (XSS, SQL injection vulnerabilities being identified) than some scanners out there that cost you thousands of dollars.
So going back to what I think scanners are good at, like fuzzing parameter values to look for things like XSS and SQL injection problems.
First off, the basic and fundamental way web app scanners work – is they essentially send a request to the application, then they look at a response to see if the request the scanner made affected the application in some way and made it send something back that it shouldn’t have (in a way that could be a potential security problem or vulnerability).
I’ll talk about a few examples that are probably the two most common (and arguably the highest impact) vulnerabilities in web applications that most scanners look for, XSS and SQL injection.
Let’s talk about XSS – the basic (easy, yet effective) way most scanners look for XSS is they send a request to the web server – and they replace or add on to the original value of the parameter with some potential javascript code – then see if it gets echoed back in a response. For example, a scanner might change something like this:
param=123
to something like this:
param=123″/><SCRIPT>alert(’XSS’);</SCRIPT>
Then they simply perform a regex on the response looking for /><SCRIPT>alert(’XSS’);</SCRIPT>. If they see it – then they’ll flag it as a possible XSS vulnerability. Really not too hard.
Now there are some applications or web app firewalls that filter things like <SCRIPT>, <IMG>, etc. so what you can do is add say, RSnake’s XSS list for filter evasion (a list of signatures) to what your scanner adds or substitutes for parameter values. Simply cycle through that list of signatures until (if and when) you come across one that gets echoed back in a response. RSnake’s cheat sheet can be used as a starter for signatures. As you play with web apps more and become more acquainted with filter evasion and XSS you can just add those to your list of signatures in your scanner.
Now I do have a friend who is working on a scanner that is a bit more sophisticated in detecting XSS, in that it will eliminate false positives and cut down on the number of overall requests (like not having to cycle through the whole list of XSS signatures on every parameter being submitted to the web application). But I told him I won’t talk about it too much until after he releases it at Def Con. However, even though his technique is more efficient – the above technique is what 99% of web app scanners do when looking for XSS – and this method works quite well, even though for some reason – there’s a lot of expensive web app scanners out there that can’t even get this part right, and manage to screw this part up somehow.
SQL injections are a little more complicated to look for in a scanner, but not much – remember, this isn’t rocket science.
There’s basically two different kind of SQL injections – regular (verbose database messages) and blind SQL injections.
To check for regular or verbose SQL injections – you send a request, like using a single tick ( ‘ ) as a parameter value, or at the end of a parameter value and look for the response.
Using our example of param=123 we might substitute the original value for something like paramm=123′1
If you get some database error message like this in the response then chalk it up as a possible SQL injection:
Microsoft OLE DB Provider for ODBC Drivers error
So there could be different back end databases that they might be using so you might want to look for other error messages from different databases other than MSSQL like Oracle, IBM DB2, MS Access, PostgreSQL, MySQL, etc.
Also, we could try different encoding on our single ticks like CHAR(39), 0xbf27, amongst others.
Besides single quotes (or ticks) we can also try to sneak in things like semi-colons ( ; ) and double dashes ( — ) and their encoded equivalents to try and generate database error messages.
Blind SQL injections are a little bit different beast in that we don’t just regex a response looking for a database error message, but rather we look for a change in behavior of some sort from the application.
There are basically two different types of blind SQL injections – conditional and time delays.
We’ll cover how to test both really quick.
For the time delay blind SQL injection detection you simply add something like this to the original parameter value:
‘;WAITFOR+DELAY+’0:0:10′– (MSSQL)
This tells the SQL backend to wait for ten seconds before responding. So a way to implement this in a scanner is you make a regular (non-fuzzed) request with no “waitfor delay” manipulation in the parameter value, then you calculate the time it took to make a regular request (let’s say it takes 950ms). Then, go ahead and send the time delay fuzzed parameter value (such as param=123′;WAITFOR+DELAY+’0:0:10′–). If you get a response right away – then, mark the parameter as not vulnerable, if you get a response from the webserver that took 10 seconds or later (you can calculate in the time it takes for the request such as the 950ms) then you can mark that as being a possible time based SQL injection vulnerability.
One can also use other time based queries for different databases other than MSSQL, such as the following:
SELECT pg_sleep(10); (PostgreSQL)
BENCHMARK() function (MySql)
Also – we could try adding parenthesis and such to escape from SQL subqueries like the following:
param=123;waitfor+delay+’0:0:10′–
param=123);waitfor+delay+’0:0:10′–
param=123′;waitfor+delay+’0:0:10′–
param=123′);waitfor+delay+’0:0:10′–
param=123));waitfor+delay+’0:0:10′–
param=123′));waitfor+delay+’0:0:10′–
Also – we would want to try the encoded equivalents of semi-colons (%3B), dashes (%2D), plus signs (%2B), etc. with all of these queries.
Next, we have conditional blind SQL injection vulnerabilities to hunt for. For this type of SQL injection vulnerability identification the scanner must also look for some behavioral change from the application.
According to webappsec.org the following is how to detect blind conditional SQL injection vulnerabilities:
A common way to detect Blind SQL Injection is to put a false and true statement into the parameter value.
Executing the following request to a web site:
http://example/article.asp?ID=2+and+1=1
should return the same web page as:
http://example/article.asp?ID=2
because the SQL statement ‘and 1=1′ is always true.
Executing the following request to a web site:
http://example/article.asp?ID=2+and+1=0
would then cause the web site to return a friendly error or no page at all. This is because the SQL statement “and 1=0″ is always false.
They’re not far off, by issuing a series of true/false type queries in a request (parameter value) then we can see if there is any difference behaviorally with the application – sometimes in a “false” query you get an error page, sometimes other types of changes in the response.
Easy enough, so for a scanner we can just do something like the following:
param=123′ and ‘1′=’1
and
param=123′ and ‘1′=’2
If we get a different page for each response – then we could chalk that up as being a possible vulnerability and worthy of looking into.
We could also use different true/false queries such as:
param=123′ or ‘a’='a
param=123′ or ‘a’='b
or even better, just substitute some random string for ‘a’ and another random string for ‘b.’
There are other things – that one could look for in (and add to) a web app scanner such as command injection, directory traversal attacks, CRLF injection, CSRF, session problems like session fixation, etc. but, again – it’s all fundamentally based on the concept of making a request to the application, then checking the response to see if the request the scanner made affected the application in some way and made it send something back that it shouldn’t have (in a way that could be a potential security problem or vulnerability).
I did mention that there was something out there that one could get for free that is a really good starting point for a good scanner. Here it is: sts-scanner. It is pretty limited in it’s functionality – much like the original ExtendedScanner, as a matter of fact it’s based on the ExtendedScanner. But with a few tweaks – like adding some more XSS signatures and adding some of the SQL injection scanning logic mentioned above (it already includes some of it, plus things like column enumeration when it finds a sql injection) – I would put money on it against any of the expensive (or non-free) web app scanners out there when it came to looking for things that it was designed to look for.
Cheers,
Chuck B.
2 responses so far ↓
1 Caleb Sima // Jul 14, 2008 at 7:55 pm
First off I agree 100% on that scanners are not meant to replace manual testing and honestly I’m not sure where people got that idea in the first place. In fact webinspect was born because I was tired of munging around with my perl scripts when doing assessments. I needed a tool to help me do things quicker.. thus the product.
A lot of people are quick to judge on the product not finding session hijacking or detecting logic errors but I say to them we do our best to automate as much as possible and make it easier for YOU to do your job but the rest is up to you.. besides thats what they pay you for
I would like to comment back on what “99% of web app scanners do when looking for XSS”.
I realize this is the most obvious way to detect for XSS but Webinspect and Appscan(I’m pretty sure) stopped using regex’s (as much as I love em) about 4 years ago. Today our xss detection method is slightly more advanced. For instance step 1 involves sending probe queries to determine where our attacks are being placed in the DOM, are we in an href? javascript? css? etc.. Once we identify where we are we then craft our attack based on that so that we escape out of anything that we need to in order to get proper execution. (we also use to identify what characters were being filtered here so that we crafted our attack only using allowed chars but we removed that due to false negatives). Once we have our attack we send it in and then actually evaluate the response in order to determine execution. So no regex parsing. We load the script and execute the page and if our script executes.. bam! XSS. Now this is a much simplified explanation and this is only for vanilla reflective XSS.. we have not even delved into stored XSS and how complicated that can be for an automated product.
Its humorous to me how many people really don’t realize how complicated these things get. Web app scanning is definitely a world where experience is the key. You may find that a perl script helps you on sites that you test on but if we were to put it in front of our thousands of customers with web apps that range from junk to enterprise.. you find out very quickly how much is missing.
Keep up the good postings.. hope you don’t mind me throwing in a little correction now and then
2 Chuck B. // Jul 14, 2008 at 10:29 pm
Caleb,
I do appreciate you taking the time to comment on my post. Your comments are generally thoughtful, insightful and honestly just plain better than most that I get (not that I really get a lot at the moment).
However, I don’t think you’ve corrected me so far. When I said “the above technique is what 99% of web app scanners do when looking for XSS” you commented that that’s not how your product currently looks for XSS. I never said that’s how your particular product did work, I never singled out webinspect and said “this is how they do it” – apparently your product is in the minority.
That being said – there are some scanners that do a lot more complicated things to detect vulnerabilities (like XSS) than I described. It doesn’t always mean that it makes them much better at actually finding vulnerabilities.
Some of the “more complicated” scanning techniques sound really good in theory. From what I’ve played with and with in-house testing (as described in my NTOSpider post) the end results a scanner produces just don’t always match up with cost, complication or bloat.
And that is what got me going on this topic – just that I can’t seem to find anything (or hear of anything from someone else) that works that much better than what I described above in a real-world comparison.
They all sound good – but they don’t all work good.
Finally, I’d like to say that I sincerely hope that someone does come up with something that works really well and blows everyone out of the water – and makes finding vulnerabilities a ton easier.
And not that I agree with that crack-pot comparison by Larry Suto, but web inspect didn’t necessarily blow the competition out of the water in any way – and I’ve never heard of a third party comparison test where it did.
From what I can tell from working with a lot (personally just hundreds, not thousands) of web apps from junk to enterprise, IMHO the big boy expensive scanners still have a long way to go before they can justify their cost.
Cheers,
Chuck B.
Leave a Comment