Tags: racecondition hardware avr pwn timing-attack
Rating: 4.2
# AVR (hardware) - 320 points, 16 solves
Writeup by poortho
## Problem Description
We found this old terminal with access to some top secret data, but it's secured by passwords. Can you break in anyway?
`avr.2020.ctfcompetition.com 1337`
Attachments:
[code.c](./code.c)
[code.hex](./code.hex)
[simavr_diff](./simavr_diff)
[simduino.elf](./simduino.elf)
[Makefile](./Makefile)
## Solution
From the files given, it looks like the challenge is running some AVR program on an arduino simulator.
Let's start with the obvious - `code.c`:
```c
#undef F_CPU
#define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/cpufunc.h>
#include <stdio.h>
#include <string.h>
#define BAUD 125000UL
#include <util/setbaud.h>
#ifndef PASS1
#define PASS1 "PASSWORD_REDACTED_XYZ"
#endif
#ifndef PASS2
#define PASS2 "TOPSECRET_PASSWORD_ALSO_REDACTED_TOPSECRET"
#endif
#ifndef FLAG
#define FLAG "CTF{_REAL_FLAG_IS_ON_THE_SERVER_}"
#endif
const char* correctpass = PASS1;
const char* top_secret_password = PASS2;
const char* top_secret_data =
"INTELLIGENCE REPORT:\n"
"FLAG CAPTURED FROM ENEMY.\n"
"FLAG IS " FLAG ".";
char buf[512];
char secret[256] =
"Operation SIERRA TANGO ROMEO:\n"
"Radio frequency: 13.37MHz\n"
"Received message: ATTACK AT DAWN\n";
char timer_status[16] = "off";
volatile char logged_in;
int top_secret_index;
volatile char uart_ready;
ISR(USART_RX_vect) {
uart_ready = 1;
}
void uart_init(void) {
UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE;
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0);
}
static int uart_getchar(FILE* stream) {
while (1) {
cli();
if (!uart_ready) {
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
}
cli();
if (uart_ready) {
uart_ready = 0;
unsigned int c = UDR0;
sei();
return c;
}
sei();
}
}
static int uart_putchar(char c, FILE* stream) {
loop_until_bit_is_set(UCSR0A, UDRE0);
UDR0 = c;
return 0;
}
static FILE uart = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
void quit() {
printf("Quitting...\n");
_delay_ms(100);
cli();
sleep_enable();
sleep_cpu();
while (1);
}
volatile uint32_t overflow_count;
uint32_t get_time() {
uint32_t t;
cli();
t = (overflow_count << 16) + TCNT1;
sei();
return t;
}
void timer_on_off(char enable) {
overflow_count = 0;
strcpy(timer_status, enable ? "on" : "off");
if (enable) {
TCCR1B = (1<<CS10);
sei();
}
else {
TCCR1B = 0;
}
}
ISR(TIMER1_OVF_vect) {
if (!logged_in) {
overflow_count++;
// Allow ten seconds.
if (overflow_count >= ((10*F_CPU)>>16)) {
printf("Timed out logging in.\n");
quit();
}
}
else {
// If logged in, timer is used to securely copy top secret data.
secret[top_secret_index] = top_secret_data[top_secret_index];
timer_on_off(top_secret_data[top_secret_index]);
top_secret_index++;
}
}
void read_data(char* buf) {
scanf("%200s", buf);
}
void print_timer_status() {
printf("Timer: %s.\n", timer_status);
}
int main() {
uart_init();
stdout = &uart;
stdin = &uart;
TCCR1A = 0;
TIMSK1 = (1<