728x90
반응형
이번에는 드림핵의 robot only문제를 한번 풀이해보겠다.
아래의 문제 코드이다.
#!/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()
이 코드는 robot으로 verify 한 후 gamble을 통해서 돈을 얻어서 flag를 얻는 것이다.
verify는 주어진 문자열을 빠르게 입력하면 되고, gamble에서는 음수 입력이 가능해서 -100000000000000 를 해서 잃으면 1000000000000000 만큼 얻을 수 있다.
하지만 verify는 시간 제한이 있기 때문에 파이썬 코드를 아래와 같이 짜서 verify 후 interactive()를 이용해서 사용자 입력 모드로 전환하여 나머지 작업을 할 수 있게 한다.
from pwn import *
import time
r = remote("host3.dreamhack.games",24360)
r.recv()
sleep(0.1)
r.sendline(b"2")
recv_str = r.recv()[24:-4]
r.sendline(recv_str)
r.interactive()
이제 이를 이용하여 아래와 같이 flag를 획득할 수 있다.
728x90
반응형
'Cryptography' 카테고리의 다른 글
Dreamhack - d (writeup) (0) | 2023.02.22 |
---|---|
Dreamhack - ICM2022(writeup) (0) | 2023.02.22 |
Dreamhack - darimchal_001(writeup) (0) | 2023.02.22 |
Cryptography(암호학) - Hash(해시) (0) | 2021.12.26 |
Cryptography(암호학) - RSA(공개키 암호) (0) | 2021.12.23 |