第三十一关:
换了个闭合
第三十二关:
数据库连接的致命性错误,导致二层ubuntu服务器mysql无法连接
遂跳过
第三十三关:
这一关开始就可以回到我们的phpstudy了,不再需要jspstudy和ubuntu虚拟机的辅助
发现我们的单引号前面被加了一个斜杠 \
观察源码,发现此内容过滤函数:
这里需要涉及一个新的注入姿势:
宽字节注入
当用户提交
此时,发生如下转换
第一步:'被 check_addslashes 函数转义为 \'
第二步:在执行sql查询之前,也即\'代入MySQL服务器之前,mysql_query("SET NAMES gbk");将MySQL的三个字符集设置为 gbk 编码
第三步:character_set_client告诉MySQL Server,传入的是gbk编码,也就是\'被当做了%5C%27传入
第四步:character_set_client -> character_set_connection编码完全一致,数据没有做任何转换,所以输入是%5C%27,输出的是%5C%27
第五步:character_set_connection-> table charset这里我们需要关注下所使用的表的字符集
可以看到id参数没有设置编码方式,不会对%5C%27进行处理。在这里MySQL服务器将查询语句执行,并返回结果。
执行的SQL语句为:
$sql="SELECT * FROM users WHERE id='1\'' LIMIT 0,1";
'被转义无法进行注入
第六步:table charset -> character_set_results由于character_set_results字符集也设定为 gbk ,保证了输出内容没有乱码。
通过上面的分析,我们发现用户提交的数据实际上只被处理了两次,一次是check_addslashes对危险字符的处理,另一次是gbk编码。所以,我们可以将以上步骤简化为:
数据 ==== (check_addslashes)====XXX====(GBK)====代入数据库执行的内容
宽字节注入
提交:
http://127.0.0.1/Less-33/?id=1%df'('浏览器自动进行url编码%27)
根据以上分析,发生如下转换:
%df%27====>(check_addslashes)====>%df
%5c%27====>(GBK)====>運'
(%5c就是 \ )
%df%27在线url解码是
估计是字符不识别吧
MySQL执行的语句为:
$sql="SELECT * FROM users WHERE id='1運'' LIMIT 0,1";成功将单引号闭合,可以进行SQL注入。
宽字节注入2.0
为了避免漏洞,网站一般会设置UTF-8编码,然后进行转义过滤。但是由于一些不经意的字符集转换,又会导致漏洞。
使用set names UTF-8指定了UTF-8字符集,并且也使用转义函数进行转义。有时候,为了避免乱码,会将一些用户提交的GBK字符使用iconv函数先转为UTF-8,然后再拼接入SQL语句。
mysql_query(“set names UTF-8”) ;
$bar =iconv(“GBK”,”UTF-8”, addslashes($_GET[‘’bar])) ;
提交:
http://127.0.0.1/Less-32/?id=1%e5%5c%27
转换:(%e5%5c转为UTF-8为e9%8c%a6)
%e5%5c%27====>(addslashes)====>%e5%5c%5c%5c%27====(iconv)====>%e9%8c%a6%5c%5c%27
可以看到,多出了一个%5c,将转义符(反斜杠)本身转义,使得后面的%27单引号发挥了作用
第三十三关最终答案:
?id=-1
%df%27%20union%20select%201,2,3%20%23 成功爆除了显示位:2和3
第三十四关:
又回到了POST:
发现输入了单引号闭合以后:
加了注释;
所以可以试试宽字节注入,但是这里没有url的转义,所以我们直接输入:�'
开始报错
试着构造一个永远为真的用户名,注释掉后面的验证密码环节:�' or 1=1 #
爆出了id=1的用户名和密码
然后在此基础上利用报错注入的手段:
�' AND(SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT(SELECT CONCAT(CAST(DATABASE() AS CHAR),0x7e)) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema=DATABASE() LIMIT 0,1),FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.TABLES GROUP BY x)a) #
要是前端限制了输入长度就可以用burp直接输入
数据库名就出来了
第三十五关:
这是什么鬼,
直接没有闭合,虽然后注释符号防御但是宛如没有一样
第三十六关:
这里也是可以通关宽字节注入进去
但是这里的注释防御的函数变成了这个:
第三十七关:
又成post了......
这里再次用宽字节成功绕过:
试试报错注入:
数据库名出来了。。。
第三十八关:
嗯嗯嗯???
看一看源码:
没毛病
看一看大佬博客:
好吧,堆叠注入
国内有的称为堆查询注入,也有称之为堆叠注入;
在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句
比如我查询数据库的同时在users表里面新建一个alexz的用户(密码同用户名):
id=-1' union select 1,database(),3;insert into users values(18,'alexz','alexz') --+
敲了回车之后,我在id=18试试:
好了
第三十九关:
无言独上西楼,月如钩
第四十关:
我觉得我已经打到堆叠关卡了
好吧,要不SQL-injection就先到这儿
毕竟我还要去拯救世界呢
= =