You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
3.2 KiB
Lua

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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