2023 Cyber Apocalypse: Janken

Challenge Information

AttributeDetails
Event2023 Cyber Apocalypse
CategoryMisc
ChallengeJanken

Summary

This challenge is a variant of Rock-Paper-Scissors (Janken) where the winning condition is not standard game rules but rather checking if the opponent’s choice appears as a substring within the player’s input. By understanding this logic flaw, we can send a string containing all possible choices and win every round.


Analysis

The vulnerable game logic checks whether the opponent’s choice is found within the player’s input:

pcVar5 = strstr((char *)&local_38, local_58[iVar1 % 3]);
if (pcVar5 == (char *)0x0) {
fprintf(stdout,"%s\n[-] You lost the game..\n\n",&DAT_00102083);
exit(0x16);
}
fprintf(stdout,"\n%s[+] You won this round! Congrats!\n%s",&DAT_0010207b,&DAT_00102008);

Vulnerability: The winning condition uses strstr() which searches for a substring. If the opponent chooses ‘rock’, the game checks if ‘rock’ exists anywhere in the player’s input.

Key insight: If the player submits a string containing all three options (“rockpaperscissors”), the string will always contain the opponent’s choice and the player will always win.


Solution

The exploitation approach is straightforward:

import socket
IP = "159.65.81.51"
PORT = 31895
# Connect to server
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((IP, PORT))
# Receive initial prompt
data = sock.recv(1024).decode("utf-8")
sock.sendall(b"1\n")
# The magic string containing all choices
# When opponent chooses any option, this string will contain it
winning_input = "rockpaperscissors"
# Play 100 rounds
for i in range(101):
# Receive the game prompt
data = sock.recv(1024).decode("utf-8")
print(data)
# Send the winning string
sock.sendall(winning_input.encode("utf-8") + b"\n")
# Receive the final message
data = sock.recv(1024).decode("utf-8")
print(data)
sock.close()

Why this works:

  • Opponent chooses: rock, paper, or scissors
  • Player sends: “rockpaperscissors”
  • Game checks: Does “rockpaperscissors” contain opponent’s choice? YES
  • Result: Player wins every round

Key Takeaways

  • Game logic vulnerabilities can be more impactful than cryptographic flaws
  • String matching functions like strstr() can be exploited
  • Input validation should check exact matches, not substring presence
  • Order matters in security checks and game rules
  • Automated scripting enables repeated exploitation
  • Understanding the exact winning condition is critical for exploitation