-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
1,701 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
--- | ||
title: Nginx 的 WAF 规则 LuaJIT 低危险版 | ||
tags: | ||
- 规则 | ||
categories: | ||
- 网络安全 | ||
date: 2023-12-17 00:00:00 | ||
--- | ||
|
||
> 前段时间杜老师发表了一篇《自建 CDN 服务器思路》其中介绍南墙 Web 应用防火墙,有些小伙伴们对其名字很感兴趣,而杜老师注意到了它的防护规则,感觉非常实用,顺手整理了下,分享给需要的小伙伴们。此篇为低危险防护规则! | ||
<!-- more --> | ||
|
||
### 防CC攻击规则 | ||
|
||
过滤阶段:请求阶段 | ||
|
||
规则描述:当一分钟访问/api/路径频率超过360次,则在5分钟内拦截该ip访问 | ||
|
||
规则内容: | ||
|
||
``` | ||
if not waf.startWith(waf.toLower(waf.uri), "/api/") then | ||
return false | ||
end | ||
local sh = ngx.shared.ipCache | ||
local ccIp = 'cc-' .. waf.ip | ||
local c, f = sh:get(ccIp) | ||
if not c then | ||
sh:set(ccIp, 1, 60, 1) -- 设置1分钟也就是60秒访问计数时间 | ||
else | ||
if f == 2 then | ||
return waf.block(true) -- 重置TCP连接,不记录日志 | ||
end | ||
sh:incr(ccIp, 1) | ||
if c + 1 >= 360 then | ||
sh:set(ccIp, c + 1, 300, 2) -- 设置5分钟也就是300秒拦截时间 | ||
return true, ccIp, true | ||
end | ||
end | ||
return false | ||
``` | ||
|
||
### IIS报错检测 | ||
|
||
过滤阶段:返回页面 | ||
|
||
规则描述:IIS返回页面的报错可能会泄露服务器敏感信息 | ||
|
||
规则内容: | ||
|
||
``` | ||
local rgx = waf.rgxMatch | ||
local rb = waf.respBody | ||
local m = rgx(rb, "[a-z]:\\x5cinetpub\\b", "jo") | ||
if m then | ||
return m, rb, true | ||
end | ||
if waf.status == 500 then | ||
local m = rgx(rb, "Microsoft OLE DB Provider for SQL Server(?:</font>.{1,20}?error '800(?:04005|40e31)'.{1,40}?Timeout expired| \\(0x80040e31\\)<br>Timeout expired<br>)|<h1>internal server error</h1>.*?<h2>part of the server has crashed or it has a configuration error\\.</h2>|cannot connect to the server: timed out", "jo") | ||
if m then | ||
return m, rb, true | ||
end | ||
local m = rgx(rb, "\\b(?:A(?:DODB\\.Command\\b.{0,100}?\\b(?:Application uses a value of the wrong type for the current operation\\b|error')| trappable error occurred in an external object\\. The script cannot continue running\\b)|Microsoft VBScript (?:compilation (?:\\(0x8|error)|runtime (?:Error|\\(0x8))\\b|Object required: '|error '800)|<b>Version Information:</b>(?: |\\s)(?:Microsoft \\.NET Framework|ASP\\.NET) Version:|>error 'ASP\\b|An Error Has Occurred|>Syntax error in string in query expression|/[Ee]rror[Mm]essage\\.aspx?\\?[Ee]rror\\b", "jo") | ||
if m then | ||
return m, rb, true | ||
end | ||
end | ||
if waf.status == 404 then | ||
local m = rgx(rb, "\\bServer Error in.{0,50}?\\bApplication\\b", "jo") | ||
if m then | ||
return m, rb, true | ||
end | ||
end | ||
return false | ||
``` | ||
|
||
### php报错检测 | ||
|
||
过滤阶段:返回页面 | ||
|
||
规则描述:返回页面的php报错可能会泄露服务器敏感信息 | ||
|
||
规则内容: | ||
|
||
``` | ||
local check = waf.plugins.phpErrorDetection.check | ||
local rb = waf.respBody | ||
if waf.status == 500 then | ||
local m, d = check(rb) | ||
if m then | ||
return m, "php error: " .. d, true | ||
end | ||
end | ||
return false | ||
``` | ||
|
||
### Java报错检测 | ||
|
||
过滤阶段:返回页面 | ||
|
||
规则描述:返回页面的java报错可能会泄露服务器敏感信息 | ||
|
||
规则内容: | ||
|
||
``` | ||
local check = waf.plugins.javaErrorDetection.check | ||
local rb = waf.respBody | ||
if waf.status == 500 then | ||
local m,d = check(rb) | ||
if m then | ||
return m, "Java error: " .. d, true | ||
end | ||
end | ||
return false | ||
``` | ||
|
||
### 请求方法加强 | ||
|
||
过滤阶段:请求阶段 | ||
|
||
规则描述:不常用的http请求方法会出现一些安全漏洞,如:历史上Apache平台TRACE请求方法出现过XSS相关漏洞 | ||
|
||
规则内容: | ||
|
||
``` | ||
if not waf.rgxMatch(waf.method, "^(?:GET|HEAD|POST|PUT|DELETE|OPTIONS)$") then | ||
return true, waf.method, true | ||
end | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
--- | ||
title: Nginx 的 WAF 规则 LuaJIT 中危险版 | ||
tags: | ||
- 规则 | ||
categories: | ||
- 网络安全 | ||
date: 2023-12-20 00:00:00 | ||
--- | ||
|
||
> 前段时间杜老师发表了一篇《自建 CDN 服务器思路》其中介绍南墙 Web 应用防火墙,有些小伙伴们对其名字很感兴趣,而杜老师注意到了它的防护规则,感觉非常实用,顺手整理了下,分享给需要的小伙伴们。此篇为中危险防护规则! | ||
<!-- more --> | ||
|
||
### 机器人攻击防护 | ||
|
||
过滤阶段:请求阶段 | ||
|
||
规则描述:通过生成滑动旋转验证码来拦截机器人攻击,如漏洞扫描、网络爬虫、CC攻击等自动化攻击行为,Token有效期30分钟。 | ||
|
||
规则内容: | ||
|
||
``` | ||
local sh = ngx.shared.ipCache | ||
local robotIp = 'rb:' .. waf.ip | ||
local c, f = sh:get(robotIp) | ||
-- 如果是静态页面且没有进行滑动旋转验证码验证则返回 | ||
if not (waf.isQueryString or waf.reqContentLength > 0) and f ~= 2 then | ||
return false | ||
end | ||
if not c then | ||
sh:set(robotIp, 1, 60, 1) -- 设置1分钟也就是60秒访问计数时间段 | ||
else | ||
if f == 2 then | ||
return waf.checkRobot(waf) -- 启动机器人滑动旋转验证码验证 | ||
end | ||
sh:incr(robotIp, 1) | ||
if c + 1 >= 360 then | ||
sh:set(robotIp, c + 1, 1800, 2) -- 达到了60秒内请求超过360次的阈值,进入机器人验证模式 | ||
return true, robotIp, true | ||
end | ||
end | ||
return false | ||
``` | ||
|
||
### 弱口令检测 | ||
|
||
过滤阶段:请求阶段 | ||
|
||
规则描述:检测常见登录页面的弱口令问题 | ||
|
||
规则内容: | ||
|
||
``` | ||
local check = waf.plugins.weakPwdDetection.check | ||
local toLower = waf.toLower | ||
local has = waf.contains | ||
local form = waf.form | ||
local uri = toLower(waf.uri) | ||
if form and (has(uri, "login") or has(uri, "logon") or has(uri, "signin")) then | ||
local f = form["FORM"] | ||
if f then | ||
for k, v in pairs(f) do | ||
k = toLower(k) | ||
if (k == "pass" or has(k, "pwd") or has(k, "passwd") or has(k, "password")) and check(v) then | ||
return true, form["RAW"], false | ||
end | ||
end | ||
end | ||
end | ||
return false | ||
``` | ||
|
||
### 敏感文件泄露检测 | ||
|
||
过滤阶段:请求阶段 | ||
|
||
规则描述:检测url中各种敏感泄露文件的路径,如svn、git、sql、log、bak等,防止被攻击者利用 | ||
|
||
规则内容: | ||
|
||
``` | ||
local m, d = waf.plugins.fileLeakDetection.check() | ||
if m then | ||
return true, d, true | ||
end | ||
return false | ||
``` | ||
|
||
### 请求body大小限制 | ||
|
||
过滤阶段:请求阶段 | ||
|
||
规则描述:限制请求body大小为8M以下,黑客会尝试大数据包绕过waf过滤 | ||
|
||
规则内容: | ||
|
||
``` | ||
if waf.reqContentLength>8388608 then | ||
return true,"reqBody length is "..waf.reqContentLength ,true | ||
end | ||
return false | ||
``` | ||
|
||
### HTTP Parameter Pollution | ||
|
||
过滤阶段:请求阶段 | ||
|
||
规则描述:http参数污染攻击,该规则查找具有相同名称的多个参数,并检查一些后端参数弱校验时产生的绕过问题,如:foo[1]a=bar&foo[1]b=<evil>或foo[1]x[1]=bar&foo[1]x[2]=<evil>等。 | ||
|
||
规则内容: | ||
|
||
``` | ||
local rgx = waf.rgxMatch | ||
local function rMatch(v) | ||
local m = rgx(v, "(?:][^\\]]+$|][^\\]]+\\[)", "jos") | ||
if m then | ||
return m, v | ||
end | ||
return false | ||
end | ||
local form = waf.form | ||
if form then | ||
for k, v in pairs(form["FORM"]) do | ||
if type(v) == "table" then | ||
return true, k.."="..table.concat(v, ","), true | ||
end | ||
local m, d = rMatch(k) | ||
if m then | ||
return m, d, true | ||
end | ||
end | ||
end | ||
local queryString = waf.queryString | ||
if queryString then | ||
for k, v in pairs(queryString) do | ||
if type(v) == "table" then | ||
return true, k.."="..table.concat(v, ","), true | ||
end | ||
local m, d = rMatch(k) | ||
if m then | ||
return m, d, true | ||
end | ||
end | ||
end | ||
local cookies = waf.cookies | ||
if cookies then | ||
for k, v in pairs(cookies) do | ||
if type(v) == "table" then | ||
return true, k.."="..table.concat(v, ","), true | ||
end | ||
local m, d = rMatch(k) | ||
if m then | ||
return m, d, true | ||
end | ||
end | ||
end | ||
return false | ||
``` | ||
|
||
### 扫描器检测 | ||
|
||
过滤阶段:请求阶段 | ||
|
||
规则描述:检测常见的各种扫描器,如awvs、sqlmap、nessus、appscan、nmap等,拦截它们有助于减少黑客发现漏洞的风险 | ||
|
||
规则内容: | ||
|
||
``` | ||
local m, d = waf.plugins.scannerDetection.check() | ||
if m then | ||
return true, d, true | ||
end | ||
return false | ||
``` |
Oops, something went wrong.