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.