SQL注入(SQL Injection)总结

注: 全文以 MySQL 数据库为例。

1、SQL注入简述

SQL注入(SQL Injection)是指,由于开发人员在编写网站的数据交互代码,也就是拼接的SQL语句时,对用户输入的参数没有做安全过滤,导致用户输入的一些不合法的查询参数被成功解析,并在数据库中执行,窃取数据库内容。

产生原因:

  • 构建的SQL语句中包含了不被信任的数据,如用户输入信息等,但是又没有做安全防范。

比如某站点构建的查询语句参数是id值,一般都是传入id = 1、2、3等这类数字,但是当用户非法输入参数:id = 1 and database(),那么就有可能查询出当前的数据库名,以此类推。

SQL注入由于直接对网站的内部数据造成威胁,窃取和修改用户信息,破坏数据的机密性和完整性,因此危害极大,前些年这类漏洞比较多,但是随着各种框架的产生,和程序员本身的安全意识的提升,目前SQL注入漏洞已经很少了。

2、SQL注入分类

SQL注入的分类比较多,是从以下几个不同的角度来分类的:
参数类型、注入位置、结果反馈。

参数类型:

  1. 数字型:注入点的参数是整型,也就是 id = id
  2. 字符型:注入点的参数是字符型,也就是 id = ‘id’。(宽字节注入也属于字符型)

注入位置:

  1. GET注入:注入位置在URL参数中
  2. POST注入:注入字符在POST数据中
  3. Cookie注入:向Cookie字段中注入内容
  4. HTTP头注入:HTTP头的Referer和user-agent字段中存在注入漏洞

结果反馈:

  1. 基于报错:注入结果会显示在页面上
  2. 盲注
    2.1)基于布尔的盲注
    通过加入一些判断命令,如判断数据库名长度:1’ and length(database()) = 10 #,根据是否有响应来猜测判断是否正确。可以借助SUBSTR、LIMIT、ASCII等一些特殊的命令及函数进行猜测。
    2.2)基于时间的盲注
    在SQL语句中添加延时函数,根据相应时间来判断是否存在SQL注入,常用的延时函数或指令有sleep、repeat等。

一些盲注常用的函数:

  1. if(condition,A,B):若condition返回真则执行A,假则执行B
  2. substr(str,A,B):字符串截取函数,截取str字符串从A位置开始,截取B个字符
  3. left(str,A):类似字符串截取函数,返回str字符串从左往右数的A个字符
  4. count(A):计算A的数目,常用与查询数据表、数据列、数据内容的条数
  5. len(A):计算A的长度,常用于返回数据库名、数据表名、数据列名的长度
  6. ascii(A):返回A的ascii码,当逐字猜解限制单引号的输入时,可以通过查询ascii码来绕过

3、SQL注入流程

SQL注入一般有以下几个步骤:

  • 找出注入点,并判断是字符型还是数字型。
    (使用 and 1=1 或 or 1=1,和 and 1=2 或 or 1=2)
  • 猜当前表的字段数
    (使用 order by)
  • 确定显示的字段顺序
    (使用联合查询 union select)
  • 获取当前数据库
    (database())
  • 获取当前表
    (select table_name from information.schema.tables where table_schema=database())
  • 获取字段
    (select column_name from information_schema.columns where table_name=‘TableName’ )
  • 得到数据

table_schema是数据库的名称,table_name是具体的表名,table_type指的是表的类型

注: 一般的SQL注入就是按照这个流程,盲注也是如此,只不过所有的查询信息都通过一些构造的反馈来显示,如时延。

一些数据库常用的函数:

  • user() 当前用户名
  • database() 当前所用数据库
  • current_user() 当前用户名(可以用来查看权限)
  • version() 数据库的版本
  • @@datadir 数据库的路径
  • load_file() 读文件操作 into
  • outfile()/into dumpfile 写文件操作

其中,特别注意:information_schema 库

information_schema是MySQL中自带的一个特别特殊的库,它存储着数据库中所有的库名、表名和字段信息以及访问权限,也就是存储数据库元数据(关于数据的数据),访问该数据库就可以得到数据库中所有信息。

因此SQL注入的关键是查询该数据库中的内容,可通过下面两个语句,查询指定数据库中的所有表名和字段:

1)select table_name from information_schema.tables;
在这里插入图片描述
2)select column_name from information_schema.columns;
在这里插入图片描述
所以,SQL注入中查询数据时,information_schema库必不可少。

4、SQL注入防范

防范SQL注入,要根据其形成原因来分析,因此可以总结为以下几个方面:

  1. 不构建动态SQL语句!
    比起过滤、转译,能从根本预防SQL注入的方法,就是不直接使用用户的输入拼接SQL语句,而是使用参数化查询,或者是使用准备好的查询语句。
    但是,这种情况下也不能忘记过滤,要对用户的输入做安全过滤。
  2. 严格区分用户权限和管理员权限
    对普通用户的权限,尽可能做到最低,且要明确区分管理员权限和用户权限。
  3. 避免向用户提示数据库错误
    攻击者可以利用这些报错信息,来进行渗透。

除此之外,还有一些其他的方法,如数据加密、使用Web防火墙、及时更新数据库、打补丁等,这些都是广谱防护,有效范围广。

发布了88 篇原创文章 · 获赞 121 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43968080/article/details/104147180