第1章 什么是SQL注入 本章目标 ·理解Web应用的工作原理 ·理解SQL注入 ●理解SQL注入的产生过程
2SQL注入攻击与防御 1.1 概述 很多人声称自己了解$QL注入,但他们听说或经历的情况都是比较常见的。SQL注入是 影响企业运营且最具破坏性的漏洞之一,它会泄露保存在应用程序数据库中的敏感信息,包括 用户名、口令、姓名、地址、电话号码以及信用卡明细等易被利用的信息。 那么,应该怎样来准确定义SQL注入呢?SQL注入(SOL Injection)是这样一种漏洞:应用 程序在向后台数据库传递SQL(Structured Query Language,结构化查询语言)查询时,如果为攻 击者提供了影响该查询的能力,则会引发SQL注入。攻击者通过影响传递给数据库的内容来 修改SQL自身的语法和功能,并且会影响SQL所支持数据库和操作系统的功能和灵活性。SQL 注入不只是一种会影响Wb应用的漏洞:对于任何从不可信源获取输入的代码来说,如果使 用了该输入来构造动态SQL语句,那么就很可能也会受到攻击(例如,客户端/服务器架构中的 “胖客户端”程序。 自SQL数据库开始连接至Web应用起,SQL注入就可能已经存在。Rain Forest Puppy因 首次发现它(或至少将其引入了公众的视野)而备受赞誉。1998年圣诞节,Rain Forest Puppy为 Phrack(www.phrack.com/issues.html?issue=54&id-8#article)(一本由黑客创办且面向黑客的电子 杂志)撰写了一篇名为“NT Web Technology Vulnerabilities(NT Web技术漏洞)”的文章。20oo 年早期,Rain Forest Puppy还发布了一篇关于SQL注入的报告(“How I hacked PacketStorm”, 位于www.wiretrip.net/rfp/txt/rfp2k0l.txt),其中详述了如何使用SQL注入来破坏一个当时很流 行的Wb站点。自此,许多研究人员开始研究并细化利用SQL注入进行攻击的技术。但时至 今日,仍有许多开发人员和安全专家对$QL注入不甚了解。 本章将介绍SQL注入的成因。首先概述wb应用通用的构建方式,为理解SQL注入的产 生过程提供一些背景知识。接下来从Wb应用的代码层介绍引发SQL注入的因素以及哪些开 发实践和行为会引发SQL注入。 1.2 理解Web应用的工作原理 大多数人在日常生活中都会用到Wb应用。有时是作为假期生活的一部分,有时是为了 访问E-mail、预定假期、从在线商店购买商品或是查看感兴趣的新闻消息等。Web应用的形式 有很多种。 不管是用何种语言编写的Wb应用,有一点是相同的:它们都具有交互性并且多半是数 据库驱动的。在互联网中,数据库驱动的Wb应用非常普遍。它们通常都包含一个后台数据 库和很多Wb页面,这些页面中包含了使用某种编程语言编写的服务器端脚本,而这些脚本则 能够根据Wb页面与用户的交互从数据库中提取特定的信总。电子商务是数据库驱动的Wb应 用的最常见形式之一。电子商务应用的很多信息,如产品信息、库存水平、价格、邮资、包装 成本等均保存在数据库中。如果读者曾经从电子零售商那里在线购买过商品和产品,那么应该 不会对这种类型的应用感到陌生。数据库驱动的Web应用通常包含三层:表示层(Wb浏览器 或呈现引擎)、逻辑层(如C#、ASP、NET、PHP、JSP等编程语言)和存储层(如Microsoft SQL Server、MySQL、Oracle等数据库)。Web测览器(表示层,如Internet Explorer、.Safari、Firefox 等)向中间层(逻辑层)发送请求,中间层通过查询、更新数据库(存储层)来响应该请求
第1章什么是SQL注入3 下面看一个在线零售商店的例子。该在线商店提供了一个搜索表单,顾客可以按特定的兴 趣对商品进行过滤、分类。另外,它还提供了对所显示商品作进一步筛选的选项,以满足顾客 在经济上的预算需求。可以使用下列URL查看商店中所有价格低于$100的商品: http://www.victim.com/products.php?val=100 下列PHP脚本说明了如何将用户输入(v)传递给动态创建的SQL语句。当请求上述URL 时,将会执行下列PHP代码段: /connect to the database $conn mysql_connect ("localhost","username","password"); /dynamically build the sql statement with the input Squery "SELECT FROM Products WHERE Price 'GET["val"]'". "ORDER BY ProductDescription"; /execute the query against the database Sresult mysql_query(Squery); /iterate through the record set while(Srow=mysql fetch array(Sresult,MYSOL ASSOC)) /display the results to the browser echo "Description (Srow['ProductDescription'])<br>". "Product ID (Srow ['ProductID'])<br>" "Price (Ssow['Price'])<br><br>"; 接下来的代码示例更清晰地说明了PHP脚本构造并执行的SQL语句。该语句返回数据库 中所有价格低于$100的商品,之后在Wb浏览器上显示并呈现这些商品以方使顾客在预算范 围内继续购物。 SELECT FROM Products WHERE Price '100.00' ORDER BY ProductDescription; 一般来说,所有可交互的数据库驱动的Wb应用均以相同的(至少是类似的)方式运行。 1.2.1一种简单的应用架构 前面讲过,数据库驱动的Wb应用通常包含三层:表示层、逻辑层和存储层。为更好地 帮助读者理解Wb应用技术是如何进行交互的,从而为用户带来功能丰富的Web体验,我们 借助图1-1来说明前面描述的那个简单的三层架构示例。 表示层是应用的最高层,它显示与商品浏览、购买、购物车内容等服务相关的信息,并通 过将结果输出到浏览器/客户端层和网络上的所有其他层来与应用架构的其他层进行通信。逻 辑层是从表示层剥离出来的,作为单独的一层,它通过执行细节处理来控制应用的功能。数据 层包括数据库服务器,用于对信息进行存储和检索。数据层保证数据独立于应用服务器或业务 逻辑。将数据作为单独的一层还可以提高程序的可扩展性和性能。在图1-1中,Wb浏览器(表
4SQL注入攻击与防御 示层)向中间层(逻辑层)发送请求,中间层通过查询、更新数据库(存储层)响应该请求。三层架 构中一条最基本的规则是:表示层不应直接与数据层通信。在三层架构中,所有通信都必须经 过中间件层。从概念上看,三层架构是一种线性关系。 表示层 逻辑层 存储层 访问http:/www.victim.com 加载、编译并执行index..asp 执行SOL 脚本引紫 RDBMS 返回数据 呈现HTML 发送HTML web浏览器/星现引 编程语言:C#、ASP、,NET、PHP、JSP等 数据库:MSSQL、MySQL,Oracle等 图1-1简单的三层架构 在图l-l中,用户激活Web浏览器并连接到http:/www.victim.com。位于逻辑层的Web服 务器从文件系统中加载脚本并将其传递给脚本引擎,脚本引整负责解析并执行脚本。脚本使用 数据库连接器打开存储层连接并对数据库执行SQL语句。数据库将数据返回给数据库连接器, 后者将其传递给逻辑层的脚本引擎。逻辑层在将Wb页面以HTML格式返回给表示层的用户 的Web浏览器之前,先执行相关的应用或业务逻辑规则。用户的Wb浏览器呈现HTML并借 助代码的图形化表示展现给用户。所有操作都将在数秒内完成,并且对用户是透明的。 1.2.2一种较复杂的架构 三层解决方案不具有扩展性,所以最近几年研究人员不断地对三层架构进行改进,并在可 扩展性和可维护性基础之上创建了一种新概念:层应用开发范式。其中包括一种四层解决方 案,该方案在Wb服务器和数据库之间使用了一层中间件(通常称为应用服务器)。n层架构中的 应用服务器负责将AP(应用编程接口)提供给业务逻辑和业务流程以供程序使用。可以根据需要 引入其他的Wb服务器。此外,应用服务器可以与多个数据源通信,包括数据库、大型机以及其 他旧式系统。 图1-2描绘了一种简单的四层架构。 在图1-2中,Wb浏览器(表示层)向中间层(逻辑层)发送请求,后者依次调用由位于应用层 的应用服务器所提供的API,应用层通过查询、更新数据库(存储层)来响应该请求。 在图1-2中,用户激活Web浏览器并连接到htp:/www.victim.com。位于逻辑层的Wb服 务器从文件系统中加载脚本并将其传递给脚本引整,脚本引擎负责解析并执行脚本。脚本调用 由位于应用层的应用服务器所提供的API。应用服务器使用数据库连接器打开存储层连接并对 数据库执行SQL语句。数据库将数据返回给数据库连接器,应用服务器在将数据返回给Wb 服务器之前先执行相关的应用或业务逻辑规则。Wb服务器在将数据以HTML格式返回给表 示层的用户的Wb浏览器之前先执行最后的有关逻辑。用户的Web浏览器呈现HTML并借助 代码的图形化表示展现给用户。所有操作都将在数秒内完成,并且对用户是透明的
第1章什么是S0L注入5 表示层■ 逻辑层。 应用层 存储层 访间 加载、编译并执行 与数据存储交互,利用 执行SQL index.asp http://www.yictim.com 应用程序和业务逻辑 脚本引擊 RDBMS 星现HTML 发送HTML 为Web服务器提供数期 返回数据 Web浏览器/星现引翠 编程语言:C#、ASP、 CFC、EJB、SOAP、RMI 数据库:MSSQL、 ,NET、PHP、JSP等 Web服务等 MySQL、Oracle等 图1-2四层架构 层式架构的基本思想是将应用分解成多个逻辑块(或层),其中每一层都分配有通用或特定 的角色。各个层部署在不同的机器上,或者虽然位于同一台机器上,但实际上或概念上是彼此 分离的。使用的层越多,每一层的角色就越具体。将应用的职责分成多个层能使应用更易于扩 展,可以更好地为开发人员分配开发任务,提高应用的可读性和组件的可复用性。该方法还可 以通过消除单点失败来提高应用的健壮性。例如,决定更换数据库提供商时,只需修改应用层 的相关部分即可,表示层和逻辑层可保持不变。在互联网上,三层架构和四层架构是最常见的 部署架构。正如前面所介绍的,·层架构非常灵活,在概念上它支持多层之间的逻辑分离,并 且支持以多种方式进行部署。 1.3 理解SQL注入 Web应用越来越成熟,技术也越来越复杂。它们涵盖了从动态Internet和内部网入口(如电 子商务网站和合作企业外部网)到以HTTP方式传递数据的企业应用(如文档管理系统和ERP应 用)。这些系统的有效性及其存储、处理数据的敏感性对于主要业务而言都极其关键(而不仅仅 是在线电子商务商店)。Wb应用及其支持的基础结构和环境使用了多种技术,这些技术可能 包含很多在他人代码基础上修改得到的代码。正是这种功能丰富的特性以及便于通过Internet 或内部网对信息进行比较、处理、散播的能力,使它们成为流行的攻击目标。此外,随着网络 安全技术的不断成熟,通过基于网络的漏洞来攻破信息系统的机会正不断减少,黑客开始将重 心转向尝试危害应用上。 SQL注入是一种将SQL代码插入或添加到应用(用户)的输入参数中的攻击,之后再将这些 参数传递给后台的SQL服务器加以解析并执行。凡是构造SQL语句的步骤均存在被潜在攻击 的风险,因为SQL的多样性和构造时使用的方法均提供了丰富的编码手段。SQL注入的主要 方式是直接将代码插入到参数中,这些参数会被置入SQL命令中加以执行。不太直接的攻击 方式是将恶意代码插入到字符串中,之后再将这些字符串保存到数据库的数据表中或将其当作 元数据。当将存储的字符串置入动态SQL命令中时,恶意代码就将被执行。如果Wb应用未 对动态构造的SQL语句所使用的参数进行正确性审查(即便使用了参数化技术),那么攻击者就 很可能会修改后台SQL语句的构造。如果攻击者能够修改$QL语句,那么该语句将与应用的 用户拥有相同的运行权限。当使用SQL服务器执行与操行系统交互的命令时,该进程将与执