Centos7下基于LNMP部署modsecurity并编写简单sql注入环境进行防火墙rules的验证和编写
链接:
https://www.nginx.com/blog/compiling-and-installing-modsecurity-for-open-source2-nginx/
http://www.duyaofei.com/2018/05/06/centos7下nginx使用modsecurity进行waf防护/
http://kael-aiur.com/linux/centos下安装开发者工具.html
https://github.com/SpiderLabs/ModSecurity-nginx/issues/117
http://blog.sina.com.cn/s/blog_a97c61460102xgfq.html
等。:
环境:centos 7.7.1980;nginx1.16.1
以下基本是按照官方文档进行操作,软件包部分来自其他收集,我主要做报错的记录与解决;
安装必备软件包(centos):
$ yum group install "Development Tools"
$ yum install -y gperftools gperftools-devel gd-devel perl-devel perl-ExtUtils-Embed GeoIP GeoIP-devel GeoIP-data pcre pcre-devel openssl openssl-devel libtool libtool-ltdl-devel gcc gcc-c++ gcc-g77 autoconf automake geoip geip-devel libcurl libcurl-devel yajl yajl-devel lmdb-devel ssdeep-devel lua-devel
下载并编译ModSecurity 3.0源代码
1.克隆GitHub存储库
$ git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity
2.转到ModSecurity目录并编译源代码:
$ cd ModSecurity
$ git submodule init
$ git submodule update
$ ./build.sh
$ ./configure
$ make
$ make install
注意:在构建过程中忽略以下消息是安全的。即使它们出现,编译也将完成并创建工作对象。
fatal: No names found, cannot describe anything.
下载用于ModSecurity的NGINX连接器并将其编译为动态模块
1.克隆GitHub存储库:
$ git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git
note:这里我回到了之前下载ModSecurity 3.0的目录,以免杂乱;
2.确定哪个版本的NGINX在要加载ModSecurity模块的主机上运行:
$ nginx -v
$ nginx version: nginx/1.16.1
note:若是nginx版本不匹配,后面启动nginx会报错,,,某教程挖的坑:
[emerg] 5685#0: module “/usr/share/nginx/modules/ngx_http_modsecurity_module.so” version 1013001 instead of 1016001 in /etc/nginx/nginx.conf:6
$ wget http://nginx.org/download/nginx-1.16.1.tar.gz
$ tar zxvf nginx-1.16.1.tar.gz
$ cd nginx-1.16.1
$ ./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
$ make modules
$ cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules
Note1:第四个命令最好find先确定文件路径,大概率不是上述路径。
Note2:这里有一个小问题,经验不足,不知道是我的问题还是官方文档的。
第二个命令中参数:–with-compat 经查://
启用后–with-compat,最终用户可以更轻松地在自定义图像中为NGINX构建和使用动态模块。
NGINX动态模块编译的工作方式是用户必须下载匹配的NGINX版本的源代码,然后运行:
./configure --with-compat --add-dynamic-module=/module/src/path
make modules
这将为匹配的NGINX版本编译动态模块。但是,仅当使用编译主NGINX二进制文件时,此方法才有效–with-compat。如果不是这种情况,那么该./configure行必须指定与编译主要NGINX二进制文件完全相同的编译选项。这使动态模块的构建过程变得更加复杂,尤其是对于OpenResty,在OpenResty中,外部库(如OpenSSL和PCRE)已下载到构建系统之外。
幕后情况是在内部数据结构中添加了额外的字段或保留了额外的内存。这确实会导致内存使用量略有增加。
参见:
https : //forum.nginx.org/read.php ? 29,270210,270213# msg- 270213
https://mailman.nginx.org/pipermail/nginx-devel/2018-May/011119.html
–with-compat在上游NGINX软件包和Docker映像中启用了该选项。
它已在Ubuntu中与Disco Dingo一起启用。
///
看上去是没有问题的,但是,,,
8814#0: module “/usr/share/nginx/modules/ngx_http_modsecurity_module.so” is not binary compatible in /etc/nginx/nginx.conf:5
经查:这个错误就是由于这个参数引起的,规避方法是在第二步之前
$ nginx -V
将输出configure arguments:之后的内容留作备用;
第二步改为
$ ./configure --add-dynamic-module=../ModSecurity-nginx 刚刚的内容。
加载NGINX ModSecurity Connector动态模块
$ mkdir /etc/nginx/modsec
$ wget -P /etc/nginx/modsec/ https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended $ mv /etc/nginx/modsec/modsecurity.conf-recommended /etc/nginx/modsec/modsecurity.conf
$ sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/nginx/modsec/modsecurity.conf
DetectionOnly(仅记录)
From https://github.com/SpiderLabs/ModSecurity/blob/master/
modsecurity.conf-recommended
Edit to set SecRuleEngine On
Include "/etc/nginx/modsec/modsecurity.conf"
Basic test rule
SecRule ARGS:testparam "@contains test" "id:1234,deny,status:403"
在生产环境中,您大概会使用实际上可防止恶意流量的规则,例如免费的OWASP核心规则集。
4. 将modsecurity和modsecurity_rules_file指令添加到NGINX配置以启用ModSecurity:
server {
# …
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;
}
5.重启nginx
service nginx restart
6. 发出以下curl命令。该403状态代码确认规则工作。
$ curl localhost?testparam=test
因为这个规则有点简单,后面找了一个完善一点的。
配置WAF核心规则
WAF进行web应用防护全靠规则的配置,我们下载热心网友维护的核心规则库
git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git
cd owasp-modsecurity-crs/
cp -R rules/ /etc/nginx/conf/
cp crs-setup.conf.example /etc/nginx/crs-setup.conf
设置启用这些规则
vim /etc/nginx/modsecurity.conf
增加以下几行
#加载规则配置文件
Include crs-setup.conf
#加载所有规则
Include rules/*.conf
#禁用某个规则方法
#SecRuleRemoveById 911250
修改配置文件
vim /etc/nginx/nginx.conf
增加下面一行
load_module /usr/share/nginx/modules/ngx_http_modsecurity_module.so
修改主机定义,或者虚拟主机定义文件
load_module /usr/share/nginx/modules/ngx_http_modsecurity_module.so;
http {
server {
#针对全局启用
modsecurity on;
modsecurity_rules_file /etc/nginx/modsecurity.conf;
location / {
#如果需要针对单个应用启用,编辑这里
}
}
}
8. 重启nginx
service nginx restart
9. 日志位置
tailf /var/log/modsec_audit.log
补充报错:
Fail to locate *** file from: **** looking at ‘***’,’***(path)’,in etc/nginx/nginx.conf
这是OWASP核心规则集(CRS)文档,也是接下来我所使用的;
规则配置文件和规则文件按照文档所给路径cp的不合适,find出来cp到looking at后的搜索路径即可。
https://github.com/SpiderLabs/owasp-modsecurity-crs.git
终于:
Ps:tailf
在屏幕上显示指定文件的末尾若干行内容,通常用于日志文件的跟踪输出
-n, --lines NUMBER # 输出最后数行
-NUMBER # 与NUMBER相同 `-n NUMBER’
-V, --version # 输出版本信息并退出
-h, --help # 显示帮助并退出
tailf -n 5 log2014.log # 显示文件最后5行内容
tailf /var/log/modsec_audit.log
下面部署mysql用于sql注入测试:
https://help.aliyun.com/document_detail/97251.html
删除Mysql
yum remove mysql mysql-server mysql-libs mysql-server;
find / -name mysql 将找到的相关东西delete掉;
rpm -qa|grep mysql(查询出来的东东yum remove掉)
安装MySQL
d. 按Esc键后,输入:wq并回车以保存并关闭配置文件。
2. 运行以下命令启动PHP-FPM。
systemctl start php-fpm
3. 运行以下命令设置PHP-FPM开机自启动。
systemctl enable php-fpm
步骤八:测试访问LNMP平台
mysql基本命令学习和php基本语句学习:
资料来源菜鸟教程。
WHERE 子句用于提取满足指定标准的的记录。
SELECT column_name(s)
FROM table_name
WHERE column_name operator value
实例
下面的实例将从 “Persons” 表中选取所有 FirstName=‘Peter’ 的行:
Note:php语句从“”结束;
定义变量前面使用“$”;
mysqli_connect() 函数打开一个到 MySQL 服务器的新的连接。mysqli_connect(host,username,password,dbname,port,socket);
我们使用前四个即可
参数 描述
host 可选。规定主机名或 IP 地址。
username 可选。规定 MySQL 用户名。
password 可选。规定 MySQL 密码。
dbname 可选。规定默认使用的数据库。
port 可选。规定尝试连接到 MySQL 服务器的端口号。
socket 可选。规定 socket 或要使用的已命名 pipe。
;
mysqli_connect_errno() 函数返回上一次连接错误的错误代码;
PHP echo 和 print 语句
echo 和 print 区别:
• echo - 可以输出一个或多个字符串
• print - 只允许输出一个字符串,返回值总为 1
提示:echo 输出的速度比 print 快, echo 没有返回值,print有返回值1。
;
运算符之一“.”
a . b 并置 连接两个字符串 “Hi” . “Ha” HiHa
;
mysqli_query() 函数执行某个针对数据库的查询。
mysqli_query(connection,query,resultmode);
我们使用前两个即可
参数 描述
connection 必需。规定要使用的 MySQL 连接。
query 必需,规定查询字符串。
resultmode 可选。一个常量。可以是下列值中的任意一个:
• MYSQLI_USE_RESULT(如果需要检索大量数据,请使用这个)
• MYSQLI_STORE_RESULT(默认)
;
mysqli_fetch_array() 函数从结果集中取得一行作为关联数组,或数字数组,或二者兼有。
注释:该函数返回的字段名是区分大小写的。
mysqli_fetch_array(result,resulttype);
参数 描述
result 必需。规定由 mysqli_query()、mysqli_store_result() 或 mysqli_use_result() 返回的结果集标识符。
resulttype 可选。规定应该产生哪种类型的数组。可以是以下值中的一个:
• MYSQLI_ASSOC
• MYSQLI_NUM
• MYSQLI_BOTH
;
PHP 表单处理
有一点很重要的事情值得注意,当处理 HTML 表单时,PHP 能把来自 HTML 页面中的表单元素自动变成可供 PHP 脚本使用。
实例
下面的实例包含了一个 HTML 表单,带有两个输入框和一个提交按钮。
form.html 文件代码:
我们综合以上两个实例和相关函数及注释实现
input.php:
find.php:
"; } mysqli_close($conn); ?>,最后实现sql注入环境:
查看防火墙记录:
第一看这个多少看不懂,只能看到敏感词汇。
现在找出上述绿色文件:
找到相关资料:
https://www.cnblogs.com/wuweidong/p/8559177.html
https://malware.expert/modsecurity/processing-phases-modsecurity/
本文旨在显示ModSecurity如何保护Apache Web Server上运行的Web应用程序。下图说明了在标准的Apache Web服务器请求周期内实现的Modsecurity的5个处理阶段。
在这5个阶段中,ModSecurity查看HTTP(S)数据并进行分析。这五个阶段旨在提供全面的安全防护。
ModSecurity分为五个阶段
• 请求标头(REQUEST_HEADERS)
• 请求正文(REQUEST_BODY)
• 响应标头(RESPONSE_HEADERS)
• 响应正文(RESPONSE_BODY)
• 记录(LOGGING)
让我们详细了解这些阶段。
phrase1:请求标头
这是Apache开始处理用户请求之前的初始阶段。此阶段中的规则读取并分析HTTP请求标头。此阶段规则的主要重点是在Apache开始处理请求参数之前,在请求标头中查看恶意模式。
此阶段中的规则有助于确定诸如是否缓冲请求正文或如何处理请求正文(例如,将其解析为XML)之类的事情。
Phrase2:请求正文
处理请求标头后,下一行是请求正文。在这一阶段,Apache已收到完整的请求。此阶段中的规则主要与应用程序相关。
ModSecurity在此阶段支持以下三种编码技术,这些天几乎在每台Web服务器中都使用。
• application / x-www-form-urlencoded –用于传输表格数据
• 多部分/表单数据–用于文件传输
• text / xml –用于XML数据
phrase 3:响应标题
此阶段已处理请求,服务器开始发送回请求的数据。就像请求标头规则一样,此阶段规则在将响应正文发送回用户之前,先查看响应标头中要返回的内容。此处的规则有助于做出决策,例如是否缓冲响应正文。
phrase 4:响应主体
一旦响应请求发出绿色信号以缓冲响应正文,就可以部署规则来分析针对每个请求的内容类型。在这里,您可以分析诸如身份验证失败或错误消息之类的响应。
phrase 5:记录
这是ModSecurity用来保护Apache的五个阶段周期的最后一个。此阶段中的规则仅在实际日志记录发生之前放置。在此阶段中,将分析由apache Web服务器生成的日志消息。关于此阶段的一件重要事情是,您不能在此处阻止任何连接,因为它是请求/响应之后的阶段。在这里,您还可以检查在第3阶段和第4阶段不可用的标题。
进行解读:
一、变量variable
绿色:请求变量 蓝色:server变量 紫色:响应变量 红色:请求体解析变量 青色:时间变量 橙色:实体变量
ModSecurity
Request variables 请求变量
请求变量是从当前事务的请求部分提取的
检查。描述请求行的变量(请求方法、URI和协议)
信息)和请求头信息最早在阶段1和完成时就可用
第2阶段将提供资料。
REQUEST_COOKIES cookie参数
REQUEST_COOKIES_NAMES cookie参数的名字,类型read-only collection
REQUEST_HEADERS 请求头,类型read-only collection
ARGS_NAMES 请求参数的名字, 类型read-only collection
ARGS 请求参数,类型read-only collection
XML xml dom相关的,类型read-only collection
四、动作action
绿色:disruptive action (每个rule只能有1个disruptive action,如果有多个disruptive action,那么只有最后一个有效,在rule chain中,disruptive action只能出现在第一个rule中)
蓝色:flow action
紫色:metadata action
红色 :variable action
黄色:logging action
灰色:special action
黑色:其他
block 相当于占位符,会被上下文的SecDefaultAction 指令中的动作取代
capture 将捕获结果存入TX变量,可以存储10个变量,tx变量集合的下标为0-9
setvar 设置变量
logdata 日志提供的数据作为错误消息的一部分
六、常用操作符
t 事务函数调用 e.g. t:lowercase
语法:SecRule VARIABLES OPERATOR [TRANSFORMATION_FUNCTIONS, ACTIONS]
Variables 以下几种:
Regular variables
Contain only one piece of information, or one string. For example, REMOTE_ADDR, always
contains the IP address of the client.
Collections
Groups of regular variables. Some collections (e.g., ARGS) allow enumeration, making
it possible to use its every member in a rule. Some other collections (e.g., ENV)
are not as flexible, but there is always going to be some way to extract individual regular
variables out of them.
Read-only collections
Many of the collections point to some data that cannot be modified, in which case
the collection itself will be available only for reading.
Read/write collections
When a collection is not based on immutable data ModSecurity will allow you to
modify it. A good example of a read/write collection is TX, which a collection that
starts empty and exists only as long as the currently processed transaction exists.
Special collections
Sometimes a collection is just a handy mechanism to retrieve information from
something that is not organised as a collection but it can seem that way. This is the
case with the XML collection, which takes an XPath expression as a (mandatory) parameter
and allows you to extract values out of an XML file.
Persistent collections
Some collections can be stored and retrieved later. This feature allows you to adopt a
wider view of your systems, for example tracking access per IP address or per session,
or per user account.
正则变量
只包含一条信息或一个字符串。例如,REMOTE_ADDR,总是
包含客户端的IP地址。
集合
常规变量组。有些集合(例如ARGS)允许枚举、生成
可以在一个规则中使用它的每个成员。其他一些集合(例如ENV)
是不是都没有那么灵活,但总会有办法提取出个别的规律呢
变量。
只读集合
在这种情况下,许多集合指向一些无法修改的数据
合集本身仅供阅读。
读/写集合
当一个集合不是基于不可变的数据时,ModSecurity将允许你这样做
修改它。读/写集合的一个好例子是TX,它是一个
开始时为空,并且仅在当前处理的事务存在时才存在。
特殊的集合
有时,集合只是一种方便的检索信息的机制
一些没有被组织成一个集合的东西,但是看起来是这样的。这是
以XML集合为例,它接受XPath表达式作为(强制的)参数
并允许您从XML文件中提取值。
持续的集合
有些集合可以稍后存储和检索。该特性允许您采用a
更广泛的系统视图,例如跟踪访问每个IP地址或每个会话,
或每个用户帐户。
另一个教程:
https://blog.csdn.net/qq_36374896/article/details/83316537
一、ModSecurity的规则
基本格式
SecRule VARIABLES OPERATOR ACTIONS
1
SecRule:ModSecurity主要的指令,用于创建安全规则。
VARIABLES :代表HTTP包中的标识项,规定了安全规则针对的对象。常见的变量包括:ARGS(所有请求参数)、FILES(所有文件名称)等。
OPERATOR:代表操作符,一般用来定义安全规则的匹配条件。常见的操作符包括:@rx(正则表达式)、@streq(字符串相同)、@ipmatch(IP相同)等。
ACTIONS:代表响应动作,一般用来定义数据包被规则命中后的响应动作。常见的动作包括:deny(数据包被拒绝)、pass(允许数据包通过)、id(定义规则的编号)、severity(定义事件严重程度)等。
二、ModeSecurity规则例解
规则1:防XSS攻击
SecRule ARGS|REQUEST_HEADERS "@rx
REQUEST_HEADERS:请求数据头部。
OPERATOR @rx
ACTIONS id:001规定该条规则编号为001;
msg: 'XSS Attack’代表记录信息为:XSS Attack;
severity:ERROR表示严重程度为ERROR;
deny表示拒绝所有请求包;
status:404表示服务器响应状态编号为404。
说明:严重程度分为8级: EMERGENCY (0)、ALERT (1)、CRITICAL (2)、ERROR (3)、WARNING (4)、
NOTICE (5)、INFO (6) 、DEBUG (7)
1
2
规则2:设置白名单
SecRule REMOTE_ADDR “@ipmatch 192.168.1.9” “id:002,phase:1,t:none,
nolog,pass,ctl:ruleEngine=off”
1
2
VARIABLES REMOTE_ADDR:远程主机IP
OPERATOR @ipmatch 192.168.1.9:如果请求主机IP地址为192.168.1.9,则规则执行。
ACTIONS id:002规定该条规则编号为002;
phase:1表示规则执行的范围为请求头部;
t:none表示VARIABLES的值不需要转换(t代表transform);
nolog代表不记录日志;pass代表继续下一条规则;
ctl:ruleEngine=off代表关闭拦截模式,所有规则失效。
说明:phase编号规定如下(就是那个phase):Request Headers (1), Request Body (2), Response Headers (3),
Response Body (4) and Logging (5).
1
2
规则3:
SecRule ARGS:username “@streq admin” chain,deny,id:003
SecRule REMOTE_ADDR “!streq 192.168.1.9”
1
2
VARIABLES ARGS:username所有表示请求参数中的用户名信息。
OPERATOR @streq admin表示用户名等于字符串"admin",则执行ACTIONS。
ACTIONS id:003规定该条规则编号为003;
chain表示用户名等于admin的情况下,必须完成第二行规则的匹配(远程主机IP不是192.168.1.9),才能执行下一个动作;
deny表示所有请求包被拒绝。
自定义规则
SecRule FILES “!\.(?i:jpe?g|gif|png|bmp)$” "deny,tag:‘WEB_ATTACK/FILEUPLOAD’,msg:‘upload
no-picture file’,id:0000001,phase:2“
1
2
SecRule FILES “@contains %00” “deny,tag:‘WEB_ATTACK/FILEUPLOAD’,msg:‘filename
has null character’,id:0000002,phase:2”
1
2
附OWASP规则详解:
http://f2ex.cn/modsecurity-crs-3-list/
经过学习,编写一条自己的rules:
Vim MYRULES.conf
SecRule REMOTE_ADDR “@ipMatch 1.2.3.4”
“id:942433,
phase:1,
log,
allow”
IP是我当前的公网IP,通过之前的日志获取,通过“@ipmatch”和“allow”实现我自己当前IP的白名单:仅记录不阻拦则再次输入注入语句: