内容简介:WAF分组安全策略匹配
糖果 2017-04-21 17:45 阅读 3 收藏 0 推荐 0
作者:糖果
上次我们做了一个WAF系统策略命中的模拟,这次新实验将要加入更复杂的集团分组策略匹配。简单说就是加入了更多更复杂的策略,为了方便演示,重新组织了策略规则的存储形式,我们用loadstring的方式,加载规则文件。实现的代码,如下:
local metadata = [[ local args = { {Id=1, RuleType="args", RuleItem="\.\./", action=1}, {Id=2, RuleType="args", RuleItem="\:\$", action=1}, {Id=3, RuleType="args", RuleItem="\$\{", action=1}, {Id=4, RuleType="args", RuleItem="select.+(from|limit)", action=1}, {Id=5, RuleType="args", RuleItem="(?:(union(.*?)select))", action=1}, {Id=6, RuleType="args", RuleItem="having|rongjitest", action=1}, {Id=7, RuleType="args", RuleItem="sleep\((\s*)(\d*)(\s*)\)", action=1}, {Id=8, RuleType="args", RuleItem="benchmark\((.*)\,(.*)\)", action=1}, {Id=9, RuleType="args", RuleItem="base64_decode\(", action=1}, {Id=10, RuleType="args", RuleItem="(?:from\W+information_schema\W)", action=1}, {Id=11, RuleType="args", RuleItem="(?:(?:current_)user|database|schema|connection_id)\s*\(", action=1}, {Id=12, RuleType="args", RuleItem="(?:etc\/\W*passwd)", action=1}, {Id=13, RuleType="args", RuleItem="into(\s+)+(?:dump|out)file\s*", action=1}, {Id=14, RuleType="args", RuleItem="group\s+by.+\(", action=1}, {Id=15, RuleType="args", RuleItem="xwork.MethodAccessor", action=1}, {Id=16, RuleType="args", RuleItem="(?: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)\(", action=1}, {Id=17, RuleType="args", RuleItem="xwork\.MethodAccessor", action=1}, {Id=18, RuleType="args", RuleItem="(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/", action=1}, {Id=19, RuleType="args", RuleItem="java\.lang", action=1}, {Id=20, RuleType="args", RuleItem="\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[", action=1}, {Id=21, RuleType="args", RuleItem="\<(iframe|script|body|img|layer|div|meta|style|base|object|input)", action=1}, {Id=22, RuleType="args", RuleItem="(onmouseover|onerror|onload)\=", action=1}, } local urls = { {Id=1, RuleType="url", RuleItem="\.(htaccess|bash_history)", action=1}, {Id=2, RuleType="url", RuleItem="\.(bak|inc|old|mdb|sql|backup|java|class|tgz|gz|tar|zip)$", action=1}, {Id=3, RuleType="url", RuleItem="(phpmyadmin|jmx-console|admin-console|jmxinvokerservlet)", action=1}, {Id=4, RuleType="url", RuleItem="java\.lang", action=1}, {Id=5, RuleType="url", RuleItem="\.svn\/", action=1}, {Id=6, RuleType="url", RuleItem="/(attachments|upimg|images|css|uploadfiles|html|uploads|templets|static|template|data|inc|forumdata|upload|includes|cache|avatar)/(\\w+).(php|jsp)", action=1}, } local useragent = { {Id=1, RuleType="useragent", RuleItem="(HTTrack|harvest|audit|dirbuster|pangolin|nmap|sqln|-scan|hydra|Parser|libwww|BBBike|sqlmap|w3af|owasp|Nikto|fimap|havij|PycURL|zmeu|BabyKrokodil|netsparker|httperf|bench)", action=1}, } return {args=args, urls=urls, cookie=cookie, useragent=useragent, post=post} ]] local script = metadata local rules = assert(loadstring(script))() return rules
我们通过最直接的可以被 lua 认识的语法方式,存储这些策略规则,接下来的任务就是将各种场景下的配对处理抽象成代码模块,数据结构已经定义完了, 看如何对这些数据进行操作。
local rules = require"meta" local matcher = {} function matcher.init(self) self.action_id = {"404","500","301"} self.match_map = { matcher_group_get = {args=0, urls=0, cookie=0, useragent=0, post=0 }, matcher_group_post= {args=0, urls=0, cookie=0, useragent=1, post=0 }, matcher_group_whiteip= {args=0, urls=0, cookie=0, useragent=0, post=0 } } self.action_seq = { {id=1, action="start", method = "GET"} , {id=2, action="start", method = "POST"}, {id=3, action="start", method = "WHITEIP"} } self.method_id = {GET="matcher_group_get", POST="matcher_group_post", WHITEIP="matcher_group_whiteip"} end function matcher.action(self, m_type, param) local group_tbl= self.match_map[m_type] for k,v in pairs(group_tbl) do if v == 1 then print(k) for key, val in pairs(rules[k]) do local regular = val["RuleItem"] if regular ~= "" and ngx.re.find(request.params.cmd_url, regular, "jo") then local id = val["action"] print(self.action_id[id]) end end end end end function matcher.match(self, param) matcher:init() for k,v in pairs(self.action_seq) do local idx = v['method'] local method = self.method_id[idx] matcher:action(method, "param") end end matcher:match("param")
我们对比一下之前在Blues框架里的模拟处理的代码,如下:
app:get("/testargs", function(request,id) local json_text = bjson.loadf("./app/data/rules/args.rule", env) local ret = bjson.decode(json_text) for _,rule in pairs(ret) do regular = rule["RuleItem"] if regular ~= "" and ngx.re.find(request.params.cmd_url, regular, "jo") then ngx.say("MATCH!") end end end)
经过数据结构模块的分离操作,我们把所有放在文件里的策略,变成了Lua的Table数据结构。然后将可能发生的用户请个场景,与在特定场景下如何进行配对进行了分层Pattern处理。
- 确认用户当前请求的场景: GET、POST、PUT等。
- 确人在特点方法下,将用户的请求的数据:URL、URI、参数、Cookie与那些策略进行配对。(args=1, urls=0, cookie=0, useragent=0, post=0 )[1:与该组策略匹配。 0:不进行匹配]
- 如果策略命中,进行预先定义好的Action响应操作。(上面的代码以print(self.action_id[id])来表示实行动作)
到此,一个较为复杂的策略命中的判断处理已经实现了, 这模块可以单成一个WAF基础项目,也可以作为框加基本的Filter模块,用于过滤用户请求中的非法数据。
下面的课题是,如何动态的维护和编辑这些策略,是采用命令行的方式,还是采用WEB界面的方式。如何将Action的拦截响应动作,交给Openresty来处理,而这些我们在尝试新的重构变化。
PS:转载到其它平台请注明作者姓名及原文链接,请勿用于商业用途。
http://www.candylab.net
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- WAF分组安全策略匹配
- Apache 反向代理及负载均衡配置+正则分组匹配
- 想写出效率更高的正则表达式?试试固化分组和占有优先匹配吧
- mybatis从数据库中取数据且分组,返回分组数据
- Java8中使用stream进行分组统计和普通实现的分组统计的性能对比
- MongoDB 分组统计
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。