0


SQL注入漏洞(类型篇)

不走一遍黑客走的路,永远也不清楚他们到底做了什么,知道也不一定理解。而亲自体验一番就会有不同的理解,也会对一些参数的注入有更深的理解。前面已经介绍过了SQL注入原理,所以这里就不再赘述了,我们直接上干货。(以下的漏洞介绍皆是以MYSQL数据库语言为例)

SQL注入有好几种分类,我们一起了解一下:

SQL注入分类

对参数而言SQL注入存在字符型注入、数字型注入

字符型注入:参数有一些其他的符号包裹,如单引号、双引号、小括号等等。

数字型注入:参数没有包裹,可以直接进行注入,这种是最危险的,连闭合的步骤的省略了。

提交方式分类则存在:GET注入、POST注入、COOKIE注入、HTTP请求头注入(User-Agent注入、XFF头注入、Referer注入)。严格意义上来说COOKIE注入也算是HTTP请求头注入的一种。

GET注入:一般是在url上直接进行手工注入(url是网页链接的意思)。

POST注入:POST提交一般存在一些账号密码的提交框框中(当然也可能是其他区域),攻击注入的点需要利用hackbar工具提交POST或者直接对其http协议中的POST提交数据进行注入。

COOKIE注入:COOKIE的修改可以直接用F12查看应用中存在的COOKIE,可对其进行修改注入。

HTTP请求头注入:这个需要对HTTP请求的数据进行修改包再发包。

按照注入的方法来分类有:联合注入、报错注入、布尔盲注、时间盲注、堆叠注入、宽字节注入、二次注入、DNSlog注入

联合注入

即一条SQL语句联合了两张表的数据,而若第一张表的数据查询出错则会使得第二张表的数据回显至页面。

基本语句为:1' union select 1,2,group_concat(schema_name) from information_schema.schemata-- 

关键点在于unionselect,如果被过滤了就得另辟蹊径,找一些绕过的方法,那种也算是sql注入学习的进阶。

报错注入

这个可利用的函数有好几个:**extractvalue()updatexml()exp()floor()**等等。

updatexml()

我这里简单介绍一下**updatexml()**的报错注入原理,看下面的例子:

UpdateXML(xml_target, xpath_expr, new_xml)

xml_target:: 需要操作的xml片段

xpath_expr: 需要更新的xml路径(Xpath格式)

new_xml: 更新后的内容

这个函数updatexml()有三个参数,第一个和第三个就不说了,直接看第二个参数,函数要求的第二个参数类型为XMLXPATH),如果XPATH路径不是XML或者存在语法错误时,就会报错,报错内容含有错误的路径内容,又因为这也算一句sql语句,所以它会把sql语句执行后再报错,最后把查询到的数据带出来了。有兴趣可以去了解一下**extractvalue(),它与updatexml()**报错的原理相似。

exp()

**exp()**原本是求e的x次方的函数,x即括号中的参数,但是经过一些脑洞大的师傅研究发现

在709以后就会报错,而这种查询语句的取反得到的值特别的大

那么有意思的就来了,我们要是在外面套一层exp(),因为这个值大于709的,那么就是报错就会将我们查询的结果携带出来。但是注意这个洞的利用MySQL版本得** >=5.5.5**,我的版本过低就没有测试结果截图了,大体了解一下是这么个流程。

floor()

说是**floor()造成的报错注入有点片面了,实际上是floor()配合group by rand()**共同操作时才会导致错误的生成。那么为什么会出现报错呢?

首先简单说一下这三个玩意儿的作用:

**floor()**:取不大于该数的最大整数,即向下取整;

group by x:取x做为主键,创建一张临时表,若x不存在于表中则新建一个,若存在且有coun(*),则**count()**计数自增1;

**rand()**:随机生成一个0到1的数。

就这几个指令也能报错注入?答案是肯定的。而且它的报错也很有意思,先看两句sql指令

select count(*),Host from user group by concat(database(),floor(rand(0)*2));

select count(*),Host from user group by concat(database(),floor(rand(1)*2));

这种结果的测试是不确定的,因为是随机数。那么为什么**rand()**中的种子不同得到的结果也不相同呢?这里其实底层的原理我也不是很清楚,但是根据其他师傅的文章以及我自己的猜测,我们可以这样理解(如果有什么地方讲的有问题欢迎指正):

首先group by 后面跟的数据是临时表中的主键,无论临时表是否存在,rand()都会执行两次,哪两次?第一次是group by 判断是否有database()floor(rand(0)*2)这个主键值,第二次是存入是又执行了一次floor(rand(0)*2),那么问题来了,如果database()1**存在,且第一次group by判断floor(rand(0)*2)为0,若临时表不存在database()0,那么我们时需要生成database()floor(rand(0)*2)这个主键,但是我们存入时有执行了一次floor(rand(0)*2),而如果这个时候floor(rand(0)*2)不是0而是1了,那么就会出现本来已存在database()1,而因为rand()的原因,强制插入一条相同的主键,已知数据库中的主键名都是不重名的,因此会报错,而它的报错就是将concat()**中的数据带出来了。

因此我们可以对此进行注入出现上述例子的情况,也就能解释为什么不同的种子出现的情况不同,这种讲究概率,所以如果没有出现报错,需要用不同的种子数多次测试即可。

布尔盲注

bool类型只有两个值----1和0。也就是对与错,我们查询到的库名或者表名或者其他数据内容是不会显示出来,只有一个查到没查到的正确或错误的回显,所以我们利用对查到的字符串截断为单个字符判断ASCII码的值,利用布尔的判断逐步提取其字符串。

具体的方法有三种,手工注入(特别麻烦)、暴力破解编写脚本跑(最简便)。

手工注入:利用substring将字符串截断后再对一个一个字符的ASCII的值利用**>、=、<**,进行判断,利用中值定理,如下:

1'and ascii(substring(database(),1,1))=100--+

暴力破解:在手工注入的基础上,对其ASCII码值的暴力破解(一百多次),最后得到的结果是其一个字符,凭借这样一个一个暴力破解得到一个完整的字符串。

写脚本:大体的思路也和手工差不多,一个一个字符串的判断如果正确了返回正常的界面,将跑出来的界面数据和其中的一些特有的做一个比较即可判断出是否正确,依次跑下去。

顺便提一下,前两种方法在开始时需要用**length()**得库名或者其他数据的长度。

时间盲注

即不会报错回显,也不会有正确和错误的回显,时间盲注是自己创造了一个查询得到的结果是对还是错的环境,可用if()配合sleep(),当我们查询对的语句执行sleep()等待,我们便能猜测这是正确的语句,否则则是错误语句,这个思路与布尔盲注有点类似。他们的区别是,布尔盲注是通过页面回显进行注入,时间盲注是通过响应时间来进行注入,但是思路都是一样,正确和错误的sql语句得到的结果不相同。

时间盲注还有个函数就是**benchmark()**,也是用于延时的,不做过多的解释了,有兴趣的可以去了解。

堆叠注入

一条SQL查询语句是以分号结束,而不做查询次数限制的话,一个分号执行一条sql查询,那么可以一条语句一次性执行多条sql查询。

因此堆叠注入的原理则是另启一个sql查询,通过另一条sql查询自己想要查询到的敏感信息。

宽字节注入

为了防止与闭合的字符冲突导致错误,因此程序设计对于一些不得不输入的特殊字符进行了转义,也就是反斜杠加持在敏感字符之前,如果我们输入了一个单引号而实际上会是** ' **这种。

绕过这种转义的方法称为宽字节注入。已知字符是占一个字节,而汉字是占两个字节,因此在GBK编码中如果刚好机缘巧合碰上了两个字符的GBK编码,且恰好为一个汉字,编码也为GBK格式。那么原本的两个字符就变成了一个汉字,这也就是宽字节注入的原理,我们想办法在单引号前面加一点东西,使得其与反斜杠能结合为一个字符,最后达到吞并反斜杠的功能。看个例子,

可以看到我们输入的单引号被转义了,那么想办法绕过这个反斜杠,经过查询得知反斜杠GBK编码为%5C

那么有意思的就来,经过对GBK编码表的查询得知,以上几个**%DE、%DF、%E0**会将5C吞并为一个汉字。

二次注入

第一次插入SQL语句的数据没有什么特殊的作用和回显,但是在程序的运行中发生的注入的问题。sqli-labs中有个题就是已存在admin用户,这时候创建一个admin'#用户,但是入库后利用这个账户登录修改密码发现admin管理员的密码被修改了,也就是二次注入的结果。

这种注入攻击属于那种滞留型的长期的攻击,而且很难被觉察。

DNSLOG就不说了,有点多,以后单独写一篇介绍。

参考:关于floor()报错注入,你真的懂了吗? - FreeBuf网络安全行业门户

宽字节注入讲解_web安全工具库的博客-CSDN博客_宽字节注入原理

报错型sql注入原理分析 - 程序员大本营

报错注入的原理分析 - JavaShuo

mysql的floor()报错注入方法详细分析(转载)_Vap0R的博客-CSDN博客

标签: sql 数据库 database

本文转载自: https://blog.csdn.net/qq_51295677/article/details/125408885
版权归原作者 errorr0 所有, 如有侵权,请联系我们删除。

“SQL注入漏洞(类型篇)”的评论:

还没有评论