Secret Location - Base ; Google BeginnerQuest 2021 challenge 4

Table of Contents

Secret Location - Base

This is the fourth challenge of the google beginner quest.

Description

You’re taking a stroll in the lab, when Dr. Klostermann is calling your name: “Agent, we’ve discovered the origin of the device. This time you won’t be able to reach your destination by air, but by the new Trans-Sibiriean Railway, as opposed to the old one, which runs along side it at the same time, it is a bit odd. And it goes to Shenzhen. I am sorry agent, but the further you go into this task, the more precautions you will have to take, and remember, the enemy can be anyone. It could be a conductor, the engineer, it could even be our own people that will meet you at the spot you need to be at. Be selective with who you trust. I think you got the point, go now, I got much to do. Agent, much depends on you!.”

Challenge

The challenge is a zip file containing the chal.c code and pico.ucf2. So this seems related to Arduino, which I have not used so far.

#include <stdbool.h>

#include "hardware/gpio.h"
#include "hardware/structs/sio.h"
#include "pico/stdlib.h"

int main(void)
{
	for (int i = 0; i < 8; i++) {
		gpio_init(i);
		gpio_set_dir(i, GPIO_OUT);
	}
	gpio_put_all(0);

	for (;;) {
		gpio_set_mask(67);
		gpio_clr_mask(0);
		sleep_us(100);
		gpio_set_mask(20);
		gpio_clr_mask(3);
		sleep_us(100);
		gpio_set_mask(2);
		gpio_clr_mask(16);
		sleep_us(100);
		gpio_set_mask(57);
		gpio_clr_mask(4);
		sleep_us(100);
		gpio_set_mask(0);
		gpio_clr_mask(25);
		sleep_us(100);
		gpio_set_mask(5);
		gpio_clr_mask(2);
		sleep_us(100);
		gpio_set_mask(18);
		gpio_clr_mask(65);
		sleep_us(100);
		gpio_set_mask(1);
		gpio_clr_mask(2);
		sleep_us(100);
		gpio_set_mask(64);
		gpio_clr_mask(17);
		sleep_us(100);
		gpio_set_mask(2);
		gpio_clr_mask(0);
		sleep_us(100);
		gpio_set_mask(1);
		gpio_clr_mask(6);
		sleep_us(100);
		gpio_set_mask(18);
		gpio_clr_mask(65);
		sleep_us(100);
		gpio_set_mask(1);
		gpio_clr_mask(0);
		sleep_us(100);
		gpio_set_mask(4);
		gpio_clr_mask(2);
		sleep_us(100);
		gpio_set_mask(0);
		gpio_clr_mask(0);
		sleep_us(100);
		gpio_set_mask(64);
		gpio_clr_mask(16);
		sleep_us(100);
		gpio_set_mask(16);
		gpio_clr_mask(64);
		sleep_us(100);
		gpio_set_mask(2);
		gpio_clr_mask(4);
		sleep_us(100);
		gpio_set_mask(0);
		gpio_clr_mask(3);
		sleep_us(100);
		gpio_set_mask(9);
		gpio_clr_mask(0);
		sleep_us(100);
		gpio_set_mask(0);
		gpio_clr_mask(1);
		sleep_us(100);
		gpio_set_mask(0);
		gpio_clr_mask(8);
		sleep_us(100);
		gpio_set_mask(8);
		gpio_clr_mask(0);
		sleep_us(100);
		gpio_set_mask(65);
		gpio_clr_mask(24);
		sleep_us(100);
		gpio_set_mask(22);
		gpio_clr_mask(64);
		sleep_us(100);
		gpio_set_mask(0);
		gpio_clr_mask(0);
		sleep_us(100);
		gpio_set_mask(0);
		gpio_clr_mask(5);
		sleep_us(100);
		gpio_set_mask(0);
		gpio_clr_mask(2);
		sleep_us(100);
		gpio_set_mask(65);
		gpio_clr_mask(16);
		sleep_us(100);
		gpio_set_mask(22);
		gpio_clr_mask(65);
		sleep_us(100);
		gpio_set_mask(1);
		gpio_clr_mask(6);
		sleep_us(100);
		gpio_set_mask(4);
		gpio_clr_mask(0);
		sleep_us(100);
		gpio_set_mask(66);
		gpio_clr_mask(21);
		sleep_us(100);
		gpio_set_mask(1);
		gpio_clr_mask(0);
		sleep_us(100);
		gpio_set_mask(0);
		gpio_clr_mask(2);
		sleep_us(100);
		gpio_set_mask(24);
		gpio_clr_mask(65);
		sleep_us(100);
		gpio_set_mask(67);
		gpio_clr_mask(24);
		sleep_us(100);
		gpio_set_mask(24);
		gpio_clr_mask(67);
		sleep_us(100);
		gpio_set_mask(2);
		gpio_clr_mask(8);
		sleep_us(100);
		gpio_set_mask(65);
		gpio_clr_mask(18);
		sleep_us(100);
		gpio_set_mask(16);
		gpio_clr_mask(64);
		sleep_us(100);
		gpio_set_mask(2);
		gpio_clr_mask(0);
		sleep_us(100);
		gpio_set_mask(68);
		gpio_clr_mask(19);
		sleep_us(100);
		gpio_set_mask(19);
		gpio_clr_mask(64);
		sleep_us(100);
		gpio_set_mask(72);
		gpio_clr_mask(2);
		sleep_us(100);
		gpio_set_mask(2);
		gpio_clr_mask(117);
		sleep_us(100);

		gpio_put_all(0);
		sleep_ms(500);
	}

	return 0;
}

The code looks like it only sets bits and clears them. All the bits seem to be set in the range of a byte, so it is possible that they all represent printable characters. Based on this assumption I created a small python script, by defining functions that set the bits and printing the final value at the end.

current = 0
out = ""
#Drive high every GPIO appearing in mask. Drive high every GPIO appearing in mask. 
def gpio_set_mask(b):
    global current
    current |= b

#Drive low every GPIO appearing in mask. 
def gpio_clr_mask(b):
    global current
    current &= (b ^ 0xFF)
    

def sleep_us(a):
    global current
    global out
    #print(chr(current))
    out = out + chr(current)

gpio_set_mask(67)
gpio_clr_mask(0)
sleep_us(100)
gpio_set_mask(20)
gpio_clr_mask(3)
sleep_us(100)
gpio_set_mask(2)
gpio_clr_mask(16)
sleep_us(100)
gpio_set_mask(57)
gpio_clr_mask(4)
sleep_us(100)
gpio_set_mask(0)
gpio_clr_mask(25)
sleep_us(100)
gpio_set_mask(5)
gpio_clr_mask(2)
sleep_us(100)
gpio_set_mask(18)
gpio_clr_mask(65)
sleep_us(100)
gpio_set_mask(1)
gpio_clr_mask(2)
sleep_us(100)
gpio_set_mask(64)
gpio_clr_mask(17)
sleep_us(100)
gpio_set_mask(2)
gpio_clr_mask(0)
sleep_us(100)
gpio_set_mask(1)
gpio_clr_mask(6)
sleep_us(100)
gpio_set_mask(18)
gpio_clr_mask(65)
sleep_us(100)
gpio_set_mask(1)
gpio_clr_mask(0)
sleep_us(100)
gpio_set_mask(4)
gpio_clr_mask(2)
sleep_us(100)
gpio_set_mask(0)
gpio_clr_mask(0)
sleep_us(100)
gpio_set_mask(64)
gpio_clr_mask(16)
sleep_us(100)
gpio_set_mask(16)
gpio_clr_mask(64)
sleep_us(100)
gpio_set_mask(2)
gpio_clr_mask(4)
sleep_us(100)
gpio_set_mask(0)
gpio_clr_mask(3)
sleep_us(100)
gpio_set_mask(9)
gpio_clr_mask(0)
sleep_us(100)
gpio_set_mask(0)
gpio_clr_mask(1)
sleep_us(100)
gpio_set_mask(0)
gpio_clr_mask(8)
sleep_us(100)
gpio_set_mask(8)
gpio_clr_mask(0)
sleep_us(100)
gpio_set_mask(65)
gpio_clr_mask(24)
sleep_us(100)
gpio_set_mask(22)
gpio_clr_mask(64)
sleep_us(100)
gpio_set_mask(0)
gpio_clr_mask(0)
sleep_us(100)
gpio_set_mask(0)
gpio_clr_mask(5)
sleep_us(100)
gpio_set_mask(0)
gpio_clr_mask(2)
sleep_us(100)
gpio_set_mask(65)
gpio_clr_mask(16)
sleep_us(100)
gpio_set_mask(22)
gpio_clr_mask(65)
sleep_us(100)
gpio_set_mask(1)
gpio_clr_mask(6)
sleep_us(100)
gpio_set_mask(4)
gpio_clr_mask(0)
sleep_us(100)
gpio_set_mask(66)
gpio_clr_mask(21)
sleep_us(100)
gpio_set_mask(1)
gpio_clr_mask(0)
sleep_us(100)
gpio_set_mask(0)
gpio_clr_mask(2)
sleep_us(100)
gpio_set_mask(24)
gpio_clr_mask(65)
sleep_us(100)
gpio_set_mask(67)
gpio_clr_mask(24)
sleep_us(100)
gpio_set_mask(24)
gpio_clr_mask(67)
sleep_us(100)
gpio_set_mask(2)
gpio_clr_mask(8)
sleep_us(100)
gpio_set_mask(65)
gpio_clr_mask(18)
sleep_us(100)
gpio_set_mask(16)
gpio_clr_mask(64)
sleep_us(100)
gpio_set_mask(2)
gpio_clr_mask(0)
sleep_us(100)
gpio_set_mask(68)
gpio_clr_mask(19)
sleep_us(100)
gpio_set_mask(19)
gpio_clr_mask(64)
sleep_us(100)
gpio_set_mask(72)
gpio_clr_mask(2)
sleep_us(100)
gpio_set_mask(2)
gpio_clr_mask(117)
sleep_us(100)

print(out)

Flag

Luckily this seems to work as the results of the script is looking like a flag:

python .\google_4.py
CTF{be65dfa2355e5309808a7720a615bca8c82a13d7}

Inputing this flag into the website shows the completion message. solved