2017-赛客夏令营-Web-Injection V2.0
WP
还是一道SQL注入的题目。经过尝试,用户名是admin,但是过滤了空格和括号。空格可以用/**/或者TAB来绕过,但是括号的过滤导致了各种函数都不能使用。
我在网上查找绕过括号过滤的方式,找到了order by盲注,文章如下:
sql注入之order by注入
本来我以为的是要不断的**密码,但是我直接就爆出flag了:
本来这种方式的用法是这样的,如果你联合注入的内容比真实的密码小,就会回显admin的结果。如果你联合注入的内容比真实的密码大,就会回显你select的用户名为1的结果。但是这里却直接爆了flag。
后来上网查了一下,原来是后端对于登录判断的方式的不同导致的。
一种是这样:
$username=$_POST['username'];
$password=$_POST['password'];
$sql='select * from user where username='$username' and password='$password'';
#查询
#登陆成功
#第一种方法就是一起验证用户名和密码
另一种是这样:
$username=$_POST['username'];
$password=$_POST['password'];
$sql='select password from user where username='$username'';
#查询
if($row){
if($row['password']==$password)
{
echo 'success';}
else{
echo 'fail';}
}
else{
echo '用户不存在';
}
#第二种方法就是通过先查询用户名,如果用户存在之后验证密码是不是和数据库里面的密码一样。
我用order by注入的时候,以为后端的判断的方式是第一种,其实是第二种。也就是根据你输入的username进行查询,将查询的结果与你输入的password进行比较。如果相等那么就判断登录成功。这也就是我用order by直接就出flag的原因。
user=admin' union select 3 order by 1-- -&pass=3
我也不清楚真实的密码是什么,但是真实的密码与select的3进行比较,3是比密码要大的,order by的结果是select 3是第一个查询出的结果,然后pass与select的结果相同,就可以爆出flag。因此我这样的姿势其实也有些取巧,有些偏了。
正统的方式应该是这样:
user=-1' union select 1-- -&pass=1
不需要考虑真实的密码与select进行比较的结果,直接查询的结果就是你联合注入的内容。
不过order by其实也可以,如果直接order by 1不能出结果,可以尝试order by 1 desc
,因为正序不行,那倒序肯定就可以了呀。
还需要注意的是,如果回显的结果是用户名或者密码错误,大概率判断登录是否成功用的是第一种方式,如果是用户名不存在或者密码错误这样的,大概率是第二种方式。