php slim 教程,php框架slim架构上存在XXE漏洞(XXE的典型存在形式)-程序员宅基地

技术标签: php slim 教程  

现代cms框架(laraval/symfony/slim)的出现,导致现今的php漏洞出现点、原理、利用方法,发生了一些变化,这个系列希望可以总结一下自己挖掘的此类cms漏洞。

slim是一个设计思路超前的知名的php轻框架,完美结合了psr7来设计,至今用户已超过100w:

bab4db435be38de8299106d264ff7642.png

在阅读其源码的过程中,我发现其存在一个只有在框架式CMS中才会出现的漏洞。

漏洞详情

这个漏洞存在于最新版(3.0)中。

首先用conposer安装之

composer require slim/slim “^3.0@RC”

00b28169a469d478f3e4a7fe1ea35efe.png

很典型的问题,在这篇帖子里也提到过: http://zone.wooyun.org/content/19908

有时候框架会帮开发者一些他可能并不需要的『忙』,比如slimphp这里,常规的POST的content-type为application/x- www-form-urlencoded,但只要我将其修改为application/json,我就可以传入json格式的POST数据,修改为 application/xml,我就可以传入XML格式的数据。

这个特性将会导致两个问题:

WAF绕过

可能存在的XXE漏洞

WAF绕过这个肯定不用说了,常规的WAF一般只检测application/x-www-form-urlencoded的数据,一旦修改数据类型则将通杀各大WAF。

XXE是本漏洞的重点。

我们看到解析body的代码:

Default

public function __construct($method, UriInterface $uri, HeadersInterface $headers, array $cookies, array $serverParams, StreamInterface $body, array $uploadedFiles = [])

{

$this->originalMethod = $this->filterMethod($method);

$this->uri = $uri;

$this->headers = $headers;

$this->cookies = $cookies;

$this->serverParams = $serverParams;

$this->attributes = new Collection();

$this->body = $body;

$this->uploadedFiles = $uploadedFiles;

if (!$this->headers->has('Host') || $this->uri->getHost() !== '') {

$this->headers->set('Host', $this->uri->getHost());

}

$this->registerMediaTypeParser('application/json', function ($input) {

return json_decode($input, true);

});

$this->registerMediaTypeParser('application/xml', function ($input) {

return simplexml_load_string($input);

});

$this->registerMediaTypeParser('text/xml', function ($input) {

return simplexml_load_string($input);

});

$this->registerMediaTypeParser('application/x-www-form-urlencoded', function ($input) {

parse_str($input, $data);

return $data;

});

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

publicfunction__construct($method,UriInterface$uri,HeadersInterface$headers,array$cookies,array$serverParams,StreamInterface$body,array$uploadedFiles=[])

{

$this->originalMethod=$this->filterMethod($method);

$this->uri=$uri;

$this->headers=$headers;

$this->cookies=$cookies;

$this->serverParams=$serverParams;

$this->attributes=newCollection();

$this->body=$body;

$this->uploadedFiles=$uploadedFiles;

if(!$this->headers->has('Host')||$this->uri->getHost()!==''){

$this->headers->set('Host',$this->uri->getHost());

}

$this->registerMediaTypeParser('application/json',function($input){

returnjson_decode($input,true);

});

$this->registerMediaTypeParser('application/xml',function($input){

returnsimplexml_load_string($input);

});

$this->registerMediaTypeParser('text/xml',function($input){

returnsimplexml_load_string($input);

});

$this->registerMediaTypeParser('application/x-www-form-urlencoded',function($input){

parse_str($input,$data);

return$data;

});

}

实际上解析代码是作为回调函数写在Request类的构造方法里了。

可见这里直接调用了simplexml_load_string解析$input,造成XML实体注入漏洞。

所以,用slim framework 3.0开发的CMS,只要获取了POST数据,都将受到此XXE漏洞的影响。

漏洞证明

编写一个最简单的demo页面,只有一个获取POST信息并输出的功能:

Default

require 'vendor/autoload.php';

$app = new \Slim\App();

$app->post("/post", function($request, $response) {

$parsedBody = $request->getParsedBody();

print_r($parsedBody);

});

$app->run();

1

2

3

4

5

6

7

require'vendor/autoload.php';

$app=new\Slim\App();

$app->post("/post",function($request,$response){

$parsedBody=$request->getParsedBody();

print_r($parsedBody);

});

$app->run();

55a187184f5bcba7e9f7d482149d708d.png

触发XXE漏洞并读取/etc/passwd:

a098f833f227b31bfe10580c4e8e102e.png

漏洞修复

在slimphp2中,官方是对这块进行一定处理了:

Default

/**

* Parse XML

*

* This method creates a SimpleXMLElement

* based upon the XML input. If the SimpleXML

* extension is not available, the raw input

* will be returned unchanged.

*

* @param string $input

* @return \SimpleXMLElement|string

*/

protected function parseXml($input)

{

if (class_exists('SimpleXMLElement')) {

try {

$backup = libxml_disable_entity_loader(true);

$result = new \SimpleXMLElement($input);

libxml_disable_entity_loader($backup);

return $result;

} catch (\Exception $e) {

// Do nothing

}

}

return $input;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

/**

* Parse XML

*

* This method creates a SimpleXMLElement

* based upon the XML input. If the SimpleXML

* extension is not available, the raw input

* will be returned unchanged.

*

* @param  string                  $input

* @return \SimpleXMLElement|string

*/

protectedfunctionparseXml($input)

{

if(class_exists('SimpleXMLElement')){

try{

$backup=libxml_disable_entity_loader(true);

$result=new\SimpleXMLElement($input);

libxml_disable_entity_loader($backup);

return$result;

}catch(\Exception$e){

// Do nothing

}

}

return$input;

}

不知为何在3.0版本中官方就无视这个问题了。

我猜可能有两个原因:

官方注意到了这个问题,但认为3.0版本需求的php版本在5.5以上,而错以为5.5以上的php就已经不存在XXE的隐患了。但实际上XML外部实体的解析,和php版本并无关系,而是和编译时的libxml库版本有关。

官方尚未注意到这个问题。

感觉前者的可能性较大。

所以解决方案也还是按照2中的方案进行。

【via@phith0n】注:文章来自P牛,他博客不错,对审计有兴趣的同学推荐关注。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_35149268/article/details/115424470

智能推荐

SimpleFOC(五)—— 双电机控制_loop222-程序员宅基地

文章浏览阅读7.4k次,点赞2次,收藏37次。目录一、硬件说明1、硬件清单2、硬件连接二、程序演示三、其他控制模式1、速度模式2、速度和力矩混合模式 一、硬件说明1、硬件清单序号名称数量1Arduino UNO12simpleFOCShield V2.0.323带磁编码器的云台电机2412V电源15方口USB线1如下图所示: 2、硬件连接  ⑴、驱动板背面跳线  两个驱动板,一个接9、5、6、8,另一个接3、10、11、7。  ⑵、编码器连接  Arduin_loop222

Linux高级IO-程序员宅基地

文章浏览阅读1k次,点赞16次,收藏20次。IO主要分为两步:第一步是等,即等待IO条件就绪。第二步是拷贝,也就是当IO条件就绪后将数据拷贝到内存或外设。任何IO的过程,都包含“等”和“拷贝”这两个步骤,但在实际的应用场景中“等”消耗的时间往往比“拷贝”消耗的时间多,因此要让IO变得高效,最核心的办法就是尽量减少“等”的时间。

python websocket-http实现fastapi-sse_sse_starlette flask-程序员宅基地

文章浏览阅读1.6k次。实现目的:因为项目从flask迁移到fastapi上,导致flask-sse无法使用期间尝试了很多websocket相关库如:starlette.websocketssse_starlette.sse import EventSourceResponse等期间踩了无数坑后来发现了websocket-client库第一步 搭建简单的fastapi 服务from fastapi import FastAPI, Requestfrom client_web import_sse_starlette flask

Am335x 应用层之SPI操作_spi_ioc_message-程序员宅基地

文章浏览阅读1w次。我们先来看一下SPI的时序图,下面的内容转自http://blog.chinaunix.net/uid-8307196-id-2032955.htmlSPI接口有四种不同的数据传输时序,取决于CPOL和CPHL这两位的组合。图1中表现了这四种时序,时序与CPOL、CPHL的关系也可以从图中看出。图1CPOL是用来决定SCK时钟信号空闲时的电平,CPOL=0,空闲_spi_ioc_message

时序预测 | MATLAB实现基于LSTM-AdaBoost长短期记忆网络结合AdaBoost时间序列预测 替换数据可以直接使用,注释清楚,适合新手_adaboost能集成lstm-程序员宅基地

文章浏览阅读858次,点赞18次,收藏21次。在金融市场、气象预测、股票走势等领域,时间序列预测一直是一个重要的问题。随着人工智能和机器学习的发展,越来越多的方法被应用于时间序列预测中。本文将介绍一种基于长短期记忆网络(LSTM)结合AdaBoost的时间序列预测方法。长短期记忆网络是一种特殊的循环神经网络,它在处理时间序列数据时表现出色。LSTM网络能够学习长期依赖关系,对于时间序列数据中的趋势和周期性变化有着较好的表现。然而,单独的LSTM网络可能无法充分捕捉时间序列数据中的复杂特征,因此需要结合其他方法进行预测。_adaboost能集成lstm

一文弄懂神经网络中的反向传播法——BackPropagation_神经元模型 反向传播-程序员宅基地

文章浏览阅读307次,点赞2次,收藏2次。最近在看深度学习的东西,一开始看的吴恩达的UFLDL教程,有中文版就直接看了,后来发现有些地方总是不是很明确,又去看英文版,然后又找了些资料看,才发现,中文版的译者在翻译的时候会对省略的公式推导过程进行补充,但是补充的又是错的,难怪觉得有问题。反向传播法其实是神经网络的基础了,但是很多人在学的时候总是会遇到一些问题,或者看到大篇的公式觉得好像很难就退缩了,其实不难,就是一个链式求导法则反复用。如果不想看公式,可以直接把数值带进去,实际的计算一下,体会一下这个过程之后再来推导公式,这样就会觉得很容易了。 _神经元模型 反向传播

随便推点

代码大全2(读书笔记10)_把一段代码放入一个命名恰当的子程序内,是说-程序员宅基地

文章浏览阅读418次。109、为未来的变化做准备  如果你预计到某个程序会被修改,你可以把预计要被改动的部分放到单独的类里,同其他部分隔离开,这是个好主意。之后你就可以只修改这个类或用新的类来取代它,而不会影响到程序的其余部分了。 110、子程序优点一-----------降低复杂度  创建子程序的一个最重要的原因,就是为了降低程序的复杂度。可能通过创建子程序来隐藏一些信息,这样你就不必再考虑这些信息了_把一段代码放入一个命名恰当的子程序内,是说

CAM 和 Grad-CAM 实现_guided_model-程序员宅基地

文章浏览阅读1.5w次,点赞9次,收藏66次。https://bindog.github.io/blog/2018/02/10/model-explanation/推荐这个博客,感觉原理讲的比较清楚。代码: 代码参考链接:https://github.com/jacobgil/keras-grad-cam 对其中有问题的地方进行了更改。from keras.applications.vgg16 import ( V..._guided_model

C# wince5.0下的插入、删除、更新源码_c#wince源码-程序员宅基地

文章浏览阅读1k次。using System;using System.Collections.Generic;using System.Text;using System.Data.SqlServerCe;using System.IO;using System.Collections;using System.Data;using System.Drawing;using System.Windo_c#wince源码

算法导论第三版 10.1-6习题答案_算法导论15.3-6答案-程序员宅基地

文章浏览阅读436次。10.1-6答案:设定两个栈为s1和s2,那么s1用来ENQUEUE(),s2用来DEQUEUE(),当然s1需要用来为DEQUEUE()操作作过渡,流程如下:(1)首先将入队元素1,2,3依次放进栈s1。此时s1元素从低到高为1,2,3,s2中暂时无元素。(2)然后依次将1,2,3从s1中弹出并且放入s2中。此时s1栈空,s2中元素从低到高依次为3,2,1(3)若此时进行还需要ENQU..._算法导论15.3-6答案

java编译提示错误_javac编译提示错误需要为 class、interface 或 enum-程序员宅基地

文章浏览阅读1k次。HelloWorld.java:1: 需要为 class、interface 或 enum锘缝ublic class HelloWorld{^1 错误这个错误出现的原因主要是在中文操作系统中,使用一贯的“javac HelloWorld.java”方式编译UTF-8(带BOM)编码的.java源文件,在没有指定编码参数(encoding)的情况下,默认是使用GBK编码。当编译器用GBK编码来编译U..._d:\jdkcode>javac helloworld.java helloworld.java:1: 错误: 需要 class、interf

spring security 集成cas单点登录核心配置及相关java代码_cas登录核心代码-程序员宅基地

文章浏览阅读3.1k次。最近项目中需要集成单点登录,所以最近研究了下,同时也在前面的章介绍了cas服务端的搭建,接下来security 集成cas 亲测可行,网上也是有很多不完整的代码,免得误导大家1.web.xml配置 kun-web contextConfigLocation classpath:webApplication.xml,classpath:application_cas登录核心代码