diff --git a/plugins/op_waf/index.html b/plugins/op_waf/index.html
index a4de78d0e..9e4dad280 100755
--- a/plugins/op_waf/index.html
+++ b/plugins/op_waf/index.html
@@ -246,7 +246,7 @@
diff --git a/plugins/op_waf/index.py b/plugins/op_waf/index.py
index 73c963344..14386106f 100755
--- a/plugins/op_waf/index.py
+++ b/plugins/op_waf/index.py
@@ -217,7 +217,9 @@ def initTotalInfo():
tmp['get'] = 0
tmp['post'] = 0
tmp['total'] = 0
- tmp['url_ext'] = 0
+ tmp['path'] = 0
+ tmp['php_path'] = 0
+ tmp['upload_ext'] = 0
_name = {}
_name[name] = tmp
total_contents['sites'] = _name
@@ -589,6 +591,8 @@ def addSiteRule():
cjson = mw.getJson(content)
mw.writeFile(path, cjson)
+
+ autoMakeConfig()
mw.restartWeb()
return mw.returnJson(True, '设置成功!')
@@ -625,6 +629,9 @@ def addIpWhite():
cjson = mw.getJson(content)
mw.writeFile(path, cjson)
+
+ autoMakeConfig()
+
mw.restartWeb()
return mw.returnJson(True, '设置成功!')
@@ -646,6 +653,8 @@ def removeIpWhite():
cjson = mw.getJson(content)
mw.writeFile(path, cjson)
+
+ autoMakeConfig()
mw.restartWeb()
return mw.returnJson(True, '设置成功!')
@@ -682,6 +691,8 @@ def addIpBlack():
cjson = mw.getJson(content)
mw.writeFile(path, cjson)
+
+ autoMakeConfig()
mw.restartWeb()
return mw.returnJson(True, '设置成功!')
@@ -703,6 +714,8 @@ def removeIpBlack():
cjson = mw.getJson(content)
mw.writeFile(path, cjson)
+
+ autoMakeConfig()
mw.restartWeb()
return mw.returnJson(True, '设置成功!')
@@ -722,6 +735,8 @@ def setIpv6Black():
cjson = mw.getJson(content)
mw.writeFile(path, cjson)
+
+ autoMakeConfig()
mw.restartWeb()
return mw.returnJson(True, '设置成功!')
@@ -741,6 +756,8 @@ def delIpv6Black():
content.remove(addr)
cjson = mw.getJson(content)
+
+ autoMakeConfig()
mw.writeFile(path, cjson)
return mw.returnJson(True, '设置成功!')
@@ -764,6 +781,8 @@ def removeSiteRule():
cjson = mw.getJson(content)
mw.writeFile(path, cjson)
+
+ autoMakeConfig()
mw.restartWeb()
return mw.returnJson(True, '设置成功!')
@@ -784,6 +803,8 @@ def setObjStatus():
cjson = mw.getJson(cobj)
mw.writeFile(conf, cjson)
+
+ autoMakeConfig()
mw.restartWeb()
return mw.returnJson(True, '设置成功!')
@@ -803,6 +824,8 @@ def setRetry():
cjson = mw.getJson(cobj)
mw.writeFile(conf, cjson)
+
+ autoMakeConfig()
mw.restartWeb()
return mw.returnJson(True, '设置成功!', [])
@@ -827,6 +850,8 @@ def setSafeVerify():
cjson = mw.getJson(cobj)
mw.writeFile(conf, cjson)
+
+ autoMakeConfig()
mw.restartWeb()
return mw.returnJson(True, '设置成功!', [])
@@ -857,6 +882,8 @@ def setCcConf():
cjson = mw.getJson(cobj)
mw.writeFile(conf, cjson)
+
+ autoMakeConfig()
mw.restartWeb()
return mw.returnJson(True, '设置成功!', [])
@@ -874,6 +901,8 @@ def saveScanRule():
path = getRuleJsonPath('scan_black')
cjson = mw.getJson(args)
mw.writeFile(path, cjson)
+
+ autoMakeConfig()
mw.restartWeb()
return mw.returnJson(True, '设置成功!', [])
@@ -967,6 +996,8 @@ def addSiteCdnHeader():
cjson = mw.getJson(content)
mw.writeFile(path, cjson)
+
+ autoMakeConfig()
mw.restartWeb()
return mw.returnJson(True, '添加成功!')
@@ -987,6 +1018,8 @@ def removeSiteCdnHeader():
cjson = mw.getJson(content)
mw.writeFile(path, cjson)
+
+ autoMakeConfig()
mw.restartWeb()
return mw.returnJson(True, '删除成功!')
@@ -1128,7 +1161,6 @@ def setSiteObjOpen():
mw.writeFile(path, cjson)
autoMakeConfig()
-
mw.restartWeb()
return mw.returnJson(True, '设置成功!')
diff --git a/plugins/op_waf/js/op_waf.js b/plugins/op_waf/js/op_waf.js
index 4b722d456..bed8eac2b 100755
--- a/plugins/op_waf/js/op_waf.js
+++ b/plugins/op_waf/js/op_waf.js
@@ -878,7 +878,7 @@ function wafScreen(){
con += '
\
POST渗透'+rdata.rules.post+'
\
-
GET渗透0
\
+
GET渗透'+rdata.rules.args+'
\
CC攻击'+rdata.rules.cc+'
\
恶意User-Agent'+rdata.rules.user_agent+'
\
Cookie渗透'+rdata.rules.cookie+'
\
@@ -886,9 +886,9 @@ function wafScreen(){
恶意HEAD请求0
\
URI自定义拦截'+rdata.rules.args+'
\
URI保护'+rdata.rules.args+'
\
-
恶意文件上传0
\
-
禁止的扩展名'+rdata.rules.url_ext+'
\
-
禁止PHP脚本0
\
+
恶意文件上传'+rdata.rules.upload_ext+'
\
+
禁止的扩展名'+rdata.rules.path+'
\
+
禁止PHP脚本'+rdata.rules.php_path+'
\
';
con += '
\
diff --git a/plugins/op_waf/waf/lua/common.lua b/plugins/op_waf/waf/lua/common.lua
index 5b5e7a21f..bb8712e41 100644
--- a/plugins/op_waf/waf/lua/common.lua
+++ b/plugins/op_waf/waf/lua/common.lua
@@ -437,8 +437,8 @@ end
-function _M.is_ngx_match_orgin(self,rule,match, sign)
- if ngx_match(ngx.unescape_uri(match), rule,"isjo") then
+function _M.is_ngx_match_orgin(self,rule, match, sign)
+ if ngx_match(ngx.unescape_uri(match), rule, "isjo") then
error_rule = rule .. ' >> ' .. sign .. ':' .. match
return true
end
@@ -456,18 +456,21 @@ function _M.ngx_match_string(self, rule, content,sign)
end
function _M.ngx_match_list(self, rules, content)
+ local args_type = type(content)
for i,rule in ipairs(rules)
do
if rule[1] == 1 then
- if type(content) == "string" then
+ if args_type == 'string' then
+ -- self:D("string: "..tostring(rule[2])..":".. tostring(content)..":"..tostring(rule[3]))
local t = self:is_ngx_match_orgin(rule[2], content, rule[3])
if t then
return true
end
end
- if type(content) == "table" then
- for arg_k,arg_v in ipairs(content) do
+ if args_type == 'table' then
+ for _,arg_v in pairs(content) do
+ -- self:D("table : "..tostring(rule[2])..":".. tostring(arg_v)..":"..tostring(rule[3]))
local t = self:is_ngx_match_orgin(rule[2], arg_v, rule[3])
if t then
return true
@@ -582,8 +585,8 @@ function _M.write_log(self, name, rule)
end
local count = ngx.shared.waf_drop_ip:get(ip)
-
- if (count > retry) then
+ self:D("write_log; count:" ..tostring(count).. ",retry:" .. tostring(retry) )
+ if (count > retry and name ~= 'cc') then
local safe_count,_ = ngx.shared.waf_drop_sum:get(ip)
if not safe_count then
ngx.shared.waf_drop_sum:set(ip, 1, 86400)
@@ -599,9 +602,8 @@ function _M.write_log(self, name, rule)
local reason = retry_cycle .. '秒以内累计超过'..retry..'次以上非法请求,封锁'.. lock_time ..'秒'
self:log(params, name, reason)
- else
-
- self:log(params, name, rule)
+ -- else
+ -- self:log(params, name, rule)
end
self:stats_total(name, rule)
@@ -672,6 +674,16 @@ function _M.get_boundary(self)
end
+function _M.is_key(self, arr, key)
+ for _,v in ipairs(arr) do
+ if v == key then
+ return true
+ end
+ end
+ return false
+end
+
+
function _M.return_post_data(self)
if method ~= "POST" then return false end
content_length = tonumber(self.params["request_header"]['content-length'])
diff --git a/plugins/op_waf/waf/lua/init.lua b/plugins/op_waf/waf/lua/init.lua
index 5d6f057d4..34e6a6072 100644
--- a/plugins/op_waf/waf/lua/init.lua
+++ b/plugins/op_waf/waf/lua/init.lua
@@ -19,6 +19,7 @@ C:setDebug(true)
local get_html = require "html_get"
local post_html = require "html_post"
+local other_html = require "html_other"
local user_agent_html = require "html_user_agent"
local cc_safe_js_html = require "html_safe_js"
@@ -67,7 +68,7 @@ local function get_return_state(rstate,rmsg)
end
local function get_waf_drop_ip()
- local data = ngx.shared.waf_waf_drop_ip:get_keys(0)
+ local data = ngx.shared.waf_drop_ip:get_keys(0)
return data
end
@@ -163,8 +164,7 @@ end
local function waf_get_args()
if not config['get']['open'] or not C:is_site_config('get') then return false end
-
- C:D(C:to_json(args_rules)..":"..json.encode(params['uri_request_args']))
+ -- C:D("waf_get_args:"..C:to_json(args_rules)..":"..json.encode(params['uri_request_args']))
if C:ngx_match_list(args_rules, params['uri_request_args']) then
C:write_log('args','regular')
C:return_html(config['get']['status'], get_html)
@@ -208,40 +208,51 @@ end
local function waf_user_agent()
-- user_agent 过滤
- if not config['user-agent']['open'] or not C:is_site_config('user-agent') then return false end
- if C:is_ngx_match_ua(user_agent_rules,params['request_header']['user-agent']) then
+ -- if not config['user-agent']['open'] or not C:is_site_config('user-agent') then return false end
+
+ -- C:D("waf_user_agent;user_agent_rules:"..json.encode(user_agent_rules)..",ua:"..tostring(params['request_header']['user-agent']))
+ if C:is_ngx_match_ua(user_agent_rules, params['request_header']['user-agent']) then
+ -- C:D("waf_user_agent........... true")
C:write_log('user_agent','regular')
- C:return_html(config['user-agent']['status'],user_agent_html)
+ C:return_html(config['user-agent']['status'], user_agent_html)
return true
end
+
+ -- C:D("waf_user_agent........... false")
return false
end
-local function waf_drop()
+local function waf_drop_ip()
local ip = params['ip']
local count = ngx.shared.waf_drop_ip:get(ip)
if not count then return false end
- if count > config['retry']['retry'] then
+ local retry = config['retry']['retry']
+ -- C:D("waf_drop;count:"..tostring(count)..",retry:"..tostring(retry))
+ -- C:D("waf_drop;count > retry:"..tostring(count > retry))
+ if count > retry then
+ -- C:D("waf_drop_ip........... true")
ngx.exit(config['cc']['status'])
return true
end
+ -- C:D("waf_drop_ip........... false")
return false
end
local function waf_cc()
- local ip = params['ip']
+ if not config['cc']['open'] or not C:is_site_config('cc') then return false end
- local ip_lock = ngx.shared.waf_drop_ip:get(ip)
- if ip_lock then
- if ip_lock > 0 then
- ngx.exit(config['cc']['status'])
- return true
- end
- end
+ local ip = params['ip']
- if not config['cc']['open'] or not C:is_site_config('cc') then return false end
+ -- 多次cc,才封禁。
+ -- local ip_lock = ngx.shared.waf_drop_ip:get(ip)
+ -- if ip_lock then
+ -- if ip_lock > 0 then
+ -- ngx.exit(config['cc']['status'])
+ -- return true
+ -- end
+ -- end
local request_uri = params['request_uri']
@@ -252,7 +263,6 @@ local function waf_cc()
local waf_limit = config['cc']['limit']
local cycle = config['cc']['cycle']
-
if count then
if count > waf_limit then
@@ -267,7 +277,9 @@ local function waf_cc()
if lock_time > 86400 then lock_time = 86400 end
ngx.shared.waf_drop_ip:set(ip, 1, lock_time)
- C:write_log('cc',cycle..'秒内累计超过'..waf_limit..'次请求,封锁' .. lock_time .. '秒')
+ local reason = cycle..'秒内累计超过'..waf_limit..'次请求,封锁' .. lock_time .. '秒'
+ C:write_log('cc', reason)
+ C:log(params, 'cc',reason)
ngx.exit(config['cc']['status'])
return true
else
@@ -383,15 +395,14 @@ end
local function waf_post()
if not config['post']['open'] or not C:is_site_config('post') then return false end
if params['method'] ~= "POST" then return false end
- content_length = tonumber(params["request_header"]['content-length'])
- max_len = 640 * 1020000
+ local content_length = tonumber(params["request_header"]['content-length'])
+ local max_len = 640 * 1020000
if content_length > max_len then return false end
if C:get_boundary() then return false end
ngx.req.read_body()
- request_args = ngx.req.get_post_args()
- if not request_args then
- return false
- end
+
+ local request_args = params['uri_request_args']
+ if not request_args then return false end
for key, val in pairs(request_args) do
if type(val) == "table" then
@@ -402,32 +413,40 @@ local function waf_post()
else
data = val
end
-
end
- if C:is_ngx_match_post(post_rules,data) then
+ -- C:D("post:"..json.encode(data))
+ if C:ngx_match_list(post_rules, data) then
C:write_log('post','regular')
- C:return_html(config['post']['status'],post_html)
+ C:return_html(config['post']['status'], post_html)
return true
end
return false
end
+local function waf_post_data_check()
+ if params['method'] == "POST" then
-local function post_data_chekc()
- if params['method'] =="POST" then
+ C:D("post_data_check start")
if C:return_post_data() then return false end
ngx.req.read_body()
- request_args = ngx.req.get_post_args()
+
+ local request_args = params['uri_request_args']
if not request_args then return false end
- if request_header then
- if not request_header['Content-Type'] then return false end
- av = string.match(request_header['Content-Type'],"=.+")
+ C:D("post_data_check:"..json.encode(params['request_header']))
+
+ local av = nil
+ if params['request_header'] then
+ if not params['request_header']['content-type'] then return false end
+ av = string.match(params['request_header']['content-type'], "=.+")
+
+ C:D("post_data_check[av]:"..json.encode(av))
end
+
if not av then return false end
- ac = split(av,'=')
+ ac = C:split(av,'=')
if not ac then return false end
@@ -448,14 +467,17 @@ local function post_data_chekc()
if not aaa then return false end
if tostring(aaa) == 'true' then return false end
if type(aaa) ~= "string" then return false end
- data_len = split(aaa,list_list)
+ data_len = C:split(aaa, list_list)
if not data_len then return false end
- if arrlen(data_len) ==0 then return false end
+ if arrlen(data_len) == 0 then return false end
+
+
+ C:D("post_rules:"..json.encode(post_rules).."data_len:"..json.encode(data_len))
if C:is_ngx_match_post(post_rules , data_len) then
C:write_log('post','regular')
- C:return_html(config['post']['status'],post_html)
+ C:return_html(config['post']['status'], post_html)
return true
end
@@ -467,10 +489,11 @@ local function X_Forwarded()
if params['method'] ~= "GET" then return false end
if not config['get']['open'] or not C:is_site_config('get') then return false end
+ if not params["request_header"]['X-forwarded-For'] then return false end
- if C:is_ngx_match(args_rules,params["request_header"]['X-forwarded-For'],'args') then
+ if C:ngx_match_list(args_rules, params["request_header"]['X-forwarded-For']) then
C:write_log('args','regular')
- C:return_html(config['get']['status'],get_html)
+ C:return_html(config['get']['status'], get_html)
return true
end
return false
@@ -480,47 +503,25 @@ end
local function post_X_Forwarded()
if not config['post']['open'] or not C:is_site_config('post') then return false end
if params['method'] ~= "POST" then return false end
- if C:is_ngx_match_post(post_rules,params["request_header"]['X-forwarded-For']) then
+ if not params["request_header"]['X-forwarded-For'] then return false end
+ if C:is_ngx_match_list(post_rules, params["request_header"]['X-forwarded-For']) then
C:write_log('post','regular')
- C:return_html(config['post']['status'],post_html)
+ C:return_html(config['post']['status'], post_html)
return true
end
return false
end
-
--- function php_path()
--- if site_config[server_name] == nil then return false end
--- for _,rule in ipairs(site_config[server_name]['disable_php_path'])
--- do
--- if C:ngx_match_string(params['uri'],rule .. "/?.*\\.php$","isjo") then
--- C:write_log('php_path','regular')
--- C:return_html(config['other']['status'],other_html)
--- return C:return_message(200,uri)
--- end
--- end
--- return false
--- end
-
--- function url_path()
--- if site_config[server_name] == nil then return false end
--- for _,rule in ipairs(site_config[server_name]['disable_path'])
--- do
--- if ngx_match(uri,rule,"isjo") then
--- C:write_log('path','regular')
--- C:return_html(config['other']['status'],other_html)
--- return true
--- end
--- end
--- return false
--- end
-
local function url_ext()
if site_config[server_name] == nil then return false end
for _,rule in ipairs(site_config[server_name]['disable_ext'])
do
if C:ngx_match_string("\\."..rule.."$", params['uri'],'url_ext') then
- C:write_log('url_ext','regular')
+ if rule == "php" then
+ C:write_log('php_path','regular')
+ else
+ C:write_log('path','regular')
+ end
C:return_html(config['other']['status'], other_html)
return true
end
@@ -528,59 +529,11 @@ local function url_ext()
return false
end
-local function url_rule_ex()
- if site_config[server_name] == nil then return false end
- if method == "POST" and not request_args then
- content_length = tonumber(request_header['content-length'])
- max_len = 640 * 102400000
- request_args = nil
- if content_length < max_len then
- ngx.req.read_body()
- request_args = ngx.req.get_post_args()
- end
- end
- for _,rule in ipairs(site_config[server_name]['url_rule'])
- do
- if ngx_match(uri,rule[1],"isjo") then
- if C:is_ngx_match(rule[2],uri_request_args,false) then
- C:write_log('url_rule','regular')
- C:return_html(config['other']['status'],other_html)
- return true
- end
-
- if params['method'] == "POST" and request_args ~= nil then
- if C:is_ngx_match(rule[2],request_args,'post') then
- C:write_log('post','regular')
- C:return_html(config['other']['status'],other_html)
- return true
- end
- end
- end
- end
- return false
-end
-
-local function url_tell()
- if site_config[server_name] == nil then return false end
- for _,rule in ipairs(site_config[server_name]['url_tell'])
- do
- if ngx_match(uri,rule[1],"isjo") then
- if uri_request_args[rule[2]] ~= rule[3] then
- C:write_log('url_tell','regular')
- C:return_html(config['other']['status'],other_html)
- return true
- end
- end
- end
- return false
-end
-
-
local function disable_upload_ext(ext)
if not ext then return false end
ext = string.lower(ext)
- if is_key(site_config[server_name]['disable_upload_ext'],ext) then
- C:write_log('upload_ext','上传扩展名黑名单')
+ if C:is_key(site_config[server_name]['disable_upload_ext'], ext) then
+ C:write_log('upload_ext', '上传扩展名黑名单')
C:return_html(config['other']['status'],other_html)
return true
end
@@ -590,9 +543,9 @@ local function data_in_php(data)
if not data then
return false
else
- if C:is_ngx_match('php',data,'post') then
+ if C:is_ngx_match('php', data, 'post') then
C:write_log('upload_ext','上传扩展名黑名单')
- C:return_html(config['other']['status'],other_html)
+ C:return_html(config['other']['status'], other_html)
return true
else
return false
@@ -602,9 +555,9 @@ end
local function post_data()
if params["method"] ~= "POST" then return false end
- content_length = tonumber(params["request_header"]['content-length'])
+ local content_length = tonumber(params["request_header"]['content-length'])
if not content_length then return false end
- max_len = 2560 * 1024000
+ local max_len = 2560 * 1024000
if content_length > max_len then return false end
local boundary = C:get_boundary()
if boundary then
@@ -614,11 +567,10 @@ local function post_data()
local tmp = ngx.re.match(data,[[filename=\"(.+)\.(.*)\"]])
if not tmp then return false end
if not tmp[2] then return false end
- local tmp2=ngx.re.match(ngx.req.get_body_data(),[[Content-Type:[^\+]{45}]])
+ local tmp2 = ngx.re.match(ngx.req.get_body_data(),[[Content-Type:[^\+]{45}]])
disable_upload_ext(tmp[2])
if tmp2 == nil then return false end
data_in_php(tmp2[0])
-
end
return false
end
@@ -647,7 +599,7 @@ function waf()
if waf_ip_black() then return true end
-- 封禁ip返回
- if waf_drop() then return true end
+ if waf_drop_ip() then return true end
-- ua check
if waf_user_agent() then return true end
@@ -667,16 +619,13 @@ function waf()
if waf_scan_black() then return true end
if waf_post() then return true end
- if post_data_chekc() then return true end
+ -- if waf_post_data_check() then return true end
if site_config[server_name] and site_config[server_name]['open'] then
- -- if X_Forwarded() then return true end
- -- if post_X_Forwarded() then return true end
- -- url_path()
+ if X_Forwarded() then return true end
+ if post_X_Forwarded() then return true end
if url_ext() then return true end
- -- url_rule_ex()
- -- url_tell()
- -- post_data()
+ if post_data() then return true end
end
end
diff --git a/plugins/op_waf/waf/total.json b/plugins/op_waf/waf/total.json
index 4d111b7ed..f9a5f91d2 100644
--- a/plugins/op_waf/waf/total.json
+++ b/plugins/op_waf/waf/total.json
@@ -1 +1 @@
-{"rules":{"url_ext":0,"user_agent":0,"scan":0,"cookie":0,"post":0,"args":0,"url":0,"cc":0},"sites":{},"total":0}
\ No newline at end of file
+{"rules":{"path":0,"php_path":0,"upload_ext":0,"user_agent":0,"scan":0,"cookie":0,"post":0,"args":0,"url":0,"cc":0},"sites":{},"total":0}
\ No newline at end of file