sql注入原理

本文参考书目<web安全攻防:渗透测试实战指南>
有pdf,若想认真学习请支持正版买本纸质的

2020-3-18修改部分内容


介绍

首先引用下书中的话:

SQL注入就是指Web 应用程序对用户输入数据的合法性没有判断,前端传入后端的参数是攻击者可控的并且参数带入数据库查询,攻击者可以通过构造不同的SQL语句来实现对数据库的任意操作。

举个例子,加入php中带入musql查询语句的是如下语句
$query =” SELECT * FROM users WHERE id= $_GET['id’] ”

很明显以上语句中存在浏览器传入的参数id,且不经过任何判断。若用户并不按照正常的id输入,而是加入了些sql语句,则返回值可能会改变开发者的初衷,存在被拖库的风险。



以下按照个人理解来介绍各种类型的sql注入类型

先说点个人的想法,以下各种各样的类型注入,说到底,只是mysql语法的使用,只不过是在sql注入中得到了使用而被分门别类。


盲注

盲注分成布尔型注入时间型注入,盲注简单地说就是在页面不存在回显数据的情况下使用的一种获取数据的方式。(然而用来判断是否可注入也是非常不错的)

布尔型注入

简单来说,布尔型就是通过判断对错来达到某些目的。

举个例子,服务器就是你的线人,只能回答是和不是。
你为了获得信息,只能想好问什么后进行提问获得是和否的回答。

比如你问它,这个地方是用单引号封闭的吗,它回答否。你继续问是用双引号封闭的吗,它回答是,那么你就判断出来此参数的封闭所使用的是双引号。

实际中,判断封闭条件算是sql注入必备环节,除了布尔型也能用时间型来判断。而具体有哪些类型,则在练习中一一讲解。

20020-3-18更:事实上布尔型注入比时间型的效率高得多,且在网络不好的情况下也准确的多。举个例子,可以利用返回页面的大小来作为对错的判断。

时间型注入

简单地说,时间型注入就是布尔型的兄弟,通过返回时间的长短来判断对错。

以下是mysql数据库中一个时间延迟的例子,如果当前使用的database名字的长度超过1,则执行 sleep (5),否则返回1。
if( length (database()) ) > 1, sleep (5), 1)

用来判断下是否可注入就好了,用来获取数据的话就算了吧。除非这个数据值得花这么多时间



对以上布尔型和时间型做个小总结:

  • 一般来说,只要存在sql注入,那么时间型注入都是可用的,毕竟就只是通过网页刷新时间来判断的。然而它的缺点也是耗时间,一条句子的判断至少2s左右才能保证准确性(网络延时高的时候可能要提高点时间)。
  • 布尔型注入则一般用于有回显的页面。什么叫有回显呢,比如你输入密码正确,页面会有successfully等字样,而输入错误则会有invalid等字样,通过判断这些页面特有的字符来判断对错,就很快速了。

union注入

简单来说,union注入就是查找所需数据拼接到原本返回的正常数据中。

使用union之前,应该先知道order by的使用方法。
SELECT user_name,password FROM users WHERE id= 1 order by 1;
以上语句要求结果按照第一列进行从小到大的排序(如果是字母则从a到z)。
这是正确的语法。然而如果 将order by 1 改成 order by 3则是错误的。(通过以上时间型或者布尔型能够判断出是否出错,或者直接页面报错)
假设order by的参数为a,假设a初始值为10,那么使用二分查找法,就能够收敛于a=2,从而求得列数。

此处二分查找的细节。设b=0,a=c=10,当a=10的时候报错,c=a=10, a=(b+c)/2=5。a继续判断还是报错,c=a=5,a=(b+c)/2=2 。 a没有报错 b=a=2,a=(b+c)/2=3。a报错,此时达到条件a-1不报错,a报错,则列数为a-1。

已知多少列后,那么就能够通过以下语句获取数据并将数据拼接到原本数据的后面 (此处用1,2代替,毕竟假设还不知道列名)
SELECT user_name,password FROM users WHERE id= 1 union select 1,2 from users


报错注入

简单来说,SQL报错注入就是利用数据库的某些机制,人为地制造错误条件,使得查询结果能够出现在错误信息中。

在这里不讨论各种报错利用的原理,只说简单挑一个例子来详细的讨论下。
首先放出原理链接:https://www.cnblogs.com/litlife/p/8472323.html
举例:floor()函数报错:
SELECT COUNT(*) FROM user GROUP BY FLOOR(RAND(0)*2);

简单解释下就是mysql的一种运行特性,rand(0)*2所展示的数是011011…(检测和添加的时候都会改变值,第一次检测为0,添加的时候是第二个1,再次检测的时候是第三个1,下次检测的时候是第二个0,然而并没有此元素,因此需要添加,添加的时候是第四个1,因为有1元素在表中,报出冗余错误。)

举两个实例:
mysql> select * from user where id=1 and (select 1 from (select count(*),concat(table_name,floor(rand(0)*2))x from information_schema.tables group by x)a);

ERROR 1062 (23000): Duplicate entry ‘global_status0’ for key ‘<group_key>’


mysql> select * from user where id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from user group by x)a);

ERROR 1062 (23000): Duplicate entry ‘root@localhost1’ for key ‘<group_key>’

只要更改黑体字部分,错误就能返回我们想要的内容。ps:floor爆出的名字会默认在尾巴那带个1,粘贴复制使用的时候别忘了删除,别问我为什么强调,都是泪。


堆叠注入

简单来说,就是通过添加分号来执行第二个句子。
比如原本id=1,则语句为
select user_name,id from users where id=1;
然而输入id=1;select 1,2;
则句子变为
select user_name,id from users where id=1;select 1,2;
变成需要执行两条语句。

二次注入

2020-3-18 修改,当时理解不完全。
简单的来说,应用两个不同但相关联的地方执行注入
例子1:
在页面1.php?username=test’ order by 2 %23 注册一个用户名test’ order by 1 %23(假设知道此新用户id为32)
在页面2.php?id=32查找此用户的文章,则其查找语句可能为
select article from articles where username = test’ order by 2 %23

若页面返回正常,则说明此语句正常执行,说明查找内容有2列。否则页面返回白页或其他不正常界面,则说明语句执行失败,说明查找内容没有2列。这也相当于用布尔型进行判断吧。

例子2:
应用insert函数插入数据时进行注入,然后在页面或其他地方能够对此数据进行查看。

插入数据 ‘insert into TABLE values( 22, \‘’.$a\’.’)’
$a=zhangsan则正常插入数据
$a=0’+hex(database())+’0
语句变成
insert into TABLE values( 22,’0’+hex(hex(database()))+’0’)
则数据变成database()的16进制编码

宽字节注入

简单地说,在数据库编码为GBK时,我们可以通过添加一些字符而构成GBK字符,更改原本字符的意义。
为什么叫宽字节呢,因为原本默认的字符编码是一字节一字符,而GBK为2字节一字符。因此才能够通过构造字符而消去原本程序员所设计的语义。

举个例子:
参数id=l 在数据库查询时是被单引号包围的。当传入id=l ’时, 传入的单引号又被转义符(反斜线〉转义,导致参数ID无法逃逸单引号的包围,此处是不存在SQL注入漏洞的。不过有一个特例,就是当数据库的编码为GB时,可以使用宽宇节注入,宽宇节的格式是在地址后先加一个 %df, 再加单引号, 因为反斜杠的编码为%5c,而在GBK 编码中, %df%5c 是繁体字“迪”,所以这时, 单引 号成功逃逸,报出MySQL 数据库的错误。
实例举例:
因为还暂时没遇到过需要使用宽字节注入的场景,因此拿书中的截图进行讲解
在这里插入图片描述
要说的都在图片中写了,字小的话放大网页就能看了。或者图片下载后放大来看。
在这里插入图片描述
在这里插入图片描述
突然想到我也能放大来截图。

总结

我认为基本的sql注入技巧就是以上所有了。一定要记住开头的介绍,他是SQL注入的本质
SQL注入就是指Web 应用程序对用户输入数据的合法性没有判断,前端传入后端的参数是攻击者可控的并且参数带入数据库查询,攻击者可以通过构造不同的SQL语句来实现对数据库的任意操作。

比如最普通的GET参数和POST参数,或者是cookie参数、xml数据引用等都有可能进行sql注入。
所以只要是能够带入数据查询的参数,如果不加防护且找到利用方法,那么都是可用的。

放图

在这里插入图片描述
如果有错误或者有什么想讨论的
联系方式1062290728@qq.com

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值