许久没打安全比赛了,Tencent跟上交的oops战队联合举办,应该属于高级别赛事了,希望以后真正能好好参加。前12名可以参加决赛,第一获得世界Defcon资格。 (总计48h)
题目跟排名一览:


特别要指出的是ROIS 这个队,主要成员来自福州大学。 上次LCTF也是他们一枝独秀。还是很令人佩服的(前12进决赛)
0x00.ezDoor
一般web的题目,直接给裸php代码,都属于比较难或很难的,因为没有其他突破口,只能硬看。如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| <?php
error_reporting(0);
$dir = 'sandbox/' . sha1($_SERVER['REMOTE_ADDR']) . '/'; if(!file_exists($dir)){ mkdir($dir); } if(!file_exists($dir . "index.php")){ touch($dir . "index.php"); }
function clear($dir){ if(!is_dir($dir)){ unlink($dir); return; } foreach (scandir($dir) as $file) { if (in_array($file, [".", ".."])) { continue; } unlink($dir . $file); } rmdir($dir); }
switch ($_GET["action"] ?? "") { case 'pwd': echo $dir; break; case 'phpinfo': echo file_get_contents("phpinfo.txt"); break; case 'reset': clear($dir); break; case 'time': echo time(); break; case 'upload': if (!isset($_GET["name"]) || !isset($_FILES['file'])) { break; }
if ($_FILES['file']['size'] > 100000) { clear($dir); break; }
$name = $dir . $_GET["name"]; if (preg_match("/[^a-zA-Z0-9.\/]/", $name) || stristr(pathinfo($name)["extension"], "h")) { break; } move_uploaded_file($_FILES['file']['tmp_name'], $name); $size = 0; foreach (scandir($dir) as $file) { if (in_array($file, [".", ".."])) { continue; } $size += filesize($dir . $file); } if ($size > 100000) { clear($dir); } break; case 'shell': ini_set("open_basedir", "/var/www/html/$dir:/var/www/html/flag"); include $dir . "index.php"; break; default: highlight_file(__FILE__); break; }
|
上来就是sandbox,真是醉了。 不过好在我们去年已经经历(挨揍)过了hitcon,所以还是有勇气看看的。简单翻译了一下。核心应该是在upload ,尝试口get请求发送
尝试action=pwd ,输出sandbox/92cac2f823b26b6f275f9f9e25f1aad26cb07f73/ ,ip不变的话,目录是固定的
尝试phpinfo

尝试upload ,但是我的工具机被关了。。pc的firefox更新到58老的工具都不能用了。。蛋疼
0x01.Easy User Manage System
Welcome to the Easy UMS. Click Here
P.S. The waf doesn’t matter. (不用花式绕WAF了,是好事)
进来登录页面。有注册跟登录。 来到register.php

这里很有新意。。验证码是通过http请求发到80端口? 问题是我走的vpn连接。。主机权限根本不在我这,我怎么捕获到remoteIP:80 的信息呢。
0x02.h4x0rs.club 1(什么鬼名字)
Flag is biography of the administrator. There are more than one way to get this flag.
h4x0rs.club

这题看起来挺有意思?居然是个很友好界面的小游戏,验证码算出来之后注册进去。。最后得知admin 陷阱即可
0x03.h4x0rs.club 2(加强)
Get document.cookie of the administartor.
h4x0rs.club
跟上一关一样的地址,说明
0x04.h4x0rs.space(变种)
I’ve made a blog platform let you write your secret.
Nobody can know it since I enabled all of modern web security mechanism, is it cool, huh?
Get document.cookie of the admin.
h4x0rs.space
博客留言系统,又出现了document.cookie ,它说网站采用了新的安全机制,是什么呢?

可以写标题,内容,上传图片。下面有个反馈信息。我估计两个关卡,第一个是图片上传,第二个是下面的report,先试试正常效果。

效果倒是不错,下面有一个一维码。。唔,对比看看?
0x05.login me
Hi, I’ve been learning NodeJS for a day!!!
I’m trying to make a simple login page with this awesome language, can you please check it out.
LoginMe1
给一个网址,界面登录如下。。输常见或空或admin 进入都是提示ok(html)

一个js源码,先看源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| var express = require('express') var app = express()
var bodyParser = require('body-parser') app.use(bodyParser.urlencoded({}));
var path = require("path"); var moment = require('moment'); var MongoClient = require('mongodb').MongoClient; var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) { if (err) throw err; dbo = db.db("test_db"); var collection_name = "users"; var password_column = "password_"+Math.random().toString(36).slice(2) var password = "XXXXXXXXXXXXXXXXXXXXXX"; var myobj = { "username": "admin", "last_access": moment().format('YYYY-MM-DD HH:mm:ss Z')}; myobj[password_column] = password; dbo.collection(collection_name).remove({}); dbo.collection(collection_name).update( { name: myobj.name }, myobj, { upsert: true } );
app.get('/', function (req, res) { res.sendFile(path.join(__dirname,'index.html')); }) app.post('/check', function (req, res) { var check_function = 'if(this.username == #username# && #username# == "admin" && hex_md5(#password#) == this.'+password_column+'){\nreturn 1;\n}else{\nreturn 0;}';
for(var k in req.body){ var valid = ['#','(',')'].every((x)=>{return req.body[k].indexOf(x) == -1}); if(!valid) res.send('Nope'); check_function = check_function.replace( new RegExp('#'+k+'#','gm') ,JSON.stringify(req.body[k])) } var query = {"$where" : check_function}; var newvalue = {$set : {last_access: moment().format('YYYY-MM-DD HH:mm:ss Z')}} dbo.collection(collection_name).updateOne(query,newvalue,function (e,r){ if(e) throw e; res.send('ok'); }); }) app.listen(8081) });
|
WEB题来说,我觉得还是挺有意思的,基本都是登录或者上传题。虽然除了