前言

本篇内容介绍针对一些自定义的http包条件过滤要如何实现

1.开启nginx的http请求日志

$ vim vim /usr/local/nginx/conf/nginx.conf

将http下的log_format字段去掉注释并新增http请求体字段,以及部分日志文字注释

修改前:

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

修改后:

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent request_body:$request_body http_referer:"$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

将server中的access_log字段取消注释

access_log  logs/host.access.log  main;

重载nginx配置

$ /usr/local/nginx/sbin/nginx -s reload

2.查看http请求日志

先用tail命令打开日志

$ tail -f /usr/local/nginx/logs/host.access.log

此时对代理服务器进行任意访问,就可以看到实时刷出的日志了

image.png

3.根据http请求自定义流量清洗策略

(1)根据url参数内容过滤

现在我们假定以下请求的日志为攻击请求,该请求访问了index.html并且附带了url参数sql,参数内容为where 1+1

image.png

在modsecurity策略文件配置中加入新文件custom.conf

$ echo "include owasp-modsecurity-crs/rules/custom.conf" >> /usr/local/nginx/conf/modsec_includes.conf

编辑custom.conf文件内容

$ vim /usr/local/nginx/conf/owasp-modsecurity-crs/rules/custom.conf

SecRule ARGS "1=1" \
        "msg:'sql injection',\
        id:7777,\
        phase:request,\
        deny,\
        status:404"

重载nginx

$ /usr/local/nginx/sbin/nginx -s reload

访问http://10.90.3.36/index.html?sql=where 1=1提示404

image.png

查看nginx日志以及modsecurity日志,发现请求被阻止了

image.png

(2)根据url参数名过滤

还是同上请求,现在我们认为url参数中带有参数名sql即判定为攻击请求

$ vim /usr/local/nginx/conf/owasp-modsecurity-crs/rules/custom.conf

SecRule ARGS_NAMES "sql" \
        "msg:'sql injection',\
        id:7778,\
        phase:request,\
        deny,\
        status:404"

请求链接http://10.90.3.36/index.html?sql=test提示404

image.png

查看日志

image.png

(3)根据post中的请求体body内容过滤

现在我们认为所有post请求中,请求体带有action字符串的,均为攻击请求,无论是处于请求体的参数名称还是参数值

$ vim /usr/local/nginx/conf/owasp-modsecurity-crs/rules/custom.conf

SecRule REQUEST_BODY "action" \
        "msg:'struts2 injection',\
        id:7779,\
        phase:2,\
        deny,\
        status:404"

请求发现无论如何请求体中在何处出现action关键字都会被404

image.png

image.png

4.基础规则语法

通用格式
SecRule VARIABLES OPERATOR [TRANSFORMATION_FUNCTIONS, ACTIONS]

阶段phase
(1)request headers
(2)request body
(3)response headers
(4)response body
(5) logging

一、变量variable

绿色:请求变量 蓝色:server变量 紫色:响应变量 红色:请求体解析变量 黑色:时间变量 橙色:实体变量
ModSecurity
Request variables 请求变量
Request variables are those extracted from the request part of the transaction that is being
inspected. The variables that describe the request line (request method, URI and protocol
information) and the request headers become available as early as phase 1 and the complete
information will be available for phase 2.

ARGS 请求参数,类型read-only collection
ARGS_COMBINED_SIZE 请求参数的总大小
ARGS_NAMES 请求参数的名字, 类型read-only collection
ARGS_GET 查询字符串参数,类型read-only collection
ARGS_GET_NAMES 查询字符串参数,类型read-only collection
ARGS_POST 请求体参数,类型read-only collection
ARGS_POST_NAMES 请求体参数的名字,类型read-only collection
FILES 上传文件域,类型read-only collection
FILES_COMBINED_SIZE 上传文件大小
FILES_NAMES 上传文件表单文件域参数的名字,类型read-only collection
FILES_SIZES 上传文件的大小,类型read-only collection
FILES_TMPNAMES 文件临时名字,类型read-only collection
PATH_INFO URI path
QUERY_STRING 查询字符串
REQUESET_BASENAME URI basename,同时支持/与\这两种文件分隔符
REQUEST_BODY 请求体,默认处理application/x-www-form-urlencoded 请求
REQUEST_COOKIES cookie参数
REQUEST_COOKIES_NAMES cookie参数的名字,类型read-only collection
REQUEST_FILENAME URI filename/path
REQUEST_HEADERS 请求头,类型read-only collection
REQUEST_HEADERS_NAMES 请求头参数的名字, 类型read-only collection
REQUEST_LINE 请求行
REQUEST_METHOD 请求方法
REQUEST_PROTOCOL 请求协议
REQUEST_URI 请求URI,但不包括hostname
REQUEST_URI_RAW 请求URI,包括hostname
Server variables
Server variables contain the pieces of information available to the server, most of them valid
only for the transaction being processed at the moment they are evaluated.

AUTH_TYPE 认证类型,代理模式下非本地认证,需要指定Authorization头
REMOTE_ADDR 远程地址, 访问者ip
REMOTE_HOST 远程host,访问者hostname,当HostnameLookUps开启时,为dns解析的域名,否则为ip地址
REMOTE_PORT 远程端口,访问者端口
REMOTE_USER 访问者用户名
SERVER_ADDR 服务端地址
SERVER_NAME 服务端hostname,取值Host请求头
SERVER_PORT 服务端端口
SCRIPT_BASENAME 脚本basename, 代理模式不可用
SCRIPT_FILENAME 脚本 filename,代理模式不可用
SCRIPT_GID 脚本group ID,代理模式不可用
SCRIPT_GROUPNAME 脚本 group name,代理模式不可用
SCRIPT_MODE 脚本权限 ,代理模式不可用
1 表示可执行
2 表示可写
4 表示可读
7 表示可写可读可执行
SCRIPT_UID 脚本 user ID,代理模式不可用
SCRIPT_USERNAME 脚本 user name,代理模式不可用
Response variables
Response variables are those extracted from the response part of the transaction that is being
inspected. Most response variables will be available in phase 3. The arguably most important
response variable, RESPONSE_BODY, is only available in phase 4 (the phase is also called
RESPONSE_BODY).

RESPONSE_BODY 响应体
RESPONSE_CONTENT_LENGTH 响应实体长度,单位bytes
RESPONSE_CONTENT_TYPE 响应实体类型,仅仅在phase3可用
RESPONSE_HEADERS 响应头,类型read-only collection
在内嵌模式中,像那种会优先将数据发送给客户端的响应头是不可获得的,例如Server,Date,Connection,Content-Type
在代理模式中,阶段5可用
RESPONSE_HEADERS_NAMES 响应头参数的名字,类型read-only collection
在内嵌模式中,像那种会优先将数据发送给客户端的响应头是不可获得的,例如Server,Date,Connection,Content-Type
在代理模式中,阶段5可用
RESPONSE_PROTOCOL 响应协议
RESPONSE_STATUS 响应码,仅代理模式可用

Collections
Collections are the special kind of variables that can contain other variables. With exception
of the persistent collections, all collections are essentially one-offs, special variables that give
access to the information to which ModSecurity has access.

TX 事件内变量, 类型read/write collection
当使用operator @rx或@pm时,TX:0表示capture action捕获的变量 TX:1-TX:9:表示capture action捕获的子串
RULE rule元数据, 类型read/write collection, 用于设置Rule对象的属性:id,rev,severity,logdata, msg
SESSION session数据,类型read/write collection
仅当setsid action执行后使用, session对象的属性,SCORE得分, BLOCKED是否阻塞

例如:下面的例子说明了怎么用setsid初始化一个SESSION集合,怎么使用setvar增加session.score的值,怎么设置session.blocked的值,最后怎么拒绝基于session.blocked的值的集合。

SecRule REQUEST_COOKIES:PHPSESSID !^$ chain,nolog,pass

SecAction setsid:%{REQUEST_COOKIES.PHPSESSID}

SecRule REQUEST_URI “^/cgi-bin/finger$” \

“phase:2,t:none,t:lowercase,t:normalizePath,pass,log,setvar:session.score=+10”

SecRule SESSION:SCORE “@gt 50” “pass,log,setvar:session.blocked=q1”

SecRule SESSION:BLOCKED “@eq 1” “log,deny,status:403”

GEO geo信息,类型read-only collection,Geo lookup information from the last @geoLookup invocation (read-only collection)
ENV 环境变量,类型read-only collection,但可以使用setvar来修改变量的值
GLOBAL 全局变量,类型read/write collection
IP 存储的ip数据 ,类型read/write collection
USER user数据,类型read/write collection
XML xml dom相关的,类型read-only collection
Miscellaneous variables

Miscellaneous variables are exactly what they are called: they are the variables that couldn’t
fit in any other category.

HIGHEST_SEVERITY 严重级别,值越小级别越高,255表示未设置严重级别

MATCHED_VAR 最近一次匹配的变量
MATCHED_VAR_NAME 最近一次匹配的变量的名字
MODSEC_BUILD modsecurity版本号
SESSION_ID sessionID associated with current transaction
USERID user ID associated with current transaction
WEBAPPID web app ID Web associated with current transaction
WEBSERVER_ERROR_LOG server产生的错误信息
Time variables
Time variables all represent the moment in time when the transaction that ModSecurity is
processing began.

TIME HH:mm:ss
TIME_DAY 1-31
TIME_EPOCH
TIME_HOUR 0-23
TIME_MIN 0-59
TIME_MON 0-11
TIME_SEC 0-59
TIME_WDAY 0-6
TIME_YEAR
DURATION 时间花费,milliseconds
Parsing flags
Parsing flags are used by ModSecurity to signal important parsing events. The idea is to
avoid taking implicit action (e.g., blocking in response to an invalid request), but allow the
rules to decide what to do.

MULTIPART_BOUNDARY_QUOTED multipart 解析错误:boudnary中有引号
MULTIPART_BOUNDARY_WHITESPACE multipart 解析错误:boudnary中有空格
MULTIPART_CRLF_LF_LINES multipart 解析错误:混合使用\r\n 与\n作为分界线, 当允许使用混合粉各符时设置为1
MULTIPART_DATA_BEFORE multipart 解析错误:第一个boudnary前有数据
MULTIPART_DATA_AFTER multipart 解析错误:最后一个boudnary后有数据
MUTLIPART_HEADER_FOLDING multipart 解析错误:boudnary中
MULTIPART_LF_LINE multipart 解析错误:使用\n作为分界线
MULTIPART_SEMICOLON_MISSIONG multipart 解析错误:缺少分号
MULTIPART_STRICT_ERROR 当以下值为1时,该值为1;
REQBODY_PROCESSOR_ERROR
MULTIPART_BOUNDARY_QUOTED
MULTIPART_BOUNDARY_WHITESPACE
MULTIPART_DATA_BEFORE
MULTIPART_DATA_AFTER
MULTIPART_HEADER_FOLDING
MULTIPART_LF_LINE 使用换行做分界线
MULTPART_SEMICOLON_MISSING 分号缺失
MULTPART_INVALID_QUOTING 无效引号
MULTIPART_INVALID_QUOTING multipart 解析错误: 无效引号
MULTIPART_UNMATCHED_BOUDDARY multipart 解析错误:不合规范的boudnary,容易漏报
REQBODY_PROCESSOR 处理request解析,内置的解析功能包括URLENCODED, MULTIPART, XML
REQBODY_PROCESSOR_ERROR request解析错误标记,1表示错误,0表示ok
REQBODY_PROCESSOR_ERROR_MSG request解析错误信息
URLENCODED_ERROR 当解析application/x-www-form-urlencoded格式的请求体出错时值为1

二、操作符 operator
绿色:字符串操作符 蓝色:数字操作符 橙色:验证操作副
ModSecurity
@beginsWith
@contains
@containsWord
@endsWith
@rx Regular pattern match 正则
@pm 特征字符串的匹配, 大小不敏感,基于Aho-Corasick匹配算法
@pmFromFile 从文件读取匹配特征字符串 ,Parallel matching, with arguments from a file
@streq String equal to
@within Within
@eq 相等
@ge 大于等于
@gt 大于
@le 小于等于
@lt 小于
Validation operators 验证操作符
Validation operators, in Table 5.11, “Validation operators”, all validate input in some way.

@validateByteRange
@validateDTD XML相关
@validateSchema XML相关
@validateUrlEncoding
@validateUtf8Encoding
Miscellaneous operators :杂项操作符
@geoLookup Determines the physical location of an IP address
@inspectFile 使用外部脚本处理
@rbl 去RBL REAL-TIME BLANKHOLE LISTS反垃圾邮件黑名单里查找ipv4地址,或hostname
@verifyCC Checks if the parameter is a valid credit card number

三、 事件函数transform function
ModSecurity
base64Decode
base64Encode
compressWhitespace
cssDecode
escapeSeqDecode 解码ANSI C escape 序列
hexDecode
hexEncode
htmlEntityDecode
jsDecode
length
lowercase
md5
none 移除当前rule的所有transformation functions
normalizePath 移除掉多个斜杠
normalizePathWin 移除掉多个斜杠,但首先会将\(win正斜杠) 转化成 /(linux反斜杠)
parityEven7bit
parityOdd7bit
parityZero7bit
removeNulls 删除空字节
removeWhiteSpace 删除空格字符
replaceComments 将c格式的注视语句/.../转换为空格ASCII 32
replaceNulls 将null字节转换为空格ASCII 32
urlDecode
urlDecodeUni url解码%uXXXX 编码范围FF01 -FF5E
urlEncode
sha1
trimLeft 移除左边的空格
trimeRight 移除右边的空格
trim 移除左右两端的空格

四、动作action
绿色:disruptive action (每个rule只能有1个disruptive action,如果有多个disruptive action,那么只有最后一个有效,在rule chain中,disruptive action只能出现在第一个rule中)
蓝色:flow action
紫色:metadata action
红色 :variable action
黄色:logging action
灰色:special action
黑色:其他

ModSecurity
allow
2.5版本之前是只影响当前阶段

2.5版本之后,遵守以下规则
(1)如果单独使用,除了log阶段,其他阶段都停止处理
(2)如果和参数phase一起使用,allow将停止当前阶段的处理,其他阶段不受影响
Stop processing of one or more remaining phases
block 相当于占位符,会被上下文的SecDefaultAction 指令中的动作取代
deny 使用错误页面block 当前事务,Block transaction with an error page
drop 断开网络连接
pass 继续执行下一个规则
proxy 代理请求到后端web server
redirect 重定向请求到其他web server
Flow actions
Flow actions (Table 5.14, “Flow actions”) alter the way rules are processed within a phase.

chain 相当于多个规则的and操作
skip 跳过指定的规则,值为跳过的规则个数,不能跳过同一个规则链中的规则
skipAfter 调转到指定的规则
Metadata actions 规则属性
Metadata actions (Table 5.15, “Metadata actions”) provide additional information about
rules. The information is meant to accompany the error messages to make it easier to understand
why they occurred.

id 设置规则ID
phase 指明处理阶段
msg
rev 设置版本号
severity 设置rule的严重级别,最好用文本来指定,v2.5.0版本已弃用
tag
Variable actions 变量
Variable actions (Table 5.16, “Variable actions”) deal with variables. They allow you to set,
change and remove variables.

capture 将捕获结果存入TX变量,可以存储10个变量,tx变量集合的下标为0-9
deprecatevar 设置指定时间内递减数字型变量
expirevar 设置指定时间内移除过期的变量
initcol 创建持久性collections,通常在阶段1中设置
setenv 设置环境变量
setvar 设置变量
setuid 设置当前事务的user ID
setsid 设置当前事务的session ID
Logging actions
Logging actions (Table 5.17, “Logging actions”) influence the way logging is done. The actions
that influence if logging takes place (auditlog, log, noauditlog, and nolog) only control
current rule affects logging if it matches. To control logging for the transaction as a
whole you’ll need to use the ctl action.

auditlog 将当前事务记录到审计log中
log Log error message; implies auditlog
logdata Log supplied data as part of error message
noauditlog Do not log current transaction to audit log
nolog Do not log error message; implies noauditlog
sanitiseArg 在日志中将指定的请求参数替换为*
sanitiseMatched 在日志中将指定的请求参数,请求头,响应头替换为*
sanitiseRequestHeader 在日志中将指定的请求头替换为*
sanitiseResponseHeader 在日志中将指定的响应头替换为*
ctl 改变当前事务的配置
可以改变以下配置

multiMatch 每次变量发生变化会进行一次匹配计算
t 在对变量作匹配操作前指定调用的事务处理函数
append 响应体中注入内容,该action必须开启SecContentInjection指令
exec 执行外部脚本或二进制文件
pause 暂定事务处理
prepend 响应体中注入内容,该action必须开启SecContentInjection指令
status action 为 deny与redirect action时指定响应码
xmlns XML专用

cloudflare 增加了以下action
disabled DIS exit_blocked(self, "DIS", rulefile, nolog)
simulate SIM exit_blocked(self, "SIM", rulefile, nolog)

五、指令directory
ModSecurity
SecRule
SecRuleInheritance 配置当前环境是否继承父节点环境(大部分情况下都配置成可继承,你应当查一下文档的每一个指令,以明确它继承与否)
SecRuleRemoveById 使用ID方式从上级环境中删除规则,
备注:这个指令支持多个参数,每个参数可以是一个规则ID,也可以是范围。带有空格的参数必须使用双引号括起来。
SecRuleRemoveById 1 2 5 10-20 "400-556" 673
SecRuleRemoveByMsg 使用规则方式从上级环境中删除规则
SecRuleUpdateActionById 更新指定RuleID的rule action
SecRuleScript :这个指令创建一个特殊的规则,执行Lua脚本来决定是否匹配,和SecRule主要的不同是这个没有目的也没有操作符,这个脚本可以从ModSecurity环境中取到所有的变量,并使用(Lua)操作符来进行测试,第二个参数可选,与SecRule相同,是一些动作列表。
SecMarker
SecAction
SecDefaultAction 设置默认的action
六、常用操作符

| 或者操作符 e.g.REQUEST_URI|REQUEST_PROTOCOL

: 数组取值操作符 e.g. ARGS:p

! 非操作符 e.g. ARGS|!ARGS:z

@ 操作符函数调用 e.g. @rx

t 事务函数调用 e.g. t:lowercase

& 取数组个数符 e.g. &ARGS @ge 1

%{COLNAME.VARNAME}变量扩展符 e.g. SecRule REQUEST_URI_RAW "!@beginsWith http://%{REQUEST_HEADERS.Host}" "drop,tag:'WEB_ATTACK/ILLEGALHTTPPROTOCOL',msg:'host header
illegal',id:00001,phase:2"


参考

modSecurity规则学习(三)——SecRule


相关文章

waf流量清洗nginx反向代理+ModSecurity(一)
最后修改:2023 年 03 月 29 日
如果觉得我的文章对你有用,请随意赞赏