GPIO binary password (100)
Descripción del desafío
Has encontrado un Arduino olvidado en el aula de robótica. Está encendido y todos sus pines digitales están en diferentes estados (HIGH o LOW). Un post-it pegado al Arduino dice:
"Si lees correctamente el estado de los pines, descubrirás la contraseña del laboratorio.
Pines D2-D9 contienen el secreto. HIGH = 1, LOW = 0
La flag tiene el siguiente formato: ikerlan{contraseña}"
Análisis inicial
Al observar el diagrama del Arduino, podemos ver que los pines digitales D2 a D9 están en diferentes estados. Según la pista, debemos interpretar HIGH como 1 y LOW como 0 para formar un byte binario. Por ejemplo, el carácter uno se representa de la siguiente manera:
CHARACTER #1:
Arduino UNO
+----------------+
| |
| D2 ● HIGH 5V |
| D3 ● HIGH 5V |
| D4 ● HIGH 5V |
| D5 ○ LOW 0V |
| D6 ● HIGH 5V |
| D7 ○ LOW 0V |
| D8 ● HIGH 5V |
| D9 ○ LOW 0V |
| |
+----------------+
Podemos pensar que este byte codifica un carácter en ASCII. Si leemos los pines de D2 a D9, obtenemos el byte 11101010. Usando una herramienta como CyberChef, podemos convertir este byte binario a su representación ASCII, que en este caso es el carácter 'ê'.
Me parece que es una letra extraña para la flag, es posible que los bytes estén en orden inverso (little-endian). Si invertimos el byte a 01010111, obtenemos el carácter 'W', que es más probable que forme parte de la flag.
Extracción de la contraseña
Podemos ir copiando los estados de los pines y traduciéndolos a caracteres ASCII uno por uno (solo son 13 caracteres). Otra opción es usar un script en Python para automatizar el proceso:
Como podréis imaginar, preferí traducir uno a uno los estados a tener que escribir el script, pero aquí lo tenéis por si queréis usarlo.
import re
def decode_arduino_file(filename):
with open(filename, 'r', encoding='utf-8') as f:
content = f.read()
# dividir en bloques CHARACTER
characters = re.split(r'-{20,}', content)
result = ""
for block in characters:
if "D2" not in block:
continue
# extraer líneas D2..D9
bits = []
for pin in range(2, 10):
match = re.search(rf"D{pin}\s+[●○]", block)
if not match:
continue
symbol = match.group(0)[-1]
bits.append('1' if symbol == '●' else '0')
if len(bits) != 8:
continue
# D2 = LSB → bits[0] = bit0 ... bits[7] = bit7
byte_val = int(''.join(bits[::-1]), 2) # invertimos porque bits[0]=LSB
result += chr(byte_val)
return result
if __name__ == "__main__":
path = "visual_diagram.txt" # nombre del archivo de entrada
message = decode_arduino_file(path)
print("Mensaje decodificado:")
print(message)
Al ejecutar este script obtenemos la flag parcial: Who_Said_GP10. Añadiendo el prefijo y sufijo, la flag completa es:
ikerlan{Who_Said_GP10}