メインコンテンツまでスキップ
非公開のページ
このページは非公開です。 検索対象外となり、このページのリンクに直接アクセスできるユーザーのみに公開されます。

「web」タグの記事が5件件あります

全てのタグを見る

[SECCON Beginners CTF 2020] Spy

metarin

As a spy, you are spying on the "ctf4b company".

You got the name-list of employees and the URL to the in-house web tool used by some of them.

Your task is to enumerate the employees who use this tool in order to make it available for social engineering.

import os
import time

from flask import Flask, render_template, request, session

# Database and Authentication libraries (you can't see this :p).
import db
import auth

# ====================

app = Flask(__name__)
app.SALT = os.getenv("CTF4B_SALT")
app.FLAG = os.getenv("CTF4B_FLAG")
app.SECRET_KEY = os.getenv("CTF4B_SECRET_KEY")

db.init()
employees = db.get_all_employees()

# ====================

@app.route("/", methods=["GET", "POST"])
def index():
t = time.perf_counter()

if request.method == "GET":
return render_template("index.html", message="Please login.", sec="{:.7f}".format(time.perf_counter()-t))

if request.method == "POST":
name = request.form["name"]
password = request.form["password"]

exists, account = db.get_account(name)

if not exists:
return render_template("index.html", message="Login failed, try again.", sec="{:.7f}".format(time.perf_counter()-t))

# auth.calc_password_hash(salt, password) adds salt and performs stretching so many times.
# You know, it's really secure... isn't it? :-)
hashed_password = auth.calc_password_hash(app.SALT, password)
if hashed_password != account.password:
return render_template("index.html", message="Login failed, try again.", sec="{:.7f}".format(time.perf_counter()-t))

session["name"] = name
return render_template("dashboard.html", sec="{:.7f}".format(time.perf_counter()-t))

# ====================

@app.route("/challenge", methods=["GET", "POST"])
def challenge():
t = time.perf_counter()

if request.method == "GET":
return render_template("challenge.html", employees=employees, sec="{:.7f}".format(time.perf_counter()-t))

if request.method == "POST":
answer = request.form.getlist("answer")

# If you can enumerate all accounts, I'll give you FLAG!
if set(answer) == set(account.name for account in db.get_all_accounts()):
message = app.FLAG
else:
message = "Wrong!!"

return render_template("challenge.html", message=message, employees=employees, sec="{:.7f}".format(time.perf_counter()-t))

# ====================

if __name__ == '__main__':
db.init()
app.run(host=os.getenv("CTF4B_HOST"), port=os.getenv("CTF4B_PORT"))

解説

何故かログイン処理にかかった時間を表示しています 試しにタイミング攻撃をしてみると綺麗に差さりました

全員試して明らかに時間がかかった人をリストアップしていきます

[SECCON BEGINNERS CTF 2021] cant_use_db

Nakanome

Can't use DB. I have so little money that I can't even buy the ingredients for ramen. 🍜 https://cant-use-db.quals.beginners.seccon.jp/

問題

ソースコードが与えられます。 ユーザーのデータ管理がDBではなくファイルで行われている&書き込みをtime.sleepで行っています。

ramem.png は移行元に含まれていないため、画像を掲載できていません。

[SECCON Beginners CTF 2021] check_url

Nakanome

Have you ever used curl ? 想定難易度: Easy

問題

https://check-url.quals.beginners.seccon.jp/ URLとソースコードを与えられます。

check-url-source.png は移行元に含まれていないため、画像を掲載できていません。

解法

ソースコードから接続元がローカルであればフラグをもらえます。 それ以外の場合はcurlで取得したページをそのまま出力してきます。

問題の厄介な所はURLがlocalhostやapacheを含んでいるとスクリプトがdieします。 あとは /[^a-zA-Z0-9\/:]+/u以外の文字を含んでいると、スーパーサニタイジングの影響により該当部位が👻(文字)になります。

[SECCON Beginners CTF 2021] json

Nakanome

WEB json 外部公開されている社内システムを見つけました。このシステムからFlagを取り出してください。 https://json.quals.beginners.seccon.jp/

問題

ソースコードが与えられています。 この問題の肝は多分Goライブラリでのjsonのパースの違いを利用します。 BFFサーバーではリクエストのペイロードのjsonをjson.Unmarshal(body, &info);で解釈しますが、 apiサーバーではjsonparser.GetInt(body, "id")で解釈します。

[SECCON Beginners CTF 2021] osoba

shihei

美味しいお蕎麦を食べたいですね。フラグはサーバの /flag にあります!

##解説 URLのリンク先から適当なページを開きURLを見るとパラメータが?page=public/kikin.htmlとなっています。 ここを弄ってフラグファイルを相対指定してあげればよさそうですね。 配布されたファイルにはこのサイト内のファイル一式がそのままのフォルダ構造で入っており、以下のようになっています。