web应用一般采用基于表单的身份验证方式(页面雏形如下图所示),处理逻辑就是将表单中提交的用户名和密
码传递到后台数据库去查询,并根据查询结果判断是否通过身份验证。对于LAMP架构的web应用而言,处理逻辑采用PHP,后台数据库采用MySQL。而
在这一处理过程,由于种种处理不善,会导致不少严重的漏洞,除去弱口令与暴力破解,最常见的就是SQL注入。SQL注入可以在SQLNuke——mysql 注入load_file Fuzz工具看到如何利用,而本篇博客的重点是利用MySQL隐形的类型转换绕过WAF的检测。
(1)表单login.html
<html>
<body>
<form
id
=
"form1"
name
=
"form1"
method
=
"post"
action
=
"login.php"
>
<label>
UserName
<input
name
=
"user"
type
=
"text"
id
=
"user"
/>
</label>
<br/>
<label>
Password
<input
name
=
"password"
type
=
"text"
id
=
"password"
/>
</label>
<br/>
<label>
<input
name
=
"login"
type
=
"submit"
id
=
"login"
value
=
"Login"
/>
</label>
</body>
</html>
(2)认证处理login.php
<?
php
if
(
isset
(
$_POST
[
"login"
]))
{
$link
=
mysql_connect
(
"localhost"
,
"root"
,
"toor"
)
or
die
(
"cannot connect database"
.
mysql_error
());
mysql_select_db
(
"member"
)
or
die
(
"cannot select the db"
);
$query
=
"select * from user where user='"
.
$_POST
[
"user"
].
"'and password='"
.
md5
(
$_POST
[
"password"
]).
"'"
;
echo $query
.
"<br/>"
;
$result
=
mysql_query
(
$query
)
or
die
(
"the query failed:"
.
mysql_error
());
echo
"<br/>"
;
$match_count
=
mysql_num_rows
(
$result
);
if
(
$match_count
){
while
(
$row
=
mysql_fetch_assoc
(
$result
)){
echo
"<strong>User: </strong>"
.
$row
[
"user"
].
"<br/>"
;
echo
"<strong>Password: </strong>"
.
$row
[
"password"
].
"<br/>"
;
echo
"<br/>"
;
}
}
else
{
echo
"Wrong User or password <br/>"
;
echo
'<a href="http://10.1.36.34/login.html">Back</a><br/>'
;
}
mysql_free_result
(
$result
);
mysql_close
(
$link
);
}
注意红色字体部分,为用户输入的用户名和密码,没有进行任何过滤就传入到数据库中去进行查询. 该脚本将查询字符串及查询结果展示在页面中以供直观的演示SQL查询结果。
大家看一张常见的用户表user表,由两个字段构成user用户名和password字段。
表中包含8行数据
查询结果如下图所示
(2)输入用户名45a’+'b’#
dani,tanjiti,dani123,0dani 对应的数值为0
123dani,123tanjiti对应的数值为123
45dani,045tanjiti对应的数值为45
'a'+'b'对应数值为0+0=0,会把类型转换后为0的用户名搜索出来
'45a'+'b'对应数值为45+0=45,会把类型转换后为45的用户名搜索出来
(3)输入用户名a’MOD’1′#
’a'MOD’1′对应的数值为0 MOD 1 =0,会把user对应数值为0的搜索出来
”-”对应的数值为0 -0 =0,会把user对应数值为0的搜索出来
bit操作符&,|,^,<< ,>>也有同样的效果
”/’1′对应的数值为0 /1 =0,会把user对应数值为0的搜索出来
bit操作符&,|,^,<< ,>>也有同样的效果
(6)输入用户名a’&’b'#
’a'&’b'对应的数值为0&0 =0,会把user对应数值为0的搜索出来
对应WAF防火墙而言,当输入’ or 1=’1 时,ModSecurity防火墙会报错(我没有试验过ModSecurity,博客中有介绍)