From 3d9ff7687f8b2a8762dcf26c3a5b42dfddb535a9 Mon Sep 17 00:00:00 2001 From: "lj2007331@gmail.com" Date: Sun, 24 Jun 2018 20:16:03 +0800 Subject: [PATCH] commit --- README.md | 4 +- access.lua | 18 +++++ config.lua | 60 ++++++++++++++++ init.lua | 178 ++++++++++++++++++++++++++++++++++++++++++++++ lib.lua | 84 ++++++++++++++++++++++ wafconf/args | 22 ++++++ wafconf/blackip | 0 wafconf/blackurl | 6 ++ wafconf/cookie | 20 ++++++ wafconf/post | 20 ++++++ wafconf/useragent | 1 + wafconf/whiteip | 1 + wafconf/whiteurl | 2 + 13 files changed, 414 insertions(+), 2 deletions(-) create mode 100644 access.lua create mode 100644 config.lua create mode 100644 init.lua create mode 100644 lib.lua create mode 100644 wafconf/args create mode 100644 wafconf/blackip create mode 100644 wafconf/blackurl create mode 100644 wafconf/cookie create mode 100644 wafconf/post create mode 100644 wafconf/useragent create mode 100644 wafconf/whiteip create mode 100644 wafconf/whiteurl diff --git a/README.md b/README.md index 69dce8d..77408c5 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,6 @@ sed -i "s@^nginx_modules_options=.*@nginx_modules_options='--add-module=../lua-n ``` ### Copyright -完全copy以下项目: +完全copy以下项目:
+https://github.com/loveshell/ngx_lua_waf
https://github.com/unixhot/waf -https://github.com/loveshell/ngx_lua_waf diff --git a/access.lua b/access.lua new file mode 100644 index 0000000..354b27d --- /dev/null +++ b/access.lua @@ -0,0 +1,18 @@ +require 'init' + +function waf_main() + if black_ip_check() then + elseif white_ip_check() then + elseif white_url_check() then + elseif user_agent_attack_check() then + elseif cc_attack_check() then + elseif cookie_attack_check() then + elseif url_attack_check() then + elseif url_args_attack_check() then + --elseif post_attack_check() then + else + return + end +end + +waf_main() diff --git a/config.lua b/config.lua new file mode 100644 index 0000000..b91ff98 --- /dev/null +++ b/config.lua @@ -0,0 +1,60 @@ +--WAF config file,enable = "on",disable = "off" + +--waf status +config_waf_enable = "on" +--log dir +config_log_dir = "/data/wwwlogs" +--rule setting +config_rule_dir = "/usr/local/nginx/conf/waf/wafconf" +--enable/disable white url +config_white_url_check = "on" +--enable/disable white ip +config_white_ip_check = "on" +--enable/disable block ip +config_black_ip_check = "on" +--enable/disable url filtering +config_url_check = "on" +--enalbe/disable url args filtering +config_url_args_check = "on" +--enable/disable user agent filtering +config_user_agent_check = "on" +--enable/disable cookie deny filtering +config_cookie_check = "on" +--enable/disable cc filtering +config_cc_check = "on" +--cc rate the xxx of xxx seconds +config_cc_rate = "20/60" +--enable/disable post filtering +config_post_check = "on" +--config waf output redirect/html +config_waf_output = "html" +--if config_waf_output ,setting url +config_waf_redirect_url = "/captcha" +config_output_html=[[ + + +网站防火墙 + + + +
+
+
网站防火墙
+
+

您的请求带有不合法参数,已被网站管理员设置拦截!

+

可能原因:您提交的内容包含危险的攻击请求

+

如何解决:

+
  • 1)检查提交内容;
  • +
  • 2)如网站托管,请联系空间提供商;
  • +
  • 3)普通网站访客,请联系网站管理员;
+
+
+
+ +]] diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..327a393 --- /dev/null +++ b/init.lua @@ -0,0 +1,178 @@ +--WAF Action +require 'config' +require 'lib' + +--args +local rulematch = ngx.re.find +local unescape = ngx.unescape_uri + +--allow white ip +function white_ip_check() + if config_white_ip_check == "on" then + local IP_WHITE_RULE = get_rule('whiteip') + local WHITE_IP = get_client_ip() + if IP_WHITE_RULE ~= nil then + for _,rule in pairs(IP_WHITE_RULE) do + if rule ~= "" and rulematch(WHITE_IP,rule,"jo") then + log_record('White_IP',ngx.var_request_uri,"_","_") + return true + end + end + end + end +end + +--deny black ip +function black_ip_check() + if config_black_ip_check == "on" then + local IP_BLACK_RULE = get_rule('blackip') + local BLACK_IP = get_client_ip() + if IP_BLACK_RULE ~= nil then + for _,rule in pairs(IP_BLACK_RULE) do + if rule ~= "" and rulematch(BLACK_IP,rule,"jo") then + log_record('BlackList_IP',ngx.var_request_uri,"_","_") + if config_waf_enable == "on" then + ngx.exit(403) + return true + end + end + end + end + end +end + +--allow white url +function white_url_check() + if config_white_url_check == "on" then + local URL_WHITE_RULES = get_rule('whiteurl') + local REQ_URI = ngx.var.request_uri + if URL_WHITE_RULES ~= nil then + for _,rule in pairs(URL_WHITE_RULES) do + if rule ~= "" and rulematch(REQ_URI,rule,"jo") then + return true + end + end + end + end +end + +--deny cc attack +function cc_attack_check() + if config_cc_check == "on" then + local USER_AGENT = get_user_agent() + local ATTACK_URL = ngx.var.host .. ngx.var.request_uri + local CC_TOKEN = get_client_ip() .. "." .. ngx.md5(ATTACK_URL .. USER_AGENT) + local limit = ngx.shared.limit + local CCcount=tonumber(string.match(config_cc_rate,'(.*)/')) + local CCseconds=tonumber(string.match(config_cc_rate,'/(.*)')) + local req,_ = limit:get(CC_TOKEN) + if req then + if req > CCcount then + log_record('CC_Attack',ngx.var.request_uri,"-","-") + if config_waf_enable == "on" then + waf_output() + ngx.exit(403) + end + else + limit:incr(CC_TOKEN,1) + end + else + limit:set(CC_TOKEN,1,CCseconds) + end + end + return false +end + +--deny cookie +function cookie_attack_check() + if config_cookie_check == "on" then + local COOKIE_RULES = get_rule('cookie') + local USER_COOKIE = ngx.var.http_cookie + if USER_COOKIE ~= nil then + for _,rule in pairs(COOKIE_RULES) do + if rule ~="" and rulematch(USER_COOKIE,rule,"jo") then + log_record('Deny_Cookie',ngx.var.request_uri,"-",rule) + if config_waf_enable == "on" then + waf_output() + return true + end + end + end + end + end + return false +end + +--deny url +function url_attack_check() + if config_url_check == "on" then + local URL_RULES = get_rule('blackurl') + local REQ_URI = ngx.var.request_uri + for _,rule in pairs(URL_RULES) do + if rule ~="" and rulematch(REQ_URI,rule,"jo") then + log_record('Deny_URL',REQ_URI,"-",rule) + if config_waf_enable == "on" then + waf_output() + return true + end + end + end + end + return false +end + +--deny url args +function url_args_attack_check() + if config_url_args_check == "on" then + local ARGS_RULES = get_rule('args') + for _,rule in pairs(ARGS_RULES) do + local REQ_ARGS = ngx.req.get_uri_args() + for key, val in pairs(REQ_ARGS) do + if type(val) == 'table' then + ARGS_DATA = table.concat(val, " ") + else + ARGS_DATA = val + end + if ARGS_DATA and type(ARGS_DATA) ~= "boolean" and rule ~="" and rulematch(unescape(ARGS_DATA),rule,"jo") then + log_record('Deny_URL_Args',ngx.var.request_uri,"-",rule) + if config_waf_enable == "on" then + waf_output() + return true + end + end + end + end + end + return false +end +--deny user agent +function user_agent_attack_check() + if config_user_agent_check == "on" then + local USER_AGENT_RULES = get_rule('useragent') + local USER_AGENT = ngx.var.http_user_agent + if USER_AGENT ~= nil then + for _,rule in pairs(USER_AGENT_RULES) do + if rule ~="" and rulematch(USER_AGENT,rule,"jo") then + log_record('Deny_USER_AGENT',ngx.var.request_uri,"-",rule) + if config_waf_enable == "on" then + waf_output() + return true + end + end + end + end + end + return false +end + +--deny post +function post_attack_check() + if config_post_check == "on" then + local POST_RULES = get_rule('post') + for _,rule in pairs(ARGS_RULES) do + local POST_ARGS = ngx.req.get_post_args() + end + return true + end + return false +end diff --git a/lib.lua b/lib.lua new file mode 100644 index 0000000..b30e3db --- /dev/null +++ b/lib.lua @@ -0,0 +1,84 @@ +--waf core lib +require 'config' + +--Get the client IP +function get_client_ip() + CLIENT_IP = ngx.req.get_headers()["X_real_ip"] + if CLIENT_IP == nil then + CLIENT_IP = ngx.req.get_headers()["X_Forwarded_For"] + end + if CLIENT_IP == nil then + CLIENT_IP = ngx.var.remote_addr + end + if CLIENT_IP == nil then + CLIENT_IP = "unknown" + end + return CLIENT_IP +end + +--Get the client user agent +function get_user_agent() + USER_AGENT = ngx.var.http_user_agent + if USER_AGENT == nil then + USER_AGENT = "unknown" + end + return USER_AGENT +end + +--Get WAF rule +function get_rule(rulefilename) + local io = require 'io' + local RULE_PATH = config_rule_dir + local RULE_FILE = io.open(RULE_PATH..'/'..rulefilename,"r") + if RULE_FILE == nil then + return + end + RULE_TABLE = {} + for line in RULE_FILE:lines() do + table.insert(RULE_TABLE,line) + end + RULE_FILE:close() + return(RULE_TABLE) +end + +--WAF log record for json,(use logstash codec => json) +function log_record(method,url,data,ruletag) + local cjson = require("cjson") + local io = require 'io' + local LOG_PATH = config_log_dir + local CLIENT_IP = get_client_ip() + local USER_AGENT = get_user_agent() + local SERVER_NAME = ngx.var.host + local LOCAL_TIME = ngx.localtime() + local log_json_obj = { + client_ip = CLIENT_IP, + local_time = LOCAL_TIME, + server_name = SERVER_NAME, + req_url = url, + attack_method = method, + req_data = data, + rule_tag = ruletag, + user_agent = USER_AGENT, + } + local LOG_LINE = cjson.encode(log_json_obj) + local LOG_NAME = LOG_PATH..'/'..ngx.today().."_sec.log" + local file = io.open(LOG_NAME,"a") + if file == nil then + return + end + file:write(LOG_LINE.."\n") + file:flush() + file:close() +end + +--WAF return +function waf_output() + if config_waf_output == "redirect" then + ngx.redirect(config_waf_redirect_url, 301) + else + ngx.header.content_type = "text/html" + ngx.status = ngx.HTTP_FORBIDDEN + ngx.say(config_output_html) + ngx.exit(ngx.status) + end +end diff --git a/wafconf/args b/wafconf/args new file mode 100644 index 0000000..d5bf8e8 --- /dev/null +++ b/wafconf/args @@ -0,0 +1,22 @@ +\.\./ +\:\$ +\$\{ +select.+(from|limit) +(?:(union(.*?)select)) +having|rongjitest +sleep\((\s*)(\d*)(\s*)\) +benchmark\((.*)\,(.*)\) +base64_decode\( +(?:from\W+information_schema\W) +(?:(?:current_)user|database|schema|connection_id)\s*\( +(?:etc\/\W*passwd) +into(\s+)+(?:dump|out)file\s* +group\s+by.+\( +xwork.MethodAccessor +(?: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)\( +xwork\.MethodAccessor +(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/ +java\.lang +\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[ +\<(iframe|script|body|img|layer|div|meta|style|base|object|input) +(onmouseover|onerror|onload)\= diff --git a/wafconf/blackip b/wafconf/blackip new file mode 100644 index 0000000..e69de29 diff --git a/wafconf/blackurl b/wafconf/blackurl new file mode 100644 index 0000000..0eccfec --- /dev/null +++ b/wafconf/blackurl @@ -0,0 +1,6 @@ +\.(htaccess|bash_history) +\.(bak|inc|old|mdb|sql|backup|java|class|tgz|gz|tar|zip)$ +(phpmyadmin|jmx-console|admin-console|jmxinvokerservlet) +java\.lang +\.svn\/ +/(attachments|upimg|images|css|uploadfiles|html|uploads|templets|static|template|data|inc|forumdata|upload|includes|cache|avatar)/(\\w+).(php|jsp) diff --git a/wafconf/cookie b/wafconf/cookie new file mode 100644 index 0000000..30554ca --- /dev/null +++ b/wafconf/cookie @@ -0,0 +1,20 @@ +\.\./ +\:\$ +\$\{ +select.+(from|limit) +(?:(union(.*?)select)) +having|rongjitest +sleep\((\s*)(\d*)(\s*)\) +benchmark\((.*)\,(.*)\) +base64_decode\( +(?:from\W+information_schema\W) +(?:(?:current_)user|database|schema|connection_id)\s*\( +(?:etc\/\W*passwd) +into(\s+)+(?:dump|out)file\s* +group\s+by.+\( +xwork.MethodAccessor +(?: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)\( +xwork\.MethodAccessor +(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/ +java\.lang +\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[ diff --git a/wafconf/post b/wafconf/post new file mode 100644 index 0000000..3b2365b --- /dev/null +++ b/wafconf/post @@ -0,0 +1,20 @@ +\.\./ +select.+(from|limit) +(?:(union(.*?)select)) +having|rongjitest +sleep\((\s*)(\d*)(\s*)\) +benchmark\((.*)\,(.*)\) +base64_decode\( +(?:from\W+information_schema\W) +(?:(?:current_)user|database|schema|connection_id)\s*\( +(?:etc\/\W*passwd) +into(\s+)+(?:dump|out)file\s* +group\s+by.+\( +xwork.MethodAccessor +(?: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)\( +xwork\.MethodAccessor +(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/ +java\.lang +\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[ +\<(iframe|script|body|img|layer|div|meta|style|base|object|input) +(onmouseover|onerror|onload)\= diff --git a/wafconf/useragent b/wafconf/useragent new file mode 100644 index 0000000..b3edddf --- /dev/null +++ b/wafconf/useragent @@ -0,0 +1 @@ +(HTTrack|harvest|audit|dirbuster|pangolin|nmap|sqln|-scan|hydra|Parser|libwww|BBBike|sqlmap|w3af|owasp|Nikto|fimap|havij|PycURL|zmeu|BabyKrokodil|netsparker|httperf|bench) diff --git a/wafconf/whiteip b/wafconf/whiteip new file mode 100644 index 0000000..7b9ad53 --- /dev/null +++ b/wafconf/whiteip @@ -0,0 +1 @@ +127.0.0.1 diff --git a/wafconf/whiteurl b/wafconf/whiteurl new file mode 100644 index 0000000..00b54a5 --- /dev/null +++ b/wafconf/whiteurl @@ -0,0 +1,2 @@ +\.(js|css)$ +\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$