安装ModSecurity
一、安装VCredist
在安装ModSecurity之前需要安装VCredist,点击https://visualstudio.microsoft.com/zh-hans/downloads/进入下载页进行下载。
二、安装 ModSecurity
根据操作系统下载下载 ModSecurity http://modsecurity.cn/,下载后直接安装。
安装成功后,applicationHost.config文件(位于C:\Windows\System32\inetsrv\Config目录下),会自动添加以下内容,表示IIS下所有网站都会默认使用ModSecurity进行防护:
<section name="ModSecurity" overrideModeDefault="Allow" allowDefinition="Everywhere" /></sectionGroup>
三、规则配置
虽然IIS版的ModSecurity安装后自动包含了规则文件,但由于自带的规则文件版本较老,因此需要手动将规则文件进行更新。
首先,访问https://github.com/coreruleset/coreruleset下载规则文件。
下载后上传到服务器,将解压后的"crs-setup.conf.example"重命名为"crs-setup.conf"后复制到ModSecurity安装目录下,即C:\Program Files\ModSecurity IIS。
修改modsecurity_iis.conf,将文件中的"Include crs-setup.conf.example"修改为"Include crs-setup.conf"。
修改modsecurity.conf,将"SecRuleEngine DetectionOnly"改为"SecRuleEngine On"。
将解压后的rules文件夹复制到C:\Program Files\ModSecurity IIS\owasp_crs\下,同时修改REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example与RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example两个文件的文件名,将".example"删除,可将自己写的规则放置于此两个文件中。
将c:\inetpub\temp\文件夹与c:\inetpub\logs\赋予IIS_IUSRS与IUSR完全控制权限。
重启IIS。
四、测试防御效果
访问http://服务器IP或域名/?param=%22%3E%3Cscript%3Ealert(1);%3C/script%3E,查看防御效果。![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9WJ998Rn-1609730668662)(https://b3logfile.com/file/2020/12/202005311590931635832839-77b4f224.png)]
同时可在"控制面板-管理工具-事件查看器-Windows日志-应用程序"中查看拦截日志。
ModSecurity日志保存至MySQL数据库(通过Logstash)
一、安装 jdk
二、安装 logstash
下载logstash https://www.elastic.co/cn/downloads/logstash
解压后放到磁盘根目录下,比如C:
首先,测试Logstash是否可以正常工作,在控制台输入以下命令等待Logstash启动:
C:\logstash-7.10.1\bin\logstash.bat -e 'input { stdin { } } output { stdout {} }'
启动成功后,可以看到 Successfully started Logstash API endpoint {:port=>9600}
输入 111 后直接回车,看到如下信息,说明 logstash 正常工作
三、安装logstash-output-jdbc
由于要把日志输入到数据库中,因此需要安装logstash-output-jdbc,该插件为第三方所开发。
C:\logstash-7.10.1\bin\logstash-plugin.bat install logstash-output-jdbc
在 C:\logstash-7.10.1\bin\logstash-plugin.bat 头部添加 JAVA_HOME ,
SET JAVA_HOME=C:\Program Files\Java\jdk1.8.0_181
四、创建日志同步配置文件
在Logstash目录下创建文件mslogtomysql.conf,并将以下内容复制进文件中,保存时要使用UTF8格式,或将中文注释删除,否则Logstash启动时会报错:
input {
file {
path => ["C:/inetpub/logs/modsecurity/*/*/*/*"]
start_position => "beginning"
codec => "json"
close_older => 120
ignore_older => 3600
stat_interval => 10
}
}
filter {
json{
source => "message"
remove_field => ["message"]
}
mutate{
split => ["[transaction][time]"," "]
add_field => { "date" => "yyyy-MM-dd HH:mm:ss" }
add_field => { "month" => "%{[transaction][time][1]}" }
add_field => { "day" => "%{[transaction][time][2]}" }
add_field => { "time" => "%{[transaction][time][3]}" }
add_field => { "year" => "%{[transaction][time][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 {
stdout {
codec => json {
charset => "UTF-8"
}
}
jdbc {
driver_jar_path => "C:/logstash-7.10.1/mysql-connector-java-5.1.49.jar"
driver_class => "com.mysql.jdbc.Driver"
connection_string => "jdbc:mysql://ip:port/modsecurity?user=root&password=password&useUnicode=true&characterEncoding=utf8"
statement => ["insert into modlog (client_ip,time_stamp,client_port,host_ip,host_port,uri,request,response,producer,messages) values (?,?,?,?,?,?,?,?,?,?)","[transaction][remote_address]","[transaction][time]","[transaction][remote_port]","[transaction][local_address]","[transaction][local_port]","[request][request_line]","[request]","[request]","[audit_data][producer]","[audit_data][messages]"]
}
}
ModSecurity JSON 日志
{
"transaction": {
"time": "14/Dec/2020:08:59:00 +0800",
"transaction_id": "17654110541439827990",
"remote_address": "",
"remote_port": 80,
"local_address": "127.0.0.1",
"local_port": 80
},
"request": {
"request_line": "GET /cwbase/weblogin/images/APhoneDC.png HTTP/1.1",
"headers": {
"Connection": "Keep-Alive",
"Accept": "image/png, image/svg+xml, image/jxr, image/*;q=0.8, */*;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN",
"Cookie": "ASPSESSIONIDQSBDBBAS=FJCJGMFDCJLIPKJANBAKOOAC",
"Host": "localhost",
"Referer": "http://localhost/cwbase/weblogin/index.aspx",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko",
"DNT": "1"
}
},
"response": {
"protocol": "HTTP/1.1",
"status": 0,
"headers": {
"Content-Type": "image/png",
"Last-Modified": "Wed, 07 Jan 2015 08:39:32 GMT",
"Accept-Ranges": "bytes",
"Etag": "\"0ba2975552ad01:0\"",
"Server": "Microsoft-IIS/10.0"
},
"body": ""
},
"audit_data": {
"messages": ["IPmatch: bad IPv4 specification \"\".", "Rule processing failed (id=905110, msg=)."],
"handler": "IIS",
"stopwatch": {
"p1": 0,
"p2": 0,
"p3": 0,
"p4": 0,
"p5": 0,
"sr": 0,
"sw": 0,
"l": 0,
"gc": 0
},
"response_body_dechunked": true,
"producer": ["ModSecurity for IIS (STABLE)/2.9.3 (http://www.modsecurity.org/)", "OWASP_CRS/3.3.0"],
"server": "ModSecurity Standalone",
"engine_mode": "DETECTION_ONLY"
}
}
Tips:
- mslogtomysql.conf 中的 statement中获取数据需要的 ModSecurity JSON 格式的日志统一。注意审查。
- input file path 注意和 modsecurity 中的 SecAuditLogStorageDir 匹配
五、创建数据库
创建名为modsecurity的数据库,并执行以下SQL创建数据表
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `data`
-- ----------------------------
DROP TABLE IF EXISTS `data`;
CREATE TABLE `data` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`client_ip` varchar(255) DEFAULT NULL,
`time_stamp` varchar(255) DEFAULT NULL,
`date` datetime DEFAULT NULL,
`server_id` varchar(255) DEFAULT NULL,
`client_port` int(11) DEFAULT NULL,
`host_ip` varchar(255) DEFAULT NULL,
`host_port` int(11) DEFAULT NULL,
`uri` varchar(255) DEFAULT NULL,
`unique_id` varchar(255) DEFAULT NULL,
`request` mediumtext,
`response` mediumtext,
`producer` mediumtext,
`messages` mediumtext,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
六、配置ModSecurity记录审计日志
modsecurity.conf文件需进行以下配置:
SecAuditEngine On
#注意,ModSecurity 3.x版本中目前不支持使用IJ记录请求体内容,如果要记录请求体,请用C代替IJ
#但此时会有一个情况,如果通过网站进行文件上传,文件的内容也会被记录到日志中,因此请勿通过网站上传大容量文件
SecAuditLogParts ABIJDEFHZ
#设置并行方式记录日志
SecAuditLogType Concurrent
#配置存放日志的目录,该目录必须存在且赋予777权限,否则可能无法正常写入日志
SecAuditLogStorageDir C:/inetpub/logs/modsecurity/
#配置记录的日志为JSON格式
SecAuditLogFormat JSON
配置完成后需要重新加载WEB服务
七、同步日志
运行以下命令,使Logstash以指定的配置文件启动:
C:\logstash-7.10.1\bin\logstash.bat -f C:\logstash-7.10.1\config\mslogtashtomysql.conf
八、最后工作(可选)
编写脚本,将Logstash以后台服务方式运行,并设置开机自启;
编写定时脚本,在凌晨1点时,将前一天的ModSecurity审计日志删除,避免日志越来越多,占用磁盘空间。