漏洞重温之sql注入(四)

漏洞重温之sql注入(四)

sqli-labs通关之旅

Less-16

进入第十六关,首先可以看到网页上有登录选项。猜测跟上一关内容应该一样。

不多废话,直接看源码。

首先,我们注意这几条代码。

$uname='"'.$uname.'"';
$passwd='"'.$passwd.'"';
@$sql="SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1";

如果看过我写的前几篇文章,应该明白我注意这三条代码的原因,因为我们的目的是为了闭合原有的sql语句,拼接我们希望系统执行的语句,所以要进行sql注入,我们首先要闭合原有内容。

通过上面三条代码,我们知道,该处闭合,我们需要使用 ") 进行闭合。

又因为网页是使用post请求获取参数的,所以我们可以利用抓包工具在数据包中进行注入,也可以使用hackbar的post data属性直接在网页进行注入。

我使用的是后者。

随后,我们可以查看if代码块里面的内容,我们可以看到,虽然两块代码是有足够区别的,但是却不能直接返回我们希望返回的信息,所以这里我们只能利用盲注。

构造测试payload:

1") or 1=1 -- 
1") or 1=2 -- 

如果上面两条代码都成功执行,并且网页返回有明显区别,那么我们就可以直接使用布尔型盲注手法进行注入。

可以看到,区别很明显,所以我们可以使用布尔型盲注手法获取我们想要的数据,这里因为步骤比较繁琐,我之前的文章里有详细步骤,这里就不多赘述。

第十六关,通关。

Less-20

前几关因为我对报错注入的函数的理解个人认为尚且不足,17.18.19三关我会在研究之后总结文章补上,所以先看20关。

进入二十关,首先可以看到,网页和前面几关并没有太大区别。

但是代码的位置我们却可以明显的看到问题。

首先,我们可以看到,网页先封装了一个check_input函数。

在这个函数中,使用了mysql_real_escape_string这个函数对值进行转义。

然后,我们看登录页面代码。

网站在登录页面代码中,调用了这个函数将我们输入的uname和passwd进行转义,所以一般情况来说,我们无法在这种情况下进行注入。

因为我们输入的代码,在转义之后,无法发挥我们希望他发挥的作用。

但是,接着往下看,我们可以发现另外一个问题。

当我们登录成功后,网站利用我们提交的数据生成了一个$cookee参数,而我们访问登录成功后的页面时,我们的个人信息会被网站直接利用$cookee参数从数据库查询。

这也就说明了,虽然在登录页面,我们无法进行sql注入,但是在登录成功后,我们却可以利用$cookee参数完成注入攻击的目的。

同时,我们观察这条代码:

$sql="SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";

这条代码告诉我们,如果想要利用$cookee参数完成注入,我们必须要使用单引号进行闭合。

所以,首先我们先利用Dumb/Dumb账号登录。

可以看到,我们的信息会被网站反馈回来。

因为我们需要利用cookie进行注入,刷新页面,使用burp抓包。

直接在uname参数后面,按照联合查询的方式构造语句。

payload:

' and 1=1 -- 
' and 1=2 -- 

可以发现,网站因为我们代码不同,返回的结果也不同,继续注入。

payload:

' order by 3 -- 

' and 1=2 union select 1,2,3 -- 

如果对于剩下的操作还不熟悉的话,可以多看看我前面几关通关过程。

第二十关,通关。

Less-21

二十一关页面和20关一致,查看源码。

登录页面代码是一样的,所以这一关也需要在登录之后利用$cookee参数进行注入。

但是这里我们要注意两个代码。

$cookee = base64_decode($cookee);
$sql="SELECT * FROM user WHERE username=('$cookee') LIMIT 0,1";

第一条代码,明确的告诉了我们,这一关的cookee参数使用base64加密了,同时,第二条代码告诉我,这里的闭合,需要使用')。

先登录,然后刷新页面抓包。

我们将uname后面的值复制之后进行解码。

得到了我们之前登录使用的用户名,也就可以确认,如果我们想要利用cookee参数完成注入,那么我们的payload也需要使用base64进行加密。

将加密后的代码复制到uname后面,即可完成注入。

第二十一关,通关。

Less-22

这一关依然只需要关注几行代码。

$cookee = base64_decode($cookee);
$cookee1 = '"'. $cookee. '"';
$sql="SELECT * FROM users WHERE username=$cookee1 LIMIT 0,1";

首先,第一行告诉我们,这里依然使用的是base64加密。第二行和第三行告诉我们,想要完成闭合,需要使用双引号。

登录,抓包,构造payload:

Dumb" and 1=2 union select 1,version(),database() -- 

二十二关,通关。

Less-23

进入二十三关,页面直接显示输入id参数,直接可以判断该位置是get型注入。

给出参数之后,直接查看源码。

可以看到,网站使用了preg_replace函数将# 和 -- 两个注释符号替换为空,这就导致了我们无法使用注释符号来进行注入,但并非无法注入。

首先我们要清楚,我们使用注释符号的原因是因为我们需要闭合原有的sql语句,需要使用包裹参数值的符号进行闭合,但是我们输入闭合之后,又会导致原本的语句多出一个符号导致代码出错,所以需要使用注释来将多余的符号注释掉。

但是,如果我们构造的代码可以直接利用到闭合的符号,那就不需要注释了。

构造payload:

-1' union select 1,version(),3 or '1' = '1

这里,要注意两点。

首先,我们使用的是union联合查询语句,所以,我们需要让原本的语句执行错误,这里我们可以直接将参数改为负数,或者可以在参数后面跟上 and 1=2来达到目的。

其次,我们需要的是让闭合之后,单引号不再多余,这里我使用的是'1'='1'的方式,之所以使用or连接符,是因为我们需要执行的代码在前,我们知道代码是没有错误的,所以or后面理论上只要可以让闭合符不再多余,拼接什么都可以。

当然,这只是一种方法,也是我在面对问题的时候第一个想到的办法,如果有其他更好的办法,可以联系我,再学习研究之后,我会再次对该关卡进行总结。

第二十三关,通关。

posted @ 2020-08-27 06:26  小明-o3rr0r  阅读(238)  评论(0编辑  收藏  举报