渗透测试步骤

攻击的首要任务是查明应用程序执行的最初查询所返回的列数。有两种方法可以完成这项任务。

(1)可以利用NULL被转换为任何数据类型这一事实,系统性地注入包含不同列数的查询,直到注入的查询得到执行,例如:

‘ UNION SELECT NULL--

‘ UNION SELECT NULL, NULL--

‘ UNION SELECT NULL, NULL, NULL--

查询得到执行就说明使用了正确的列数。如果应用程序不返回数据库错误消息,仍然可以了解注入的查询是否成功执行,因为会收到另外一行数据,其中包含NULL或一个空字符串。注意,注入行可能只包含空单元格,因此不容易得知何时以HTML提交。出于这个原因,进行攻击的最好是查看行响应。

(2)确定所需的列数后,下一项任务就是找到一个使用字符串数据类型的列,以便通过它从数据库中提取出任意数据。和前面一样,可以通过注入一个包含NULL值的查询,并系统性地用a代替每个NULL,从而完成这项任务。例如,如果知道查询必须返回3列,可以注入以下查询:

‘ UNION SELECT ‘a’, NULL, NULL--

‘ UNION SELECT NULL, ‘a’, NULL--

‘ UNION SELECT NULL, NULL, ‘a’--

如果注入的查询得到执行,将看到另一行包含a值的数据,然后就可以使用相关列从数据库中提取数据。

img001  注解  在Oracle数据库中,每个SELECT语句必须包含一个FROM属性,因此,无论列数是否正确,注入UNION SELECT NULL将产生一个错误。可以选择使用全局可访问表(globally accessible table)DUAL来满足这一要求。例如:

‘ UNION SELECT NULL FROM DUAL--

如果已经确定注入的查询所需的列数,并且已经找到一个使用字符串数据类型的列,就能够提取出任意数据。一个简单的概念验证测试是提取数据库的版本字符串,可以对任何数据库管理系统(DBMS)进行测试。例如,如果查询一共有3列,第一列可以提取字符串数据,可以在MS-SQL和MySQL中注入以下查询提取数据库版本:

img246a

对Oracle注入以下查询将得到相同的结果:

img246b

在前面介绍的易受攻击的图书搜索应用程序中,可以使用这个字符串作为搜索项来获得Oracle 数据库的版本:

作 者 书 名 出版年份
CORE 9.2.0.1.0 Production
NLSRTL Version 9.2.0.1.0 - Production
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
PL/SQL Release 9.2.0.1.0 - Production
TNS for 32-bit Windows: Version 9.2.0.1.0 - Production

当然,虽然数据库版本字符串值得我们注意,并且可帮助搜索特殊软件中的漏洞,但是,在多数情况下,我们仍然对从数据库中提取数据更感兴趣。要做到这一点,渗透测试员需要解除前面描述的第二个限制;也就是说,需要知道想要攻击的数据库表的名称以及相关列的名称。

9.2.6 提取有用的数据

为了从数据库中提取有用的数据,通常需要了解表以及包含预访问的数据所属列的名称。大型企业DBMS中包含大量数据库元数据,可以查询这些数据查明数据库中每一个表和列的名称。在各种情况下,提取有用数据所使用的方法完全相同;但是,在不同数据库平台上的应用细节各不相同。

9.2.7 使用UNION提取数据

下面我们将分析一个攻击,虽然该攻击针对的是MS-SQL数据库,但它采用的攻击方法适用于所有数据库技术。以用户维护联系人列表及查询和更新联系人信息的通讯录应用程序为例。如果用户在通讯录中搜索名为Matthew的联系人,浏览器将提交以下参数:

img247a

应用程序将返回以下结果:

人 名 电子邮件地址
Matthew Adamson handytrick@gmail.com