촉촉한초코칩

[Dreamhack] Robot Only 본문

Study/MISC

[Dreamhack] Robot Only

햄친구베이컨 2024. 9. 17. 20:53

 

문제 파일

#!/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. show_menu()를 호출해서 메뉴를 보여주고
  2. menu에 숫자를 입력받는다.
  3. 해당 메뉴에 따라 함수를 실행한다. 

menu는 숫자로 입력받고, 위에 숫자에 맞는 메뉴 문자열?을 선언했다. 맞는 함수를 실행하는 것 같다.

 

공격

flag 함수를 실행해보았다. 

money가 10000000000 보다 적어야 flag가 열리는 것같아서 money 값을 바꿨다. 

문제.. flag가 없음 

 

우선 로봇임을 인증하는 걸 먼저 해야 할 것 같다. https://s0scod3.tistory.com/22

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

challenge = randn224 ^ 0xdeaddeadbeefbeefcafecafe13371337DEFACED0DEFACED0

문제에서 challenge를 랜덤으로 생성하고 우리는 3초 안에 숫자를 입력해야 한다. 그런데 3초 너무 짧아서 10초로 늘리고 복붙해서 인증에 성공했다. -> nc로 접속하면 코드를 바꿀 수 없으므로 Ctrl+shift+c, Ctrl+shift+v를 통해서 잽싸게 인증한다.. 아니면 코드로 하는 방법도 있긴 함 

gamble()

배팅할 돈을 입력하고 1~5 사이에 랜덤으로 정해지는 숫자와 입력한 숫자가 같으면 돈을 얻는다. 

만약 money가 500이고, bet으로 -10000000000 입력하면, 
bet가 음수이므로 if문 money < bet 에서 false가 된다. 

랜덤 값을 못 맞추면 else문에 들어가게 되는데, bet가 음수라서 제대로 계산이 안되는 것 같다..? 

최종 money 값은 -1000000000가 된다. 

flag()

이후에 flag 함수를 실행하면 10000000000 보다 많아져서 flag가 출력된다. 

 

 

정리

  1. flag 파일이 없으므로 무조건 웹 서버에 접속해야 함 
  2. 함수 내 취약점 찾기 -> 음수 입력 시 다음 조건문의 결과가 어떻게 나오는지 생각하기 

'Study > MISC' 카테고리의 다른 글

[Dreamhack] whatsdifferent  (1) 2024.10.02
[Dreamhack] file-special-bit  (0) 2024.09.29
[Dreamhack] Snowing!  (0) 2024.09.17
[Dreamhack] addition-quiz  (0) 2024.09.11
[Dreamhack] littlevsbig  (0) 2024.09.04