pull/109/head
midoks 6 years ago
parent d9ef18f9f6
commit c8ca8b60f8
  1. 33
      plugins/op_waf/waf/lua/common.lua
  2. 418
      plugins/op_waf/waf/lua/init.lua
  3. 2
      plugins/op_waf/waf/rule/ip_white.json
  4. 1
      plugins/op_waf/waf/rule/url.json
  5. 1
      plugins/op_waf/waf/rule/url_black.json
  6. 1
      plugins/op_waf/waf/rule/url_white.json

@ -25,8 +25,6 @@ function _M.setConfData( self, config, site_config )
self.config = config self.config = config
self.site_config = site_config self.site_config = site_config
-- ngx.say(json.encode(self.config))
-- ngx.exit(0)
end end
@ -36,7 +34,6 @@ end
function _M.is_min(self, ip1, ip2) function _M.is_min(self, ip1, ip2)
n = 0 n = 0
for _,v in ipairs({1,2,3,4}) for _,v in ipairs({1,2,3,4})
do do
@ -66,6 +63,36 @@ function _M.is_max(self,ip1,ip2)
return true return true
end end
function _M.split(self, str,reps )
local resultStrList = {}
string.gsub(str,'[^'..reps..']+',function(w)
table.insert(resultStrList,w)
end)
return resultStrList
end
function _M.arrip(self, ipstr)
if ipstr == 'unknown' then return {0,0,0,0} end
if string.find(ipstr,':') then return ipstr end
iparr = self:split(ipstr,'.')
iparr[1] = tonumber(iparr[1])
iparr[2] = tonumber(iparr[2])
iparr[3] = tonumber(iparr[3])
iparr[4] = tonumber(iparr[4])
return iparr
end
function _M.compare_ip(self,ips)
local ip = self.params["ip"]
local ipn = self.params["ipn"]
if ip == 'unknown' then return true end
if string.find(ip,':') then return false end
if not self:is_max(ipn,ips[2]) then return false end
if not self:is_min(ipn,ips[1]) then return false end
return true
end
function _M.return_message(self, status, msg) function _M.return_message(self, status, msg)
ngx.header.content_type = "application/json;" ngx.header.content_type = "application/json;"

@ -12,16 +12,10 @@ local config = C:read_file_body_decode(cpath .. 'config.json')
local site_config = C:read_file_body_decode(cpath .. 'site.json') local site_config = C:read_file_body_decode(cpath .. 'site.json')
C:setConfData(config, site_config) C:setConfData(config, site_config)
local get_html = C:read_file_body(config["reqfile_path"] .. '/' .. config["get"]["reqfile"])
local args_rules = C:read_file_table('args')
local ip_white_rules = C:read_file('ip_white')
function initParams() function initParams()
local data = {} local data = {}
data['ip'] = C:get_client_ip() data['ip'] = C:get_client_ip()
data['ipn'] = C:arrip(data['ip'])
data['request_header'] = ngx.req.get_headers() data['request_header'] = ngx.req.get_headers()
data['uri'] = ngx.unescape_uri(ngx.var.uri) data['uri'] = ngx.unescape_uri(ngx.var.uri)
data['server_name'] = string.gsub(C:get_server_name(),'_','.') data['server_name'] = string.gsub(C:get_server_name(),'_','.')
@ -32,6 +26,8 @@ end
local params = initParams() local params = initParams()
C:setParams(params) C:setParams(params)
-- function min_route() -- function min_route()
-- if ngx.var.remote_addr ~= '127.0.0.1' then return false end -- if ngx.var.remote_addr ~= '127.0.0.1' then return false end
-- if uri == '/get_waf_drop_ip' then -- if uri == '/get_waf_drop_ip' then
@ -43,6 +39,8 @@ C:setParams(params)
-- end -- end
-- end -- end
local get_html = C:read_file_body(config["reqfile_path"] .. '/' .. config["get"]["reqfile"])
local args_rules = C:read_file_table('args')
function waf_args() function waf_args()
if not config['get']['open'] or not C:is_site_config('get') then return false end if not config['get']['open'] or not C:is_site_config('get') then return false end
if C:is_ngx_match(args_rules, params['uri_request_args'],'args') then if C:is_ngx_match(args_rules, params['uri_request_args'],'args') then
@ -53,9 +51,415 @@ function waf_args()
return false return false
end end
local ip_white_rules = C:read_file('ip_white')
function waf_ip_white()
for _,rule in ipairs(ip_white_rules)
do
if C:compare_ip(rule) then
return true
end
end
return false
end
local ip_black_rules = C:read_file('ip_black')
function waf_ip_black()
for _,rule in ipairs(ip_black_rules)
do
if C:compare_ip(rule) then
ngx.exit(config['cc']['status'])
return true
end
end
return false
end
local url_white_rules = C:read_file('url_white')
function waf_url_white()
if C:is_ngx_match(url_white_rules,params['request_uri'],false) then
return true
end
if site_config[server_name] ~= nil then
if C:is_ngx_match(site_config[server_name]['url_white'], params['request_uri'],false) then
return true
end
end
return false
end
local url_black_rules = C:read_file('url_black')
function waf_url_black()
if C:is_ngx_match(url_black_rules,params['request_uri'],false) then
ngx.exit(config['get']['status'])
return true
end
return false
end
function waf_drop()
local count,_ = ngx.shared.drop_ip:get(ip)
if not count then return false end
if count > config['retry'] then
ngx.exit(config['cc']['status'])
return true
end
return false
end
local user_agent_html = C:read_file_body(config["reqfile_path"] .. '/' .. config["user-agent"]["reqfile"])
function waf_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(user_agent_rules,params['request_header']['user-agent'],'user_agent') then
C:write_log('user_agent','regular')
C:return_html(config['user-agent']['status'],user_agent_html)
return true
end
return false
end
-- function cc()
-- local ip = params['ip']
-- local request_uri = params['request_uri']
-- local endtime = config['cc']['endtime']
-- if not config['cc']['open'] or not site_cc then return false end
-- local token = ngx.md5(ip .. '_' .. request_uri)
-- local count,_ = ngx.shared.limit:get(token)
-- if count then
-- if count > limit then
-- local safe_count,_ = ngx.shared.drop_sum:get(ip)
-- if not safe_count then
-- ngx.shared.drop_sum:set(ip,1,86400)
-- safe_count = 1
-- else
-- ngx.shared.drop_sum:incr(ip,1)
-- end
-- local lock_time = (endtime * safe_count)
-- if lock_time > 86400 then lock_time = 86400 end
-- ngx.shared.drop_ip:set(ip,retry+1,lock_time)
-- C:write_log('cc',cycle..'秒内累计超过'..limit..'次请求,封锁' .. lock_time .. '秒')
-- C:write_drop_ip('cc',lock_time)
-- if not server_name then
-- insert_ip_list(ip,lock_time,os.time(),'1111')
-- else
-- insert_ip_list(ip,lock_time,os.time(),server_name)
-- end
-- ngx.exit(config['cc']['status'])
-- return true
-- else
-- ngx.shared.limit:incr(token,1)
-- end
-- else
-- ngx.shared.limit:set(token,1,cycle)
-- end
-- return false
-- end
--强制验证是否使用正常浏览器访问网站
function waf_cc_increase()
if not config['cc']['open'] or not site_cc then return false end
if not site_config[server_name] then return false end
if not site_config[server_name]['cc']['increase'] then return false end
local cache_token = ngx.md5(ip .. '_' .. server_name)
--判断是否已经通过验证
if ngx.shared.btwaf:get(cache_token) then return false end
if cc_uri_white() then
ngx.shared.btwaf:delete(cache_token .. '_key')
ngx.shared.btwaf:set(cache_token,1,60)
return false
end
if security_verification() then return false end
send_check_heml(cache_token)
end
function waf_url()
if not config['get']['open'] or not C:is_site_config('get') then return false end
--正则--
if C:is_ngx_match(url_rules,params["uri"],'url') then
C:write_log('url','regular')
C:return_html(config['get']['status'],get_html)
return true
end
return false
end
function waf_scan_black()
if not config['scan']['open'] or not C:is_site_config('scan') then return false end
if C:is_ngx_match(scan_black_rules['cookie'],request_header['cookie'],false) then
C:write_log('scan','regular')
ngx.exit(config['scan']['status'])
return true
end
if C:is_ngx_match(scan_black_rules['args'],request_uri,false) then
C:write_log('scan','regular')
ngx.exit(config['scan']['status'])
return true
end
for key,value in pairs(request_header)
do
if C:is_ngx_match(scan_black_rules['header'],key,false) then
C:write_log('scan','regular')
ngx.exit(config['scan']['status'])
return true
end
end
return false
end
function get_boundary()
local header = request_header["content-type"]
if not header then return nil end
if type(header) == "table" then
header = header[1]
end
local m = string.match(header, ";%s*boundary=\"([^\"]+)\"")
if m then
return m
end
return string.match(header, ";%s*boundary=([^\",;]+)")
end
function waf_post_referer()
if method ~= "POST" then return false end
if C:is_ngx_match(referer_local, request_header['Referer'],'post') then
C:write_log('post_referer','regular')
rC:eturn_html(config['post']['status'],post_html)
return true
end
return false
end
function waf_post()
if not config['post']['open'] or not is_site_config('post') then return false end
if method ~= "POST" then return false end
if waf_post_referer() then return true end
content_length = tonumber(request_header['content-length'])
max_len = 640 * 1020000
if content_length > max_len then return false end
if 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
--return return_message(200,request_args)
if C:is_ngx_match(post_rules,request_args,'post') then
C:write_log('post','regular')
C:return_html(config['post']['status'],post_html)
return true
end
return false
end
function post_data_chekc()
if method =="POST" then
if return_post_data() then return false end
request_args = ngx.req.get_post_args()
if not request_args then return false end
if not request_header['Content-Type'] then return false end
av=string.match(request_header['Content-Type'],"=.+")
if not av then return false end
ac=split(av,'=')
if not ac then return false end
list_list=nil
for i,v in ipairs(ac)
do
list_list='--'..v
end
if not list_list then return false end
aaa=nil
for k,v in pairs(request_args)
do
aaa=v
end
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)
--return return_message(200,data_len)
if not data_len then return false end
if arrlen(data_len) ==0 then return false end
if is_ngx_match(post_rules,data_len,'post') then
write_log('post','regular')
return_html(config['post']['status'],post_html)
return true
end
end
end
function X_Forwarded()
if method ~= "GET" then return false end
if not config['get']['open'] or not is_site_config('get') then return false end
if is_ngx_match(args_rules,request_header['X-forwarded-For'],'args') then
write_log('args','regular')
return_html(config['get']['status'],get_html)
return true
end
return false
end
function post_X_Forwarded()
if not config['post']['open'] or not is_site_config('post') then return false end
if method ~= "POST" then return false end
if is_ngx_match(post_rules,request_header['X-forwarded-For'],'post') then
write_log('post','regular')
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 string.find(uri,rule .. "/.*\\.php$") then
if ngx_match(uri,rule .. "/?.*\\.php$","isjo") then
write_log('php_path','regular')
return_html(config['other']['status'],other_html)
return 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
write_log('path','regular')
return_html(config['other']['status'],other_html)
return true
end
end
return false
end
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 ngx_match(uri,"\\."..rule.."$","isjo") then
write_log('url_ext','regular')
return_html(config['other']['status'],other_html)
return true
end
end
return false
end
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 is_ngx_match(rule[2],uri_request_args,false) then
write_log('url_rule','regular')
return_html(config['other']['status'],other_html)
return true
end
if method == "POST" and request_args ~= nil then
if is_ngx_match(rule[2],request_args,'post') then
write_log('post','regular')
return_html(config['other']['status'],other_html)
return true
end
end
end
end
return false
end
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
write_log('url_tell','regular')
return_html(config['other']['status'],other_html)
return true
end
end
end
return false
end
ngx.header.content_type = "text/html" ngx.header.content_type = "text/html"
function waf() function waf()
if waf_ip_white() then return true end
waf_ip_black()
if waf_url_white() then return true end
waf_url_black()
waf_drop()
waf_user_agent()
waf_url()
if method == "GET" then
-- waf_referer()
-- waf_cookie()
end
if method == "POST" then
-- ngx.req.read_body()
-- request_args111 = ngx.req.get_post_args()
-- waf_cookie()
end
waf_args() waf_args()
waf_scan_black()
waf_post()
-- post_data_chekc()
-- if site_config[server_name] then
-- X_Forwarded()
-- post_X_Forwarded()
-- php_path()
-- url_path()
-- url_ext()
-- url_rule_ex()
-- url_tell()
-- post_data()
-- end
end end
waf() waf()

@ -1 +1 @@
[[[127, 0, 0, 1], [127, 0, 0, 255]]] [[[127, 0, 0, 2], [127, 0, 0, 255]]]

@ -0,0 +1 @@
[[1, "\\.(htaccess|mysql_history|bash_history|DS_Store|idea|user\\.ini)", "\u6587\u4ef6\u76ee\u5f55\u8fc7\u6ee41", 0], [1, "\\.(bak|inc|old|mdb|sql|php~|swp|java|class)$", "\u6587\u4ef6\u76ee\u5f55\u8fc7\u6ee42", 0], [1, "^/(vhost|bbs|host|wwwroot|www|site|root|backup|data|ftp|db|admin|website|web).*\\.(rar|sql|zip|tar\\.gz|tar)$", "\u6587\u4ef6\u76ee\u5f55\u8fc7\u6ee43", 0], [1, "/(hack|shell|spy|phpspy)\\.php$", "PHP\u811a\u672c\u6267\u884c\u8fc7\u6ee41", 0], [1, "^/(attachments|css|uploadfiles|static|forumdata|cache|avatar)/(\\w+).(php|jsp)$", "PHP\u811a\u672c\u6267\u884c\u8fc7\u6ee42", 0], [1, "(?:(union(.*?)select))", "SQL\u6ce8\u5165\u8fc7\u6ee41", 0], [1, "(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\\(", "\u4e00\u53e5\u8bdd\u6728\u9a6c\u8fc7\u6ee41", 1]]

@ -0,0 +1 @@
["^/phpmyadmin_", "^/wp-content/themes/begin/timthumb\\.php", "^/web/index\\.php\\?c=cloud", "^/\\.well-known/"]
Loading…
Cancel
Save