<< Back to handbook   CU网友原创,转载请注明出自ChinaUnix.net及原作者

请求过滤

当过滤引擎被激活的情况下,每个进入的请求在被处理前都要被解释和分析。分析会以一系列事先设计用来校验请求格式的内置检查作为开始。这些检查可以通过配置指示来控制。在第二个阶段,请求会通过一系列的和这个请求相匹配的用户定义的过滤器。每当发生一个肯定的匹配,特定的动作会被执行。

 

简单过滤

最简单的规律形式是“简单”形式。看上去是这样的:

SecFilter KEYWORD

这样的每一个简单过滤器,ModSecurity会在请求中查找关键字。搜索范围很松,会应用在请求的第一行上(这个样子GET /index.php?parameter=value HTTP/1.0)。对POST请求来说,请求体也会被搜索(当让是在请求体缓存被激活的前提下)。

 

路径标准化

过滤器不是作用在原始的请求数据上的,而是在一个标准化了的副本上。这样做是因为攻击者可以(而且正在)通过使用不同的躲避技术来逃过监测。比如,你可能希望通过创建一个过滤器来监测shell命令的执行

SecFilter /bin/sh

但是攻击者可以使用一个字符串:/bin/./sh(具有相同的含义)来逃过过滤器。

ModSecurity自动采用下列转换:

l         只对Windows平台生效,\转换成/

l         /./缩减为/

l         //缩减为/

l         解码使用URL编码过的字符

你可以选择激活或禁止下列检查:

l         检验URL编码

l         只允许使用指定范围内的字节

ModeSecurity当前版本中实现的标准化有时候会影响你的正常工作。你可能在写一个在其他地方检查URI的信号的时候遇到很大困难。这是因为URI在请求中的形式是“http://” ,而这个字符串会在标准化过程中翻译成“http:/”。注意在后面这个版本中只有一个斜线。

 

防止空字节攻击

空字节攻击会迷惑C/C++开发的程序,是它们误认为一个字符串在实际的结束位置之前就结束。这种类型的攻击通常会被合理设置的SecFilterByteRange过滤器拒绝掉。但是如果你没有这样做,空字节会干扰ModSecurity的处理。为了击败这类攻击,ModSecurity在解码阶段搜索空字节并把他们转换成空格。因此,在以前的版本这个过滤器

SecFilter hidden

不会检测到下列请求中的单词hidden

GET /one/two/three?p=visible%00hidden HTTP/1.0

但是在现在的版本是可以检测到的。

 

正则表达式

我们前面讨论的最简单的过滤器实际上要稍微复杂一点。它的完整的语法是这样的:

SecFilter KEYWORD [ACTIONS]

首先,KEYWORD不是一个普通单词,而是一个正则表达式。正则表达式是设计用来在文本中匹配模式的迷你编程语言。为了充分理解这个强大的工具,需要先充分理解正则表达式。我推荐从下面的资源之一入手:

l         Perl兼容的正则表达式的手册页:http://www.pcre.org/pcre.txt

l         Perl正则表达式: http://www.perldoc.com/perl5.6/pod/perlre.html

l         精通正则表达式:http://www.oreilly.com/catalog/regex

l         Google搜索“正则表达式”:http://www.google.com/search?q=regular%20expressions

要小心(A|B)+类型的正则表达式,在海量的文本上使用这样的表达式会在尺寸比较小的平台,比如Windows上导致溢出。溢出会导致无法不可回复的段错误。

第二个参数是动作列表的定义,用来指定当过滤器匹配成功是发生的动作。关于动作会在后面解释。

 

反转表达式

如果一个正则表达式的第一个字符是惊叹号,过滤器会反转这个表达式。比如下面的例子:

SecFilter !php

会拒绝所有的不包含单词php的请求。

 

高级过滤

所以SecFilter可以让你快速上手,但是你很快会发现它的搜索面太宽,工作的不是很好。另一个指示:

SecFilterSelective LOCATION KEYWORD [ACTIONS]

让你可以准确的选择在哪里进行搜索。

KEYWORD和ACTIONS设置和SedFilter是一样的。LOCATION需要解释一下。LOCATION参数包含用管道符分开的一系列的位置标识符。看一下下边的例子:

SecFilterSelective "REMOTE_ADDR|REMOTE_HOST" KEYWORD

只在客户端的IP地址和主机名上使用正则表达式。可能的位置标识符包括所有的CGI变量和其他的一些内容。下面是完整的列表:

l         REMOTE_ADDR

l         REMOTE_HOST

l         REMOTE_USER

l         REMOTE_IDENT

l         REQUEST_METHOD

l         SCRIPT_FILENAME

l         PATH_INFO

l         QUERY_STRING

l         AUTH_TYPE

l         DOCUMENT_ROOT

l         SERVER_ADMIN

l         SERVER_NAME

l         SERVER_ADDR

l         SERVER_PORT

l         SERVER_PROTOCOL

l         SERVER_SOFTWARE

l         TIME_YEAR

l         TIME_MON

l         TIME_DAY

l         TIME_HOUR

l         TIME_MIN

l         TIME_SEC

l         TIME_WDAY

l         TIME

l         API_VERSION

l         THE_REQUEST

l         REQUEST_URI

l         REQUEST_FILENAME

l         IS_SUBREQ

还有一些特殊的位置:

POST_PAYLOAD – filter the body of the POST request

ARGS - filter arguments, the same as QUERY_STRING|POST_PAYLOAD

ARGS_NAMES – variable/parameter names only

ARGS_VALUES – variable/parameter values only

COOKIES_NAMES - cookie names only

COOKIES_VALUES - cookie values only

甚至还有更特殊的:

HTTP_header – search request header header

ENV_variable – search environment variable variable

ARG_variable – search request variable/parameter variable

COOKIE_name - search cookie with name name

 

参数过滤的特殊情况

位置标识符ARG_variable在和ARG位置合并使用的时候支持反转。例如:

SecFilterSelective "ARGS|!ARG_param" KEYWORD

会搜索除了名字是“param”的参数之外的所有的参数。

 

                                                                                               

Cookies

 

ModSecurity Cookies提供完全支持。默认情况下,版本 0 Cookies被使用 (Netscape 类型的cookies, Netscape-style cookies)。然而,ModSecurity 同时也支持版本 1 CookiesRFC 2965 中定义的Cookies. 你可以使用以下的格式,定义支持版本 1 cookies

 

# enable version 1 (RFC 2965) cookies

SecFilterCookieFormat 1

 

 

默认情况下,ModSecurity不会去尝试标准化cookie的名称及值。 然而,一些应用程序或者平台(例如:PHP)会对cookeie编码,以便你可以选择为cookie添加标准化技术。你可以通过对SecFilterNormalizeCookies指令的定义实现

 

SecFilterNormalizeCookies On

 

ModSesurity 1.8.7版本以前支持SecFilterCheckCookieFormat指令。在1.8.7以后的新版本中这条指令已经被取消。这条指令可以仍然用在配置文件中,但是不起任何作用。在1.9.X以后的版本中这条指令已经被完全取消。

 

输出过滤(Output filtering

MoSecurity Apache 2版本中支持输出过滤。默认情况下,输出过滤是被禁止的,如果你想要使用必需首先打开这个选项:

 

SecFilterScanOutput On

 

之后,使用特殊变量OUTPUT简单添加选择过滤器:

SecFilterSelective OUTPUT "credit card numbers"

 

http://www.webkreator.com/php/许多和我一起研究这些朋友知道我对防止PHP致命错误( fatal errors)有些无能为力。我花了很长时间去研究防止PHP致命错误信息泄漏给用户。 (×××)(参考:http://www.webkreator.com/php/configuration/handling-fatal-and-parse-errors.html

但是现在,最终在这方面我不用太担心了。以下的指令可以从返回信息(response的主体文件中捕获PHP输出错误,而不是从单独的错误回应(response)中捕获,并且执行定制的PHP脚本(同时通报应用程序管理员)。

SecFilterSelective OUTPUT "Fatal error:" deny,status:500

ErrorDocument 500 /php-fatal-error.html

你应该注意到尽管你可以混合输入输出过滤器,但是它们不能在同一时间执行。输入过滤器在一个请求被Apache处理之前被执行。输出过滤器在Apache完成请求处理以后被执行。

 

动作(Actionsskipnext chain不能在输出(output)过滤器工作。输出过滤仅仅用于纯文本和HTML输出的过滤。添加常规的二进制内容的表达式(例如:Image)将仅仅会使服务器慢下来(~~~~~~.ModSecurity 能基于它的mime类型有选择的添加输出过滤给响应(responses)。使用SecFilterOutputMimeTypes指令你能告诉它哪一个mime 类型去监视:

SecFilterOutputMimeTypes "(null) text/html text/plain"

上面的一个简单ModScurity的配置实例会给纯文本文件HTML文件,、和mime类型不是被特殊的"(null)"位置的文件添加输出过滤。使用输出缓冲将使ModSecurity 保持完整的内存中的页输出,无论它本身有多大。内存开销是页长度的2倍以上。

 

动作(Actions

 

有以下几种动作:

 

主动作(action)将生成一个决策决定是否去继续请求或者拒绝请求。有且只有一个主动作存在。如果你在parameter里设置了几个主动作,最后一个动作将被执行。主动作为deny,

pass, redirect(转向).

第二动作将由主动作在决策中作定义,并在一个独立匹配的过滤器(filter)中被执行。在第二动作中可以是任何值,例如:exec 是一个第二动作。

 

下面的动作能改变相应的规则的流向,因为过滤引擎能跳到其他规则,或者跳到一个或几个规则。实现动作是chain skip.

 

参数不是真正的动作,而是一个针对过滤器的附加参数的方法(method)。有些参数能被用于真正的动作。例如:status deny提供一个响应编码。

 

指定动作(Specifying actions

 

你可以把动作放在三个地方。一个是SecFilterDefaultAction指令,在这里你可以定义你想在大多数过滤匹配中被执行的动作:

SecFilterDefaultAction "deny,log,status:500"

这个例子定义了一个由三个动作组成的动作列表。逗号用与在列表中分开动作。开始的两个动作是由单个的单词组成。但是第三个动作需要一个参数,用冒号把参数和动作名分隔开。

 

你也能指定过滤器预处理动作。做为一个可选参数,有两个过滤器指令可以接受一个指定动作的设置(SecFilter SecFilterSelective)。当使用的过滤器预处理动作是一个伪装请求时,这个请求在过滤匹配器中将会被拒绝。如果你想容许请求继续,你必须明确的设置一个non-fatal动作(例如:log,pass”.

对于1.8.6,如果你指定了non-fatal为默认动作(例如:log,pass”.,那么在mod_security初始化的阶段它就会被忽略。初始化阶段仅仅用来收集关于请求的信息,容许non-fatal动作是因为一些请求块错误(在mod_security中对于内部处理)。因此,如果你想mod_security在探测"detect-only"模式下运行,你应该禁止所有固有确认(检查 URL encoding, Unicode, cookie 格式化, byterange).

内置动作(Built-in actions

pass

容许在过滤匹配中请求被继续。这个动作用在当你想纪录一个匹配(match)而不并不想执行其他的动作时候。

SecFilter KEYWORD "log,pass"

allow

 

在这个动作执行后,请求将被容许通过,并且没有别的过滤器被重试。

# stop filter processing for request coming from

# the administrator's workstation

SecFilterSelective REMOTE_ADDR "^192.168.2.99$" allow

 

deny

 

在过滤匹配中中断一个请求处理。除非status动作也在使用。ModSecurity 会立即返回一个HTTP 500错误代码。如果一个请求被拒绝,文件头mod_security-action将会被添加到请求文件头列表中去。这个文件头包括code使用状态。

 

Status

 

当一个请求被拒绝的时候使用替代HTTP状态代码。

下面的规则:

SecFilter KEYWORD "deny,status:404"

当他被触发的时候将返回"Page not found"信息。如果在配置里有这条规则Apache 错误提示信息会被触发。所以,如果你以前已经为一个设定的状态定义了一个定制的错误页,那么它将会被执行并且给用户显示。

 

Redirect

 

在过滤匹配中可以重定向用户到指定的URL.例如:

SecFilter KEYWORD "redirect:http://www.modsecurity.org"

这个配置指令不考虑HTTP状态代码或者deny关键字。注意,URL中不能包括逗号。

 

Exec

 

在过滤匹配中执行二进制文件,需要在指令中添加要执行的文件的完整路径,例如:

SecFilter KEYWORD "exec:/home/ivanr/report-attack.pl"

如果这条指令存在,它对主动作不产生影响。这个动作总是调用不带参数的脚本,但是提供所有在环境中的信息。所有的通用的CGI环境变量都将放在这里。你可以在预过滤匹配中执行一个二进制文件。完成以后将增加一个mod_security-executed的报头到请求包列表中。你应该理解调用线程会导致在所有的线程将会复制到新的线程。在多进程选项中调用会导致更大的开销。

 

log