SQL注入—基础知识总结
- 1、注释符
- 1.1、Mysql中注释符有三种
- 1.2、总结
- 2、information_schema库
- 2.1、了解information_schema库
- 2.2、常用注入语句
- 3、order by
- 3.1、了解order by
- 3.2、order by之判断列数
- 4、union select
- 4.1、了解union select
1、注释符
SQL注入的时候经常会用到注释符注释掉SQL语句后边的拼接内容,在字符型参数注入中常见。
1.1、Mysql中注释符有三种
(1) 注释符:- -
– 在mysql中使用时有时会出错。原因是 - - 后面的空格在URL中最后会被忽略,导致- -与后面的语句连接在一起,无法形成有效的mysql语句。在使用时将空格替换成 + ,即- -+
就可以了。在注入时除了- -+外,- -‘也可以完成注入语句。
(2) 注释符:#
#比较少用,很多情况使用会出错。原因是 # 不能被浏览器识别进行URL编码,数据传输过程中不会把它一起带入后端,转换成URL编码%23就可以使用了。
(url中 # 号是用来指导浏览器动作的(例如锚点),对服务器端完全无用,所以HTTP请求中不包括 #)
(3) 注释符: /**/
因为注释符#、-- 都是把后面的语句全部注释掉了,而内联注释则是注释指定部分,需要一前一后闭合,所以在传参那里几乎不做注释语句用,而是用于过滤空格等bypass。
?id=-1'/**/union/**/select/**/1,2,database()--+
过滤空格,用/**/代替空格
(4) 注释符:payload结尾单引号闭合
http://localhost/sqlilabs/Less-1/?id=-1’ union select 1,2,database()’
1.2、总结
GET提交方式:
- –(--后面有空格)
- %23
- payload结尾单引号闭合
POST提交方式:
- –(--后面有空格)
- #(POST提交的数据,不用进行url编码,是POST原文)
- payload结尾单引号闭合
2、information_schema库
2.1、了解information_schema库
information_schema可以看作是数据库,保存了Mysql服务器所有数据库的信息。
information_schema库保存了Mysql服务器所有数据库的信息。如数据库名、数据库的表与访问权限等。简单点说,Mysql服务器上,到底有哪些数据库,各个数据库有哪些表,每张表的字段类型是什么,各个数据库要什么访问权限才能访问,等等信息都保存在information_schema这张表中。
mysql的information_schema数据库包含了一些表和视图,提供了访问数据库元数据的方式。
元数据,是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。有时用于表述该信息的其他术语包括 “数据词典” 和 “系统目录”。
下面列举一些重要的数据字典表:
(1)SCHEMATA表:提供了关于数据库的信息,show database的结果取自这里
(2)TABLES表:提供了关于数据库中表的信息
(3)COLUMNS表:提供了表中列的信息
2.2、常用注入语句
查询所有数据库名
select group_concat(schema_name) from information_schema.schemata
查询test库中的所有表名
select group_concat(table_name) from information_schema.tables where table_schema=‘test’
查询users表中的所有列名
select group_concat(column_name) from information_schema.columns where table_name=‘users’
查询表中的内容
select group_concat(username,password) from test.users
3、order by
3.1、了解order by
order by 是mysql中对查询数据进行排序的方法,使用示例:
select * from 表名 order by 列名(或数字)asc;升序(默认)
select * from 表名 order by 列名(或数字)desc;降序
这里的重点在于order by后既可以填列名或数字。举个例子,id是user表中第一列的列名,如果根据id来进行排序,有两种写法:
select * from user order by id;
select * from user order by 1;
3.2、order by之判断列数
sql注入时,常用下面的语句来判断列数:
id=1’ order by 3- -+
id=1’ order by 4- -+
当第一条语句正常回显,第二条语句报错时,就可以判断表有三列。(当排序超出了范围就会报错)
这里的order by判断列数,实际是猜测查询出的列数,而不是表实际的列数。order by本来就是对查询的结果进行排序,针对的就是查询结果而不是原表。所以order by猜解得到的列数还跟后端的逻辑有关。
在sql注入时,将order by后面的数字增加直至报错,就可以判断列数。
4、union select
4.1、了解union select
union的作用是将两个select查询结果合并
如下图所示,union将两个select的查询结果合并在一起。
这里我们只想显示我们要查询的结果,即1,2,3。只有当第一个select结果是空集时,页面才会只显示第二个select查询的结果。 所以,我们这里将id置为-1,即第一个select结果为空集。页面就只会显示第二个select查询的结果。
MySQL中UNIOIN规则
- UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分隔
- UNION中的每个查询必须包含相同的列
- UNION会从查询结果集中自动去除了重复行
- 只有最后一个SELECT语句可以使用INTO OUTFILE,当然,全部UNION的结果会写到文件中去。
UNION注入的流程
- 首先判断是否存在注入点及注入的类型。
- 观察回显的位置。
- 使用order by查询列数。
- 获取数据库名。
- 获取数据库中的所有表名。
- 获取数据库的表中的所有字段名。
- 获取字段中的数据。
常使用下列语句来探测数据库信息:
url?id=-1 union select 1,database(),3- -+
常见查询函数
version() — 数据库版本
user() — 数据库用户
database() — 当前所在数据库
current_user() — 当前用户名
system_user() —系统用户名
session_user() — 连接到数据库的用户名
@@basedir — 数据库的安装位置
@@datadir — 数据库文件存放目录