← Back to Writeups
HTBN/AMisc

Stop Drop and Roll

XESXOR8/23/20265 min read
#misc#htb#n/a

Stop Drop and Roll

Platform: HackTheBox | Category: Misc | Type: Challenge | Difficulty: Easy | OS: NA | Author: D3v0o0Nu11 | Date: 2026-01-29 | Status: Solved Techniques: interactive_exploitation, string_parsing

Summary

Task: Interactive text game requiring automated responses to scenarios (GORGE→STOP, PHREAK→DROP, FIRE→ROLL). Solution: Used pwntools for interactive connection and regex parsing to extract scenarios and send correct responses.

Recon

Port scan

nmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
PortServiceVersionNotes
<PORT><SVC><VER><notes>

Enumeration highlights

  • Event: hackthebox | ID: 20260129_htb_stop_drop_and_roll
  • Tags: pwntools, interactive, nc, scripting
  • Indicators: interactive nc service, game simulation, response mapping
  • Source: 20260129_htb_stop_drop_and_roll.md

Foothold

Vulnerability / Misconfiguration

  1. Interactive_exploitation
  2. String_parsing
<command>

Exploitation

  • See original writeup content for detailed exploitation.

Privilege Escalation

Enumeration

sudo -l
find / -perm -4000 2>/dev/null
getcap -r / 2>/dev/null
cat /etc/crontab
ps aux

Exploitation

  1. N/A for challenge-type writeup; see exploitation above.
  2. Flag obtained via challenge solve.
<command>

Flags

FlagLocationValue
flagREDACTED

Key Takeaways / Lessons

  • interactive_exploitation
  • string_parsing
  • Tags: pwntools, interactive, nc, scripting

Original Writeup

<details><summary>Click to expand original content</summary>

Description

An interactive HackTheBox challenge featuring a text-based game "The Fray: The Video Game". The player must respond to various scenarios with the correct actions:

ScenarioAction
GORGESTOP
PHREAKDROP
FIREROLL

When multiple scenarios are presented together (e.g., "GORGE, FIRE, PHREAK"), the response should be "STOP-ROLL-DROP" (actions joined by hyphens).

Reconnaissance

Connecting to the Service

nc 94.237.120.233 51681

Upon connection, we receive a prompt to start the game:

Welcome to The Fray: The Video Game!

We will present you with various scenarios that you must react to.
If you have any questions, please direct them to the organisers.
Do you want to start? (y/n):

After sending 'y', the game starts with an endless stream of scenarios:

What do you do?
GORGE

Your response:

Protocol Analysis

Key observations:

  1. Interactivity — the server expects an immediate response to each scenario
  2. Scenario format — scenarios can be on the same line as "What do you do?" or on a separate line
  3. Response format — individual actions are joined by hyphens, no spaces
  4. Completion — the flag appears after successfully completing several rounds

Solution

Strategy

  1. Use pwntools for stable interactive connection
  2. Create a dictionary mapping scenarios to actions
  3. Parse incoming data, extracting keywords GORGE/PHREAK/FIRE
  4. Form responses in the required format
  5. Continue until receiving the flag

Implementation

#!/usr/bin/env python3
"""
HTB - Stop Drop and Roll
Interactive challenge solution using pwntools.

The challenge simulates a video game where the player must respond
to scenarios with correct actions:
- GORGE → STOP
- PHREAK → DROP
- FIRE → ROLL
"""

from pwn import *

# Logging setup
context.log_level = 'info'

def solve():
    """
    Main solution function that handles the interactive game.
    """
    # Connect to the service
    io = remote('94.237.120.233', 51681)
    
    try:
        # Wait for prompt and start the game
        io.recvuntil(b'Do you want to start? (y/n):')
        io.sendline(b'y')
        
        log.info("Game started!")
        
        # Dictionary mapping scenarios to actions
        action_map = {
            'GORGE': 'STOP',
            'PHREAK': 'DROP',
            'FIRE': 'ROLL'
        }
        
        # Round counter
        round_num = 0
        
        while True:
            round_num += 1
            
            # Receive data from server
            data = io.recvuntil(b'\n').decode('utf-8')
            log.debug(f"Received: {data!r}")
            
            # Skip empty lines and service messages
            if 'What do you do?' in data:
                # Sometimes scenario is on the same line, sometimes on the next
                # Read next line if needed
                more_data = io.recvuntil(b'\n').decode('utf-8')
                log.debug(f"More data: {more_data!r}")
                
                # Combine for parsing
                scenario_line = more_data.strip()
            else:
                scenario_line = data.strip()
            
            # Check for flag
            if 'HTB{' in scenario_line:
                log.success(f"Flag found: {scenario_line}")
                print(scenario_line)
                break
            
            # Skip service lines
            if 'Your response:' in data or 'Your response:' in more_data:
                continue
            
            # Extract scenarios from the line
            scenarios = []
            for keyword in action_map.keys():
                if keyword in scenario_line:
                    scenarios.append(keyword)
            
            # Form response
            if scenarios:
                # Sort by order of appearance in the original line
                scenarios_sorted = sorted(scenarios, key=lambda x: scenario_line.find(x))
                response = '-'.join(action_map[s] for s in scenarios_sorted)
                
                log.info(f"Round {round_num}: {scenario_line} → {response}")
                
                # Send response
                io.sendline(response.encode('utf-8'))
            else:
                # If scenario not recognized, continue
                log.warning(f"Unknown scenario: {scenario_line}")
        
    except Exception as e:
        log.error(f"Error: {e}")
        raise
    finally:
        io.close()

if __name__ == '__main__':
    solve()

Optimized Version

For more reliable parsing, regular expressions can be used:

#!/usr/bin/env python3
"""
Optimized version with better parsing using regex.
"""

from pwn import *
import re

def solve():
    io = remote('94.237.120.233', 51681)
    
    io.recvuntil(b'Do you want to start? (y/n):')
    io.sendline(b'y')
    
    action_map = {
        'GORGE': 'STOP',
        'PHREAK': 'DROP',
        'FIRE': 'ROLL'
    }
    
    # Pattern for finding scenarios
    pattern = re.compile(r'\b(GORGE|PHREAK|FIRE)\b')
    
    while True:
        # Read line and search for scenarios
        data = io.recvline().decode('utf-8')
        
        if 'HTB{' in data:
            match = re.search(r'HTB{[^}]+}', data)
            if match:
                print(match.group(0))
                break
        
        if 'What do you do?' in data:
            # Read next line with scenario
            scenario = io.recvline().decode('utf-8').strip()
            
            # Extract scenarios
            found = pattern.findall(scenario)
            
            if found:
                response = '-'.join(action_map[a] for a in found)
                log.info(f"Response: {response}")
                io.sendline(response.encode('utf-8'))

if __name__ == '__main__':
    solve()

Key Takeaways

  1. pwntools for interactivity — the pwn module provides convenient functions for working with network connections (remote(), recvuntil(), sendline())

  2. Parsing dynamic input — the server may combine multiple messages into one line, so flexible parsing is needed

  3. Automating routine tasks — when a challenge requires repeated similar actions, a script saves time and eliminates human errors

  4. Regular expressions — for extracting patterns from strings (re.findall(), re.search()) — more reliable than in + substring search

  5. Error handling — always use try/finally to guarantee connection closure

  6. Logging contextcontext.log_level = 'info' allows seeing progress without excessive debug message noise

</details>

Auto-tracked: saved to WriteUps; run /xesor-revise to fold lessons into XESXor_Methodology.md.

signed by XESXOR