1. 编译
cd nginx-$NGINX_VER
./configure --add-dynamic-module=../naxsi-$NAXSI_VER/naxsi_src/
make modules
2. 启动
2.1 加载规则和库
load_module /etc/nginx/modules/ngx_http_naxsi_module.so; # load naxsi
http {
include /etc/nginx/naxsi_core.rules; # load naxsi core rules
}
2.2 在不同location设置 naxsi flag
server {
location / { # naxsi is enabled, and in learning mode
SecRulesEnabled; #enable naxsi
LearningMode; #enable learning mode
LibInjectionSql; #enable libinjection support for SQLI
LibInjectionXss; #enable libinjection support for XSS
DeniedUrl "/RequestDenied"; #the location where naxsi will redirect the request when it is blocked
CheckRule "$SQL >= 8" BLOCK; #the action to take when the $SQL score is superior or equal to 8
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 5" BLOCK;
CheckRule "$UPLOAD >= 5" BLOCK;
CheckRule "$XSS >= 8" BLOCK;
proxy_pass http://127.0.0.1;
}
location /admin { # naxsi is disabled
SecRulesDisabled; #optional, naxsi is disabled by default
allow 1.2.3.4;
deny all;
proxy_pass http://127.0.0.1;
}
location /vuln_page.php { # naxsi is enabled, and is *not* in learning mode
SecRulesEnabled;
proxy_pass http://127.0.0.1;
}
location /RequestDenied {
internal;
return 403;
}
}
2.3 白名单
白名单的意义:解决误杀。
示例:
若已知 /search 界面 请求参数值可以为 table,但table为SQL关键字,被规则 1000检查,
则设置 白名单,让 uri为 /search 且 请求变量为 q 的请求 不使用 1000规则
server {
location / {
SecRulesEnabled; #enable naxsi
LearningMode; #enable learning mode
LibInjectionSql; #enable libinjection support for SQLI
LibInjectionXss; #enable libinjection support for XSS
DeniedUrl "/RequestDenied"; #the location where naxsi will redirect the request when it is blocked
CheckRule "$SQL >= 8" BLOCK; #the action to take when the $SQL score is superior or equal to 8
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 5" BLOCK;
CheckRule "$UPLOAD >= 5" BLOCK;
CheckRule "$XSS >= 8" BLOCK;
BasicRule wl:1000 "mz:$URL:/search|$ARGS_VAR:q";
proxy_pass http://127.0.0.1;
}
}
2.3.1 白名单详解
2.3.1.1 请求头
对所有 请求,屏蔽 规则1000,匹配域为空
BasicRule wl:1000;
设置匹配域,对 成功匹配的 请求 使用白名单
BasicRule wl:1000 "mz:$ARGS_VAR:foo";
# uri为 /bar 且 GET请求参数名为 foo
BasicRule wl:1000 "mz:$ARGS_VAR:foo|$URL:/bar";
# uri为 /bar 的 带参数GET请求
BasicRule wl:1000 "mz:$URL:/bar|ARGS";
# GET请求 存在请求参数,并 参数只有名称,没有值
BasicRule wl:1000 "mz:ARGS|NAME";
# GET请求 存在请求参数,并 参数只有名称,没有值,且 uri为 /bar
BasicRule wl:1000 "mz:$URL:/bar|ARGS|NAME";
使用正则匹配域的白名单
# GET请求参数 包含meh
BasicRule wl:1000 "mz:$ARGS_VAR_X:meh";
# GET请求参数 以meh开头
BasicRule wl:1000 "mz:$ARGS_VAR_X:^meh";
BasicRule wl:1000 "mz:$ARGS_VAR_X:^meh_[0-9]+$"
# uri 以 /foo 开头 且 为 GET请求带参数
BasicRule wl:1000 "mz:$URL_X:^/foo|ARGS";
# uri 以 /foo 开头 且 为 GET请求带参数,且参数名以 数字开头
BasicRule wl:1000 "mz:$URL_X:^/foo|$ARGS_VAR_X:^[0-9]";
2.3.1.1 请求体
raw body检查
规则 4241 检查 raw_body 中有 RANDOMTHINGS 则丢弃请求
MainRule id:4241 s:DROP str:RANDOMTHINGS mz:RAW_BODY;
白名单可以设置为
BasicRule wl:4241 "mz:$URL:/|BODY";
file ext 检测
检测规则为
MainRule "rx:\.ph|\.asp|\.ht|\.jsp" "msg:asp/php/jsp file upload" "mz:FILE_EXT" "s:$UPLOAD:8" id:1500;
白名单为
BasicRule wl:1337 "mz:$URL:/index.html|FILE_EXT";
json 检测
有规则
BasicRule wl:1302 "mz:$BODY_VAR:lol";
白名单
BasicRule wl:1302 "mz:$BODY_VAR:lol";
则让下面json请求通过
{
"lol" : "foo<bar"
}
2.4 黑名单
黑名单的意义:快速修补已知漏洞
示例:
若已知 脚本 vuln_page.php 的 id 参数 存在漏洞,通常黑客使用如下方式注入
GET /vuln_page.php?id=1‘+or+1=1/*
则设置 url 为 /vuln_page.php 且 请求参数名为 id 的请求,不能包含 数字
server {
location / {
SecRulesEnabled; #enable naxsi
LearningMode; #enable learning mode
LibInjectionSql; #enable libinjection support for SQLI
LibInjectionXss; #enable libinjection support for XSS
DeniedUrl "/RequestDenied"; #the location where naxsi will redirect the request when it is blocked
CheckRule "$SQL >= 8" BLOCK; #the action to take when the $SQL score is superior or equal to 8
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 5" BLOCK;
CheckRule "$UPLOAD >= 5" BLOCK;
CheckRule "$XSS >= 8" BLOCK;
BasicRule id:4242 "mz:$URL:/vuln_page.php|$ARGS_VAR:id" "rx:[^\d]+" "s:DROP" "msg:blacklist for SQLI in /vuln_page.php";
proxy_pass http://127.0.0.1;
....
}
}
相关概念
1. RAW
naxsi不解析请求体,进行 全文 模式匹配.
当 naxsi 不能识别 content-type,则将 body 当成 RAW。
1.2 RAW 和 规则11
内部规则11 若被使用,则会 拦截 所有 content-type 不认识的请求,导致关于 RAW 的规则 不会触发
内部规则11 若被屏蔽,则 RAW规则 会有用。
1.3 示例
http {
...
MainRule "id:4241" "s:DROP" "str:RANDOMTHINGS" "mz:RAW_BODY";
...
location / {
...
BasicRule wl:11 "mz:$URL:/|BODY";
...
}
...
对于请求
POST / ...
Content-Type: RAFARAFA
...
RANDOMTHINGS
规则 4241会被触发,但如果 规则11 开启,则规则4241不会被使用,因为请求已经被规则11阻塞了。
1.4 注意
传送给 raw解析 前,所有null字节被替换成真实的 0. (?)