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()

문제에서 제공된 코드를 살펴보면 문제풀이 순서는 다음과 같다.

1. 로봇임을 증명한다 : 출력된 숫자를 똑같이 입력

2. 1~5사이의 숫자를 찍는 gamble을 통해서 돈을 얻는다

3. 10000000000 의 돈을 내고 flag를 구매한다

 

pwntool 로 로봇인증을 시도하다가 실력 부족으로 삽질하다가, 그냥 복붙을 해봤는데 됐다..음?

 

from pwn import *

r = remote('host3.dreamhack.games', 13576)

r.recvuntil(b'> ')
r.sendline(b'2') 
 
r.recvuntil(b':')
num = r.recvline()[2:-2] 

r.sendlineafter(b'> ', num)  

r.interactive()

 

나중에 작성한 코드

 

돈을 잃으면 어떻게 되는지 확인하고 싶어서 입력을 했는데 맞춰버렸다.

잃어서 다시 500으로 돌아왔다.

이쯤에서 코드를 다시 살펴보니 배팅 금액에 대해서 가진 돈보다 작아야하는 제한만 있고 음수제한은 없는 것을 확인했다.

혹시나 해서 -200을 입력을 했는데 lost -200을 했다고 나왔다. 가진 돈을 확인해보니 700으로 늘어나있었다.

 

이제 큰 음수로 금액을 설정하고 배팅을 실패하면,

flag를 얻을 수 있다.

'Write-up > Crypto' 카테고리의 다른 글

[Dreamhack] Double DES  (0) 2024.09.20
[Dreamhack] ICM2022  (0) 2024.09.13
[Dreamhack] RSA-wiener  (1) 2024.05.01
[Dreamhack] Textbook-RSA  (0) 2024.04.08
[Dreamhack] chinese what?  (0) 2024.04.08

+ Recent posts