En este post pongo la solución a uno de los retos de la categoría 'Programming' de Brixel CTF 2020, competición en modalidad 'on-line' , estilo CTF (del inglés, 'Capture the Flag') y formato 'Jeopardy'.
Se trata de uno de los desafíos que más me ha gustado de esta competición, ya que, aunque en la carrera, hace ya demasiado tiempo, algo hicimos de programación de microprocesadores para controlar ciertos dispositivos (LED, displays de 7 segmentos,...), este reto me obligó a investigar por Internet para intentar resolverlo, cosa que no pude hacer durante la competición por falta de tiempo de dedicación, pero me "picó" y creo que finalmente, aunque fuera de plazo, lo conseguí :).
El reto concreto lleva por título "An arduino project" y, en mi opinión, presenta un nivel de dificultad medio (★★★☆☆).
Enunciado:
Se proporciona un archivo con el código de un programa (arduino_project.ino) y, además, se puede obtener una pista a cambio de 5 puntos.El programa en cuestión es el siguiente:
int msg[] = {9,0,9,0,9,0,9,0,7,8,3,4,0,7,6,5,4,3,2,0,7,8,6,5,4,2,0,2,3,4,0,7,2,3,8,4,5,0,2,3,4,5,6,7,8,0,7,6,0,7,2,3,8,4,5,0,2,3,4,5,6,7,0,2,3,8,4,5,0,2,3,8,4,5,0,2,3,8,6,5,0};
void setup()
{
pinMode(2, OUTPUT); //A
pinMode(3, OUTPUT); //B
pinMode(4, OUTPUT); //C
pinMode(5, OUTPUT); //D
pinMode(6, OUTPUT); //E
pinMode(7, OUTPUT); //F
pinMode(8, OUTPUT); //G
pinMode(9, OUTPUT); //DP
//COMMON = 5V with 1K resistor
}
void loop()
{
for (byte i = 0; i < (sizeof(msg)/ sizeof(msg[0])); i++) {
if(msg[i] > 0) {
digitalWrite(msg[i],LOW);
}else{
delay(500);
reset();
}
}
}
void reset()
{
for(int p = 2; p < 10;p++)
{
digitalWrite(p,HIGH);
}
delay(500);
}
Solución: Tal y como digo, este reto me obligó a investigar por Internet y, antes de pasar a la solución, pongo los aspectos fundamentales que fui averiguando. Como ha quedado más que suficientemente puesto de manifiesto, no soy ningún experto en esta materia, por lo que si cometo errores en las explicaciones básicas que doy a continuación, como siempre, agradecería que algún amable lector de este blog me saque de los mismos mediante las oportunas correcciones en forma de comentario.
"Arduino es una compañía de desarrollo de software y hardware libres, así como una comunidad internacional que diseña y manufactura placas de desarrollo de hardware para construir dispositivos digitales y dispositivos interactivos que puedan detectar y controlar objetos del mundo real.
...
Los diseños de las placas Arduino usan diversos microcontroladores y microprocesadores. Generalmente el hardware consiste de un microcontrolador Atmel AVR, conectado bajo la configuración de 'sistema mínimo' sobre una placa de circuito impreso..."
(Fuente: wikipedia).
Por tanto, deduje que el reto consistía en que el programa que se proporciona ejecutado en un microcontrolador de una placa Arduino sirve para controlar algún tipo de dispositivo que muestra la flag, pero: ¿Qué tipo de dispositivo?
Llegado a este punto, es decir, nada más empezar :), no me quedó más remedio que descubrir la pista del reto:
Vale, ya sé que el dispositivo con el que el microcontrolador de la placa interactúa cuando ejecuta el programa es un display de 7 segmentos.
Los displays de 7 segmentos constan de 7 LED, llamados segmentos, dispuestos en forma de "8". La mayoría de ellos en realidad tienen 8 segmentos (7 de ellos identificados con una letra de la "A" a la "G", y el octavo, que sirve como punto decimal, identificado como "DP").
Los displays de 7 segmentos de un solo dígito suelen tener 10 pines, 8 de ellos se conectan individualmente a uno de los 8 segmentos y dos son "comunes". En la siguiente figura se muestran los 10 pines con diferentes colores indicándose con el mismo color el segmento al que se asocia cada uno de ellos:Los dos pines identificados con la etiqueta "Común" en la figura anterior son en realidad el mismo pin y están compartidos por todos los segmentos.Dicho todo lo anterior, examinando el programa que se proporciona con el reto (un programa de Arduino se denomina 'sketch' y la extensión del archivo que lo contiene es .ino) entendí que cada segmento o LED se enciende cuando se le aplica un valor lógico LOW (0) y se apaga cuando se le aplica un valor lógico HIGH (1), por lo que se estaría utilizando un display de 7 segmentos de ánodo común.
La pista del reto me proponía dos alternativas para obtener la bandera: conectar el display de 7 segmentos a una placa Arduino y ejecutar el programa, o decodificar el mensaje a mano.
Aunque con lo que ya había leído en Internet hasta el momento me creía capaz de resolver el reto mediante la segunda opción, Arduino utiliza un lenguaje de programación propio basado en C++ que no es difícil de entender, como no estaba del todo seguro me decidí a utilizar la primera. Para ello, busqué por Internet algún simulador que me permitiera ejecutar el 'sketch' y encontré 'TinkerCad'.
Lo primero que hice fue conectar los pines de un display de 7 segmentos de ánodo común a los pines digitales de una placa Arduino Uno siguiendo las especificaciones indicada en la sección de configuración del 'sketch' del reto, void setup(), es decir, de la siguiente manera (utilicé cables de diferentes colores para que se apreciara mejor):
- A: DIGITAL 2 (cable verde).
- B: DIGITAL 3 (cable naranja).
- C: DIGITAL 4 (cable amarillo).
- D: DIGITAL 5 (cable azul).
- E: DIGITAL 6 (cable morado).
- F: DIGITAL 7 (cable rosado).
- G: DIGITAL 8 (cable marrón).
- DP: DIGITAL 9 (cable turquesa).
Después, conecté el ánodo común a 5V (cable rojo).Y, finalmente, ejecuté la simulación:
El display muestra cuatro "." de forma consecutiva y después va mostrando los siguientes dígitos (que serían la flag o solución a este reto): 406798190332Y ya que estaba :), no me quedé con la duda de si a partir del mensaje que figura en el programa hubiera sido capaz de realizar la decodificación de forma manual:
Flag: 406798190332
Comentarios
Publicar un comentario