MENU

PWNHub公开赛 傻 fufu的工作日

题目不知道有没有关 地址在这:http://54.223.120.147:8088/
超菜 花钱绕过了php解密 还是做不来

自己的进度

看到题目 应该是文件上传 尝试了一下发现都不行
扫目录发现了源码 .bak 但是是加密的 花钱去解密了 不过据说考点是解密
一共两个文件 不过最关键的代码 就下面这段

public function upload()
    {
        if (empty($_FILES[$this->field])) {
            return $this->error('上传文件为空');
        }
        if (is_array($_FILES[$this->field]['error'])) {
            return $this->error('一次只能上传一个文件');
        }
        if ($_FILES[$this->field]['error'] != UPLOAD_ERR_OK) {
            return $this->error($this->codeToMessage($_FILES[$this->field]['error']));
        }
        $filename = !empty($_POST[$this->field]) ? $_POST[$this->field] : $_FILES[$this->field]['name'];
        if (!is_array($filename)) {
            $filename = explode('.', $filename);
        }
        foreach ($filename as $name) {
            if (preg_match('#[<>:"/\\|?*.]#is', $name)) {
                return $this->error('文件名中包含非法字符');
            }
        }
        if ($_FILES[$this->field]['size'] > $this->allow_size) {
            return $this->error('你上传的文件太大');
        }
        if (!in_array($filename[count($filename) - 1], $this->allow_ext)) {
            return $this->error('只允许上传图片文件');
        }
        // 用.分割文件名,只保留首尾两个字符串,防御Apache解析漏洞
        $origin_name = current($filename);
        $ext = end($filename);
        $new_name = ($this->new_name ? $this->new_name : $origin_name) . '.' . $ext;
        $target_fullpath = $this->dist_path . DIRECTORY_SEPARATOR . $new_name;
        // 创建目录
        if (!is_dir($this->dist_path)) {
            mkdir($this->dist_path);
        }
        if (is_uploaded_file($_FILES[$this->field]['tmp_name']) && move_uploaded_file($_FILES[$this->field]['tmp_name'], $target_fullpath)) {
            // Success upload
        } elseif (rename($_FILES[$this->field]['tmp_name'], $target_fullpath)) {
            // Success upload
        } else {
            return $this->error('写入文件失败,可能是目标目录不可写');
        }
        return ['name' => $origin_name, 'filename' => $new_name, 'type' => $ext];
    }

不过做的时候 思路偏了 一直在想 怎么去绕过 in_array()
最后也发现 0 确实可以绕过 in_array()

看完大佬的 Write-Up

然后看了WP 之后才知道 正真的问题在 下面那段代码的 count()

if (!in_array($filename[count($filename) - 1], $this->allow_ext)) {
    return $this->error('只允许上传图片文件');
}

忽略了一点 $filename[count($filename) - 1] 的结果是可以伪造的

假设 count($filename) == 3
那么结果 $filename[2]
但是数组是可控的 我们可以传入这样的数组
$filename = ["0" => "1", "2" => "jpg", "3" => "php"]
这样 $filename[2] == "jpg" 成功绕过

然后我们看代码 可以知道重命名之后的后缀名是传入的数组的最后一个值
这样就能把后缀名改成 .php
上传的数据可以这么改 至于为啥用了 show_flag()
php有一个函数 get_defined_functions() 可以查看定义的函数

mark

flag:pwnhub{flag:ec8ae6e67b7e4369e49075426e5e47ef}

Tags: WEB
Archives QR Code
QR Code for this page
Tipping QR Code