目录
1 SQL注入简介
1.1 SQL注入概述
- 定义:SQL注入就是指Web应用程序对用户输入数据的合法性没有判断,前端传入后端的参数是攻击者可控的,并且参数带入数据库查询,攻击者可以通过构造不同的SQL语句来实现对数据库的任意操作。
- 动态SQL语句:一般情况下,开发人员可以使用动态SQL 语句创建通用、灵活的应用。动态SQL语句是在执行过程中构造的,它根据不同的条件产生不同的SQL 语句。当开发人员在运行过程中需要根据不同的查询标准决定提取什么字段(如select语句),或者根据不同的条件选择不同的查询表时,动态地构造SQL语句会非常有用。
- 下面以PHP语句为例。由于这里的参数ID可控,且带入数据库查询,所以非法用户可以任意拼接SQL语句进行攻击。
$query =”SELECT * FROM users WHERE id= $_GET['id']";
1.2 SQL注入原理
- 目前,大多数Web编程语言提供了操作SQL的接口,以方便与数据库进行交互。但是在开发Web应用的过程中,由于忽视了代码的健壮性和安全性,攻击者可以构造巧妙的SQL语句从而获取到敏感数据,因此导致了SQL这种攻击方式的流行。
- SQL 注入漏洞的产生需要满足以下两个条件:
- 参数用户可控:前端传给后端的参数内容是用户可以控制的。
- 参数带入数据库查询: 传入的参数拼接到SQL吾句,且带入数据库查询。
1.3 SQL注入漏洞的危害
- 攻击者未经授权可以访问数据库中的数据,盗取用户的隐私以及个人信息,造成用户的信息泄露。
- 可以对数据库的数据进行增加或删除操作,例如私自添加或删除管理员账号。
- 如果网站目录存在写入权限,可以写入网页木马。攻击者进而可以对网页进行篡改,发布一些违法信息等。
- 经过提权等步骤,服务器最高权限被攻击者获取。攻击者可以远程控制服务器,安装后门,得以修改或控制操作系统。
2 SQL注入漏洞分类
2.1 注入位置分类
根据SQL注入漏洞原理,在用户“可控参数”中注入SQL语法,也就是说WEB应用在获取用户数据的地方,只要带入数据库查询,都有可能存在注入,这些地方通常包括:
- GET 数据
- POST 数据
- http请求头参数注入
- HTTP Referer:是header的一部分,当浏览器请求网页时,会自动携带一个请求来源,如果后端存在交互,则会引发注入问题的产生。
- User-Agent 请求头,该请求头携带的是用户浏览器的标识信息,如果此时带入数据库查询,则同样会触发注入问题的产生。
- X-Forwarded-For:简称XFF头,它代表客户端,用于记录代理信息的,每经过一级代理(匿名代理除外),代理服务器都会把这次请求的来源IP追加在X-Forwarded-For中
- Cookie:指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)
- X-Real-IP:只记录真实发出请求的客户端IP。
- Accept-Language:请求头允许客户端声明它可以理解的自然语言,以及优先选择的区域方言
- HTTP_CLIENT_IP:该属性是PHP内置属性,同样取得的是客户端的IP,同样可控,如果带入数据库,则会产生注入问题。
- ……
2.2 注入数据类型分类
从数据类型分类来看,SQL注入分为数字型和字符型。
- 数字型注入:注入点的数据拼接到SQL语句中是以数字型出现的,数据两边没有单引号、双引号括起来。
- 字符型注入:注入点的数据两边有单引号、双引号括起来。
2.3 注入手法分类
- union联合查询注入
union查询注入是最基础的注入。在SQL中, UNION 操作符用于合并两个或多个 SELECT 语句的结果。union 查询注入利用 UNION 关键字可以追加一条或者多条额外的 SELECT 查询,并将结果追加到原始查询中。 - 盲注
盲注指的是在不知道数据库返回值的情况下对数据中的内容进行猜测,实施SQL注入。主要分为布尔盲注与基于时间的盲注。 - 报错注入
黑客攻击时常根据错误回显进行判断,但是现在非常多的Web程序没有正常的错误回显,这样就需要我们利用报错注入的方式来进行SQL注入了。 - 堆叠查询注入
堆叠注入为攻击者提供了很多的攻击手段,通过添加一个新的查询或者终止查询,可以达到修改数据和调用存储过程的目的。 - 二次注入
在将数据(一次注入的)存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入。比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中;然后在下一次使用中在拼凑的过程中,就形成了二次注入。 - 宽字节注入
在使用PHP连接MySQL的时候,当设置“set character_set_client = gbk”时会导致一个编码转换的问题,这就是常说的宽字节注入。 - base64注入
base64注入是针对传递的参数被base64加密后的注入点进行注入。除了数据被加密以外,其中注入方式与常规注入一般无二。
3 SQL知识基础
为了更好地进行SQL注入,需要对SQL有所了解,在之前专栏学过的SQL基础语句后,此处对与SQL注入相关性较大的知识做一个温习。
3.1 MySQL 元数据库 information_schema 内容简介
information_schema 数据库跟 performance_schema 一样,都是 MySQL 自带的信息数据库。其中 performance_schema 用于性能分析,而 information_schema 用于存储数据库元数据(关于数据的数据),例如数据库名、表名、列的数据类型、访问权限等。
在该数据库中,有三个表对SQL注入帮助较大,分别是schemata表、tables表、和columns表。.
- schemata:记录当前 mysql 中所有数据库的信息。该表中字段名SCHEMA_NAME记录着所有数据库的名字。
- tables:存储 mysql 中的所有表的信息。该表主要字段名如下:
- TABLE_SCHEMA:记录该表属于哪个数据库。
- TABLE_NAME:记录该表的名字。
- colunms:存储 mysql 中所有字段信息。该表主要字段名如下:
- TABLE_SCHEMA:记录该字段名属于哪个数据库。
- TABLE_NAME:记录该字段属于哪个表。
- COLUMN_NAME:记录该字段名。
3.2 MySQL 常用参数
可以利用select语句加上下列常用参数,来查询所需要的信息。比如select 1 <>2
数据库将返回1
,又比如select version()
数据库将返回版本号 。常用参数如下,更多参数、运算符、函数参考文章《SQL常用运算符、通配符及参数》《SQL常用函数简要解析》
参数名 | 用途 |
---|---|
version() | 返回当前数据库软件版本 |
database() | 返回当前数据库名 |
user() | 返回用户名 |
current_user() | 返回当前用户名 |
system_user() | 返回系统用户名 |
@@datadir | 返回数据库路径 |
@@version_compile_os | 返回操作系统版本 |
4 总结
- 了解SQL注入漏洞的概念和危害;
- 理解SQL注入漏洞产生的两个条件;
- 了解SQL注入分类方式;
- 加深SQL和数据库相关知识的理解。