长亭WAF绕过测试

本文的Bypass WAF 的核心思想在于,一些 WAF 产品处于降低误报考虑,对用户上传文件的内

容不做匹配,直接放行

0、环境

环境:两台服务器,一台配置宝塔面板,一台配置长亭雷池WAF

思路主要围绕:multipart/form-data,也就是主要针对于 POST 参数,对于漏洞点在 GET 参数位置则用处不大。

我们知道,HTTP 协议 POST 请求,除了常规的application/x-www-form-urlencoded以外,还有multipart/form-data这种形式,主要是为了解决上传文件场景下文件内容较大且内置字符不可控的问题。multipart/form-data格式也是可以传递 POST 参数的。对于 Nginx+PHP 的架构,Nginx 实际上是不负责解析multipart/form-data的body部分的,而是交由 PHP 来解析,因此 WAF 所获取的内容就很有可能与后端的 PHP 发生不一致。

1、multipart/form-data特性

以 PHP 为例,我们写一个简单的测试脚本:

<?php
echo "POST Content:\n";
echo file_get_contents("php://input");echo "\n\n";
echo "\$_POST Content:  \n";
var_dump($_POST);echo "\n\n";
echo "\$_FILES Content: \n";
var_dump($_FILES);
?>

先使用BP来进行一些测试,以便了解一些特性

这是在Content_Type:application/x-www-form-urlencoded情况下的一个request和response

然后,在观察一下Content-Type:multipart/form-data的情况:

参数并没有进入$_FILES 数组,而是进入了$_POST 数组。

可以发现将Content-Type改成传输文件,并且在没有filename参数的情况下,我们是可以将文件内容传输为POST参数的。而正常情况下,传输文件还需要有一个filename参数,有了个参数,才会将文件内容装载成文件

那么,何时是上传文件?何时是 POST 参数呢?这个关键点在于有没有一个完整的 filename=。这 9 个字符是经过反复测试的,缺一个字符不可,替换一个字符也不可,在其中添加一个字符更不可。

加上了 filename=以后的效果:

Bypass WAF 的核心思想在于,一些 WAF 产品处理降低误报考虑,对用户上传文件的内容不做匹配,直接放行。事实上,这些内容在绝大多数场景也无法引起攻击。但关键问题在于,WAF 能否准确有效识别出哪些内容是传给$_POST 数组的,哪些传给$_FILES 数组?如果不能,那我们是否就可以想办法让 WAF 以为我们是在上传文件,而实际上却是在 POST 一个参数,这个参数可以是命令注入、SQL 注入、SSRF 等任意的一种攻击,这样就实现了通用 WAF Bypass。

小结:通过上传文件时,不使用filename=,来使文件内容传递给$_POST数组,通过这样就可以达到POST传参并且不会绕过WAF的目的

2、基础绕过

可以看到当我们进行sql注入时,是会对我们进行阻拦的

可以考虑某些绕过去进行单一规则绕过,但是进行到下一条语句时,很有可能需要重新去尝试绕过的规则。所以我们可以想象通用性绕过。

那么利用multipart/form-data的特性来绕过,但是发现WAF还是检测到了。

尝试一下其他方法

0x00截断filename

在 filename 前加入了 0x00,因为有些 WAF 在检测前会删除 HTTP 协议中的 0x00、空格,这样就导致了 WAF 认为是含有 filename 的普通上传,而后端 PHP 则认为是 POST 参数。空格也可以试试

但是在长亭的雷池WAF中并没有绕过

双写上传描述行

双写描述行后,一些 WAF 会取第二行,而实际 PHP 会获取第一行。

在没有\t,00,20的破坏下,WAF取第二行,而PHP取第一行

可以看到使用双写描述行的方法成功绕过了WAF

双写整个 part 开头部分

原理与双写上传描述行类似,但是可惜的是并没有绕过

但是当两个part头中的空格去除时,就能成功

个人理解为有空格的情况下,那么这两个part头是分开的个体,而当空格去除时,这两个part头就合成一个part头了,只是它们的赋值语句重复了,那么就取决于赋值语句的选取第一个还是第二个

需要注意的是,如果双写part头能成功,那么就需要考虑它的一些垃圾数据的影响,因为该参数会引入一些垃圾数据,在命令注入及 SQL 注入的攻击场景,需要尽可能将前面的内容闭合。

构造假的 part 部分 1

原理都是相似的

可以看到POST内容的开始是由--a决定的,而结束是由--a--决定的,那么是否可以构造两个开始来影响WAF的决定呢?

通过测试可以发现雷池WAF取得是第二个,还是覆盖那一套。而php则是取得第一个

当然,php取得第一个开始,那么第二个开始是会成为垃圾数据,所以需要注意引号的闭合

构造假的 part 部分 2

与构造part部分1相比缺少了一个空行,但是我觉得这还是将两个开始合成一个开始,考虑的是对于语句的复写选择,但相比于构造1的好处是数据会纯净许多

两个 boundary

写两个boundary,思路是考虑WAF与PHP后端的选择差异

测试发现,PHP后端选择的是第一个boundary,那么思考的点就是WAF的取值是否是第二个

很遗憾,WAF的取值貌似也是第一个,并不能绕过。

有一点疑惑是PHP取得是第一个boundary,即a,那么WAF不管取得是第一个还是第二个,它的参数应该是都含有-1' union select user(),database()#这个危险语句的。只是取一个是该语句,而取第二个只是包含该语句。因此在我看来这个方法无论如何都是无法成功

解决了,第二个boundary是具有filename的,也就是如果WAF取第二个那就不会检测内容

两个 Content-Type

与两个boundary类似,使用了两个Conten-Type

可以看到PHP取得还是第一个并且WAF也是第一个,所以没有成功

空 boundary

也就是说boundary并不设值,而结束符是分号;,那么是否可以引起歧义。因为作为最后一个

参数,它有没有分号都是不影响的。

这边的原理是让WAF认为boundary为分号,而PHP是将boundary认为是空

很遗憾,并没有成功

空格 boundary

原理与空boundary类似,想让WAF认为是空

但是也没有成功

boundary 中的逗号

boundary遇到逗号,结束,同理是否可以让WAF认为是a,b

或者以逗号,,来让WAF认为分界为逗号,,而实际是空值

失败

3、进阶绕过

0x00截断进阶

从前面可知,0x00对于一些WAF来说可能会先删除在检测,而PHP又是自动选择第一行,所以在基础的0x00截断中并没有成功将filename=截断

进阶的内容就是,当我们在适当的地方加入0x00、空格和\t后,就会破坏第一行,让PHP反以第二行为主

这三个位置为首选:替换成0x00、0x20同理

此外还有:

最容易被忽视的是参数名中的 0x00

由此测试还有一个十分鸡肋的方式,用处不大,但有意思。只有当网站获取全部 POST 数组

后以参数前缀来取值的场景才可利用,因为参数名后缀部分不可控。

在三个首选位置中,最后一个位置成功了

boundary 进阶

boundary 的名称是可以前后加入任意内容的,WAF 如果严格按 boundary 去取,又要上当了。

通过空格去破坏Content-Type,使PHP取第二个,WAF取一个。但是比较吃Nginx的版本

很可惜的是WAF并没有取后面的b

单双引号混合进阶

通过不规范的单双引号破坏,使PHP取第二个,WAF取第一个

WAF也取了第二个,失败

urlencoded 伪装成为 multipart

这个 poc 很特殊。实际上是 urlencoded,但是伪装成了 multipart,通过&来截取前后装饰部分,保留 id 参数的完整性。理论上 multipart/form-data 下的内容不进行 urldecoded,一些 WAF 也正是这样设计的,这样做本没有问题,但是如果是 urlencoded 格式的内容,不进行 url 解码就会引入%0a 这样字符,而这样的字符不解码是可以直接绕过防护规则的,从而导致了绕过。

也就是说,它想要通过urlencoded去传递参数,而传递的这三个参数构成了form-data的一个样子

由于版本限制,并不能直接按照上图做

猜测它的想法应该是想要利用WAF自动去补齐,然后去第二个Content-Type,那我直接补齐试试

很遗憾没有成功。

4、高阶绕过

skip_upload 进阶 1

在 PHP 中,实际上是有一个 skip_upload 来控制上传行是否为上传文件的。来看这样一个例子:

前面内容中我们介绍了,如果在第一行的 Content-Disposition 位置添加\0,是有可能引起第一行失效,从而从上传文件变为 POST 参数的。

除此以外,我们来看一下php源码 php-5.3.3/main/rfc1867.c,其中 line: 991 有这样一段内容

if (!skip_upload) {char *tmp = param;long c = 0;while (*tmp) {if (*tmp == '[') {c++;} else if (*tmp == ']') {c--;if (tmp[1] && tmp[1] != '[') {skip_upload = 1;break;}}if (c < 0) {skip_upload = 1;break;}tmp++; }
}

其中的 param 参数是 name="f" 也就是 id 这个参数,那么请问,如何能让它 skip_upload

呢?

没错,一些理解代码含义的同学应该已经有答案了。通过想办法进入 c < 0,c 原本是0,遇到[就自增 1,遇到]就减一。那么,我们构造 name="f]" 即可让 c=-1 。

事实上,只要参数中有不成对匹配的左右中括号都可以引发 skip_upload。

但是长亭WAF还是没有绕过

skip_upload 进阶 2

在 php 源码 rfc1867.c line 909

/* If file_uploads=off, skip the file part */
if (!PG(file_uploads)) {
skip_upload = 1;
} else if (upload_cnt <= 0) {
skip_upload = 1;
sapi_module.sapi_error(E_WARNING, "Maximum number of allowable file uploads has been exceeded");
}

Maximum number of allowable file uploads has been exceeded ,已超过允许的最大文件上传数

如何达到 Maximum?发现在 php 5.2.12 和以上的版本,有一个隐藏的文件上传限制是在 php.ini 里没有的,就是这个 max_file_uploads 的设定,该默认值是 20, 在 php 5.2.17 的版本中该值已不再隐藏。

文件上传限制最大默认设为 20,所以一次上传最大就是 20 个文档,所以超出 20 个就会出错了。即skip_upload

那么:

看看是否能绕过,还是失败了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/145641.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【渐冻勇士的营养秘籍!这些营养素让爱更坚强】

Hey小伙伴们~&#x1f44b; 今天我们来聊聊一个温暖而坚强的话题——渐冻症患者的营养补充攻略&#xff01;&#x1f4aa; 在这个充满挑战的路上&#xff0c;合理的营养摄入就像是他们最坚实的盔甲&#xff0c;让爱与希望的光芒更加耀眼。✨ &#x1f308; ‌蛋白质&#xff1…

Altium Designer(AD)百度云下载与安装(附安装步骤)

在我们日常使用当中&#xff0c;Altium designer常常也被简称为AD&#xff0c;是一款一体化的电子产品开发系统软件&#xff0c;主要运行在Windows操作系统上。 我们通过Altium designer把原理图设计、电路仿真、PCB绘制编辑、拓扑逻辑自动布线、信号完整性分析和设计输出等技…

商业终端架构技术-未来之窗行业应用跨平台架构

未来之窗行业应用跨平台架构 以下是对未来之窗行业应用跨平台架构中客户端的稳定优势和网页跨平台性质的扩展列举&#xff1a; 一、客户端的稳定优势&#xff1a; 1. 离线可用性 - 即使在没有网络连接的…

AI与量化投资人才培养计划-连接职场 助力走在金融行业前沿

AI与量化投资人才培养计划-连接职场 助力走在金融行业前沿 人工智能&#xff08;AI&#xff09;的快速发展&#xff0c;量化投资已逐渐成为金融行业的新趋势&#xff0c;对专业人才的需求日益迫切。本文将深入探讨一项针对AI与量化投资的人才培养计划&#xff0c;旨在为金融专业…

电气自动化入门05:三相异步电动机的正反转点动控制电路

视频链接&#xff1a;3.2 电工知识&#xff1a;三相异步电动机的正反转点动控制电路_1_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1PJ41117PW?p6&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 1.断路器及其选型 1.1断路器定义、分类、表示符号 1.2.断路器功能、…

克隆GitHub仓库中的一个文件夹

要只克隆GitHub仓库中的一个文件夹&#xff0c;你可以使用 git sparse-checkout 功能。以下是具体步骤&#xff1a; 克隆仓库&#xff08;使用 --no-checkout 选项&#xff0c;避免下载所有内容&#xff09;&#xff1a; git clone --no-checkout <仓库地址> 进入克隆的…

[产品管理-29]:NPDP新产品开发 - 27 - 战略 - 分层战略与示例

目录 1. 公司战略 2. 经营战略 3. 创新战略 4. 新产品组合战略 5. 新产品开发战略 战略分层是企业规划和管理的重要组成部分&#xff0c;它涉及不同层级的战略制定和实施。以下是根据您的要求&#xff0c;对公司战略、经营战略、创新战略、新产品组合战略、新产品开发战略…

【CSS Tricks】如何做一个粒子效果的logo

效果展示 代码展示 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>粒子效果Logo</title>…

uniapp使用uview2上传图片功能

官网地址Upload 上传 | uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架 前提&#xff0c;需要下载vuew2插件 <view class"upload"><view class"u-demo-block__content"><view class"u-page__upload-item"&…

RabbitMQ08_保证消息可靠性

保证消息可靠性 一、生产者可靠性1、生产者重连机制&#xff08;防止网络波动&#xff09;2、生产者确认机制Publisher Return 确认机制Publisher Confirm 确认机制 二、MQ 可靠性1、数据持久化交换机、队列持久化消息持久化 2、Lazy Queue 惰性队列 三、消费者可靠性1、消费者…

CLI示例(V2R8至V2R19C00版本):直连二层组网直接转发【AP+上层网络,增加AP下行口有线接入】

CLI示例(V2R8至V2R19C00版本):直连二层组网直接转发【AP+上层网络,增加AP下行口有线接入】 适用于:V200R008至V200R019C00版本的AC,以及有空闲以太网口的AP。 说明:本示例基于“直连二层组网直接转发【AP+AC+出口网关】”场景来介绍如何增加AP下行口有线接入。 业务需求…

SPI 详解

介绍 串行外设接口是微控制器用来与外设&#xff08;如 SRAM、SD 卡、移位寄存器、传感器等&#xff09;通信的最常见通信协议之一。它是一种同步、全双工、基于主从的协议。它支持高速数据传输&#xff0c;并且 SPI 协议中的数据速度 (bps) 和时钟频率 (Hz) 之间存在直接关系…

[Redis][Hash]详细讲解

目录 0.前言1.常见命令1.HSET2.HGET3.HEXISTS4.HDEL5.HKEYS6.HVALS7.HGETALL8.HMGET9.HLEN10.HSETNX11.HINCRBY12.HINCRBYFLOAT 2.内部编码1.ziplist(压缩链表)2.hashtable(哈希表) 3.使用场景4.缓存方式对比1.原⽣字符串类型2.序列化字符串类型3.哈希类型 0.前言 在Redis中&am…

帧率和丢帧分析理论

一、丢帧问题概述 应用丢帧通常指的是在应用程序的界面绘制过程中&#xff0c;由于某些原因导致界面绘制的帧率下降&#xff0c;从而造成界面卡顿、动画不流畅等问题。以60Hz刷新率为例子&#xff0c;想要达到每秒60帧&#xff08;即60fps&#xff09;的流畅体验&#xff0c;每…

鹏哥C语言复习——函数栈帧的创建和销毁

目录 演示用代码&#xff1a; 提示&#xff1a;后文讲解时后缀为h的指的是16进制表示 疑惑1&#xff1a;自定义函数、库函数都是在main函数内部调用&#xff0c;那么是什么调用了main函数呢&#xff1f; 疑惑2&#xff1a;如何观察ebp、esp等寄存器的运行&#xff1f; 疑惑…

提升效率的AI工具集 - 轻松实现自动化

在这个快节奏、高效率的社会中&#xff0c;我们每个人都渴望能够找到提升工作效率的捷径。幸运的是&#xff0c;随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;越来越多的AI工具涌现出来&#xff0c;为我们提供了强大的支持。这些工具不仅能够帮助我们提高…

算法-分治和逆序

分治法&#xff08;Divide and Conquer&#xff09;是一种重要的算法设计范式&#xff0c;它通过将复杂的问题分解成更小、更易于管理和解决的子问题&#xff0c;然后递归地解决这些子问题&#xff0c;最后将子问题的解合并以得到原问题的解。分治法通常用于排序、搜索、数学计…

基于STM32F103C8T6单片机的DDS信号源设计

本设计能够输出三角波信号、方波信号和正弦波信号,主要由STM32F103C8T6最小核心板、电源供电电路模块、AD9833电路模块、矩阵按键电路模块、LCD1602液晶显示模块等组成。在设计中&#xff0c;使用STM32F103C8T6作为控制芯片&#xff0c;结合LCD1602液晶显示器&#xff0c;矩阵键…

稳了,搭建Docker国内源图文教程

大家好&#xff0c;之前分享了我的开源作品 Cloudflare Workers Proxy&#xff0c;它的作用是代理被屏蔽的地址&#xff0c;理论上支持代理任何被屏蔽的域名&#xff0c;使用方式也很简单&#xff0c;只需要设置环境变量 PROXY_HOSTNAME 为被屏蔽的域名&#xff0c;最后通过你的…

Unity多语言插件I2 Localization国际化应用

【就不收费了&#xff0c;要个关注不过分吧】 【图片来自插件官网&#xff0c;侵删】 前言 目前游戏往往都不会仅局限于国内语言&#xff0c;为了适应产品都要做国际化适配&#xff0c;因此会用到这个插件&#xff0c;这个插件要付费&#xff0c;因此请前往unity官网进行下载…