Robot Only 풀이

2023. 9. 5. 18:55Dreamhack Wargame

728x90

문제 제목
문제 정보

#!/usr/bin/env python3
import random
import signal
import sys

MENU_GAMBLE     = 1
MENU_VERIFY     = 2
MENU_FLAG       = 3
MENU_LEAVE      = 4

money = 500
verified = False

def show_menu():
    print('=======================================')
    print('1. go to gamble')
    print('2. verify you\'re a robot')
    print('3. buy flag')
    print('4. leave')

def get_randn():
    return random.randint(0, 0xfffffffe)

def gamble():
    global money
    global verified

    if verified is False:
        print('you\'re are not verified as a robot ;[')
        return

    print('greetings, robot :]')

    bet = int(input('how much money do you want to bet (your money: ${0})? '.format(money)))
    if money < bet:
        print('you don\'t have enough money (your money: ${0}).'.format(money))
        return

    randn = get_randn()
    answer = randn % 5 + 1

    print('[1] [2] [3] [4] [5]')
    user_answer = int(input('pick one of the box > '))

    print('answer is [{0}]!'.format(answer))

    if user_answer == answer:
        print('you earned ${0}.'.format(bet))
        money += bet
    else:
        print('you lost ${0}.'.format(bet))
        money -= bet

    if money <= 0:
        print('you busted ;]')
        sys.exit()

class MyTimeoutError(Exception):
    def __init__(self):
        pass

def timeout_handler(signum, frame):
    raise MyTimeoutError()

def verify():
    global verified

    if verified is True:
        print('you have already been verified as a robot :]')
        return

    randn224 = (get_randn() | get_randn() << 32 | get_randn() << 64 |
                get_randn() << 96 | get_randn() << 128 | get_randn() << 160)

    challenge = randn224 ^ 0xdeaddeadbeefbeefcafecafe13371337DEFACED0DEFACED0

    signal.alarm(3)
    signal.signal(signal.SIGALRM, timeout_handler)

    try:
        print('please type this same: "{0}"'.format(challenge))
        user_challenge = input('> ')

        if user_challenge == str(challenge):
            verified = True
            print('you\'re are now verified as a robot :]')
        else:
            print('you\'re not a robot ;[')
        signal.alarm(0)

    except MyTimeoutError:
        print('\nyou failed to verify! robots aren\'t that slow ;[')

def flag():
    global money

    print('price of the flag is $10,000,000,000.')

    if money < 10000000000:
        print('you don\'t have enough money (your money: ${0}).'.format(money))
        return

    with open('./flag', 'rb') as f:
        print(b'flag is ' + f.read())
    sys.exit()

def main():
    while True:
        show_menu()
        menu = int(input('> '))

        if menu == MENU_GAMBLE:
            gamble()

        elif menu == MENU_VERIFY:
            verify()

        elif menu == MENU_FLAG:
            flag()

        elif menu == MENU_LEAVE:
            sys.exit()

        else:
            print('wrong menu :[')

if __name__ == '__main__':
    main()

 

money를 10000000000$만큼 불린 후 FLAG를 획득하는 형식으로 되어있습니다.

 

로봇 인증을 마치게 되면 게임을 진행하는 메뉴 화면으로 입장합니다.

초기 자금은 500$이며, 원하는 만큼 돈을 걸고 게임을 진행합니다.

1부터 5 사이의 수 중 하나를 고르고, 정답 여부에 따라 배팅한 돈을 얻거나 잃게 됩니다.

 

우선 문제를 풀기에 앞서, 로봇이 아닙니다! 에 대한 자동화 코드를 작성해 줍니다.

아래는 로봇 인증 코드입니다.

이 코드를 처리해 주기 위한 자동화 코드를 Python으로 작성해 줬습니다.

def verify():
    global verified

    if verified is True:
        print('you have already been verified as a robot :]')
        return

    randn224 = (get_randn() | get_randn() << 32 | get_randn() << 64 |
                get_randn() << 96 | get_randn() << 128 | get_randn() << 160)

    challenge = randn224 ^ 0xdeaddeadbeefbeefcafecafe13371337DEFACED0DEFACED0

    signal.alarm(3)
    signal.signal(signal.SIGALRM, timeout_handler)

    try:
        print('please type this same: "{0}"'.format(challenge))
        user_challenge = input('> ')

        if user_challenge == str(challenge):
            verified = True
            print('you\'re are now verified as a robot :]')
        else:
            print('you\'re not a robot ;[')
        signal.alarm(0)

    except MyTimeoutError:
        print('\nyou failed to verify! robots aren\'t that slow ;[')

 

이제 money를 불릴 방법을 찾아봐야 합니다.

코드를 잘 보면, 게임에서 패배하는 부분의 코드가 money -= bet라고 되어있습니다.

지는 경우의 수가 이기는 경우의 수보다 많기 때문에, 그냥 무지성으로 -10000000000을 넣어주면 원래 가지고 있던 money에 10000000000가 더해지면서 10000000500이 됩니다.

 

최종적으로, 위와 같은 과정을 통해 flag를 살 돈을 얻을 수 있습니다.

 

FLAG 획득 완료
문제 풀이 성공

728x90

'Dreamhack Wargame' 카테고리의 다른 글

phpMyRedis 풀이  (0) 2024.04.28
sql injection bypass WAF Advanced 풀이  (1) 2024.04.25
[CodeEngn] Malware L08 풀이  (0) 2023.08.30
crt rsa 풀이  (0) 2023.04.24
crawling 풀이  (0) 2023.04.23