当前位置: 首页 > 编程日记 > 正文

PHP Multipart/form-data remote dos Vulnerability

catalog

1. Description
2. Analysis

1. Description

PHP is vulnerable to a remote denial of service, caused by repeatedly allocate memory、concatenate string、copy string and free memory when PHP parses header areas of body part of HTTP request with multipart/form-data. By sending multiple HTTP multipart requests to an affected application containing malicious header area of body part, a remote attacker could exploit this vulnerability to cause the consumption of CPU resources.
该漏洞利用PHP多次合并boundary里的参数,从而造成多次内存分配和拷贝,从而抢占CPU资源,造成性能下降。攻击者利用并发多包的方式,可以达到使目标系统拒绝服务的目的
HTTP协议中,multipart/form-data中可以包含多个报文,它们被合并在一个复杂报文中发送,每一个部分都是独立的,以':'分隔各自的参数和值,不同部分的报文通过分界字符串(boundary)连接在一起
PHP中实现了解析multipart/form-data协议的功能,在解析时,当出现一个不包含':'的行,且之前有一个有效键值对,则说明该行是上一个键值对里的值,PHP会将值拼接到上一个键值对里。在拼接的过程里,PHP进行了一次内存分配,两次内存复制,以及一次内存释放。当出现多个不包含':'的行时,PHP就会进行大量内存分配释放的操作,从而导致消耗CPU资源性能下降。短时间多次发送这类畸形请求将导致目标服务器DoS

Relevant Link:

http://www.chinaz.com/news/2015/0520/407861.shtml
https://portal.nsfocus.com/vulnerability/list/

2. Analysis

The vulnerable function is multipart_buffer_headers that is called internally by the function SAPI_POST_HANDLER_FUNC in main/rfc1867.c. SAPI_POST_HANDLER_FUNC is the entry-point function which parses body parts of HTTP request with multipart/form-data.
\php-src-master\main\rfc1867.c

SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
{..while (!multipart_buffer_eof(mbuff)){char buff[FILLUNIT];char *cd = NULL, *param = NULL, *filename = NULL, *tmp = NULL;size_t blen = 0, wlen = 0;zend_off_t offset;zend_llist_clean(&header);if (!multipart_buffer_headers(mbuff, &header)) {goto fileupload_done;}..

multipart_buffer_headers

/* parse headers */
static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
{char *line;mime_header_entry prev_entry = {0}, entry;int prev_len, cur_len;/* didn't find boundary, abort */if (!find_boundary(self, self->boundary)) {return 0;}/* get lines of text, or CRLF_CRLF *///1. Step 1. The multipart_buffer_headers executes while loop cycle to parse current body part headers, if the boundary string was found. while( (line = get_line(self)) && line[0] != '\0' ){/*2. When parseing current body part headers which is represented as (header, value), the multipart_buffer_headers function firstly call get_line function to read a line of characters, but get_line return a line when it meets character '\n', not '\r\n'. After getting a line which is stored in the variable 'line', the multipart_buffer_headers function parses the variable line. /* add header to table PHP每次读取HTTP body header中的一行*/char *key = line;char *value = NULL;if (php_rfc1867_encoding_translation()) {self->input_encoding = zend_multibyte_encoding_detector((const unsigned char *) line, strlen(line), self->detect_order, self->detect_order_size);}/* space in the beginning means same header */if (!isspace(line[0])) {//寻找":"作为key-value的分界符value = strchr(line, ':');}if (value) {*value = 0;do { value++; } while(isspace(*value)); entry.value = estrdup(value);entry.key = estrdup(key); } //3. And then, it calls zend_llist_add_element function to store entryelse if (zend_llist_count(header)) { /* If no ':' on the line, add to previous line */ /*4. In this step, the multipart_buffer_headers function thinks current line is not a new header, and current line should be append to value of prev_entry. Thus, prev_entry and current line merge into a new entry by executing the following codes: */prev_len = (int)strlen(prev_entry.value);cur_len = (int)strlen(line);entry.value = emalloc(prev_len + cur_len + 1);memcpy(entry.value, prev_entry.value, prev_len);memcpy(entry.value + prev_len, line, cur_len);entry.value[cur_len + prev_len] = '\0';entry.key = estrdup(prev_entry.key);//// free memory 
            zend_llist_remove_tail(header);} else {continue;}zend_llist_add_element(header, &entry);prev_entry = entry;}return 1;
}

0x1: The Remote Denial of Service Vulnerability

1. If value of body part header consists of n lines
2. and first character of each line is not blank character
3. and each line did constains character ':'

当满足以上条件时,multipart_buffer_headers函数会不断进行内存申请、参数解析尝试、并尝试将当前行解析出的参数归并入前一个参数键、并释放当前申请内存块

1. executes string copy operation twice, frees memory once.
2. Each time mergence of entry.value increase length of body part header's value. 每次申请的内存在不断扩大
3. thus string copy operations will cause the consumption of CPU resources, and then the service is not available.
//If n is the length of body part header's value, and copying one byte is the unit time complexity,the time complexity of multipart_buffer_headers function is O(n*m) 

0x2: example

------WebKitFormBoundarypE33TmSNWwsMphqz 
Content-Disposition: form-data; name="file"; filename="s 
a 
a 
a 
a" 
Content-Type: application/octet-stream <?php phpinfo();?> 
------WebKitFormBoundarypE33TmSNWwsMphqz 

The value of Content-Disposition consists of 5 lines, and the length of the value of Content-Disposition is 5. The multipart_buffer_headers function executes Step 2.3(内存申请、字符串复制、内存释放) 4 times

1. The first time execution copys 2 bytes
2. The second execution copys 3 bytes
3. The third time execution copys 4 bytes
4. The fourth time execution copys 5 bytes
5. Thus, the multipart_buffer_headers function executes 14 times byte copy operation. 

Default maximum size of body part is 2097152 bytes (2M), It is enough to cause the consumption of CPU resources by sending multiple HTTP multipart requests to an affected application containing malicious header area of body part.

Relevant Link:

https://bugs.php.net/bug.php?id=69364

Copyright (c) 2015 LittleHann All rights reserved

转载于:https://www.cnblogs.com/LittleHann/p/5044140.html

相关文章:

HTTP的KeepAlive是开启还是关闭?

转自&#xff1a;http://blog.csdn.net/gaogaoshan/article/details/38580013 1、KeepAlive的概念与优势 HTTP的KeepAlive就是浏览器和服务端之间保持长连接&#xff0c;这个连接是可以复用的。当客户端发送一次请求&#xff0c;收到相应内容后&#xff0c;这个连接会保持一段时…

MyBatis中jdbcType=INTEGER、VARCHAR作用

Mapper.xml中 pid #{pid,jdbcTypeINTEGER} pid #{pid} 都可以用 Mybatis中什么时候应该声明jdbcType&#xff1f; 当Mybatis不能自动识别你传入对象的类型时。 什么情况下&#xff0c;Mybatis不能自动识别我的传入类型&#xff1f; 例如&#xff1a;当你传入空值的时候。&…

我让老师失去了孩子

我永远也忘不了我的初中班主任是被我们班气得流产的。她教我们历史&#xff0c;中考前那段日子&#xff0c;由于学业紧张&#xff0c;学校又没特殊安排&#xff0c;她天天挺着大肚子给我们讲课&#xff0c;只有偶尔请假离开去医院检检查。我们班成绩不好&#xff0c;学习气氛差…

3D场景高级合成技术学习

MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch |语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09;|时长:3h 47m |大小解压后:3.61 GB 含课程文件 创建和渲染三维场景是一项艰巨的任务。但是当你需要在渲染…

Java学习总结:39(反射机制)

反射机制 JAVA中反射是动态获取信息以及动态调用对象方法的一种反射机制。 Java反射就是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意方法和属性&#xff1b;并且能改变它…

perl 编程 - 判断系统进程是否活着的方法

2019独角兽企业重金招聘Python工程师标准>>> 前言&#xff1a;我在使用perl编写CGI程序时遇到的一些问题&#xff0c;解决以后&#xff0c;记录一下我的心得&#xff0c;有心的朋友们会从中得到帮助并养成正确使用的好习惯。 perl编程中判断系统进程是否存活的方法…

2009 Competition Highlights by ICPC Live

2009 Competition Highlights by ICPC Live Links&#xff1a;http://www.youtube.com/watch?vn0oZRcAz6w0 转载于:https://www.cnblogs.com/yewei/archive/2012/09/07/2674862.html

C4D灯光照明技术学习教程

C4D的灯光照明技术 大小解压后&#xff1a;4.8G 学会用Redshift点亮3D场景&#xff0c;像专业人士一样塑造光线 灯光在任何空间都是至关重要的&#xff0c;无论是真实的还是虚拟的。它能够传递某种感觉或情感。平面设计师罗伯托冈萨雷斯观察到如此重要的方面&#xff0c;并将其…

Java学习总结:40(国际化)

国际化 所谓国际化程序指的是同一套程序代码可以在不同的国家使用&#xff0c;可以根据其应用的国家自动在项目中显示出本国的相应文字信息。 使用Locale类定义语言环境 Locale类的常用方法 No.方法类型描述1public Locale(String language,String country)构造设置使用的语…

AFNetWorking 队列请求

我们在开发过程中&#xff0c;经常会遇到有些页面不止一个网络请求&#xff0c;有时候需要两个三个甚至更多&#xff0c;这个时候我们就需要队列请求&#xff0c;下边是GET请求的多个请求放在队列里边&#xff1a; [objc] view plaincopyprint? NSURL *url [NSURL URLWithStr…

Hadoop-虚拟机环境准备

传送门&#xff1a;https://app.yinxiang.com/fx/4fdf4d09-ddc8-4c67-8bf7-cca1c913fce5

WCF实现RESTFul Web Service

共同学习了前面一些概念&#xff0c;终于开始正题了哈。RESTful的Web Service调用直观&#xff0c;返回的内容容易解析。这里先会描述一个简单的场景--Web Service提供一个方法来搜索个人信息&#xff0c;传入人名&#xff0c;返回完整个人信息。下面我们一步步用WCF实现一个RE…

VS QT插件

支持用VS编译qt工程 QT下载页&#xff1a;http://qt-project.org/downloads qt-vs-addin插件: http://download.qt-project.org/official_releases/vsaddin/qt-vs-addin-1.2.2-opensource.exe 转载于:https://www.cnblogs.com/Leo-Forest/p/3507017.html

使用AutoCAD 2021创建真实世界的土木设计项目

由工程组织创建|最后更新日期:2021年9月 时长:7h 24m | 7节| 64节讲座|视频:1280720&#xff0c;44 KHz | 大小解压后3 GB 流派:电子学习|语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; 学会快速使用AutoCAD &#xff1b;专业地制作真实世…

Java学习总结:41(文件操作类:File)

Java文件操作类&#xff1a;File 在java.io包中&#xff0c;如果要进行文件自身的操作(例如&#xff1a;创建、删除等)&#xff0c;只能依靠java.io.File类完成。 File类的常用操作方法 No.方法类型描述1public File(String pathname)构造传递完整文件操作路径2public File(F…

关于大型网站技术演进的思考(四)-存储的瓶颈4

如果数据库需要进行水平拆分&#xff0c;这其实是一件很开心的事情&#xff0c;因为它代表公司的业务正在迅猛的增长&#xff0c;对于开发人员而言那就是有不尽的项目可以做&#xff0c;虽然会感觉很忙&#xff0c;但是人过的充实&#xff0c;心里也踏实。 数据库水平拆分简单说…

2022-2028年中国环卫行业产业链深度调研及投资前景预测报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国环卫行业市场行业相关概述、中国环卫行业市场行业运行环境、分析了中国环卫行业市场行业的…

curl命令具体解释

对于windows用户假设用Cygwin模拟unix环境的话&#xff0c;里面没有带curl命令&#xff0c;要自己装&#xff0c;所以建议用Gow来模拟&#xff0c;它已经自带了curl工具&#xff0c;安装后直接在cmd环境中用curl命令就可&#xff0c;由于路径已经自己主动给你配置好了。 linux …

如何修改配置以修复ThinkPad 小红帽滚轮失效?

本人使用ThinkPad X1 Carbon超级本&#xff0c;由于近期安装了遨游浏览器(Maxthon)&#xff0c;发现其总体体验还是不错&#xff0c;但是在本机器上有个明显的Bug&#xff1a;就是小红帽的滚轮不管用。 由于就查了网上相关资料并加以试验&#xff0c;最终得以解决&#xff0c;方…

在虚幻引擎5中重塑火箭联盟——口袋联盟

流派:电子学习| MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |大小解压后:3.28 GB |时长:4h 21m 了解如何实现火箭联盟般的力学&#xff0c;并在短时间内创建最近的火箭…

Java学习总结:42(字节流和字符流)

字节流与字符流 上一节我们学习了文件操作类File&#xff0c;但是File类虽然可以操作文件&#xff0c;但是却不能操作文件的内容。如果要进行文件内容的操作&#xff0c;就必须依靠流的概念来完成。流在实际中分为输入流和输出流两种&#xff0c;输入流和输出流是一种相对的概…

用C#钩子写一个改键外挂

我的微信群——软件开发测试工程师交流群&#xff0c;欢迎扫码&#xff1a; 改键是一种习惯&#xff0c;比如在玩儿lol或者dota的时候。理论上玩儿什么游戏都可以改键。 做一个窗体&#xff08;点击Install——应用改键&#xff0c;点击Uninstall——撤销应用&#xff09;&…

Spring中WebApplicationContext

ApplicationContext是Spring的核心&#xff0c;Context我们通常解释为上下文环境&#xff0c;我想用“容器”来表述它更容易理解一 些&#xff0c;ApplicationContext则是“应用的容器”了:P&#xff0c;Spring把Bean放在这个容器中&#xff0c;在需要的时候&#xff0c;用getB…

洛谷 P1966 火柴排队

题意 给定2个等长序列a、b&#xff0c;要求通过交换使 \[\sum_{i1}^{n}(a_i-b_i)^2\] 最小。 分析 看着这个式子&#xff0c;我突然想到了方差。很明显&#xff0c;方差反应数据的波动程度&#xff0c;所以让数据集中就可以使方差变小了。而对应到这个公式&#xff0c;大方向就…

Revit结构2021-2022从零到精通

流派:电子学习| MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |大小解压后:8.6 GB 含课程文件 |时长:14h 46m 涵盖Revit结构2021-2022的基本、中级和高级功能 Revit Str…

BZOJ1922: [Sdoi2010]大陆争霸

题目&#xff1a;http://www.lydsy.com/JudgeOnline/problem.php?id1922 带限制最短路。 每个点真正的dis是max(dis[i],dis[v]),v是其保护点。 可以把题目中的保护转化为每个点的贡献。 每次扫一边连出的边做最短路把rd为0的点加入队列。 再扫一遍自己的贡献&#xff0c;更新它…

Java学习总结:43(转换流)

转换流 字节流和字符流的转换可以通过InputStreamReader、OutputStreamWriter两个类转换&#xff0c;下面是这两个类的继承结构和构造方法 名称定义构造构造方法InputStreamReaderpublic class InputStreamReader extends Readerpublic InputStreamReader(InputStream in)Out…

2022-2028年中国环保服务业投资分析及前景预测报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国环保服务行业市场行业相关概述、中国环保服务行业市场行业运行环境、分析了中国环保服务行…

一个build.xml实例

<?xml version"1.0"?> <project name"ssh" basedir"." default"usage"> <property name"name" value"ssh"/> <property name"war.dir" value"war"/> &l…

Spring Boot 2.0 常见问题总结(一)

SpringBoot2.x 依赖环境和版本新特性说明 依赖版本 jdk8 以上, Springboot2.x 用 JDK8 , 因为底层是 Spring framework5 。jar 包方式运行 SpringBoot 项目时问题 打包成jar包&#xff0c;需要增加maven依赖。 <build><plugins><plugin><groupId>org.s…