您的位置:首页 > 数据库

sqli-labs学习教程(五)

2017-02-25 11:54 218 查看
上一篇教程发在freebuf上了:安全科普:SQLi Labs 指南(Part 3)

下面开始Advanced Injections部分的学习。
第二十一节:Cookie injection – base64 encoded – singlequotes and parenthesis

这一课和Basic Injections的第二十一课是一样的,应该是作者的一个小bug吧。
第二十二节:Cookie Injection – base64 encoded – double quotes

这一课和上一课方法一样。上一课我们用的是admin') order by 4#,这一课我们用的是admin" order by 4#。





刷新一下,出来错误信息了。


第二十三节:GET –Error based – strip comments

这一课加了单引号还是会报错,但是无论加上--+注释还是#注释都没有效果。这里我们看这个错误的信息,1后面连续跟了两个单引号,说明注释#已经被删掉了。


看一下源代码,这里果然对这两种注释都进行了过滤。


那么我们的办法就是自己构造sql语句来闭合单引号。前面我们已经知道结果总共有三列,在不知道的情况下只能猜有多少列。如果union select的列数不为3时会报错The used SELECT statements have a different number of columns。 


知道有三列之后就好办了。比如我查询一下数据库的版本。


前面几课我们枚举表名、列名等使用的是类似于这样的语句(以第一课为例)

?id=0' union select1,2,table_name from information_schema.tables wheretable_schema=0x7365637572697479 limit 1,1%23 

但是这里不能再使用limit了,因为我们无法使用注释,不好处理后面加的引号。一个可行的办法是使用group_concat函数来一次性提取一列中的所有信息。


第二十四节:POST –Second Oder Injections *Real treat* – Stored Injections

这里二次注入就是说第一次先注入一个有问题的字符串存储在数据库中,第二次利用这个有问题的字符串进行sql注入。我们先来看看这个网站吧。进去以后是一个登录的页面,还可以注册新用户。我们注册一个新用户为admin' #,密码就填一个123456好了。



现在我们就可以用这个新建的账号登录了。登录进去以后可以修改密码。


这里的sql语句无非就是update users set newpassword=xxx where username='admin' #' and currentpassword='xxx'。但是我们的用户名中有注释符,所以实际执行的是update users set newpassword=xxx where username='admin'。这样就在本来不知道admin的密码的情况下重新设置了新的密码。我们把新的密码设为111111,Current Password那里随便填点什么都行,反正会被注释掉嘛。


提示修改成功。



再使用原来的密码当然就登不上去了。


第二十五节:GET –Error based – All your OR & AND belong to us – string single quote

我们先试试注入1' or '1'='1#。


下面有提示,我们看到or被过滤掉了。无论是OR、Or、oR还是OR都会被过滤。看一下代码,因为这里PHP正则表达式/i表示忽略大小写。


我们可以使用逻辑运算符&&和||来绕过黑名单。




可以看到这里直接用&&报错了,要先进行URL编码。


另外我们还可以多写几个or或者and来绕过,虽然preg_replace会替换所有匹配的字符,但是它只执行了一次。




第二十五a节:GET – Blind Based – All your OR & AND belong to us – Intigerbased

这里跟前面基本一样,只不过是没有返回错误信息,所以也就不再说了。用order by猜字段的时候要注意order中的or会被过滤。


第二十六节:GET – Error Based – All your SPACES and COMMENTS belong to us

看一下代码,这次过滤的有or、and、注释、空格和斜杠。



前面过滤注释我们用的办法是自己闭合单引号。过滤or和and我们用的办法是使用逻辑表达式或者双写。

过滤空格有哪些常见的办法呢?
一是用/**/代替空格。但是这里注释也被过滤了。
二是用括号代替空格。在MySQL中,括号是用来包围子查询的。任何可以计算出结果的语句,都可以用括号包围起来,而括号的两端可以没有多余的空格。但是在这里空格的位置是在 union select ,所以也不能用这种办法。
三是可以用URL编码。%20、%09、%0a、%0b、%0c、%0d、%a0都能起到表示空格的效果。%20是空格,%09到%0d是制表符换行符等等,这里能用的就是%a0了。正则匹配到它时识别为中文字符,所以不会被过滤掉。但是在进入SQL语句后,MYSQL不认中文字符,所以当作空格处理。比如我要查数据库的版本id=0' unionselect 1,version(),3&&'1,编码之后是id=0%27%A0union%A0select%A01%2Cversion%28%29%2C3%26%26%271。


第二十六a节:GET – Blind Based – All your SPACES andCOMMENTS belong to us –String – single quotes – Parenthesis

这里还是跟前面基本一样,只不过是没有返回错误信息,所以也就不再说了。比如我要查数据库的版本id=0') union select 1,version(),3&&('1,URL编码之后是id=0%27%29%A0u nion%A0select%A01%2Cversion%28%29%2C3%26%26%28%271。


第二十七节:GET – Error Based – All your UNION & SELECT Belong to us –String– Single quotes

还是先看一下代码,这次过滤的有注释、空格、union和select。


这里在判断union和select只包含select、union、UNION、SELECT、Union、Select这几种情况,我们改一下大小写就可以轻松绕过。


我们前面说过用括号绕过空格,这里来尝试一下。当然,union select那里还是只能用%a0的。尝试注入?id=0'%a0UNion%a0SElect(1),version(),(3)or(1)='1。


第二十七a节:GET – Blind Based – All your UNION &SELECT Belong to us – Double Quotes

这里还是跟前面基本一样,只不过是没有返回错误信息,所以也就不再说了。
第二十八节:GET – ErrorBased – All your UNION & SELECT Belong to us – String – Single quote withparenthesis 

看了一下这课的代码,没有返回错误信息,这明明是盲注嘛。应该又是作者的一个小bug吧。。。

看一下过滤的黑名单。



我们看到最后一句$id= preg_replace('/union\s+select/i',"",$id);

\s表示匹配空白符,+表示匹配多次,\i表示不分大小写。来个例子。


看来union和select之间还是只能用%a0啊。




第二十八a节:GET – Blind Based – All your UNION & SELECT Belong to us –single quote – parenthesis 

这一节和上面基本一样,过滤条件还变少了,所以就不再说了。



第二十九节:GET – Errorbased – IMPIDENCE MISMATCH – Having a WAF in front of web application 

注:这里怀疑是作者拼写有错误,IMPIDENCE 应为IMPEDANCE,后面同。

WAF是Web Application Firewall的缩写,那我们就来看一下这个WAF是怎么防止SQL注入的以及应该怎么绕过它。前面我是用xp sp3+xampp搭建的环境,这几课还需要安装jdk、tomcat和mysql-connector-java。所以我在ubuntu上重新搭建了环境,下面简单说一下搭建的过程。

1.安装apache、mysql和php并开启mysql和apache服务。

sudo apt-get install apache2 mysql-servermysql-client php5 php5-gd php5-mysql

sudo service mysql restart

sudo /etc/init.d/apache2 restart

2.把sqli-labs文件夹复制到var/www/html,把sql-connections/db-creds.inc中mysql的用户名和密码改成自己的。

         

3.下载jdk、tomcat和mysql-connector-java并解压(这里jdk的版本是8u111,tomcat的版本是7.0.73,mysql-connector-java的版本是5.1.40,其它版本类似)。


4.把mysql-connector-java中的mysql-connector-java-5.1.40-bin.jar复制到jdk1.8.0_111/jre/lib/ext中。


5.把jdk1.8.0_111复制到usr/share目录下。


6.把apache-tomcat-7.0.73复制到var/lib目录下。



7.设置PATH。



8.启动tomcat。



9.把所需要的文件复制到tomcat的webapps/ROOT目录下并解压。



如果一切顺利的话,在浏览器中访问http://localhost:8080/sqli-labs/Less-29/就可以看到第29课了。


我们先用单引号试一下。与之前的课程不同的是,加了单引号跳转到了另一个页面。


看一下代码。


首先getParameter("id")取得id的值,然后再用正则表达式匹配,如果是数字那么就认为是合法的,否则跳转到hacked.jsp页面。那么我们应该怎么绕过呢?这里为大家介绍HPP(HTTP Parameter Pollution)即HTTP参数污染的攻击方式。我们可以看到,作者在页面上给出了两个pdf资料,其中AppsecEU 09_CarettoniDiPaola_v0.8.pdf有提到这个问题。


其实,在《白帽子讲Web安全》这本书里面也提到过这个问题。在GET和POST的HTTP请求中,经常会出现多个参数的情况。


在多个参数相同的情况下,HTTP后端可能有不同的处理方式。


我们这里使用的PHP+Apache的环境,按照上表,只会对最后一个参数进行处理。那现在就来验证一下。在index.jsp中加这几行代码,方便我们看看id和qs的值。


输入http://192.168.153.137:8080/sqli-labs/Less-29/?id=1&id=8,页面返回了id为8的用户的信息。可以看到,getParameter只取得了第一个id的值1,而getQueryString取得了?后面的所有值。


构造第一个id为一个合法的数字,第二个id处填上sql注入的语句。WAF检查的是第一个id,而后台实际执行的是第二个id,这样就可以绕过WAF了。


第三十节:GET – BLIND– IMPIDENCE MISMATCH – Having a WAF in front of web application

和上一节差不多,把单引号换成双引号就行。
第三十一节:GET – BLIND– IMPIDENCE MISMATCH – Having a WAF in front of web application 

和上一节差不多,再加一个括号就行。

 

 

 
 
 
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: