ModSecurity 搭建web安全防火墙和流量检测

雷石安全实验室

共 8092字,需浏览 17分钟

 ·

2022-01-23 03:22

前言

因工作需要,需要调研WAF和IDS产品,我经过调研选择了Modsecurity作为Web端的防火墙防护软件和Suricata作为tcp和udp层的防护,并且通过logstash将结果输出到elasticsearch中进行分析。


ModSecurity

ModSecurity是一个开源的跨平台Web应用程序防火墙(WAF)引擎,用于Apache,IIS和Nginx,由Trustwave的SpiderLabs开发。作为WAF产品,ModSecurity专门关注HTTP流量,当发出HTTP请求时,ModSecurity检查请求的所有部分,如果请求是恶意的,它会被阻止和记录。


优势

完美兼容nginx,是nginx官方推荐的WAF,支持OWASP规则 3.0版本比老版本更新更快,更加稳定,并且得到了nginx、Inc和Trustwave等团队的积极支持,而且是免费的。


安装

本文假设你已经安装了nginx,如果没有nginx,那么请参考RHEL/CentOS 安装最新版Nginx

安装依赖

yum install epel-release -y
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 apt-utils autoconf automake build-essential git libcurl4-openssl-dev libgeoip-dev liblmdb-dev ibpcre++-dev libtool libxml2-dev libyajl-dev pkgconf wget zlib1g-dev -y


下载并且编译

cd /opt/    # 切换到/opt
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


ModSecurity-nginx连接器

cd /opt/
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git
nginx -v            # 查看当前nginx版本
nginx version: nginx/1.17.5
wget http://nginx.org/download/nginx-1.17.5.tar.gz
tar -xvf nginx-1.17.5.tar.gz
ls
ModSecurity  ModSecurity-nginx  nginx-1.17.5  nginx-1.17.5.tar.gz
cd nginx-1.17.5/
./configure --with-compat --add-dynamic-module=../ModSecurity-nginx      # 如果出现不兼容的问题,请去掉--with-compat参数
make modules                                  # 会生成如下*.so
 ls ./objs/ngx_http_modsecurity_module.so 
./objs/ngx_http_modsecurity_module.so       # 查看
cp ./objs/ngx_http_modsecurity_module.so /etc/nginx/modules/     # 移动位置
vim /etc/nginx/nginx.conf        
load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;     # 添加到配置文件首行


确定nginx模块加载成功:

nginx -t                                     
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful # 测试通过


启用WAF

  • Include:包括modsecurity.conf文件中建议的配置。

  • SecRule:创建一个规则,当查询字符串中的testparam参数包含字符串test时,通过阻止请求并返回状态代码403来保护应用程序。


下载OWASP规则

下载地址:https://github.com/SpiderLabs/owasp-modsecurity-crs

将规则目录 放置 /usr/local/nginx/conf/ 下,

然后将 owasp-modsecurity-crs-master 目录下的

modsecurity_crs_10_setup.conf.example 改名为 modsecurity_crs_10_setup.conf 。

[root@localhost ~]# mkdir /usr/local/nginx/conf/
[root@localhost ~]# cd /usr/local/nginx/conf/
[root@localhost modsec]# sudo wget https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended
[root@localhost modsec]# sudo mv modsecurity.conf-recommended modsecurity.conf


[root@localhost modsec]# vim  modsecurity.conf 
# -- Rule engine initialization ----------------------------------------------
...
SecRuleEngine On    <== 设置为On

#编辑modsecurity.conf 文件,将`SecRuleEngine`设置为 `on` ,并将你需要的规则导入进来:
Include modsecurity-crs/modsecurity_crs_10_setup.conf
Include modsecurity-crs/base_rules/modsecurity_crs_35_bad_robots.conf
Include modsecurity-crs/base_rules/modsecurity_crs_40_generic_attacks.conf
Include modsecurity-crs/base_rules/modsecurity_crs_41_sql_injection_attacks.conf
Include modsecurity-crs/base_rules/modsecurity_crs_41_xss_attacks.conf
Include modsecurity-crs/base_rules/modsecurity_crs_42_tight_security.conf
Include modsecurity-crs/base_rules/modsecurity_crs_45_trojans.conf

配置nginx

location \ {
  ModSecurityEnabled on;
  ModSecurityConfig modsecurity.conf; 
  ....其他配置



测试规则

SecRule ARGS:testparam "@contains leishi" "id:1234,deny,log,status:403"

curl -D - http://localhost/p?p=leishi    #则返回"403 Forbidden",说明前面配置的那条modsecuriy规则生效了,并阻拦了testparam参数中带leishi的请求


通过logstash输出到es中

logstash配置文件

input {
     file {
     #ModSecurity审计日志的存放位置,请根据实际情况进行修改
  path => ["/var/log/modsecurity/*/*/*"]
  start_position => "beginning"
 }
}
filter{
 json{
  source => "message"
  remove_field => ["message"]
 }
    #以下到filter节点结束的内容,是为了将ModSecurity记录的日期转换为数据库可存放的datetime格式
 mutate{
  split => ["[transaction][time_stamp]"," "]    
  add_field => { "date" => "yyyy-MM-dd HH:mm:ss" }
  add_field => { "month" => "%{[transaction][time_stamp][1]}" }
  add_field => { "day" => "%{[transaction][time_stamp][2]}" }
  add_field => { "time" => "%{[transaction][time_stamp][3]}" }
  add_field => { "year" => "%{[transaction][time_stamp][4]}" } 
 }
 
 if [month] == "Jan" {
  mutate {
   gsub =>["month","Jan",'01']
  }
 } else if [month] == "Feb" {
  mutate {
   gsub =>["month","Feb",'02']
  }
 } else if [month] == "Mar"{
  mutate {
   gsub =>["month","Mar",'03']
  }
 } else if [month] == "Apr"{
  mutate {
   gsub =>["month","Apr",'04']
  }
 } else if [month] == "May"{
  mutate {
   gsub =>["month","May",'05']
  }
 } else if [month] == "Jun"{
  mutate {
   gsub =>["month","Jun",'06']
  }
 } else if [month] == "Jul"{
  mutate {
   gsub =>["month","Jul",'07']
  }
 } else if [month] == "Aug"{
  mutate {
   gsub =>["month","Aug",'08']
  }
 } else if [month] == "Sep"{
  mutate {
   gsub =>["month","Sep",'09']
  }
 } else if [month] == "Oct"{
  mutate {
   gsub =>["month","Oct",'10']
  }
 } else if [month] == "Nov"{
  mutate {
   gsub =>["month","Nov",'11']
  }
 } else if [month] == "Dec"{
  mutate {
   gsub =>["month","Dec",'12']
  }
 }
 
 mutate {
  gsub =>["date","yyyy",'%{[year]}']
  gsub =>["date","MM",'%{[month]}']
  gsub =>["date","dd",'%{[day]}']
  gsub =>["date","HH:mm:ss",'%{[time]}']
 }
}


output {
    #该节点会将最终日志数据以JSON格式打印到控制台中,便于观测进行调试,测试无问题后可将此节点删除
 stdout {
  codec => json {
   charset => "UTF-8"
  }
 }
 #这是导入到mysql中的
 jdbc {
  driver_jar_path => "/usr/local/logstash-5.6.16/mysql-connector-java-5.1.48.jar"
  driver_class => "com.mysql.jdbc.Driver"
  connection_string => "jdbc:mysql://服务器IP地址:数据库端口/modsecurity?user=数据库用户名&password=数据库密码"
  statement => [ "insert into data (client_ip,time_stamp,date,server_id,client_port,host_ip,host_port,uri,unique_id,request,response,producer,messages) values (?,?,?,?,?,?,?,?,?,?,?,?,?)","[transaction][client_ip]","[transaction][time_stamp]","[date]","[transaction][server_id]","[transaction][client_port]","[transaction][host_ip]","[transaction][host_port]","[transaction][request][uri]","[transaction][unique_id","[transaction][request]","[transaction][response]","[transaction][producer]","[transaction][messages]" ]
 }
 # 这是导入到es,这是可以选择
 elasticsearch {
        hosts => ["192.168.33.129:9200"]
        index => "logwaf"
    }  

}

最后在es中的数据就是为

{
"_index""logwaf",
"_type""logs",
"_id""AX4Pdd0Mq558YisonVXR",
"_version": 1,
"_score": 1,
"_source": {
"date""2021-12-31 07:48:07",
"path""/var/log/modsecurity/audit/20211231/20211231-0748/20211231-074807-164093688737.386422",
"@timestamp""2021-12-31T07:48:08.804Z",
"month""12",
"year""2021",
"@version""1",
"host""c8bd4dde6893",
"time""07:48:07",
"day""31",
"transaction": {
"client_port": 55174,
"request": {
"http_version": 1.1,
"headers": {
"Cookie""ajs_user_id=%22d08c2741-686f-4bd1-8527-40e1e1760308%22; ajs_anonymous_id=%22764ebc96-e142-4392-ac62-a22cd43aaf1c%22; Pycharm-1a34857a=7256c262-1a06-483b-9e21-e5144bbae1a2; Hm_lvt_f4b3788b2247dd149fb7fdffe8aece79=1635765808; _ga=GA1.1.2010376713.1635765808; __51uvsct__JUFvSBqCDGdznrm5=1; __51vcke__JUFvSBqCDGdznrm5=6f1eaa0d-dafc-5edd-9afd-f6e62ef6ed88; __51vuft__JUFvSBqCDGdznrm5=1636880896220; langCookie=zh; wp-settings-time-1=1639190281; JSESSIONID=FFA49AA3640B99495C68AF8E96FE5E9C; thinkphp_show_page_trace=0|0",
"Accept""text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"User-Agent""Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36",
"Connection""keep-alive",
"Sec-Fetch-Site""none",
"Sec-Fetch-Dest""document",
"Host""localhost:8013",
"Accept-Encoding""gzip, deflate, br",
"Sec-Fetch-Mode""navigate",
"If-None-Match"""61cace6a-264"",
"sec-ch-ua""" Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"",
"sec-ch-ua-mobile""?0",
"Upgrade-Insecure-Requests""1",
"sec-ch-ua-platform"""macOS"",
"If-Modified-Since""Tue, 28 Dec 2021 08:44:26 GMT",
"Sec-Fetch-User""?1",
"Accept-Language""zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7,pl;q=0.6"
},
"method""GET",
"uri""/?id=and%201=1"
},
"host_ip""172.17.0.1",
"unique_id""164093688737.386422",
"time_stamp": [
"Fri"
,
"Dec"
,
"31"
,
"07:48:07"
,
"2021"
],
"host_port": 80,
"response": {
"http_code": 200,
"headers": {
"Server""nginx",
"ETag"""5bca3358-264"",
"Connection""keep-alive",
"Last-Modified""Fri, 19 Oct 2018 19:41:12 GMT",
"Content-Length""612",
"Date""Fri, 31 Dec 2021 07:48:06 GMT",
"Content-Type""text/html"
}
},
"producer": {
"components": [
"OWASP_CRS/3.0.2""
],
"
secrules_engine": "Enabled",
"
connector": "ModSecurity-nginx v1.0.0",
"
modsecurity": "ModSecurity v3.0.2 (Linux)"
},
"
messages": [ ],
"
client_ip": "172.17.0.1",
"
server_id": "6b4dd6eb31598154db9df92bdbaca527e7b8613d"
}
}
}

总结

Modsecurity还是非常优秀的,利用这样一款开源免费的产品做web防火墙文档和资料都不会少。而且其作者一直也在更新,值得推荐和研究,web的防火墙我们已经构建,那么tcp和udp的suricata我们下期再讲!


往期回顾

01

Struts2漏洞集合

02

常见的加密方式实例

03

走进shellcode


浏览 36
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报