SQL注入:web程序对用户输入数据的合法性没有判断,前端传入后端的参数可控的,并且参数带入数据库查询,攻击者可通过构造SQL语句来实现对数据库的任意操作。

1.sql注入原理

满足条件:

参数用户可控:前端传入后端的内容用户可以控制

参数带入数据库查询:传入的参数拼接到SQL语句,且带入数据库查询。

原因:用户输入的数据被SQL解释器执行

2.注入漏洞分类

1)数字型注入

当输入的参数为整型时,如:ID、年龄、页码,若存在注入漏洞,则可认为是数字型

测试:单引号 and语句 (1 and 1=1 , 1 and 1=2),若以上三个步骤全部满足,则可能存在SQL注入漏洞

数字型注入常出现在ASP、PHP等弱类型语言。强类型语言,若试图把一个字符串转换为int类型,会抛出异常,无法继续执行。

2)字符型注入

当输入参数为字符串时,称为字符型。

数字型与字符型注入最大的区别:数字型不需要单引号闭合,而字符型一般使用单引号来闭合。

字符型注入最关键的是如何闭合SQL语句以及注释多余的代码。

注:数据库不同,字符串连接符不同, SQL server的连接符为“+”,Oracle连接符为“||”,MySQL连接符为空格

3)SQL注入分类

SQL只分为两类数字型和字符型。其余注入都是在其两大类的不同展示形式,或者不同的展现位置。

由于数据库进行数据查询时,输入数据一般有两种:一种数字型,一种字符串型. 严格来说:数字也算字符串

post注入:注入字段在post数据中(post请求中username字段存在注入漏洞)

get注入:注入字段在get数据中

cookie注入:注入字段在cookie数据中

延时注入:使用数据库延时特性注入(sleep函数)

搜索注入:注入处为搜索的地点

base64注入:注入字符串需要经过base64加密

3.常见的数据库注入

数据库注入的利用方式:查询数据、读写文件、执行文件

mysql

mysql数据库 5.0之后,默认在数据库存放 information_schema 的数据库,在该库中存在三个表名

schemata 表示存储用户创建的所有数据库的库名

tables 。。。。。。。库名和表名 table_schema数据库库名 table_name 表名的字段名

columns 。。。。。。。。库名、表名、字段名 table_schema数据库库名 table_name 表名的字段名 columns_name 字段名的字段名

 

注释符:

#或 --空格 或 /**/

内联注释 /*! 内容 */

(1)MySQL中的注释

#:注释从#字符到行尾

--:注释从--序列到行尾(使用该注释,在其后需要跟上一个或多个空格)

SQL注入漏洞_sql注入

(2)获取元数据

A查询数据库名称

SQL注入漏洞_sql注入_02

B查询当前数据库表

SQL注入漏洞_数据_03

C查询指定表的所有字段

SQL注入漏洞_数据_04

(3)union查询

用于把多个select语句的结果组合到一个结果集合中,且每列的数据类型必须相同

SQL注入漏洞_数据_05

在Oracle和SQL server中,列的数据不确定时,最好不要用null关键字匹配

(4)MySQL函数利用

需要记住的函数:database():当前网站的数据库 version():当前MySQL版本 user()用户

A load_file()函数读取文件操作

但文件的位置必须在服务器上,文件必须为绝对路径,而且用户必须有file权限,文件容量必须小于max_allowed_packet字节(默认16m,最大1gb)

SQL注入漏洞_数据库_06

B into outfile写文件操作

MySQL提供向磁盘写入文件的操作,与load_file一样,必须持有file权限,且文件有绝对路径

SQL注入漏洞_数据_07

C 连接字符 concat() concat_ws()

(5)mysql显错式注入

A 通过updatexml函数,执行SQL

SQL注入漏洞_数据库_08

B 通过extractvalue函数,执行SQL语句

SQL注入漏洞_数据_09

C 通过floor函数,执行SQL语句

SQL注入漏洞_数据库_10

(6)宽字节注入

该注入是由编码不统一所造成的,一般出现在PHP+MySQL中

PHP配置文件php.ini存在magic_quotes_gpc选项,被称为魔术引号,当此选项打开时,使用get、post、cookie所接收的单引号、双引号、反斜线\和null字符都会被自动加上一个反斜线转义

(7)MySQL长字符截断

在 MySQL 中的一个设置里有一个sql_mode选项,当sql_mode设置为default时,即没有开启STRICT_ALL_TABLES选项时(MySQL sql_mode默认即default),MySQL对插入超长的值只会提示warning,而不是error,这样就可能会导致一些截断问题。

通过length取的长度,判断值的长度

select length(username) from users where id=1

在默认下,如果数据超过列默认长度,MySQL会将其截断

(8)延时注入

根据页面差异来判断URL是否存在SQL注入漏洞

盲注:页面无差异的注入

延时注入时盲注的一种,是基于时间差异的注入技术。

select * from users where id=1 and sleep(3); /* 3秒后执行SQL语句 */

延时注入的操作:

SQL注入漏洞_数据_11

4.注入工具

1)SQLmap

是一个开源渗透测试工具,自动检测和利用SQL注入漏洞。基于Python编写,跨平台。

具有强大的检测引擎。若URL存在注入漏洞,就可以在数据库中提取数据。若权限够大,可以在其操作系统上执行命令,读写文件。

特点:

SQL注入漏洞_数据_12

 

 

(1)判断注入点

第一步:判断是否是注入点

sqlmap.py -u "ip"

第二步:获取数据库

sqlmap.py -u "ip" --dbs 使用-dbs参数读取数据库

第三步:查看当前应用程序所用数据库

sqlmap.py -u "ip" --current-db

第四步:列出指定数据库的所有表

sqlmap.py -u "ip" --table -D "数据库名"

第五步:读取指定表中字段名称

sqlmap.py -u "ip" --columns -T "表名" -D "数据库名"

第六步:读取指定字段内容

sqlmap.py -u "ip" --dump -C "username,password" -T "表名" -D "数据库名"

--dump参数意为转存数据,-C参数指定字段名称,-T指定表名,-D指定数据库名 -U用户

在读取数据后,会把数据转存在SQLMap/output/目录下,文件以Table.cvs 保存

2)SQLmap工具详解

更新升级 sqlmap -update

帮助:sqlmap -h

sqlmap.py -u "ip" --cookie "COOKIE_VALUE" cookie注入

sqlmap.py -u "​​http://url?id=1​​" --data "id=3" post注入

sqlmap.py -u "​​http://url?id=1​​" -v 1 -f 指纹判别数据库类型

sqlmap.py -u "​​http://url?id=1​​" --proxy "​​http://127.0.0.1:8181​​" 代理注入

sqlmap.py -u "​​http://url?id=1​​" --sql -shell 执行指定SQL命令

sqlmap.py -u "​​http://url?id=1​​" --os-cmd=whoami 执行系统命令

sqlmap.py -u "​​http://url?id=1​​" --os-pwn 反弹shell

--technique 测试指定注入类型\使用的技术

不加参数默认测试所有注入技术

B: 基于布尔的 SQL 盲注

E: 基于显错 sql 注入

U: 基于 UNION 注入

S: 叠层 sql 注入

T: 基于时间盲注

--tamper 通过编码绕过web防火墙(waf)

5.防止SQL注入

SQL注入攻击就是 用户可以控制输入

防御主要分:数据类型判断和特殊字符转义

1)严格的数据类型

java,c等强类型语言可完全忽略数字型注入

严格判断数据类型 可解决数字型SQL注入

2)特殊字符转义

针对字符型注入

在数据库字符串查询时,任何字符串都必须加上单引号

3)使用预编译语句

预编译语句在创建的时候已将指定的SQL语句发送给DBMS,完成了解析、检查、编译等工作,我们需要的仅仅是将变量传给SQL语句。

4)框架技术

与数据库相关的框架:持久层框架

5)存储过程

存储过程:在大型数据库系统中,一组为了完成特定功能或经常使用的SQL语句集,经编译后存储在数据库中。

存储过程具有较高的安全性,可以防止SQL注入。

过滤危险字符:正则表达式过滤传入参数(若匹配到,则退出程序)像select "" from 等

6)不要把机密信息直接存放,加密或hash掉密码和敏感信息