Entrada

Stop Drop and Roll - CyberApocalypse2024

Reto Miscelánea basado en hacer un script de automatización en base a unas directrices.

Stop Drop and Roll - CyberApocalypse2024

Autor del reto: ir0nstone

Dificultad: Fácil

Enunciado

“The Fray: The Video Game is one of the greatest hits of the last… well, we don’t remember quite how long. Our “computers” these days can’t run much more than that, and it has a tendency to get repetitive…”

Archivos

En este reto, únicamente nos dan una conexión por netcat, al conectarnos encontraremos lo siguiente.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ nc localhost 1337
===== THE FRAY: THE VIDEO GAME =====
Welcome!
This video game is very simple
You are a competitor in The Fray, running the GAUNTLET
I will give you one of three scenarios: GORGE, PHREAK or FIRE
You have to tell me if I need to STOP, DROP or ROLL
If I tell you there's a GORGE, you send back STOP
If I tell you there's a PHREAK, you send back DROP
If I tell you there's a FIRE, you send back ROLL
Sometimes, I will send back more than one! Like this: 
GORGE, FIRE, PHREAK
In this case, you need to send back STOP-ROLL-DROP!
Are you ready? (y/n) 

Archivos utilizados aquí.

Analizando el código

Las instrucciones son muy simples. Simplemente el programa nos dirá GORGE, PHREAK o FIRE y nosotros tendremos que enviar la cadena STOP, DROP or ROLL dependiendo de lo que nos diga el programa.

Solución

Lo que deberemos de hacer es programar un script el cual reciba la cadena indicada por parte del servidor y nosotros mapearemos el siguiente esquema.

  • Si el programa nos dice GORGE enviamos STOP.
  • Si el programa nos dice PHREAK enviamos DROP.
  • Si el programa nos dice FIRE enviamos ROLL.

Además, tendremos que tener en cuenta que hay ocasiones en las que nos dice las cadenas concatenadas con varios casos simultáneos y nosotros tenemos que ser capaces de interpretarlas y de generar su correspondiente salida.

El script que utilicé para resolver el ejercicio fue el siguiente.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
from binascii import crc32
from pwn import *

def intercambiar_cadenas(cadena):
    # Decodificar la cadena de bytes y dividirla en palabras separadas
    palabras = cadena.decode().strip("b'\n").split(', ')

    # Crear un diccionario para mapear las palabras
    mapeo = {'FIRE': 'ROLL', 'PHREAK': 'DROP', 'GORGE': 'STOP'}

    # Iterar sobre cada palabra y aplicar el mapeo si es necesario
    palabras_intercambiadas = [mapeo.get(palabra, palabra) for palabra in palabras]

    # Unir las palabras intercambiadas de nuevo en una cadena
    cadena_intercambiada = '-'.join(palabras_intercambiadas)

    # Codificar la cadena intercambiada de nuevo en bytes
    cadena_intercambiada_bytes = cadena_intercambiada.encode()

    return cadena_intercambiada_bytes

def intercambiar_cadenas2(cadena):
    # Decodificar la cadena de bytes y extraer lo que sigue después de "What do you do?"
    cadena = cadena.decode()
    indice = cadena.find("What do you do?")
    cadena = cadena[indice+len("What do you do?"):].strip()
    
    # Dividir la cadena en palabras separadas
    palabras = cadena.strip("b'\n").split(', ')

    # Crear un diccionario para mapear las palabras
    mapeo = {'FIRE': 'ROLL', 'PHREAK': 'DROP', 'GORGE': 'STOP'}

    # Iterar sobre cada palabra y aplicar el mapeo si es necesario
    palabras_intercambiadas = [mapeo.get(palabra, palabra) for palabra in palabras]

    # Unir las palabras intercambiadas de nuevo en una cadena
    cadena_intercambiada = '-'.join(palabras_intercambiadas)

    # Codificar la cadena intercambiada de nuevo en bytes
    cadena_intercambiada_bytes = cadena_intercambiada.encode()

    return cadena_intercambiada_bytes
 
r = remote('94.237.61.79',  49263)
print(r.recvuntil(b"Are you ready?"))
r.sendline(b"y")
print(r.recvline())

string = r.recvline()
print("La cadena leida es: ", string)
salida = intercambiar_cadenas(string)
print("la salida es: ", salida)
r.sendline(salida)

for i in range (0,500):
    string = r.recvline()
    print("La cadena leida es: ", string)
    salida = intercambiar_cadenas2(string)
    print("la salida es: ", salida)
    r.sendline(salida)
    print(i)

Como podemos ver, el servidor nos envia 500 cadenas las cuales nosotros tenemos que contestar de forma correcta para que nos arroje la flag.

NOTA

Leyendo otros writeups, he visto un script el cual realiza el mismo procedimiento pero de manera más compacta. Lo comparto a modo de curiosidad.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from pwn import *

p = remote('127.0.0.1', 1337)

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

while True:
    recv = p.recvlineS().strip()

    if 'GORGE' not in recv and 'PHREAK' not in recv and 'FIRE' not in recv:
        print(recv)
        break

    result = recv.replace(", ", "-")
    result = result.replace("GORGE", "STOP")
    result = result.replace("PHREAK", "DROP")
    result = result.replace("FIRE", "ROLL")

    p.sendlineafter(b'do? ', result.encode())

Flag

HTB{1_wiLl_sT0p_dR0p_4nD_r0Ll_mY_w4Y_oUt!}

Esta entrada está licenciada bajo CC BY 4.0 por el autor.