파일을 다운받고, 사이트에 들어가 보자.
플래그는 flag.txt 파일과 flag 변수에 있다고 한다.
코드는 이거다.
#!/usr/bin/python3
from flask import Flask, request, render_template
import re
app = Flask(__name__)
try:
FLAG = open("./flag.txt", "r").read() # flag is here!
except:
FLAG = "[**FLAG**]"
@app.route("/", methods = ["GET", "POST"])
def index():
input_val = ""
if request.method == "POST":
input_val = request.form.get("input_val", "")
m = re.match(r'dr\w{5,7}e\d+am@[a-z]{3,7}\.\w+', input_val)
if m:
return render_template("index.html", pre_txt=input_val, flag=FLAG)
return render_template("index.html", pre_txt=input_val, flag='?')
app.run(host="0.0.0.0", port=8000)
음......뭔가 입력을 해야 flag가 출력되는 듯 하다.
이 부분을 보자.
m = re.match(r'dr\w{5,7}e\d+am@[a-z]{3,7}\.\w+', input_val)
if m:
return render_template("index.html", pre_txt=input_val, flag=FLAG)
m의 값을 해석해 보자면, dr이라는 문자열이 오고, 그 뒤에 5자리부터 7자리의 문자열이 오고, 그 문자열 뒤에 e가 붙고, 또 그 뒤에 숫자 1개 이상이 오고, 그 뒤에 am@가 오고, 그 뒤에 3개부터 5개의 알파벳 소문자가 오고, 그 뒤세 .이 붙고, 그 뒤에 w+는 앞에서의 문자열 규칙(ex> 문자열 뒤에 e가 붙거나, 5자리부터 7자리의 문자열이 오거나 등등...)을 의미한다.
이를 조합해서, 위의 규칙을 따른 무작위이 문자열 하나를 만들었다.
dr12345e6am@example.com
플래그 찾음
마찬가지로, 문제 파일을 다운받고 사이트에 접속해 보자.
#!/usr/bin/python3
import os
from flask import Flask, request, render_template, redirect, url_for
import sys
app = Flask(__name__)
try:
# flag is here!
FLAG = open("./flag.txt", "r").read()
except:
FLAG = "[**FLAG**]"
@app.route("/")
def index():
return render_template("index.html")
@app.route("/step1", methods=["GET", "POST"])
def step1():
#### 풀이와 관계없는 치팅 방지 코드
global step1_num
step1_num = int.from_bytes(os.urandom(16), sys.byteorder)
####
if request.method == "GET":
prm1 = request.args.get("param", "")
prm2 = request.args.get("param2", "")
step1_text = "param : " + prm1 + "\nparam2 : " + prm2 + "\n"
if prm1 == "getget" and prm2 == "rerequest":
return redirect(url_for("step2", prev_step_num = step1_num))
return render_template("step1.html", text = step1_text)
else:
return render_template("step1.html", text = "Not POST")
@app.route("/step2", methods=["GET", "POST"])
def step2():
if request.method == "GET":
#### 풀이와 관계없는 치팅 방지 코드
if request.args.get("prev_step_num"):
try:
prev_step_num = request.args.get("prev_step_num")
if prev_step_num == str(step1_num):
global step2_num
step2_num = int.from_bytes(os.urandom(16), sys.byteorder)
return render_template("step2.html", prev_step_num = step1_num, hidden_num = step2_num)
except:
return render_template("step2.html", text="Not yet")
return render_template("step2.html", text="Not yet")
####
else:
return render_template("step2.html", text="Not POST")
@app.route("/flag", methods=["GET", "POST"])
def flag():
if request.method == "GET":
return render_template("flag.html", flag_txt="Not yet")
else:
#### 풀이와 관계없는 치팅 방지 코드
prev_step_num = request.form.get("check", "")
try:
if prev_step_num == str(step2_num):
####
prm1 = request.form.get("param", "")
prm2 = request.form.get("param2", "")
if prm1 == "pooost" and prm2 == "requeeest":
return render_template("flag.html", flag_txt=FLAG)
else:
return redirect(url_for("step2", prev_step_num = str(step1_num)))
return render_template("flag.html", flag_txt="Not yet")
except:
return render_template("flag.html", flag_txt="Not yet")
app.run(host="0.0.0.0", port=8000)
간단하다. 위의 코드 분석만 하면 된다.
if prm1 == "getget" and prm2 == "rerequest":
return redirect(url_for("step2", prev_step_num = step1_num))
return render_template("step1.html", text = step1_text)
getget과 rerequest를 입력하면 된다. 그러면 step2로 넘어간다.
마찬가지로,
if prm1 == "pooost" and prm2 == "requeeest":
return render_template("flag.html", flag_txt=FLAG)
플래그 찾음