[CTF]WriteUp第33篇

[GYCTF2020]EasyThinking

思路

经过测试发现有登录有搜索有回显

但是不知道搜索的是什么,尝试注入失败
username有长度为20限制

报错Thinkphp框架,版本6.0,用集成工具测试框架漏洞失败
看WP

解题

BUUCTF:[GYCTF2020]EasyThinking_buuctf [gyctf2020]easythinking-CSDN博客

网站存在源码泄露www.zip

结合上面的Thinkphp版本,去看6.x版本的漏洞,有Thinkphp的session文件名构造漏洞,刚好有源码,分析一下

vendor\topthink\framework\src\think\session\Store.php

/*
这是thinkphp中存储会话信息的代码
关键行在$this->handler->write($sessionId, $data);
其中$sessionId是$this->getId();得到的
我们看看这个write和getId的实现
*/
public function save(): void
{
    $this->clearFlashData();

    $sessionId = $this->getId();

    if (!empty($this->data)) {
        $data = $this->serialize($this->data);

        $this->handler->write($sessionId, $data);
    } else {
        $this->handler->delete($sessionId);
    }

    $this->init = false;
}

/*
先看getId,我们可以看到,在id的判断中,
只要满足是字符串,并且长度为32,
就会认定为sessionid
*/
public function setId($id = null): void
{
    $this->id = is_string($id) && strlen($id) === 32 ? $id : md5(microtime(true) . session_create_id());
}
public function getId(): string
{
    return $this->id;
}

vendor\topthink\framework\src\think\session\driver\File.php

/*
接下来我们看write的实现
*/
public function write(string $sessID, string $sessData): bool
{
    $filename = $this->getFileName($sessID, true);
    $data     = $sessData;

    if ($this->config['data_compress'] && function_exists('gzcompress')) {
        //数据压缩
        $data = gzcompress($data, 3);
    }

    return $this->writeFile($filename, $data);
}

/*
可以看到,这是先得到$filename,在用writeFile写入的
我们先看$filename
*/
protected function getFileName(string $name, bool $auto = false): string
{
    if ($this->config['prefix']) {
        // 使用子目录
        $name = $this->config['prefix'] . DIRECTORY_SEPARATOR . 'sess_' . $name;
    } else {
        $name = 'sess_' . $name;
    }

    $filename = $this->config['path'] . $name;
    $dir      = dirname($filename);

    if ($auto && !is_dir($dir)) {
        try {
            mkdir($dir, 0755, true);
        } catch (\Exception $e) {
            // 创建失败
        }
    }

    return $filename;
}

/*
关键行为$this->config['prefix'] . DIRECTORY_SEPARATOR . 'sess_' . $name
可以看到,只是加了路径前缀,而上面的name就是$sessID
session文件名为[path]/sess_[sessid]
再看writeFile,就是很简单的写入
*/
protected function writeFile($path, $content): bool
{
    return (bool) file_put_contents($path, $content, LOCK_EX);
}

至此我们分析完毕,Thinkphp6.x的这个漏洞表现为,读取session值之后仅进行字符串和长度校验,然后拼接到sess_后面作为文件名,这就是说,我们可以构造sess值为0123456789012345678901234567.php来写入php文件,如果内容可控就可写马

从源码中也可以找到session的path

vendor\topthink\framework\src\think\session\driver\File.php

public function __construct(App $app, array $config = [])
{
    $this->config = array_merge($this->config, $config);

    if (empty($this->config['path'])) {
        $this->config['path'] = $app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . 'session' . DIRECTORY_SEPARATOR;
    } elseif (substr($this->config['path'], -1) != DIRECTORY_SEPARATOR) {
        $this->config['path'] .= DIRECTORY_SEPARATOR;
    }

    $this->init();
}

可以看到是runtime/session/sess_…
蚁剑连接

ret=127了,可能有disable_func,要用 bypass

注意

Thinkphp6.0的会话文件名构造漏洞

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇