SQL漏洞初次认识

0x00 前言

​ 最近开始了有关数据库的课程,又想到 ctf 中也有这方面的题目(虽然好像难度高的题的难点都不在sql上),感觉 web 也是需要了解一下,于是看起了 《CTF特训营》的 web 部分,顺便写一下相关的 sql 注入的笔记,不得不说大佬队伍的书还是挺好的,有一定基础的时候去看感觉能学到许多,即便不是很理解还是可以拓展一下见识。由于只是初步的认识,我的个人理解可能和实际有所偏差,期望大师傅们可以多加指正。

0x01 简单的分类

​ SQL 注入可以分为可回显不可回显二次注入三种类型。
​ 可回显:可以联合查询的注入、报错注入、注入DNS请求来达到可回显的目的。
​ 不可回显:布尔盲注、时间盲注。
​ 二次注入:二次注入。

0x02 可回显的注入

一、联合查询注入

​ (这个应该是最简单的注入了吧)如果数据库的查询结果会直接回显到页面中,那么就可以尝试一下联合查询注入。

​ 我们可以输入:

-1'union+select+1+--+

​ 则 php 中

$getid ="SELECT ld FROM users WHERE user_id = '$id'";

​ 会变成

SELECT ld FROM users WHERE user_id = '-1'union select 1 --'

​ playload 中的单引号会和前面的单引号形成一个闭合,而两个减号作为注释符将最后面的引号注释了,就形成了一个 SQL 注入,而利用到了 union 语句,所以称之为联合查询注入。同时传入参数的 “+” 在查询语句中消失的原因时服务器自动将加号转义为空格了。
​ 注释符号:–、--+、#

二、报错注入

​ 这个要求注入点有SQL报错信息,下面介绍三种MySQL数据库的报错注入方法:updatexml、floor 和 exp。

1、updatexml

​ 这种报错注入的方式实质上就是函数报错,然后得到函数报错的回显。

关于 updatexml () 函数:

UpdateXML(xml_target,xpath_expr,new_xml)
#xml_target: 需要操作的 xml 片段
#xpath_expr: 需要更新的 xml 路径(Xpath格式)
#new_xml: 更新后的内容

​ 具体作用:此函数用来更新选定 XML 片段的内容,将 XML 标记的给定片段的单个部分( xml_target )替换为新的XML片段 new_xml ,然后返回更改后的 XML 。xml_target 替换的部分 与 xpath_expr 用户提供的 XPath 表达式匹配。如果 xpath_expr 未找到表达式匹配 ,或者找到多个匹配项,则该函数返回原始 xml_targetXML 片段。所有三个参数都应该是字符串。当Xpath路径语法错误时,就会报错,报错内容含有错误的路径内容,我们也就可以利用这点得到数据库的信息。例子如下

在这里插入图片描述

其中 concat () 函数作用为将多个字符串连接为一个字符串,而 “0x7e” 经过 sql 转义后为字符 “~” ,此处使用 concat () 函数的原因可能是想让被连接的函数能够成功调用。

2、floor

​ floor 报错的原理是 rand 和 order by 或 group by 的冲突。

关于 floor () 函数:

floor () 函数作用为向下舍入指定小数位数。例子:

floor(1.156,0)= 1 #此意即为向下舍去(也就是只舍不入)小数,知道小数位数为 0 。

同样也有一个向上舍入的函数:ceiling () ;还有一个遵守四舍五入的函数:round ()

关于 rand () 函数:

​ 这是一个伪随机函数,可以返回一个0~1之间的数,但当指定了参数后,其返回的值是可以预测的,所以称之为伪随机函数。

关于 group by 语句:

​ 这是一个 SQL 语句,可以对数据进行分组,例如:

select column_name_1 from table_name group by column_name_1;
#意为将表 table_name 中的 column_name_1 的数据,按照 column_name_1 的数据分类合计后显示。

在这里插入图片描述

关于 floor 报错注入:

select count(*) from test group by floor(rand(0)*2);

​ 在上面的语句中,group by 语句分组合计时会建立一张虚拟表,而 count (*) 函数为其中的计数值;由于 rand () 函数在固定参数时所得到值时可预测的,floor(rand(0)*2) 可得到一个固定的序列 01101 ;group by 进行分组时,floor(rand(0)\*2)执行一次(查看分组是否存在),如果虚拟表中不存在该分组,那么在插入新分组的时候 floor(rand(0)\*2) 就又计算了一次。

为什么 group by 在插入新的分组时 rand () 就一定会重新计算一遍值。原因是官方文档上说了会多计算一次。在这里插入图片描述

#payload 利用方式:
and select count(*), concat((select database()), ‘-’, floor(rand(0)%2))x from information_schema.tables group by x; 
#将select database()换成你想要的东西
#floor(rand(0)%2))x 将前者取了个别名 x
#上述注入可以爆出当前使用的数据库

3、exp

​ exp 报错的本质就是溢出错误

关于 exp () 函数:

​ exp 函数就是以e为底的指数函数,但这个函数的参数大于 709 时会产生溢出而报错。

关于 exp 报错注入:

1' and exp(~(select* from (select user())x))%23
#select user() 执行后得到用户信息
#select * from...... 成功执行后会返回 0 
#exp(~(......)) 利用 ~ 取反后,由于数字过大会产生报错

当函数成功执行时,一般会返回 0 ,再加上符号 “~” ,将 0 取反得到最大的无符号 int 数 (18446744073709551615)。

在这里插入图片描述

三、DNS 注入

​ 通过我们构造的数据,访问搭建好的 DNS 服务器,查看 DNS 访问的日志即可获取我们想要得到的数据

使用场景:

​ 在某些无法直接利用漏洞获得回显的情况下,但是目标可以发起请求,这个时候就可以通过 DNSlog 把想获得的数据外带出来。

感觉这个注入挺难的,总结起来都不知道怎么总结,还是看其他师傅的原理讲解吧:

dns注入 - FreeBuf网络安全行业门户

SQL注入:DNS注入 - 软二的小忠晏 - 博客园 (cnblogs.com)

SQL注入篇——dns回显注入_爱国小白帽-CSDN博客

0x03 不可回显的注入

一、布尔盲注

​ 由于开发者屏蔽了报错信息,我们只能知道成功就跳转到正确页面,失败就跳转到错误页面。

关于注入的方法:

​ 当注入为整型注入时,可以再输入点后面添加 and 1=1and 1=2 来判定是否有布尔盲注。

如果存在布尔盲注,则 and 1=1 不会对结果产生影响,同时若是遇到将 1=1 过滤的情况,可以使用不常见的数字等式。

​ 如果注入为字符串型注入,需要注意单引号的闭合等问题。

​ 书中含有一些注入常用函数可以了解一下,这里就不列出来了(P46)。

二、时间盲注

​ 时间盲注出现的本质原因是由于服务器端拼接了 SQL 语句,但是正确和错误存在同样的回显。错误信息被过滤,不过,可以通过页面响应时间进行按位判断数据。

关于注入的原理:

​ 其注入类似于布尔盲注,区别在于布尔盲注是根据返回页面的不同判断,而时间盲注是根据页面相应时间来判断结果的。与其相关的常见函数有 sleep () 函数和 benchmark () 函数,具体一些的利用方式书上在讲函数时也有讲(P49)。

0x03 二次注入

​ 二次注入的起因是数据在第一次入库的时候进行了一些过滤及转义,当这条数据从数据库中取出来在SQL语句中进行拼接,而在这次拼接中没有进行过滤时,我们就能执行构造好的SQL语句了。

​ 感觉这个不是我能简单的总结的了,还是看书上怎么写的吧(P50)。

0x04 其它的注入

一、宽字节注入

​ 这种注入可以理解为:通过拼凑转义符("\"),来组成一个新的字。

关于注入产生的原因:

​ 在 SQL 中有这样一个函数 addslashes () 函数:会对单引号 ( ’ ),双引号 ( " ),斜杠 ( \ ) ,和 null 字符进行转义,就是在字符前添加一个转义符。

关于宽字节注入:

​ 为了对付上面那个函数的问题,当数据库编码为 GBK 时,我们可以在这四个字符前添加 %df ,就可以使得 %df 和转义符拼接成一个新的字(在 GBK 中两个字节代表一个汉字),而后面那个单引号就逃逸了。例如:%df\’ = %df%5c%27 = 縗’

二、Cookie 注入 & base64 注入

​ 感觉这位师傅写的很详细清楚了:cookie注入&& base64注入 原理详解_m0_46304840的博客-CSDN博客

三、XFF 注入攻击

​ 还是这位师傅写的博客,挺好的:XFF头注入原理分析_m0_46304840的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值