|
|
local waf={}
|
|
|
local cjson = require "cjson"
|
|
|
|
|
|
local match = string.match
|
|
|
local ngxmatch = ngx.re.match
|
|
|
local unescape = ngx.unescape_uri
|
|
|
local get_headers = ngx.req.get_headers
|
|
|
|
|
|
require 'functions'
|
|
|
math.randomseed(tostring(ngx.time()):reverse():sub(1, 6));
|
|
|
|
|
|
local rulepath = "./waf/wafconf"
|
|
|
local black_fileExt = {".php",".js",".py"}
|
|
|
local urlrules
|
|
|
local argsrules
|
|
|
local postrules
|
|
|
|
|
|
--返回值表示是否发现异常
|
|
|
local function Set (list)
|
|
|
local set = {}
|
|
|
for _, l in ipairs(list) do set[l] = true end
|
|
|
return set
|
|
|
end
|
|
|
|
|
|
|
|
|
local function read_rule(rulename)
|
|
|
local path = rulepath..'/'..rulename
|
|
|
ngx.log(ngx.DEBUG,'path=',path)
|
|
|
local file = io.open(path,"r")
|
|
|
if file==nil then
|
|
|
return
|
|
|
end
|
|
|
t = {}
|
|
|
for line in file:lines() do
|
|
|
table.insert(t,line)
|
|
|
end
|
|
|
file:close()
|
|
|
return t
|
|
|
end
|
|
|
|
|
|
function waf.init()
|
|
|
|
|
|
urlrules = read_rule("url")
|
|
|
argsrules = read_rule("args")
|
|
|
postrules = read_rule('post')
|
|
|
|
|
|
--table.dumpdebug(urlrule,'urlrule')
|
|
|
--table.dumpdebug(argsrules,'argsrules')
|
|
|
--table.dumpdebug(postrules,'postrules')
|
|
|
end
|
|
|
|
|
|
--检查get的参数是否有问题,返回true表示发现异常
|
|
|
function waf.args()
|
|
|
for _,rule in pairs(argsrules) do
|
|
|
local args = ngx.req.get_uri_args()
|
|
|
for key, val in pairs(args) do
|
|
|
local data = nil
|
|
|
if type(val)=='table' then
|
|
|
local t={}
|
|
|
for k,v in pairs(val) do
|
|
|
if v == true then
|
|
|
v=""
|
|
|
end
|
|
|
table.insert(t,v)
|
|
|
end
|
|
|
data=table.concat(t, " ")
|
|
|
else
|
|
|
data=val
|
|
|
end
|
|
|
--ngx.log(ngx.DEBUG,'rule=',rule,",data=",data)
|
|
|
if data and type(data) ~= "boolean" and rule ~="" and ngxmatch(unescape(data),rule,"isjo") then
|
|
|
return true
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
return false
|
|
|
end
|
|
|
|
|
|
function waf.url()
|
|
|
for _,rule in pairs(urlrules) do
|
|
|
ngx.log(ngx.DEBUG,'GET-',ngx.var.request_uri,"-",rule)
|
|
|
if rule ~="" and ngxmatch(ngx.var.request_uri,rule,"isjo") then
|
|
|
--ngx.log(ngx.DEBUG,'GET',ngx.var.request_uri,"-",rule)
|
|
|
return true
|
|
|
end
|
|
|
end
|
|
|
return false
|
|
|
end
|
|
|
|
|
|
function waf.get_boundary()
|
|
|
local header = get_headers()["content-type"]
|
|
|
if not header then
|
|
|
return nil
|
|
|
end
|
|
|
|
|
|
if type(header) == "table" then
|
|
|
header = header[1]
|
|
|
end
|
|
|
|
|
|
local m = match(header, ";%s*boundary=\"([^\"]+)\"")
|
|
|
if m then
|
|
|
return m
|
|
|
end
|
|
|
|
|
|
return match(header, ";%s*boundary=([^\",;]+)")
|
|
|
end
|
|
|
|
|
|
|
|
|
function waf.body(data)
|
|
|
|
|
|
for _,rule in pairs(postrules) do
|
|
|
-- ngx.log(ngx.DEBUG,'POST',"url=",ngx.var.request_uri,",data=",data,",rule=",rule)
|
|
|
if rule ~="" and data~="" and ngxmatch(unescape(data),rule,"isjo") then
|
|
|
return true
|
|
|
end
|
|
|
end
|
|
|
return false
|
|
|
|
|
|
end
|
|
|
|
|
|
function waf.fileExtCheck(ext)
|
|
|
local items = Set(black_fileExt)
|
|
|
ext=string.lower(ext)
|
|
|
if ext then
|
|
|
for rule in pairs(items) do
|
|
|
if ngx.re.match(ext,rule,"isjo") then
|
|
|
--ngx.log(ngx.DEBUG,'POST',ngx.var.request_uri,"-","file attack with ext "..ext)
|
|
|
return true
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
return false
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
return waf
|