Robots enjoy some strange games and we just can’t quite figure this one out. Maybe you will have better luck than us.
23.22.16.34:6969
The game offers a choice between two hex strings asking for the “bigger” one. Anyway, it doesn’t appear to be a way to determine which one is bigger just by looking at the values.
The challenge consists in winning at this game for 75 times in a row.
0 $ nc ec2-23-21-19-72.compute-1.amazonaws.com 6969 You have gotten 0 of 75 Choice 1 = 68af489d11366a85e755d95f516c48c50f Choice 2 = 9795b347f0ceb9aa35f6127cdfb7145810 Which one is bigger? ( 1 or 2) 2 2 Correct!-------------------- You have gotten 1 of 75 Choice 1 = 77c99d06baea4f703316e683a25264e3ba Choice 2 = 2dcccbe6467658ed37b35167eb9f6e3318 Which one is bigger? ( 1 or 2) 1 1 Wrong :(
After several attempts, it’s possible to see some recurrent values. Indeed, it turns out to be a finite set of hex-encoded random 17-byte strings with a strict total ordering on them. We counted 500 different strings during our experiments.
The strategy for winning is to play while keeping track of the values and sorting them on a list. The following multithread script succeeded in winning for 75 times in a row in just 1 minute and 30 seconds performing a total of 13000 requests.
#!/usr/bin/python import re import sys import time import socket import threading strings_file = "/tmp/the_game_list.txt" # order: small ----> big strings = [] run = True lock = threading . Lock () flag = "" requests = 0 def recv_tillreturn ( sock , times = 1 ): """Receive times lines of data from a socket""" total_data = [] while times > 0 : times -= 1 data = "" while 1 : char = sock . recv ( 1 ) data += char if char == " \n " : break total_data . append ( data ) return '' . join ( total_data ) def insert ( c1 , c2 ): """Insert a pair of ordered value in the strings list, where c1 > c2.""" global strings i_c1 = - 1 i_c2 = - 1 for i in range ( len ( strings )): if strings [ i ] == c1 : i_c1 = i if strings [ i ] == c2 : i_c2 = i if i_c1 == i_c2 == - 1 : # c1 and c2 not found: insert c2 in front of the list and append c1 strings . insert ( 0 , c2 ) strings . append ( c1 ) elif i_c1 != - 1 and i_c2 == - 1 : # c1 found but not c2: insert c2 just before c1 strings . insert ( i_c1 , c2 ) elif i_c1 == - 1 and i_c2 != - 1 : # c2 found but not c1: insert c1 after c2 strings . insert ( i_c2 + 1 , c1 ) else : # both c1 and c2 found: if they are already ordered in the list leave # them where they are, otherwise remove the old location of c1 and put # c1 after c2 if i_c2 > i_c1 : strings . remove ( c1 ) strings . insert ( i_c2 , c1 ) def isbigger ( c1 , c2 ): """Check whether c1 is bigger than c2.""" i_c1 = - 1 i_c2 = - 1 for i in range ( len ( strings )): if strings [ i ] == c1 : i_c1 = i if strings [ i ] == c2 : i_c2 = i return i_c1 > i_c2 def play (): """Play until victory.""" global run , requests , flag s = socket . socket ( socket . AF_INET , socket . SOCK_STREAM ) s . settimeout ( 3 ) s . connect (( "ec2-23-21-19-72.compute-1.amazonaws.com" , 6969 )) wins = 0 while run : junk = recv_tillreturn ( s , 1 ) choices = range ( 2 ) c1 = recv_tillreturn ( s , 1 ) c2 = recv_tillreturn ( s , 1 ) print ( "{}{}{}" . format ( junk , c1 , c2 )) c1 = c1 . split ()[ 3 ] c2 = c2 . split ()[ 3 ] with lock : if isbigger ( c1 , c2 ): guess = 1 else : guess = 2 s . send ( " % s \n " % guess ) answer = recv_tillreturn ( s , 4 ) print ( answer ) with lock : requests += 1 if "Correct" in answer : if guess == 1 : insert ( c1 , c2 ) else : insert ( c2 , c1 ) wins += 1 else : if guess == 1 : insert ( c2 , c1 ) else : insert ( c1 , c2 ) wins = 0 if wins > 74 : run = False flag = recv_tillreturn ( s , 2 ) s . close () def main (): global strings , run if len ( sys . argv ) < 2 : sys . stderr . write ( 'Specify the number of threads \n ' ) sys . exit ( 1 ) try : f = open ( strings_file , 'r' ) strings = eval ( f . read ()) f . close () except IOError : strings = [] threads = [] for i in range ( int ( sys . argv [ 1 ])): t = threading . Thread ( target = play ) threads . append ( t ) t . start () main_thread = threading . currentThread () for t in threading . enumerate (): if t is main_thread : continue t . join () f = open ( strings_file , "w" ) f . write ( str ( strings )) f . close () print ( "Flag: {} \n Completed after {} requests." . format ( flag , requests )) if __name__ == "__main__" : main ()
Key: d03snt_3v3ry0n3_md5