In my previous posts I talked about an overview of what makes a great security tester, and in-depth about what it means to have complete knowledge of the system. If you haven’t read those yet, I suggest you do so now, that’ll help set the stage for the following post.
A great imagination extends beyond the ability to imagine a system as it could be, but extends to envision the truly interesting bugs and vulnerabilities in a system. You need to be able to ask yourself “what’s really going on here?” and “how would I build this”?
Many of our security assessments are performed “blackbox” - without source code or direct access to internal systems. When we approach an assessment we have to make leaps of inference to make educated guesses about how the application is developed and what kinds of mistakes could be made. Ask yourself how you’d develop this solution, and what kinds of mistakes might be made in this type of system.
- Are they using Microsoft SQL server or MySQL, or are they storing everything in an XML datastore?
- If they’re using SQL, are they using Stored Procedures or Parameterized Queries?
- How can we discover whether this is or is not the case?
- If it isn’t what assumptions about the system can we make?
- Where/What is the input checking being done?
- On the server?
- Did they write their own input validation routines or are they relying on controls provided by the language or framework?
There are many other questions that a seasoned security tester will ask to better understand what is going on behind the scenes in this software system. Just as we did earlier, each time we prod the application we will gain some understanding of what’s going on behind the scenes. If there are still questions about what’s going on then we can use our imagination to fill in the gaps and reason about mistakes that could be made.
SQL injection is an exceptional example of a vulnerability that requires a creative imagination to be discovered. It’s possible, but usually very difficult to discover the exact SQL query that is used on a system. However, with enough poking and prodding we can reconstruct an approximation of the query to understand mistakes and weaknesses that we can use to attack the system further.
Let’s take a login control that requests a username and a password from the user and uses that information to query the database to locate and login the user as an example. What would the SQL look like that would perform this function? A naïve solution would be to simply query the ‘users’ table for the right username and password like this:
SELECT * FROM users WHERE username = ‘[USERINPUT]’ AND password = ‘[USERINPUT]’
After constructing a hypothesis of the query we can verify the guess against the live system by trying certain inputs in the username and password fields. If the query does follow the form above, a simple test like a single quote in a username field will cause an unclosed quotation mark error, which vets our earlier hypothesis. We can use this additional information to construct a more complex SQL injection string that may allow us to read or write arbitrary values in the database.
Without the ability to imagine the SQL statement or the back-end architecture of the system, this attack may be missed. Even if a less imaginative tester were to stumble across this vulnerability, he/she may miss other vulnerabilities with higher risk.
With a good imagination we can think about all the different components and how they may be misconfigured, developed improperly then find and exploit their weaknesses!
Tune in next time as I complete the series in the third piece that makes a great security tester: The Evil Streak.