2024 Cyber Apocalypse: Stop Drop and Roll

Challenge Information

AttributeDetails
Event2024 Cyber Apocalypse
CategoryMiscellaneous
ChallengeStop Drop and Roll
DifficultyVery Easy

Summary

Stop Drop and Roll is a miscellaneous coding challenge where participants must script responses to a text-based game. The server presents scenarios (GORGE, PHREAK, or FIRE) and expects corresponding actions (STOP, DROP, or ROLL). The challenge tests basic socket programming and string manipulation skills.


Analysis

The challenge runs a simple remote game server that:

  • Presents game scenarios in a sequence
  • Expects players to respond with the correct action mapping:
    • GORGE → STOP
    • PHREAK → DROP
    • FIRE → ROLL
  • Can present multiple scenarios at once (e.g., “GORGE, FIRE, PHREAK” → “STOP-ROLL-DROP”)
  • Terminates after all scenarios are completed, returning the flag

The vulnerability (if any) is the necessity to script automation to handle the repetitive scenarios quickly.


Solution

Step 1: Connect to the Server

The server is accessed via socket connection to the provided IP and port:

  • IP: 94.237.56.248
  • Port: 58685

Step 2: Send Initial Confirmation

Upon connection, the server presents rules and asks if you’re ready. Respond with ‘y’:

p.sendlineafter(b'(y/n) ', b'y')

Step 3: Parse and Respond to Scenarios

For each prompt, extract the scenario, map each component, and send back the action:

def send_response(sock, scenario, log_file):
"""Send the appropriate response to the server based on the scenario."""
action_map = {'GORGE': 'STOP', 'PHREAK': 'DROP', 'FIRE': 'ROLL'}
actions = [action_map[part.strip()] for part in scenario.split(',')]
response = '-'.join(actions) + '\n'
sock.sendall(response.encode())
log_file.write("Sent: " + response)

Step 4: Loop Until Flag

Continue reading prompts and sending responses until the server returns data that doesn’t contain game scenarios. This will be the flag:

while True:
prompt = recvuntil(sock, b'What do you do?')
if "What do you do?" not in prompt:
continue
scenario_lines = prompt.strip().split('\n')
scenario = scenario_lines[-1] if scenario_lines[-1] != "What do you do?" else scenario_lines[-2]
send_response(sock, scenario, log_file)

Complete Solver Script

import socket
def recvuntil(sock, delim=b'\n'):
data = b''
try:
while not data.endswith(delim):
fragment = sock.recv(1)
if not fragment:
break
data += fragment
except socket.timeout:
print("Timeout reached without finding delimiter.")
return data.decode()
def send_response(sock, scenario, log_file):
action_map = {'GORGE': 'STOP', 'PHREAK': 'DROP', 'FIRE': 'ROLL'}
actions = [action_map[part.strip()] for part in scenario.split(',')]
response = '-'.join(actions) + '\n'
sock.sendall(response.encode())
log_file.write("Sent: " + response)
def main(ip, port):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock, open("game_log.txt", "w") as log_file:
sock.connect((ip, port))
sock.settimeout(2)
intro = recvuntil(sock, b'Are you ready? (y/n)')
print(intro)
log_file.write(intro + '\n')
sock.sendall(b'y\n')
index = 0
while True:
index += 1
print(f"\nScenario {index}:")
try:
prompt = recvuntil(sock, b'What do you do?')
print(prompt)
log_file.write("Received: " + prompt + '\n')
if "What do you do?" not in prompt:
continue
scenario_lines = prompt.strip().split('\n')
scenario = scenario_lines[-1] if scenario_lines[-1] != "What do you do?" else scenario_lines[-2]
send_response(sock, scenario, log_file)
except socket.timeout:
print("No more data from the server.")
log_file.write("No more data from the server.\n")
break
if __name__ == "__main__":
IP = "94.237.56.248"
PORT = 58685
main(IP, PORT)

Key Takeaways

  • Socket programming fundamentals for remote server communication
  • String manipulation and parsing of game scenarios
  • Understanding protocol-based challenges where responses must follow specific rules
  • Logging output for debugging complex interactions
  • Timeout handling when dealing with network sockets

Flag: HTB{1_wiLl_sT0p_dR0p_4nD_r0Ll_mY_w4Y_oUt!}