HTB Apocalypse 2023 - Janken
Problem description
Janken is an easy rated Misc challenge.
As you approach an ancient tomb, you're met with a wise guru who guards its entrance. In order to proceed, he challenges you to a game of Janken, a variation of rock paper scissors with a unique twist. But there's a catch: you must win 100 rounds in a row to pass. Fail to do so, and you'll be denied entry.
Analysis
Analyzing the decompilation of the binary (janken
), we find a loop for the 100 rounds mentioned in the prompt running the following game
function.
Solution
Here's an excerpt of the pwntools script used to solve the challenge.
1 io = start()
2 info(io.recvuntil(b'>> ')) # prompt
3 io.sendline(b'1')
4
5 rps = ['rock', 'scissors', 'paper']
6
7 rps_win = {
8 'rock': 'paper',
9 'paper': 'scissors',
10 'scissors': 'rock',
11 }
12
13 def wait_for_next_second(epoch_time):
14 while int(time.time()) <= epoch_time:
15 time.sleep(0.05)
16
17 for _i in range(0, 99):
18 epoch_time = epoch_time = time.time() # time before asking for prompt
19 if epoch_time - int(epoch_time) > 0.8:
20 wait_for_next_second(epoch_time)
21 info(io.recvuntil(b'>> ')) # wait for prompt
22 time2 = time.time()
23 rand_io = process(['./rand', f"{epoch_time}"])
24 r = int(rand_io.readline().strip())
25 enemy_answer = rps[r % 3]
26 answer = rps_win[enemy_answer]
27
28 info(f"Sending result: {answer}")
29 time3 = time.time() # time before sending response
30 io.sendline(bytes(answer, encoding="utf-8"))
31 time4 = time.time() # time after sending response
32
33 print(f"{_i}: Time delta: {epoch_time:.3f}, {time2:.3f}, {(time2 - epoch_time):.3f}, {(time4-time3):3f}")
34
35 io.interactive()
Flag
We have our flag! HTB{r0ck_p4p3R_5tr5tr_l0g1c_buG}
Read more