网站入侵与脚本攻防修炼
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.3 SQL注入攻击前奏

在上节中,我们已经对SQL注入攻击的目的及原理有所了解。在本节中,将向大家详细介绍SQL注入攻击的分类、注入点的扫描及注入类型判断等,这也是攻击者在实施SQL注入攻击前必须进行的准备工作。

2.3.1 网站平台决定攻击方式

大部分网站都是采用Web动态网页结合后台数据库架设而成的。网页从用户的请求中得到某些参数,然后构成SQL语句请求发给数据库,再将从数据库中得到的结果返回给网页,从而完成网页所执行的功能。

在许多Web网站系统中,由于网站程序中的变量处理不当,或者对用户提交的数据过滤不足,很可能产生一种被为SQL注入(SQL Injection)的漏洞。恶意攻击者可以利用用户可提交或可修改的数据,构造特殊的SQL语句,将SQL语句插入到系统实际执行的SQL语句中,从而任意获取数据库中的某些重要信息,如管理员用户名和密码等;基至可以利用SQL注入漏洞控制整个网站服务器。

简单说来,SQL注入漏洞就是由于用户可构造执行特殊SQL语句的漏洞;所谓的SQL注入攻击就是用户利用SQL注入漏洞非法获取数据库信息或者入侵网站服务器的一种黑客攻击手段。

根据网站所使用的Web脚本语言不同,SQL注入攻击可以分为ASP注入、PHP、JSP、ASPX注入等多种方式。ASP注入与PHP及其他语言的注入原理是一样的,但是由于Web语言环境不同,因此实际注入时所使用的语句也不尽相同。

同时,SQL注入攻击并不仅局限在SQL Server数据库中,后台使用Access、MySQL、Oracle、Sybase等数据库的网站等都可能存在注入漏洞,遭受SQL注入攻击。

根据目前网络上的具体情况而言,大部分网站主要是采用“ASP+SQL Server (Access)”或者“PHP+MySQL”结构来架设的,因此本书也重点对这两种注入方式分别进行叙述。

2.3.2 攻击前的准备工作

攻击者在实施SQL注入攻击前,首先会进行一些准备工作,同样,我们要对自己的网站进行SQL注入漏洞的检测,也需要进行相同的准备。

1.取消友好HTTP错误信息

在进行SQL注入攻击时,要利用到从服务器返回的各种出错信息,但是在浏览器中默认设置是不显示详细错误返回信息的,不论服务器返回什么错误,我们都只能看到“HTTP 500服务器错误”(图22)。因此,每次进行SQL注入攻击测试前,首先要对IE浏览器进行一下设置:

打开IE浏览器,单击菜单【工具】→【Internet选项】命令,打开“Internet选项”,选择“高级”选项卡,在“设置”列表框中找到“浏览组”,将其下的“显示友好HTTP错误信息”前面的钩去掉(图23)。

2.准备猜解用的工具

与任何攻击手段相似,在进行每一次入侵前,都要经过检测漏洞,入侵攻击,种植木马后门长期控制等这几个步骤。同样,进行SQL注入攻击也不例外。在这几个入侵步骤中,黑客往往会使用一些特殊的工具,以大大提高入侵的效率和成功率。在进行SQL注入攻击测试前,需要准备如下攻击工具。

图22 错误页面返回信息被简化处理

图23 取消显示友好HTTP错误信息

1)SQL注入漏洞扫描与猜解工具

ASP环境的注入扫描器主要有“WIS+WED”、NBSI2(图24)、HDSI、pangolin_bin等。

图24 常用的ASP注入工具NBSI2

PHP环境的注入攻击工具主要有“二娃”和CASI(图25)。

图25 常用的PHP注入工具CASI

这些工具,大部分都是采SQL注入漏洞扫描与攻击于一体的综合利用工具,可以帮助攻击迅速完成SQL注入点寻找与数据库密码破解、系统攻击等过程。

2)Web木马后门

ASP木马后门:冰狐浪子、海阳顶端木马、ASP站长助手(图26)、蓝屏木马等,用于注入攻击后控制ASP环境的网站服务器。

图26 ASP站长助手

PHP木马后门:PHPSpy、黑客之家PHP木马等,用于注入攻击后控制PHP环境的网站服务器。

3)注入辅助工具

ASC码逆转换工具、C2C注入格式转换器、SQL注入字符转换工具(图27)等,主要用于在注入检测过程中转换注入语句编码,突破过滤防护限制。

图27 SQL注入字符转换工具

2.3.3 寻找攻击入口

对一个网站要实施SQL注入攻击检测,当然首先要找到存在SQL注入漏洞的地方,也就是所谓的寻找注入点。可能的SQL注入点一般存在于登录页面、查找页面、添加页面及信息条目浏览页面等,用户可提交修改数据的地方,比如常见的登录用户名和密码输入框或者信息条目ID显示页面等。

1.手工检测SQL注入点

最常用的SQL注入点判断方法,是在网站中寻找如下形式的网页链接:

            http://www.*****.com/***.asp? id=xx  (ASP注入)

或者

            http://www.*****.com/***.php? id=xx  (PHP注入)

其中的“xx”可能是数字,也有可能是字符串,分别被称为整数类型数据和字符型数据。

如果判断某个网页链接是否存在SQL注入漏洞呢?通常有两种检测方法。

1)“加引号”法

第一种检测SQL注入漏洞是否存在的方法是“加引号”法。

对于整数类型数据,可以直接在浏览器地址栏中的网址链接后加上一个单引号,构造如:

            http://www.*****.com/***.asp? id=11'
            http://www.*****.com/***.php? id=11'

之类的链接。如果浏览器返回如下类似信息(图28):

            Microsoft OLE DB Provider for ODBC Drivers 错误 '80040e14'
            [Microsoft][ODBC SQL Server Driver][SQL Server]字符串 '8' ' 之前
            有未闭合的引号。
            /web/ChannelContent.asp,行 45

在返回的信息中,有详细的数据库SQL语句操作执行错误信息,并出现类似的提示信息的话,则往往表明存在SQL注入漏洞。

同样,如果是字符型数据,我们也可以在后加上一个单引号,如果返回与上面类似的出错提示,那么也说明存在SQL注入漏洞。另外对于字符型数据来说,单引号的添加可以灵活些,可把单引号加入到字符串中去,构造形如“http://www.*****.com/***.php? id=puma' xy”之类的链接请求。

图28 加单引号后返回错误信息

为了便于读者对“加引号法”有一个更直观的了解,这里特意找了一个存在SQL注入的ASP网址“http://love.**.tj.cn/bbs/openarticlenew.asp? ID=11695”,分别截取了正常显示与添加单引号后的错误返回图示,见图29和图30。

图29 正常页面

图30 加单引号后的页面

对于PHP网站返回的SQL注入漏洞错误提示略有不同,注入点检测后的返回信息往往是一些SQL出错的信息提示(图31),通过这些信息,往往可以分析是否存在SQL注入漏洞。

图31 PHP注入点返回的错误信息

2)经典的“1=1和1=2”法

加引号法虽然很直接,但是由于SQL注入攻击的普及,所以很多程序员已经在网页程序将引号过滤掉。很多时候检测提交包含引号的链接时,会提示非法字符,或者不返回任何信息。但这并不等于不存在SQL注入漏洞,这时候黑客往往会使用经典的“1=1和1=2”法进行检测。

首先提交网址链接http://www.*****.com/***.asp? id=xx and 1=1。

一般应该运行正常,而且与“http://www.*****.com/***.asp? id=xx”运行显示页面相同。

再提交“http://www.*****.com/***.asp? id=xx and 1=2”,页面运行异常。

如果满足上面的显示,那么就说明当前页面中存在SQL注入漏洞,反之则可能不能注入。此方法对PHP站点同样适用。

例如,某PHP站点链接地址为“http://www.he**.com.cn/superbaby/galleryint roduced.php? ID=5404”,正常页面中显示数据库中相应的“宝宝姓名”、“所在城市”等信息及图片(图32)。

图32 正常页面

采用上面的方法,先在链接地址后添加“and 1=1”,提交链接地址为:

            http://www.he**.com.cn/superbaby/galleryintroduced.php? ID=54
            04 and 1=1

返回显示与正常状态相同(图33)。

再在链接地址后添加“and 1=2”,提交链接地址为:

            http://www.he**.com.cn/superbaby/galleryintroduced.php? ID=54
            04 and 1=2

图33 “and 1=1”页面

返回的页面中(图34),没有任何信息,说明该网页链接存在着PHP注入漏洞。

图34 “and 1=2”页面

2.快速扫描出网站的安全威胁

除了可以使用上述介绍的方法手工检测某个网站中存在的SQL注入漏洞外,还有更为简便的方法,那就是直接使用一些漏洞扫描工具对整个网站进行扫描。这些安全检测工具,一旦落入攻击者的手中,就将成为攻击的罪恶利器。

1)WIS扫描法

“WIS+WED”是一个SQL注入组合工具包,其中的WIS是一个命令行的SQL注入漏洞扫描工具,使用格式为(图35):

            wis  <Web Page>

图35 WIS命令格式

以扫描“http://net110.**.net/”网站中存在的SQL注入漏洞的网站为例,在命令行下输入命令:

            WIS http://net110.**.net/

命令执行后,会将存在SQL注入漏洞的网址链接以红色显示(图36)。

图36 扫描到SQL注入点

2)使用NBSI扫描

NBSI可以在图形界面下对网站进行注入漏洞扫描。运行程序后,单击工具栏上的“网站扫描”按钮,然后在网站地址中输入要扫描的网站链接地址,再选择扫描的方式。如果是第一次扫描的话,可以选择“快速扫描”,如果使用该方式没有扫描到漏洞时,再使用“全面扫描”项。最后单击【扫描】按钮,即可在下面的列表中看到可能存在SQL注入的链接地址(图37)。

图37 NBSI扫描SQL注入点

请注意,在扫描结果列表中将会显示注入漏洞存在的可能性,其中标记为“可能性:较高”的注入成功的机率较大些。

上面介绍的两种扫描工具都是运行于ASP网站下的,对于使用PHP语言的网站,一般没有直接进行扫描的工具,还是手工检测比较可靠些。

2.3.4 区分SQL注入点的类型

根据注入时提交的变量参数类型,SQL注入点有不同的分类,不同的注入点,其注入时需要注意的事项也有所不同。按提交参数类型,SQL注入点主要分为下面3种。

1.数字型注入点

形如“http://******? ID=50 ”,这类注入的参数是“数字”,因此称为“数字型”注入点。

此类注入点提交的SQL语句,其原形大致为:

            Select * from 表名 where 字段=50

当我们提交注入参数为“http://******? ID=50 And [查询条件]”时,向数据库提交的完整SQL语句为:

            Select * from 表名 where 字段=50 And [查询条件]

2.字符型注入点

形如“http://******? Class=日期” 这类注入的参数是“字符”,因此称为“字符型”注入点。

此类注入点提交的SQL语句,其原形大致为:

            Select * from 表名 where 字段=’日期’

当我们提交注入参数为“http://******? Class=日期And [查询条件]”时,向数据库提交的完整SQL语句为:

            Select * from 表名 where 字段=’日期’ and [查询条件]

3.搜索型注入点

这是一类特殊的注入类型。这类注入主要是指在进行数据搜索时没过滤搜索参数,一般在链接地址中有“keyword=关键字”,有的不显示明显的链接地址,而是直接通过搜索框表单提交。

此类注入点提交的SQL语句,其原形大致为:

            Select * from 表名 where 字段like ‘%关键字%’

当我们提交注入参数为“keyword=' and [查询条件] and ‘%' =' ,则向数据库提交的完整SQL语句为:

            Select * from 表名 where字段like ‘%' and [查询条件] and ‘%' =' %’

2.3.5 判断目标数据库类型

目前,网上建站使用的一般是ASP+MS SQL Server/Access或PHP+MySQL这两种架构。因此,对于PHP网站使用的数据库为可能是MS SQL、MySQL;对ASP网页来说,使用的数据库可能是Access、MS SQL,也可能是MySQL,针对不同的数据库采用的注入方式法略有差异。

判断注入漏洞网站数据库类型,主要是为了决定采取的注入攻击方式。一般来说,由于SQL Server有一些内置的系统变量,因此在注入时可以利用一些查询语句直接返回其表名或字段名;但是Access的SQL查询功能就简陋得多,无法返回正确信息,因此可构造特殊的语句来进行判断。

如何判别这两种数据库类型呢?

1.过分体贴的错误信息

为了方便网站管理者解决各种操作错误的问题,网站通常会将各种错误信息进行详细的反馈,显示在网页出错页面中。这些“体贴”的设计,反而给攻击者带来了便利,攻击者通过注入点的返回信息,可以判断出网站所使用的数据库类型。

例如,在返回信息中,看到如“Microsoft OLE DB Provider for SQL Server错误 ’80040e14' ”,由此可以看出数据库采用的是SQL Server;如果返回“Microsoft JET Database Engine错误 ’80040e14' ”之类的信息,基本上可以确定采用的是Access数据库(图38)。如果提示信息为“Microsoft OLE DB Provider for ODBC Drivers错误 ’80040e14' ”的语句,则有可能是Access数据库,也可能是SQL数据库。

例如,提示信息为:

            Microsoft OLE DB Provider for ODBC Drivers 错误 '80040e14'
            [Microsoft][ODBC SQL Server Driver][SQL Server]字符串 '8' ' 之前
            有未闭合的引号。
            /web/ChannelContent.asp,行45

图38 由[SQL Server]信息判断数据库类型

从上面的错误信息“Microsoft OLE DB Provider”,可以看出数据库采用OLE DB驱动;“[Microsoft][ODBC SQL Server Driver][SQL Server]”,则说明此网站使用的是SQL数据库(图39)。如果提示信息为:

            Microsoft OLE DB Provider for ODBC Drivers 错误 '80040e14'
            [Microsoft][ODBC Microsoft Access Driver] 字符串的语法错误 在查
            询表达式 ' b_id=175' ' 中。
            /view.asp,行8

图39 [ODBC Microsoft Access Driver]信息判断数据库类型

说明此网站数据库采用OLE DB驱动,从“[Microsoft][ODBC Microsoft Access Driver]”看出采用的是Access数据库。

2.报出数据库类型

SQL Server有一些系统变量和系统表,如果服务器IIS提示没关闭,并且SQLServer返回错误提示的话,那可以直接从出错信息获取判断数据库的类型。

1)内置变量报出数据库类型

其方法是在注入点之后加上“and user>0”字符,示例如下:

            http://www.***.com/jobs.asp? ID=1651 and user>0

这条语句很简单,但却是很典型的SQL Server注入原理的体现。我们来看看它的含义:首先,前面的语句是正常的,重点在“and user>0”, “user”是SQLServer的一个内置变量,它的值是当前连接的用户名,类型为“nvarchar”。将一个“nvarchar”的值跟“int”的数“0”比较,系统会先试图将“nvarchar”的值转成“int”型。然而在转换的过程中肯定会出错,因此SQL Server会报出错提示信息(图40):

            Microsoft OLE DB Provider for SQL Server 错误 '80040e07'
            将 nvarchar 值 ' ****' 转换为数据类型为 int 的列时发生语法错误。
            /city/dz/lx/show.asp,行 8

其中的“***”正是变量“user”的值,这样就拿到了数据库的用户名。这里重点不是在于用户名,而是数据库的判断,凡是出现上面的错误信息,都可以判断是SQL数据库。

图40 “and user>0”判断法

用上面的方法可以很方便地测试出数据库类型是否为SQL,但有时如果用户是以“sa”登录,那么提示信息将有所不同,提示信息为:

            将”dbo”转换成int的列发生错误
            这样的情况下,也可以判断是采用的SQL数据库。

反之,如果采用的是Access数据库的话,那么提示信息则会为:

            Microsoft OLE DB Provider for ODBC Drivers 错误 '80040e10'
            [Microsoft][ODBC Microsoft Access Driver] 参数不足,期待是 1。
            /index/info/jobs.asp,行 8

从“参数不足,期待是1”信息,可以肯定这是一个Access数据库(图41)。

图41 Access数据库不会显示类型转换错误

2)内置数据表报出数据库类型

在前面介绍经典的“1=1和1=2”法进行注入点检测时,通常是用于服务器不返回错误信息,或者过滤了单引号的情况。如果服务器IIS不允许返回错误提示,怎么判断数据库类型呢?在这样的情况下,只能通过数据库内置的系统数据表来进行判断。

Access和SQL Server数据库都有自己的系统表,比如存放数据库中所有对象的表,Access是在系统表[msysobjects]中,但在Web环境下读该表会提示“没有权限”, SQL Server是在表[sysobjects]中,在Web环境下可正常读取。因此,根据Access和SQLServer数据库系统表的区别,可以判断这两种数据库类型。

在注入点后提交如下语句:

            http://www.****com/showdetail.asp? id=49 and (select count(*)
            from sysobjects)>0
            http://www.****.com/showdetail.asp? id=49 and (select count(*)
             from msysobjects)>0

如果数据库是SQL Server,那么第一个网址的页面与原页面“http://www.***.com/showdetail.asp? id=49”是大致相同的(图42);而第二个网址,由于找不到表“msysobjects”,会提示出错,提示信息为:

            Microsoft OLE DB Provider for SQL Server 错误 '80040e37'
            对象名 ' mssysobjects' 无效。
            /city/dz/lx/show.asp,行 8

就算程序有容错处理,不会返回错误信息,但是页面也与原页面完全不同(图43)。

图42 SQLServer数据库正常显示

图43 SQLServer数据库中不存在“msysobjects”表

如果数据库采用的是Access,那么情况就有所不同:提交第一个网址链接的页面与原页面完全不同,提示错误信息为(见图44):

            Microsoft OLE DB Provider for ODBC Drivers 错误 '80040e37'
            [Microsoft][ODBC Microsoft Access Driver] Microsoft Jet 数据库
            引擎找不到输入表或查询 ' mssysobjects' 。 确定它是否存在,以及它的名称的
            拼写是否正确。
            /index/info/jobs.asp,行 8

图44 Access数据库中不存在“sysobjects”表

由于在Access中不存在“sysobjects”表,因此会提示“找不到输入表或查询'sysobjects' ”。在提交第二个网址链接,其返回信息根据数据库设置是否允许读该系统表,从而导致返回的错误信息不同。一般在Access中是不允许读取该表的,所以与原网址也是完全不同的。

一般来说,大多数情况下,提交第一个网址链接就可以得知系统所用的数据库类型,第二个网址只作为开启IIS错误提示时的验证。

另外,通过自动化的注入工具,也可以自动进行注入点的判断。