nd
Subscribe to the RSS feed

Keyword - SQL Injection

Entries feed - Comments feed

Tuesday, September 20 2011

PHP, variable variables, oh my!

I was just looking at some PHP code for one of our clients, and found a case I haven't seen many times before. I thought I should share it here.

The code I was looking at looks like this:

<?php

// Init the PHP array with some SQL code to start the query
$declareSQLArray = InitializedArray('stuff');

// Use a strong enough validation routine for do the input
// validation of POST variables
while(list($name, $value) = each($_POST)) {
        if(!is_array($value))   
                $$name = StrongValidation($value);
        else
                $$name = $value;
}

// Do something with my variables and always do a proper
// validation when I use the data

// Eventually, build my SQL command, and send this to the DB
$sql_command = join(' ', $declareSQLArray);
mysql_query($sql_command);

?>

The code, even if horribly constructed, does not seem to show important weaknesses, but the usual case of submitting a POST variable as an array, and bypassing the StrongValidation. Then, in that case, it would have failed every other validation routines in the code.

Even if experienced with PHP, you might not have encountered variable variables before. In short, this allows to dynamically declare named variables. Here is a simple example:

hubert:~ Romain$ php -r '$name="foo"; $$name="Hello World!\n"; echo $foo;'
Hello World!

Here, the variable $foo gets declared, and assigned using PHP's variable variables capabilities.

Getting back to our code example, I'm sure the reader will spot the issue, and what an attacker can do to exploit such scenario to trigger, in that case, a SQL injection. Since the variable $declareSQLArray is defined and initialized before the POST variables lookup, it is possible to reassign it using the variable variables. In that case, no validation is performed when we submit an array, and this is exactly what we want to do!

To exploit the SQL injection, you only need to submit POST variables to overwrite the $declareSQLArray, and add the content that we want in it!

POST /code_example.php HTTP/1.1
Host: example.com
...

declareSQLArray%5B%5D=SELECT...;&declareSQLArray%5B%5D=--&whatever...

Job done! The resulting SQL query will start with the payload that was submitted as part of $declareSQLArray. You've got your SQL injection.


Update: While driving back home, I was wondering if I could overwrite values from the SESSION using this technique. A couple of lines of code, and POST request after the answer is short: YES.

Imagine that you have an isadmin variable as part of the session (which is an associative array). This variable would be set in a code like this:

if ($user->isNotAdmin())
        $_SESSION['isadmin'] = 0;
else
        $_SESSION['isadmin'] = 1;

Exploiting the previous weakness of the code example, we are able to overwrite the $_SESSION['isadmin'] content, only by supplying what will be interpreted as an associative array by PHP:

POST /code_example.php HTTP/1.1
Host: example.com
...

_SESSION%5Bisadmin%5D=1&whatever...

I'm sure you're thinking, as I do, that this is getting more interesting!

Anyways, this issue is not new at all, it is known as Dynamic Variable Evaluation (thanks to Steve Christey).

The interesting part of it is that DAST won't be able to detect it (or maybe if you are lucky enough), and it is very hard for a SAST to deal with it (actually, I doubt any SAST vendor who supports PHP handles this case, but it's not impossible since they have all they need to solve the problem).

Update 2: Based on the comments, I did some testing and observed that even if we can overwrite data from the session, this data does not get persisted in the session. This means that you can still control a value from a super global for the remaining execution of the script, but cannot persist the data.

Tuesday, April 8 2008

MySQL table/field names

Sometimes I really don't understand developers.

Why the heck a table name such as a<script>foo(42)`cool could ever be allowed? What's the point of that? I know I am almost clueless with SQL but... what's the reason here? If someone has some idea, I would love to hear them!

Thursday, November 1 2007

My talk at the Verify Conference

Last Tuesday, I went to the Verify conference to give a talk about Web application scanners evaluation: what we are actually doing at NIST. I'm gonna make a simple entry reviewing what I actually talked about. The slides are here.

First of all, the evaluation was made with a test suite I made. The choices for the test suite are kinda simple, I wanted something really close to a real website. So I decided to use a real website (not a couple of test cases). The website contains multiple seeded vulnerabilities from different kinds (XSS, SQLi, RFi, CSRF, etc.). The website is actually configurable in a sense of vulnerability: you can choose what vulnerabilities will be in the website or not (let's say, I only want to have XSS vulnerabilities). Moreover, in order to see the web apps scanners capabilities, we can select a type of defense for the current protection: the level of defense.

Level of defenses

Programmers are different. They have different background, knowledge and approach to solve security problems. The filters we can see in wild web applications are not equivalents, some are good, some are just bad and we have the full shade of effectiveness. So, in order to test web apps scanner with different difficulties (for them) we implemented different level of protection around the vulnerabilities: the level of defenses.

A simple example: SQL Injection

  • Level 0: No protection
  • Level 1: Typecasting (in order to convert integer, boolean, double, strings, dates etc.). This protection will limit the SQL Injection on SQL native number types (integers will be converted as integer: 1' OR 1=1-- will be converted into 1).
  • Level 2: Escaping the meta-characters. We are protecting about quote injection, etc.
  • Level 3: Hiding the MySQL errors, we will now have Blind SQL Injections.
  • Level 4: Restricted user management.
  • Level 5: Using prepared statements.

Since the level of defenses will be use in combination, the order is important. (combination: level 2 = level 2(level 1(level 0))). So, using these level of defenses we are able to select the difficulty that the tool will have to break the vulnerabilities. For the results, if you are looking at the slides, in the detection rate slide, you'll see that there is not result for the level 2 which means that no tools were able to find vulnerabilities in the level of defense 2.

Attack Surface Coverage

Another point I have been working on is the attack surface coverage. A webapps scanner is not a simple piece of software which launches attacks! The crawling/parsing step is actually really important maybe the most important since it will try to understand the application. The attack surface of the test application is the places where the user has a direct interaction, means no algorithms etc. just inputs handling, error messages etc.

Here is an example of attack surface coverage check points (with numbers) for a login function:

(1) Touch the file [login.php]
if ( all fields are set ) then
	(2) All fields are set [login.php]
	Boolean goodCredentials = checkThisUser(fields)
	if ( goodCredentials ) then
		(3) Credentials are correct; the User is now log in [login.php]
		registerCurrentUser()
	else
		if ( available login test > 0 ) then
			(4) Login information incorrect [login.php]
			displayErrorLogin()
			available login test -= 1
		else
			(5) Too much try with wrong credential [login.php]
			displayErrorLogin()
			askUserToSolveCAPTCHA()
		endif
	endif
endif

Basically, we would like the scanner to use the normal behavior paths and also the abnormals (errors etc.) in order to find vulnerabilities there such as Information Leakage etc. Just a note about the attack surface coverage rate: this number cannot be interpreted alone. You need to use this with the detection rate and the false positive rate. In the slides you can see that the tool A as a 25% attack surface coverage of the application, but this is also the tool with best findings and no false positive. This means that the tool were able to find 33% of vulnerabilities (best results from all the 4 scanner we tested) in 25% of the application which can be considered as accurate compared to the others.

The attack surface coverage may have an important impact, depending on what type of testing you are doing with your webapps scanner. If you want a tool to run at the end, doing a full assessement, then you will need a tool which as a very good coverage (since you only rely on that). But if you are looking for a tool which is fully integrated in your testing process (testing == quality and security) then, I think it's better to have an accurate tool which will cover a lower surface, but the tool will cover the important points.

Conclusions

This is actually hard to make a real strong conclusion about the results given in the slides. The test application is a real simple website (banking application) and is far from a real company website; this is a huge confounding factor. Another problem is that I did the evaluation one vulnerability at the time (and one level of defense at the time). This prevent a couple of real life behaviors...

Wednesday, June 20 2007

PHP Source Code Security Scanners: Pixy

I already talked about source code scanners for PHP, and even run a simple test between SWAAT and PHP-SAT. Today, a new toy has been released: Pixy, so I decided to make it pass the test. The first test is really basic, having a quite small php source code with a bunch of possible faults: tests.php

So, you find the output of the tool here: out.pixy.result.txt

I first have to say that it's normal that the tool doesn't catch the header injection stuff, os command injection etc. it doesn't claim to do that. Pixy claims to find the Cross-Site Scripting and the SQL Injection. On that point, I would say pretty good job guy!
The tool catch all the possible Cross-Site Scripting in the echo functions, doesn't warn for the persistent XSS (line 34, the bad html injection would be inserted into the SQL database, if there is no output validation, there are Persistent XSS).

Even better on the SQL Injection where it found every thing I tagged as true-positive.

To conclude, I will definitely keep an eye on this tool which looks promising to me, I will also continue working on the PHP-SAT security configuration in order to make a solid vulnerability disclosure system.

I <3 Bots!