基于Web的入侵防御系统的设计及实现.pdf
-基于基于 WebWeb 的入侵防御系统的设计与实现的入侵防御系统的设计与实现摘 要Web 效劳器往往得不到传统防御方式的有效保护,使其成为整个网络环境中平安最薄弱的地方。缓冲区溢出、SQL 注入、基于脚本的 DDos、盗链和跨站等攻击行为对 Web 效劳器的平安和稳定造成极大的威胁,而目前缺少有效的防御和保护的方式。本课题中首先调研了当前 Web 效劳器所面对的威胁,然后针对这些平安威胁设计了一套入侵防御系统,并通过 ISAPI 实现了对 Windows 平台下的 IIS 效劳器的保护。在这套入侵防御系统中,可以通过制定策略来检测所有Web 效劳器的行为,可以有效地阻止恶意攻击从而保护 Web 效劳器的平安。这套入侵防御系统的策略引擎可以加载和调用 Lua 语言编写的策略脚本,使策略脚本的编写更加简单。关键词:入侵防御;网络平安;ISAPI;LuaDesign and Implementation of Web Intrusion Prevention SystemAbstractWeb server can not often get the effective protection of traditional defensemechanism,makes it bee the weakest area in the whole network.The attacks,such as Buffer overflow,SQL injection,DDos based on script,Resource stealand Cross-site,cause the great threat to the security and stability of Webserver,and lack effective defense and protection way at present.This paperintroduces the different attack ways to a Web server at first,then designs anintrusion prevention system for the Web server and implements theprotection of IIS server under Windows platform through ISAPI.The intrusionprevention system can measure the behaviors of all visiting Web serversthrough the strategies and protect the Web Server against the maliciousattacks.The security strategies engine of the system can load and transferthe strategy scripts written in Lua language,It make strategy scripts writingmore simpler.z-Key words:Intrusions prevention;network security;ISAPI;Lua目 录论文总页数:20 页1 引言 12 Web 效劳器所受的威胁及防御 12.1 缓冲区溢出 12.2 SQL 注入攻击 12.3 基于脚本的 DDos 攻击 22.4 其他的不平安因素 33 Web 的入侵防御系统的设计 43.1 体系构造 43.2 处理流程 53.3 对客户端的响应 73.4 策略引擎的设计 83.4.1 策略的属性 83.4.2 策略的加载 9.z-3.4.3 策略的调度 103.4.4 策略的接口 104 Web 的入侵防御系统的实现 114.1 基于 ISAPI 的解析及响应模块的实现 114.1.1 使用 ISAPI Filter 获取报文信息 114.1.2 使用 ISAPI 进展响应 134.1.3 在效劳器上的安装配置 ISAPI Filter 144.2 基于 Lua 的策略实现 154.2.1 对策略的封装 154.2.2 Lua 策略脚本例如 154.3 基于*ml 的策略管理 165 系统运行过程及测试 16结论 18参考文献 18致 谢 19.z-声 明 201 引言连接入互联网中的每一台效劳器每时每刻都会受到来自病毒蠕虫的侵扰和黑客的入侵。目前,很多针对 Web 效劳器的攻击都是通过协议发起的,所以传统的防火墙对诸如 SQL 注入这种攻击方式不能提供很好的保护。在很多网络环境中,正是由于 Web 效劳器同时对内部网络和外部网络提供效劳,使其成为整个网络中最常被攻击的目标。恶意的攻击者往往通过 Web 效劳器上的突破口,来进一步对内部网络进展渗透。所以,Web 效劳器的平安显得尤为重要。本课题的首先对 Web效劳器所受到的威胁及相应的防御方式做了一些调研,然后针对Web效劳器所受的这些威胁设计了一套专门针对Web效劳器平安的轻量级的入侵防御系统,并通过 ISAPI 实现了 Windows 平台环境下保护 IIS 效劳器的系统。这套系统通过策略来控制Web 效劳器的行为,它的策略引擎可以加载 Lua 脚本编写的策略,所以策略的编写十分容易。通过对这套系统的运行检测可以发现它能有效的保护Web效劳器的平安。2 Web效劳器所受的威胁及防御Web 效劳器在互联网环境中会遭受格式各样的平安威胁,下面列出的是一些当前主流的针对 Web 效劳器的攻击方式,它们有的会导致效劳器被非法控制,有的会使效劳器无法提供正常的效劳,而有的甚至会对者的机器造成破坏。2.1 缓冲区溢出缓冲区溢出1主要是因为 Web效劳器程序对客户端提交的数据缺少平安必要的长度检测,效劳器程序的堆栈被恶意数据填充,导致效劳器程序执行非法的指令或产生拒绝效劳。如曾经造成十分大危害的蠕虫“红色代码Red Code和“尼姆达Nimda都是利用 IIS 的缓冲区溢出的漏洞而传播的。目前,缓冲区溢出是很难杜绝的,因为Web 效劳器程序开发的测试阶段无法对所有客户端可能提交的数据进展测试,所以不能确保Web 效劳器程序完全没有缓冲区溢出威胁的存在。因为 Web效劳器程序提供专有的效劳,所以我们可以通过协议确定客户端提交数据中每个字段的长度的合理*围,通过对所有用户提交的数据都进展严格的长度检测是对缓冲区溢出攻击的有效防御方式。2.2 SQL 注入攻击SQL 注入攻击2是近几年非常流行的攻击方式。对一个内部网络的渗透往往是.z-从 Web 效劳脚本入手如ASP,PHP 等,而SQL 注入漏洞通常是 Web 效劳脚本中最容易找到的。目前互联网上仍然存在很多有此风险的效劳器。SQL 注入同样也是对客户端提交的数据没有进展必要的检测过滤造成的。构造特殊的数据提交到存在此缺陷的 Web 效劳器上后,可以导致恶意的 SQL 语句注入到 Web 脚本的 SQL 调用中,从而泄露敏感信息或者执行威胁的SQL 指令。无论是何种 Web 脚本语本语言或何种数据库,如果编码人员缺乏相关的平安意识,都可能会导致此缺陷的存在。目前对 SQL 注入攻击提出的防御方案有:(1)在效劳端正式处理之前对提交数据的合法性进展检查;(2)封装客户端提交信息;(3)替换或删除敏感字符/字符串;(4)屏蔽出错信息。方案(1)被公认是最根本的解决方案,在确认客户端的输入合法之前,效劳端拒绝进展关键性的处理操作,不过这需要开发者能够以一种平安的方式来构建网络应用程序,虽然已有大量针对在网络应用程序开发中如何平安地数据库的文档出版,但仍然有很多开发者缺乏足够的平安意识,造成开发出的产品中依旧存在注入漏洞;方案(2)的做法需要 RDBMS 的支持,目前只有 Oracle 采用该技术;方案(3)则是一种不完全的解决措施,例如,当客户端的输入为“ccmdmcmdd时,在对敏感字符串“cmd替换删除以后,剩下的字符正好是“cmd;方案.z-(4)是目前最常被采用的方法,很多平安文档都认为 SQL 注入攻击需要通过错误信息收集信息,有些甚至声称*些特殊的任务假设缺乏详细的错误信息则不能完成,这使很多平安专家形成一种观念,即注入攻击在缺乏详细错误的情况下不能实施。2.3 基于脚本的 DDos 攻击当一个入侵者无法找到目标 Web 效劳器的有效渗透方式时,很可能选择 DDos这种攻击方式。传统的 DDos 攻击方式在一台硬件防火墙面往往失去了它的威力,而基于脚本的 DDos 攻击在近几年里逐渐成为对 Web 效劳器发起拒绝效劳的有效方式。和传统的 DDos 攻击针对效劳器操作系统本身或网络带宽的消耗而言,基于脚本的攻击方式是针对应用程序的消耗来到达拒绝效劳攻击的目的。对静态网页来说,这种攻击方式往往达不到它的攻击效果,而动态网页中,都会有一些对资源占用比拟多的页面,比方包含复杂查询语句的页面,很可能在一次过程中会有较长时间数据库的行为,通过多线程,分布式的这个页面就可以造成拒绝效劳的效果。目前,流行的 CC 工具就是利用这个原理来实现基于脚本的 DDos 攻击。基于脚本的DDos的另一种攻击方法是利用Web系统*息提交的功能提交垃圾数据。防御这种攻击方式的方法有以下几种:(1)防止客户端的快速刷新,可以通过 Cookie 或者 Session 来实现.z-(2)对消耗较大的页面进展识别码认证,确保是人而不是恶意的自动化程序在这个页面。(3)限制每个客户端的线程数2.4 其他的不平安因素除了上面所列的几种 Web 效劳器常见的攻击威胁外,还存在一些其他的不平安因素。(1)缺少经历的系统管理员往往没有正确的设置效劳器文件系统的权限当一个入侵者获得到 Web 效劳器上的较低的权限时,他通常会想方设法的提升自己的权限,而效劳器文件系统的权限系统没有正确设置时,可以通过较低的权限下获取到效劳器上的敏感信息,为提升权限提供了条件。(2)盗链盗链虽然不是一种攻击手段,但因其消耗了大量的效劳器资源和带宽,所以也是对当前 Web 效劳器的稳定影响比拟大的因素。盗链的定义是:此内容不在自己效劳器上,而通过技术手段,绕过别人放广告有利益的最终页,直接在自己的有广告有利益的页面上向最终用户提供此内容。常常是一些名不见经传的小来盗取一些有实力的大的地址比方一些音乐、图片、软件的下载地址然后放置在自己的中,通过这种方法盗取大的空间和流量。另外一种盗链是像讯雷这样的P2SP 的下载软件,可以让客户端以类似 BT 的方式同时从多台效劳器上下载文件。.z-对盗链的防御往往是通过设定一些策略来实现,如检查客户端报头的 refer字段等。(3)脚本自身的 BugWeb 效劳器上所运行的动态脚本ASP、ASP.NET、JSP 和 PHP 等等自身所带的 Bug 也会给 Web 效劳器的平安带来极大的威胁。例如前面所提的 SQL 注入也是属于 Web 脚本的 Bug。恶意的攻击者可能可以利用这些脚本中的 Bug 轻易的获得 Web 效劳器的权限。很多 Web 效劳器上采用的是开源的系统,而有的管理员因为设置上的疏忽 例如编辑源码后产生的 bak 文件,数据库的路径没有保护等等,给攻击者入侵翻开了方便之门。对于这类来自脚本自身的平安威胁,好的防御方式是时常关注源码站点的补丁信息,对 Web 效劳器的环境进展平安配置,防止数据库这样会透露敏感信息的文件被下载等等。上面所介绍的这些对 Web 效劳器的威胁,虽然只是对 Web 效劳器众多攻击方式中的*几种,但我们可以看出,对Web 效劳器的攻击行为往往都具有和普通的不同的行为。我们可以通过这些非正常的行为鉴别出恶意的攻击。下面将介绍对Web 效劳器进展入侵防御系统的设计和实现。3 Web 的入侵防御系统的设计由于系统要对客户端发送的报文进展分析,这需要对报文进展解析,报文解析的方式主要有两种:.z-(1)自解析:系统对原始数据报文自行解析;(2)由 Web 效劳器进展解析,需要时系统通过 Web 效劳器提供的接口查询。方式(1)可以提供比方式(2)更好的移植性,但这种报文解析的方式需要一种截获下层原始报文的能力,这可以通过截获传输层或网际层报文的实现,由于我们将这套系统定位于仅针对 Web 的入侵防御,我们对协议外的报文并不关心,所以我们选择方式2作为我们的报文解析方案,即通过 Web 效劳器提供的接口仅仅截获应用层的报文。要对客户端发起的请求进展完全的监控光靠检测客户端的行为是不够的,因为这样我们只知道客户端发起什么样的请求但无法知道效劳器端是如何对客户端进展响应的。一次完整的会话既然包括客户端发送请求和效劳器端对请求的响应,则只有监控效劳器端响应的内容后,才能知道这次会话何时完毕。如果Web 效劳器提供报文封装的接口,则在对客户端进展响应时我们也尽量调用Web 效劳器的这些接口而不是自己组装报文。这样,这套入侵防御系统的核心便是其策略引擎,通过强大而灵活的策略引擎来实现特征检测或者异常检测。下面将介绍这个Web 的入侵防御系统的具体体系构造和处理流程。3.1 体系构造通常一个系统会采用多层或者单层的体系构造。多层的构造将不同功能的模块进展了划分,层与层之间靠定义好的接口进展通信,单层的构造将模块都紧耦合在一起,模块与模块间有穿插调用。多层的构造比单层的构造具有良好的扩展性,而单层构造可以模块间的交互更加高效。为了能使系统适合不同的Web 效劳器平台,综合以上的因素考虑后,本系统采用分层的体系构造。这个 Web 的入侵防御系统主要分层了以下三层:(1)解析及响应层这一层为整个防御系统提供对客户端发送的报文请求的解析及效劳器响应时报文封装的接口。当有客户端效劳器时,通知策略引擎调度策略检测客户端的信息,并为策略引擎提供响应的实现。按照前面的分析,这一层是由效劳器提供的接口封装实现。(2)策略引擎这一层的作用是策略的调度,在策略中通过“解析及响应层提供的接口获取客户端的信息,具体的响应也交给“解析及响应层完成。同时策略引擎还需要调度数据管理层完成策略的加载,以及日志记录的功能。(3)数据管理这一层提供日志记录、配置管理及策略脚本解析的功能。所以对数据进展处理的过程都是在这一层里完成。每一层都完成相对独立的功能,当*一层的实现发生变化时,只要提供的接口没有变化,对其他几层就没有影响。这样整个构造就有很大的扩展性,例如:我们可以把解析和响应层的具体实现是由调用 Web 效劳器自身接口的方式替换为直接截获传输层网络层封包的方式等等。下面将介绍具体的处理流程。.z-3.2 处理流程Web IPS的具体处理流程如下:当客户端发送请求时,原始的数据报文经报文解析模块解析,报文解析模块会通知策略引擎模块对客户端的信息进展检测,策略引擎会依据策略脚本中编写的策略,通知响应模块对客户端的行为做出响应,并依据策略脚本中的策略,通知日志记录模块记录相应的日志。依据 Web IPS 系统的体系构造及处理流程,系统主要模块和作用如下:(1)IPS 管理模块负责管理和连接各个模块,管理数据流,读取配置文件后完成整个系统的初始化,对整个系统的状态进展管理:运行,停顿,重新加载。当报文解析模块通知有客户端的时,调用策略引擎对客户端的行为及信息进展检测,对策略引擎返回的结果通知响应模块进展响应。(2)配置文件模块主要完成配置文件的读取及保存。提供统一的接口,具体实现可以根据需要而作修改。(3)报文的解析模块利用 Web 效劳器提供的接口,对客户端 Web 效劳器时提交的原始数据进展解析,并通知 IPS管理模块收到客户端的请求,请求策略引擎检测客户端的行为。报文的解析模块中会为每一个客户端生成一个实现了能检测客户端相关信息的接口的对象。在一般的Web 脚本例如:ASP、ASP.NET、PHP 等等中也会有这样一种获取客户端信息的接口。(4)响应模块当需要对客户端的行为进展响应时,在这一模块中对数据报文进展组装。提供以下几种响应方式:调用下一条策略、承受请求、断开、发送信息、发送文件和重定向。除了“调用下一条策略需要策略引擎继续调用其他策略外,其他的响应完毕后都表示客户端的一次请求过程的完毕,策略引擎将不会继续调用策略链上的其它策略。(5)策略引擎模块首先策略引擎对策略脚本进展解析,根据策略的属性和优先级组装策略链。当 IPS 管理模块通知策略引擎对*一个客户端的信息进展检测时,策略引擎利用报文解析模块提供的接口获取所需的客户端得信息,分析客户端得行为,通过依次调度策略来控制客户端的。在策略中,可以检测客户端请求的各个字段,并对客户端的行为进展分析或记录,通过定义好的规则对客户端不同的行为进展响应。当一个策略中没有对客户端的行为做出响应时,策略引擎调用策略链中的下一条,直到全部调用完。如果有策略返回响应,则通知响应模块完成客户端的响应,并停顿调动策略链后面的策略。如果没有任何策略对客户端的行为做出响应,策略引擎则返回承受请求的响应。策略引擎需要封装报文的解析和响应模块,及日志记录模块,供策略中调用。(6)日志模块日志模块的作用是对系统运行时产生的日志或对入侵防御行为的进展记录。使用统一的格式将日志信息记录在文本文件中。由于系统采用分层的体系构造,所以这一模块可以方便的替换成其他格式的日志记录方式。3.3 对客户端的响应在一个策略中,可以返回对客户端的行为做出的响应,或什么都不返回。如果返回的是除“调度下一条策略外的其他响应,则策略引擎停顿调动策略链中后面的策略,否则策略引擎依次调度策略链上的策略直到全部策略调度完成。下面将详细介绍每一种响应方式的效果和作用。(1)调度下一条策略.z-这是策略的默认响应方式,策略引擎将为客户端调度下一条策略。当一个策略中没有对客户端的行为做出任何响应,则策略引擎认为该客户端调用策略链上的下一条策略。(2)承受请求承受客户端的。策略引擎将不会调用后面的策略。这种响应方式通常用于白,即对特定的客户端的做出的特别响应处理,由Web效劳器处理客户端的请求,而不受发出这个响应的策略后面的策略的影响。(3)拒绝连接让 Web Server直接断开和客户端的连接,这是一种最严重的响应方式,在客户端所看到的结果就是浏览器报告说找不到效劳器。当策略引擎已经确认客户端的是恶意的攻击行为时,可以直接断开和客户端的连接。由于响应是在响应模块中完成,这个模块使用的是 Web效劳器提供的接口,响应的过程是在策略调度之后,所以客户端再次发送的报文请求还是会通过报文的解析及策略的调度,如果“拒绝连接的响应方式是由Web效劳器外的方式实现的,比方操作系统的IP 策略或硬件防火墙等,则客户端再次发送的请求不会再被报文解析模块接收到,也不会再被引擎策略调度。(4)发送信息直接发送一段文本信息到客户端,通常是一段提示或警告信息。这是一种比拟友好的交互行为,其效果为客户端的浏览器上会显示发送的这段信息。当策略引擎检测到策略返回的是这种响应方式后会停顿调用策略链后面的其他策略。(5)发送文件发送效劳器上的一个文件到客户端。这种响应方式和上一种类式,但通过文件的方式可以发送更多的信息到客户端。比方在防止图片的盗链的策略中,可以发送一个用来说明图片为盗链的图片文件到客户端。如果是采用的发送信息的响应方式,则客户端看不到这条信息。(6)重定向让 Web Server 重定向客户端的。和前两种响应方式类似,区别是客户端会检测到所的 Url 的发生跳转。跳转即可以是本效劳器的地址,也可以是外部效劳器的地址。当策略引擎检测到策略返回的是这种响应方式后也会停顿调用策略链后面的其他策略3.4 策略引擎的设计策略引擎是整个系统的核心模块,如图 3 所示为策略引擎的构造。策略引擎可以加载两种格式的策略,或者说策略可以用两种不同的方式实现,一种是使用 C+编码的 C+类,一种是使用策略脚本文件。虽然实现的方式不同,但策略引擎以同样的方式调度。C+的效率高,而脚本驱动的策略修改和编写都十分方便。这种体系构造可以方便的把策略不同的实现方式扩大进来。.z-策略引擎的初始化过程为:读取策略的属性列表,根据属性列表加载策略。初始化完成后就可以等待客户端发出效劳器的请求,为客户端的进展策略调度。下面就将介绍策略的属性及策略的加载和调度的过程。3.4.1 策略的属性策略的属性可以帮助策略引擎选择适宜的策略加载器加载策略和策略引擎按适宜的方式调度策略。(1)策略的名称用来标示不同的策略,在加载过程中,C+加载器通过此名称生成 C+策略的对象。在属性列表中这一条不能省略。(2)描述描述策略的功能。可以省略。(3)类型按类型可以把策略分为系统策略和用户策略。系统策略永远都是在用户策略前面调度。这两种不同类别的策略都可以由 C+的类或者以脚本的方式实现。此属性的作用是在增加策略优先级调度的粒度。可以在配置文件中设置此值(4)加载器表示策略该有什么样的加载器加载,加载器会将该策略转换成策略引擎能够调度的策略对象。.z-(5)开启状态可以给策略的设置开启状态:Enable 和 Disable,当一个策略处于 Disable 状态时,策略引擎会跳过对其的加载。(6)加载状态策略的加载状态:Unloaded/Loaded,当策略的加载状态不处于 Loaded 时,策略引擎不对其进展调度。这个值不能在配置文件中设置,默认为 Unloaded,当策略引擎成功加载此策略时,会将此值设置为 Loaded。(7)优先级通过优先级可以控制策略调度的顺序,优先级得*围是:0-255,值越低的优先级越高。(8)路径记录策略脚本的位置,加载时通过这个属性找到相应的策略文件的路径。这个属性只对脚本加载器有效。3.4.2 策略的加载策略引擎加载策略的步骤如下:(1)IPS 通过配置模块读取出策略属性列表,去掉此列表中策略名称重复的项,然后将此列表作为策略引擎初始化的参数或者作为策略引擎重新加载的参数。.z-(2)策略引擎将由此列表中策略类型属性和优先级属性,由系统策略到用户策略,从高优先级策略到低优先级的策略的次序,进展排序。形成一个新的策略列表。(3)按后面的步骤依次加载这个策略列表中的属性。(4)如果策略的开启状态属性不为 Enable,则跳过该策略,继续加载策略列表中后面的策略。(5)如果加载器的属性为C+则交由 C+的策略加载器处理,如果是为脚本的就由相应的脚本加载器处理。如果不能识别则跳过该策略。C+的加载器为一个策略对象的工厂类,会根据策略的名称生成不同的策略对象,如果找不到为该名称的策略则返回NULL 表示加载失败。脚本加载器会根据属性中的路径字段去读取策略脚本,加载器要完成策略脚本语法检测的步骤,加载成功时也是返回一个策略对象,加载失败返回NULL。如上所述,加载器会将策略对象的初始化C+对象是通过调用构造函数来实现。所以在策略的调度前不需要再对策略做初始化。(6)加载成功后就将该策略的状态属性置为Loaded,如果是加载失败就保持该选项为Unload。(7)直到策略列表中的所有项都处理完毕后,重新遍历这个列表,把Loaded 的项依次提取出来,形成策略调度用的策略列表。3.4.3 策略的调度策略对象中提供两个接口供策略引擎调度,一个是OnRecv,另一个是 OnSend。当策略引擎是为检测客户端的信息而调动策略时,都是调用的策略中的OnRecv接口,而当策略引擎是为检测效劳器发送的数据是,都是调用策略中的OnSend 接口。策略引擎将按下面的步骤对策略链上的策略进展调度:(1)依次按步骤2 3调动策略链上的策略(2)如果策略返回的是一个“调用下一条策略的响应时,则调用下一条策略。(3)如果策略返回的不是“调用下一条策略的响应时,则停顿调度策略链上后面的策略并返回该响应。.z-(4)重复步骤2 3直到策略全部调度完,如果没有任何策略响应,则策略引擎返回一个“承受请求的响应。3.4.4 策略的接口(1)策略调度的接口为时策略引擎能调度策略对客户端的行为进展检测,策略为策略引擎的不同阶段的调度提供三个接口:OnRecv、OnSend 和 OnEnd。在检测客户端发出的请求时,策略引擎调用策略中的 OnRecv接口;在检测效劳器端对客户端的响应时调用OnSend 接口;当会话完毕时,策略引擎调度 OnEnd 接口。策略调度时,策略引擎在调用这些接口时传入的都是client 对象。不同的方式实现的策略中都要提供这几个接口。(2)客户端对象:client策略调度接口的参数,策略引擎在调用 OnRecv和 OnSend 时传入的参数就是 client,client中提供获取客户端信息的方法:GetServerVariable。由解析模块提供其具体实现。(3)获取客户端信息的接口:GetServerVariableClient 对象的方法。策略引擎需要为策略提供能获取客户端或效劳器端的信息的方法,具体的实现是在解析与响应层来完成的。解析与响应层中会为每一个客户端的请求生成一个对象,这个对象提供获取客户端和效劳器端信息的为GetServerVariable。此接口和 Web脚本中的 GetServerVariable的作用一致,用来获得 ServerVariable。例如:REMOTE_ADDR是客户端的 IP;QUERY_STRING是查询请求中问号?后的信息;_COOKIE 是客户端发送的 Cookie,等等。可以在策略脚本中封装这个接口,使脚本显得更直观。(4)响应的接口:Response和响应的方式一一对应:Disconnect、SendMsg、SendFile、Redirect和 Accept,Ne*t Policy。策略引擎认为策略的默认响应为“Ne*t Policy。具体的实现是由响应层完成的。以上描述的是本系统的体系构造、处理流程、功能框图及各个模块的详细设计和接口,至此,设计工作就全部完成了,下面将根据此设计思想的来实现Web的入侵防御系统。4 Web的入侵防御系统的实现按照前面介绍的体系构造,整个系统分成了三层:解析及响应、策略引擎、数据管理。在Windows 平台下的 IIS 效劳器上,IIS 提供了 ISAPI 机制来实现效劳器的扩展和筛选器。我们可以利用 ISAPI 来实现的解析与响应。我们使用C+编写 ISAPI 的 DLL。在策略的实现上,除了提供C+的策略,我们同时提供Lua 脚本编写的策略。在配置文件的管理上,我们通过*ml 文件来实现。下面我们将详细介绍这三层的实现。4.1 基于 ISAPI 的解析及响应模块的实现.z-在这个 Web的入侵防御系统中,我们选择ISAPI 筛选器来实现报文的解析与响应。下面将分别介绍使用 ISAPI 获取报文信息和利用 ISAPI 进展响应的具体实现4.1.1 使用 ISAPI Filter 获取报文信息ISAPI Filter 提供两个回调函数:GetFilterVersion 和FilterProc。下面是这两个回调函数的具体作用:(1)GetFilterVersion当 IIS 加载 ISAPI Filter 的 DLL 时,会调用此函数。通过这个函数,可以设置 ISAPIFilter 的优先级和确定请求的事件。根据系统的需求,我们需要在 IIS 中注册以下几个事件:SF_NOTIFY_PREPROC_HEADERSSF_NOTIFY_SEND_RESPONSESF_NOTIFY_END_OF_REQUEST通过 SF_NOTIFY_PREPROC_HEADERS 我们可以获取客户端所发送的报文头;通过 SF_NOTIFY_SEND_RESPONSE 我们可以获取效劳器发送的报文头。通过SF_NOTIFY_END_OF_REQUEST 我们可以知道请求已完毕。(2)FilterProc当对应的事件发生时,效劳器通过调用 ISAPI Filter 的FilterProc 入口点通知为该事件注册的每个筛选器。可以通过FilterProc 以提供特殊的事件处理。当:FilterProc 被调用时,接收到的通知将确定将要如何处理该事件。我们在 GetFilterVersion 中注册了 SF_NOTIFY_PREPROC_HEADERS 事件,所以当效劳器分析好客户端所发送的报文头时,将通知我们的 ISAPI Filter 处理该报文头,并根据处理的结果进展相应的响应。我们可以在FilterProc 检测当 SF_NOTIFY_PREPROC_HEADERS 事件发生时便调用 OnPreprocHeaders 函数处理客户端发送的报文头。相关的 C+声明如下:.z-DWORD WINAPIFilterProc(P_FILTER_CONTE*T pfc,DWORD notificationType,LPVOID pvNotification);typedef struct _FILTER_CONTE*T_FILTER_CONTE*T DWORD cbSize;DWORD Revision;PVOID ServerConte*t;DWORD ulReserved;BOOL fIsSecurePort;PVOID pFilterConte*t;BOOL GetServerVariable;BOOL AddResponseHeaders;BOOL WriteClient;VOID*AllocMem;BOOL ServerSupportFunction;_FILTER_CONTE*T,*P_FILTER_CONTE*T;BOOL WINAPI GetServerVariable(P_FILTER_CONTE*T pfc,LPSTR lpszVariableName,LPVOID lpvBuffer,LPDWORD lpdwSize);我们在 OnPreprocHeaders 即可以获得通过 GetServerVariable 函数就可以获得客户端发送的请求的报文头部信息及效劳器的变量。在这里我们将封装成一个 IClient 的对象。策略引擎会对不同的策略引擎把 IClient 重新封装。4.1.2 使用 ISAPI 进展响应(1)拒绝.z-当在 ISAPI Filter 中直接返回 SF_STATUS_REQ_FINISHED 时,IIS 效劳器就会断开和客户端的连接。(2)发送信息发送信息的响应中有两个参数,一个是报文响应的状态,例如:状态200 表示正常;状态 403 表示拒绝;状态 500 表示效劳器错误等等。另一个参数是所发送信息的内容。通过 ISAPI Filter 中提供的ServerSupportFunction API 可以设置响应的报文的状态,通过 WriteClient可以直接向客户端写数据。以下为发送信息响应方式的局部实现代码void IISClient:SendMsg(const char*status,const char*msg)uint32_t bufSize;_pfc-ServerSupportFunction(SF_REQ_SEND_RESPONSE_HEADER,const_cast(status),NULL,NULL);bufSize=uint32_t(strlen(msg);_pfc-WriteClient(const_cast(msg),&bufSize);(3)发送文件发送文件的实现和发送信息的实现类似。第二个参数换成了要发送文件的路径。发送的文件内容从该路径指定的文件中读取。以下为发送文件响应的实现的局部实现代码IISClient:SendFile(const char*status,const char*filename)const DWORD BUF_SIZE=10*1024;char bufferBUF_SIZE=0;_pfc-ServerSupportFunction(SF_REQ_SEND_RESPONSE_HEADER,const_cast(status),NULL,NULL);ifstream in(filename,ios_base:binary);.z-if(in)DWORD nCount=0;for(;)in.read(buffer,BUF_SIZE);nCount=in.gcount();if(nCount=0)break;_pfc-WriteClient(buffer,&nCount);(4)重定向将效劳器端响应的报头中的状态码设置为“302 MovedPermanently,同时设置报头中的 Location 为要转向的地址。客户端的浏览器在收到这样的报文后会重新去新的地址。重定向的局部实现代码如下void IISClient:Redirect(const char*url)char buf256;sprintf(buf,Location:%srn,url);_pfc-AddResponseHeaders(buf);.z-_pfc-ServerSupportFunction(SF_REQ_SEND_RESPONSE_HEADER,302 Moved Permanently,NULL,NULL);return;4.1.3 在效劳器上的安装配置 ISAPI Filter正确的配置 ISAPI Filter 才能保证系统能够正常工作。在 Windows 2003 的效劳器上配置 IIS 的 ISAPI Filter 的步骤如下:(1)翻开 IIS 管理器(2)展开左侧的目录树,选择,单击鼠标右键,选择属性(3)选择 ISAPI 筛选器一栏(4)点击添加按钮,筛选器名称填“WebIPS,可执行文件选择 WebIPS 所在的路径,单击确定添加完毕。(5)如果需要重新加载 ISAPI,需要重启 IIS 效劳。在完成上述步骤后,通过浏览器下效劳器所在的,如果状态栏变为绿色向上箭头,说明系统已经可以正常工作,否则说明 ISAPI Filter 没有加载成功。4.2 基于 Lua 的策略实现在这个 Web 的入侵防御系统的设计中,策略引擎可以加载 C+实现的策略和脚本实现的策略脚本。C+实现的策略效率高但因为采用硬编码的方式集成到系统中,除了少量的数据信息可以通过配置文件在加载时动态配置外,其策略的逻辑.z-无法灵活的修改。而脚本由于其动态解析的特点,策略的逻辑可以很方便的通过修改策略脚本完成,也可以通过策略脚本提供更多的策略。虽然脚本方式的策略在效率方面低于 C+实现的策略,我们可以根据效劳器的配置及需求在 C+实现的策略高效和脚本的方便灵活上找到一个平衡点。在考察了各种脚本引擎的特点后,我们为本系统采用 Lua 语言作为它的策略脚本语言。4.2.1 对策略的封装要让 Lua 作为策略的脚本语言首先得完成对策略的封装。在前面的设计局部已经介绍了策略实现中需要提供的几个接口。由于 Lua 的特性,可以在 C+中很方便的调用 Lua 编写的函数,所以可以在 Lua 策略脚本中,通过 Lua 函数的方式提供策略引擎所需要的 OnRecv 和 OnSend 接口。当策略引擎调用 Lua 策略时,会向 Lua 脚本中的 OnRecv 和 OnSend 函数传递 client 对象这个参数。我们需要将此对象封装成 Lua 脚本能识别的形式。4.2.2 Lua 策略脚本例如使用 Lua 语言编写策略脚本非常简单,下面是一段用来过滤 SQL 注入关键字的Lua 策略脚本例如:warning_msg=请你自重.z-你的攻击行为已经被记录BY 林海峰所有function OnRecv(request)url=request:GetServerVariable(QUERY_STRING)Logger.Append(AntiSQLInject,url)if CheckSqlKey(url)thenreturn Response.SendMsg(request,200 OK,warning_msg);endendfunction CheckSqlKey(str)local test_key=and,or str=string.lower(str)for i,v in ipair