如何在企业中应用ModSecurity,整理相关有用的要点,用于理解和调试
一、介绍
ModSecurity
一开始有上图这哥们为了保护几个web应用程序而创建的,通过嵌入到web容器中,分析数据,阻挡恶意攻击,最初是Apache HTTP
的插件。
- 2004年,ModSecurity开始商业化
- 2006年,Thinking Stone 被Breach Security收购
- 2006年,ModSecurity2.0发布
- 2010年,Trustwave收购Breach Security
- 2017年,ModSecurity3.0发布,支持Nginx
作为WAF产品,ModSecurity
专门关注HTTP流量,当发出HTTP请求时,ModSecurity
检查请求的所有部分,如果请求被认为是恶意的,它可以被阻止、记录或同时记录,这取决于配置。
ModSecurity3.0 新的体系结构
-
ModSecurity
之前的版本中,在nginx中的兼容性很差,,这是因为ModSecurity
被包裹在一个完整的版本的Apache HTTP服务器,它提供了一个兼容性层ModSecurity非常严重依赖于Apache
-
ModSecurity 3 0
是一个完全重新改写,完美兼容nginx
,无需Apache
。 - 新的3.0版本中,将核心功能转移到了名为
libmodsecurity
的独立引擎中,此引擎通过nginx连接器连接到nginx,是nginx的一个组件,同时Apache
也有单独的连接器 -
NGINX
的ModSecurity
动态模块将libmodsecurity
和NGINX连接器
组合在一个包中。(也支持静态编译) -
NGINX Plus
发行版包含编译后的动态模块NGINX
开源用户每次更改NGINX
版本时都必须编译ModSecurity
源代码(nginx plus是付费产品) - 新版本比老版本更新更快,更加稳定,并且得到了
nginx、Inc和Trustwave
等团队的积极支持
警告说明
ModSecurity3.0
暂时还没有与上一个版本ModSecurity2.9
进行功能对比,需要注意一下限制:
- 不支持检查响应体的规则,如果配置中包含这些规则,则会被忽略,nginx的
sub_filter
指令可以用来检查和重写响应数据,OWASP中相关规则是95x。 - 不支持OWASP核心规则集DDoS规则,
REQUEST-912-DOS- PROTECTION.conf
,nginx本身支持配置DDoS限制 - 不支持在审计日志中包含请求和响应主体
- 一些指定没有实现,尝试使用会报错,ModSecurity参考手册列出了
ModSecurity
中所有可用的指令,以及libModSecurity
是否支持这些指令
二、安装ModSecurity
使用nginx plus的好处
ModSecurity 3.0
for NGINX Plus被称为NGINX WAF
,商业订阅有很多好处:
- 无需自己编译
ModSecurity
动态模块;NGINX, Inc
为您提供预编译模块,省时省力 -
NGINX, Inc
对动态模块进行了广泛的测试,所以您知道它适合于生产使用 -
NGINX, Inc
持续跟踪更改,并针对每一个重要的更改和安全漏洞更新模块 -
NGINX Plus
的每个新版本都包含了一个动态模块的新版本,所以你可以升级而不必重新编译ModSecurity
- 通过安装
ModSecurity
和OWASP
核心规则集,以及故障排除和调试帮助,您可以获得24x7支持
Nginx Plus
提供一周的试用时间。
nginx源码编译
在nginx 1.11.5或更高版本中,可以直接通过编译动态模块,不需要重新编译nginx二进制文件,直接将动态模块加载到nginx配置中进行引用。
1、从nginx官方存储库下载安装
从官网下载源码:https://nginx.org
nginx版本1.11.5或更高版本(使用nginx动态模块)
2、安装依赖包
yum install epel-release
yum install gcc-c++ flex bison yajl yajl-devel curl-devel curl GeoIP-devel doxygen zlib-devel pcre pcre-devel libxml2 libxml2-devel autoconf automake lmdb-devel ssdeep-devel ssdeep-libs lua-devel libmaxminddb-devel git
3、下载编译libmodsecurity
git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity
cd ModSecurity
git submodule init
git submodule update $ ./build.sh
./configure
make
make install
编译时间大概15分钟,取决于系统性能
4、下载nginx连接器源码,并编译成动态模块
- 克隆镜像
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git
- 确定nginx安装的版本
nginx -v
nginx version: nginx/1.13.7
- 下载NGINX安装版本对应的源代码(即使只编译动态模块,也需要完整的源代码):
wget http://nginx.org/download/nginx-1.13.7.tar.gz
tar zxvf nginx-1.13.7.tar.gz
- 编译动态模块,并复制模块到标准目录
cd nginx-1.13.7
./configure --with-compat --add-dynamic-module=../ModSecurity-nginx $ make modules
cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules
5、加载nginx连机器动态模块
load_module modules/ngx_http_modsecurity_module.so;
nginx在读取配置时,会加载动态模块
Nginx Plus 安装说明
介绍如何安装NGINX web application firewall
(WAF)。NGINX WAF
构建在ModSecurity 3.0
之上
NGINX WAF
可以作为一个下载的动态模块提供给NGINX Plus
客户,购买或开始免费试用NGINX WAF
先决条件:https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-plus/
安装Nginx WAF
- 直接通过包管理器安装
yum install nginx-plus-module-modsecurity
- 加载动态模块
load_module modules/ngx_http_modsecurity_module.so;
- 验证模块是否加载成功
nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
验证安装
配置本地demo程序
server {
listen localhost:8085;
location / {
default_type text/plain;
return 200 "Thank you for requesting ${request_uri}\n";
}
}
测试
nginx -s reload
curl -D - http://localhost:8085 HTTP/1.1 200 OK
#Server: nginx/1.11.10
#Date: Wed, 3 May 2017 08:55:29 GMT Content-Type: text/plain Content-Length: 27
#Connection: keep-alive
Thank you for requesting /
配置nginx反向代理
server {
listen 80;
location / {
proxy_pass http://localhost:8085; proxy_set_header Host $host;
}
}
测试
nginx -s reload
curl -D - http://localhost HTTP/1.1 200 OK
#Server: nginx/1.11.10
#Date: Wed, 3 May 2017 08:58:02 GMT Content-Type: text/plain Content-Length: 27
#Connection: keep-alive
Thank you for requesting /
开启SecRuleEngine,并且测试
# A test rule
SecRule ARGS:testparam "@contains test" "id:1234,deny,log,status:403"
三、安装OWASP Core Rule Set
CRS文件和目录结构
CRS的主配置文件定义了异常评分阈值、偏执级别和其他重要的ModSecurity配置
规则/ 目录包含组织成不同文件的规则,每个文件都有一个分配给它的编号
-
90x文件:
排除误报 -
91x文件:
检测恶意客户端规则 -
92x文件:
检测违反协议的规则 -
93x和94x文件:
检测运行程序攻击(SQL)或命令执行攻击规则 -
95x文件:
检测出站数据泄露规则,nginx和nginx plus不支持 -
.data 文件:
规则使用的数据
异常得分
CRS使用可配置的异常计分模型,每条触发的规则都会增加异常分数,如果分数超过配置的异常阈值,则事务被阻塞,异常级别如下:
-
Critical:
异常得分5,表示可能应用程序攻击,主要由93x 94x文件生成。 -
Error:
异常得分4,表示可能数据泄露,主要有95x文件生成,暂不支持nginx和nginx plus。 -
Warning:
异常得分3,表示可能恶意客户端,主要由91x文件生成的。 -
Notice:
异常得分2,表示可能违反协议,主要由92x文件生成。
默认情况下,CRS阻塞所有异常值为5或更高的入站流量,意味着任何引发事务的关键规则都将被丢弃,三次或更多的通知级违规也会导致事务被阻塞。
使用Nikto工具
使用Nikto
扫描工具生成恶意请求
git clone https://github.com/sullo/nikto Cloning into 'nikto'...
cd nikto
perl program/nikto.pl -h localhost
- Nikto v2.1.6
...
+ 7531 requests: 0 error(s) and 324 item(s) reported on remote host
接下来,我们启用CRS,然后测试它如何阻塞Nikto的大多数请求,从而减少报告的项目数量
安装并启动OWASP CRS
wget https://github.com/SpiderLabs/owasp-modsecurity-crs/archive/ v3.0.0.tar.gz
tar -xzvf v3.0.0.tar.gz
mv owasp-modsecurity-crs-3.0.0 /usr/local
cd /usr/local/owasp-modsecurity-crs-3.0.0
cp crs-setup.conf.example crs-setup.conf
添加包括指令在主ModSecurity配置文件/etc/nginx/modsec/main
# Include the recommended configuration
Include /etc/nginx/modsec/modsecurity.conf
# OWASP CRS v3 rules
Include /usr/local/owasp-modsecurity-crs-3.0.0/crs-setup.conf Include /usr/local/owasp-modsecurity-crs-3.0.0/rules/*.conf
nginx -s reload
Testing the CRS
了解CRS中的规则如何基于请求的特定特征来阻止Nikto
的请求,我们的最终目标是显示CRS阻止Nikto
的所有请求,这样Nikto
检测到的所有漏洞都不会被攻击者利用
基于用户代理头禁用请求阻塞
CRS识别来自扫描仪(包括Nikto)的请求,通过检查用户代理报头,CRS被预先配置为阻止具有Nikto
默认用户代理报头的请求。
curl -H "User-Agent: Nikto" http://localhost/
403 Forbidden
403 Forbidden
nginx/1.11.10
可以从日志中得知是关联了哪个规则集REQUEST-913-SCANNER- DETECTION.conf
消除对易受攻击文件的请求
当我们对web应用程序重新运行Nikto时,我们看到只有116个Nikto请求到达应用服务器,而没有启用CRS时只有324个,这表明CRS保护我们的应用程序免受Nikto请求暴露的大部分漏洞的影响
perl program/nikto.pl -h localhost
...
+ 7531 requests: 0 error(s) and 116 item(s) reported on remote host
可以通过在program/ nikto中添加-sitefile来更好地了解实际漏洞可能存在的地方,从而禁用这些请求。
# Default plug-in macros
# Remove plug-ins designed to be run standalone
@@EXTRAS=dictionary;siebel;embedded
@@DEFAULT=@@ALL;-@@EXTRAS;tests(report:500);-sitefiles
使用XSS尝试阻塞请求
perl program/nikto.pl -h localhost
- Nikto v2.1.6
...
+ 7435 requests: 0 error(s) and 26 item(s) reported on remote host
这26项中的大多数出现是因为OWASP CRS当前没有配置为阻止请求URL中包含XSS尝试的请求
为了阻止尝试XSS的请求,在CRS的XSS应用程序攻击规则集request-941-Application-Attack-xsd.conf
中,通过在每个规则的变量列表的开头添加REQUEST_URI
,编辑规则941160和941320:
SecRule REQUEST_URI|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/ ...
##重新加载nginx
nginx -s reload
重新运行nikto,会发现items变少了,然后根据日志信息,重新优化规则集
不支持检查响应体,因此配置这样的规则没有效果
四、安装Trustwave SpiderLabs 商业安全规则集
除了OWASP CRS
之外,Trustwave SpiderLabs
商业规则集还提供了其他保护,例如针对WordPress、Joomla、SharePoint
和其他应用程序的特定规则集。
本章介绍Trustwave SpiderLabs商业规则集的安装,以安装ModSecurity的基本配置为基础,展示如何配置Trustwave SpiderLabs规则来保护创建的演示web应用程序
先决条件
- 购买Trustware SpiderLabs
- 安装部署ModSecurity和nginx反向代理系统
配置Trust SpiderLabs规则
购买规则后,可以直接登入modsecurity的dashboard,然后在门户上定制Trustwate SpiderLabs规则,与OWASP CRS相比通过这个仪表盘简化了配置。
- 通过ModSecurity的SecRemoteRules功能,直接从互联网自动下载规则
- 直接在dashboard上GUI界面启用或禁用规则,而不需要在ModSecurity配置文件中去修改
dashboard.modsecurity,org
需要账号密码登入,无法注册,需要付费购买。
配置向导
为web系统配置waf
- 登入ModSecurity Dashboard,并启动配置向导
- 创建一个profile,启动与应用程序相关的规则
- 在ModSecurity配置中添加SecRemoteRules指令,需要使用license下载规则
Include "/etc/nginx/modsec/modsecurity.conf"
SecRemoteRules license-key https://url
- 默认Trustwave SpiderLabs规则只检测恶意请求,不进行阻止,需要开启一下功能
SecDefaultAction "phase:2,log,auditlog,deny,status:403"
SecDefaultAction "phase:1,log,auditlog,deny,status:403"
-
nginx -s reload
当从远程服务器下载规则时,重新加载需要时间 - 一旦向导报告NGINX下载了规则,您就可以关闭向导并开始测试规则
从Trustwave SpiderLabs下载规则需要注意一下几点
- 每次重新加载NGINX配置或重启NGINX时,规则都是从远程服务器上新下载的,
SecRemoteRulesFailAction
指令支持两个值Abort
会强制NGINX的重载或重启失败,Warn
会让NGINX的重载或重启成功,但是没有远程规则支持 - 下载规则需要一些时间,这会延迟重新加载或重新启动操作
- 每个SecRemoteRules定义会导致一个单独的下载,进一步增加重新加载/重启时间,以避免出现这种情况,尽量减少SecRemoteRules定义的数量。
- 合并规则从不同的上下文中(http、server、location)还增加了时间重新加载/重启操作并消耗大量的CPU,定义的规则尽量最小化,尽量将所有规则放在单一的域(http、server、location)中
Trustwave SpiderLabs规则集包含16000多条用于保护各种应用程序的规则,规则越多,WAF的性能就越差,因此只启用与应用程序相关的规则非常重要
限制
不支持检查响应体
五、开启项目蜜罐
Project Honeypot
维护一个已知恶意IP地址的列表,免费提供给公共ModSecurity
与Project Honeypot
集成,可以自动屏蔽Project Honeypot
列表上的IP地址,这个过程称为IP信誉
蜜罐是如何工作的
项目蜜罐是一个社区维护的IP地址在线数据库,怀疑是垃圾邮件发送者或机器人,每个IP地址被分配一个威胁得分在0到255之间;数字越高,IP地址越有可能是恶意的。
- Honeypot是网站上的一个虚假页面,当机器人扫描网站时就会显示出来,但普通人用浏览器访问网站时是看不到的
- 当扫描器跟随蜜罐链接并尝试与页面交互时(例如,获取一个嵌入式蜜罐电子邮件地址),IP地址将被添加到数据库中
- 项目蜜罐查找是在接收到HTTP请求时实时完成的,因此启用此功能可能会降低性能,但缓存结果是为了最小化性能影响,在将
Project Honeypot
集成到生产环境之前,请务必测试它对应用程序的潜在性能影响
搭建蜜罐
要开始使用项目蜜罐,请使用项目蜜罐提供的脚本在您的站点上设置一个蜜罐:
- 注册一个免费项目蜜罐账户地址
- 设置蜜罐-项目蜜罐提供蜜罐脚本在
PHP, Python, ASP
,和一些其他语言 - 下载蜜罐脚本
测试php
server {
server_name www.example.com;
location ~ \.php$ {
modsecurity off;
root /code;
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass localhost:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_ script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
Notes:
- 将www.example.com 替换你在Honeyport注册的域名
- 需要在蜜罐脚本上禁用ModSecurity,这样才能正常工作
- 在/目录中,替换为蜜罐脚本目录
- 安装脚本后,在web浏览器中访问它并单击激活链接来激活蜜罐
将蜜罐链接添加到所有页面
为了捕捉机器人和扫描器,在每个页面上插入一个到蜜罐脚本的链接,这个链接对于使用web浏览器的普通人是不可见的,但是对于机器人和扫描器是可见的,我们使用sub_filter指令将链接添加到每个页面的底部:
location / {
proxy_set_header Host $host;
proxy_pass http://my_upstream;
sub_filter '