26SQL注入攻击与防御 其他注入型数据 大多数应用都从GET或POST参数中检索数据,但HTTP请求的其他内容也可能会触发 SQL注入漏洞。 cookie就是个很好的例子。Cookie被发送给用户端的浏览器,并在每个请求中都会自动回 发给服务器。cookie一般被用于验证、会话控制和保存用户特定的信息(比如在Wb站点中的 喜好)。前面介绍过,我们可以完全控制发送给服务器的内容,所以应考虑将cookie作为一种 有效的用户数据输入方式和易受注入影响的对象。 在其他HTTP请求内容中,易受注入攻击的应用示例还包括主机头、引用站点(referer)头 和用户代理头。主机头字段指定请求资源的Internet主机和端口号。引用站点字段指定获取当 前请求的资源。用户代理头字段确定用户使用的Wb浏览器。虽然这些情况并不多见,但有 些网络监视程序和Wb趋势分析程序会使用主机头、引用站点头和用户代理头的值来创建图 形,并将它们存储在数据库中。对于这些情况,我们有必要对这些头进行测试以获取潜在的注 入漏洞。 可以借助代理软件并使用本章前面介绍的方法来修改cooki©和HTTP头。 2.操纵参数 我们先通过介绍一个非常简单的例子来帮助您熟悉$QL注入漏洞。 假定您正在访问Victim公司的Web站点(这是一个电子商务站点,可以在上面购买各种商 品)。您可以在线查找商品,根据价格对商品进行分类以及显示特定类型的商品等。当浏览不 同种类的商品时,其URL如下所示: http://www.victim.com/showproducts.php?category=bikes http://www.victim.com/showproducts.php?category-cars http://www.victim.com/showproducts.php?categoryboats showproducts.php页面收到一个名为category的参数。我们不必输入任何内容,因为上述 连接就显示在Wb站点上,只需点击它们即可。服务器端应用期望获取已知的值并将属于特 定类型的商品显示出来。 即便未开始测试操作,我们也应该大概了解了该应用的工作过程。可以断定该应用不是静 态的.该应用似乎是通过category参数的值并根据后台数据库的查询结果来显示不同的商品的。 现在开始手动修改category参数的值,将其改为应用未预料到的值。按照下列方式进行首 次尝试: http://www.victim.com/showproducts.php?category-attacker 上述例子使用不存在的类型名向服务器发出请求。服务器返回下列响应: Waring:mysql_fetch_assoc():supplied argument is not a valid MySQL result resource in /var/www/victim.com/showproducts.php on line 34 该警告是当用户尝试从空结果集中读取记录时,数据库返回的一个MySQL数据库错误。 该错误表明远程应用未能正确处理意外的数据。 继续进行推理操作,现在向之前发送的值添加一个单引号(,发送下列请求:
第2章SQL注入测试27 http://www.victim.com/showproducts.php?category=attacker' 图2-3展示了服务器的响应。 Mozilla Firefox Ble Edt Mew Hiatory Bookmarks Tools Help 年·◆,C8金回http://wwwvictim.com/showproducts.phpcategor-attacker■✉Google You have an error in your SQL syntax:check the manual that corresponds to your MySQL server version for the right syntax to use near"attacker at line I Done NA FovyProry Disabled 图2-3 MySQL服务器错误 服务器返回下列错误: You have an error in your SoL syntax;check the manual that corresponds to your MySQL server version for the right syntax to use near "attacker at line 1 不难发现,有些应用在处理用户数据时会返回意想不到的结果。Wb站点检测到的异常并 非都是由SQL注入漏洞引起的,它会受很多其他因素的影响。随着对$QL注入开发不断熟悉, 我们将逐步认识到单引号字符在检测中的重要性,并将学会如何通过向服务器发送合适的请求 来判断能进行何种类型的注入。 还可以通过进行另外一个有趣的测试来识别SQL Server和Oracle中的漏洞。向web服务 器发送下面两个请求: http://www.victim.com/showproducts.php?category-bikes http://www.victim.com/showproducts.php?category-bi'+'kes 在MySQL中,与其等价的请求为: http://www.victim.com/showproducts.php?category-bikes http://www.victim.com/showproducts.php?category=bi'kes 如果两个请求的结果相同,则很可能存在SQL注入漏洞。 现在读者可能对单引号和字符编码有些困惑,阅读完本章后,您将会清楚这些内容。本节 的目标是展示哪些操作会触发wb服务器响应而产生异常。在“2.2.6确认SQL注入”一节中, 我们将对用于寻找$QL注入漏洞的字符串进行扩展
28SQL注入攻击与防御 工具与陷阱 用户数据验证 有两个原因会引发SQL注入漏洞: 。缺少用户输入验证 ·数据和控制结构混合在同一传输通道中 到目前为止,在计算机历史上,这两个问题一直是产生某些非常重要漏洞(如堆和 堆栈溢出、格式字符串问题)的原因。缺少用户输入验证,将导致攻击者可以从数据部 分(例如,使用单引号引起来的字符串或数字)跳到注入控制命令(例如,$ELECT、 UNION、AND、OR等). 为防止出现这种漏洞,首要措施是执行严格的用户输入验证和(或)输出编码。例如, 可采用白名单方法,即如果希望将数字作为参数值,可对Wb应用进行配置以拒绝所 有由用户提供的非数字输入字符。如果希望是字符串,则只接受之前确定的不具危险性 的字符。如果这都不可行,则必须保证所有输入在用于防止$QL注入之前已被正确引 用或编码。 下面将介绍信息到达数据库服务器的流程和产生上述错误的原因。 3.信息工作流 前面介绍了一些操纵参数时显示的SQL注入错误。读者可能会问:修改参数时,为什么 Web服务器会显示数据库错误?虽然错误显示在Wb服务器的响应中,但SQL注入发生在数 据库层。本节的例子会展示如何通过Wb应用到达数据库服务器。 一定要对数据输入影响$QL查询的过程和可以从数据库期望获取的响应类型有一个清晰 的理解。图24展示了使用浏览器发送的数据来创建SQL语句并将结果返回给浏览器的整个 过程。 图24还展示了动态Wb请求所涉及的各方之间的信息工作流: 1.用户向Web服务器发送请求。 2.Wb服务器检索用户数据,创建包含用户输入的SQL语句,然后向数据库服务器发送 查询。 3.数据库服务器执行SQL查询并将结果返回给Wb服务器。请注意,数据库服务器并不 知道应用逻辑,它只是执行查询并返回结果。 4.Wb服务器根据数据库响应动态地创建HTML页面
第2章SQL注入测试29 SELECT·FROM www.victim.com/showproducts asp?categorycars PRODUCTS WHERE category='cars' 2 AUDI BMW 用户 Web服务器 FERRARI Oracle FORD 数规库服务器 FE快A用 SEAT FORD SEAT 图24三层架构中的信息流 不难发现,web服务器和数据库服务器是相互独立的实体。Wb服务器只负责创建SQL 查询,解析结果,将结果显示给用户。数据库服务器接收查询并向Wb服务器返回结果。对 于利用SQL注入漏洞来说,这一点非常重要,因为我们可以通过操纵SQL语句来让数据库服 务器返回任意数据(比如Victim公司Web站点的用户名和口令),而Web服务器却无法验证数 据是否合法。 2.2.2数据库错误 前面介绍了一些操纵参数时会显示的SQL注入错误。虽然错误显示在wb服务器的响应 中,但SQL注入发生在数据库层。本节的例子展示了如何通过Wb应用到达数据库服务器。 测试SQL注入漏洞时,可能会从Wb服务器收到不同的数据库错误,一定要熟悉这些错 误。图2-5展示了产生SQL注入错误的过程和wb服务器对错误进行处理的过程。 SELECT·FROM www.victim.com/showproducts.asp?category PRODUCTS WHERE category ='attackor' 2 用户 4 3 -01756:quoted Web服务器 ORA-01756:quoted Oracle string not properly string not property 数据库服务器 terminated terminated 图2-5产生SQL注入错误的过程中的信息流 从图25中不难发现,产生SQL注入错误的过程中发生了下列事件: 1.用户发送请求,尝试识别$QL注入漏洞。本例中,用户发送了一个带单引号的值。 2.Wb服务器检索用户数据并向数据库服务器发送SQL查询。本例中,在Web服务器创 建的SQL语句中包含了用户输入并构造了一条查询,不过该查询因末尾存在两个单引 号而导致语法错误。 3.数据库服务器接收格式不正确的SQL查询并向Wb服务器返回一条错误消息。 4.Wb服务器接收来自数据库的错误并向用户发送HTML响应。本例中发送的是错误消 息,不过,如何在HTML响应的内容中展示错误则完全取决于应用
30SQL注入攻击与防御 上述例子说明了用户请求触发数据库错误时的场景。根据应用编码方式的不同,一般按下 列方法对步骤4中返回的文件进行构造和处理: ·将SQL错误显示在页面上,它对Web浏览器用户可见。 ·将SQL错误隐藏在wb页面的源代码中以便于调试。 ·检测到错误时跳转到另一个页面。 ·返回HTTP错误代码500(内部服务器错误)或HTTP重定向代码302。 ·应用适当地处理错误但不显示结果,可能会显示一个通用的错误页面。 当您尝试识别SQL注入漏洞时,需要确定应用返回的响应类型。接下来我们将关注最常 见的几种响应类型。要想成功进行攻击和从识别漏洞过渡到进一步利用漏洞,识别远程数据库 的能力至关重要。 常见的SQL错误 上一节介绍过,数据库返回错误时,不同的应用会做不同处理。当尝试识别某一输入是否 会触发SQL漏洞时,Wb服务器的错误消息非常有用。最好的情况是应用返回完整的SQL错 误,不过这种情况不是很普遍。 下面的例子将帮助读者熟悉一些最典型的错误。不难发现,SQL错误通常与不完整的单引 号有关,因为$QL要求必须使用单引号将字母数字混合值引起来。同时您还会发现,有些典 型错误示例还会对引起错误的原因做简单的说明。 1)SQL Server错误 前面讲过,将一个单引号插入到参数中会产生数据库错误。在本小节中我们会发现,完全 相同的输入会产生不同的结果。 请思考下列请求: http://www.victim.com/showproducts.php?category=attacker' 远程应用返回类似于下列内容的错误: Server Error in 'Application. Unclosed quotation mark before the character string 'attacker;'. Description:An unhandled exception occurred during the execution of the current web request.Please review the stack trace for more information about the error and where it originated in the code. Exception Details:System.Data.Sqlclient.SqlException:Unclosed quotation mark before the character string 'attacker;'. 很明显,我们不需要记住所有错误代码,重要的是理解错误发生的时机和原因。通过上面 两个例子,我们可以确定运行在数据库上的远程SQL语句肯定与下面的内容类似: SELECT FROM products WHERE category-'attacker' 该应用并未审查单引号,所以数据库服务器拒绝了该语句并返回一个错误。 这只是一个对字母数字混合字符串进行注入的例子。下面的例子将展示注入数字值(在