Как открыть сейф с помощью ручки
Многабукаф
Я обнаружил уязвимость, которая позволяет открывать электронные сейфы компании Sentry Safe и Master Lock без пин-кода. Производителя я уведомил, но ответа от них так и не получил.
Я создал альтернативную плату и прошивку для решения этой проблемы, они доступны по ссылке.
Предыстория
Однажды по случаю я прикупил логический анализатор и задумался, что же с ним делать?
Посмотрел вокруг... Телевизор... принтер...
... электронный сейф!
Разборка
Попробуем понять, как это работает. Для начала разберём дверь и заглянем внутрь.
Там всего две платы:
1 плата снаружи с батареями, клавиатурой, светодиодами и зуммером.
1 плата внутри с памятью и соленоидом (который механически отпирает болты).
Захват
Между этими двумя платами есть 4 провода (чёрный, жёлтый, зелёный и красный). Поскольку цвета проводов не всегда соответствуют назначению, не будем безоговорочно им доверять. Мы можем осмотреть дорожки на плате, чтобы найти схему проводки, но поскольку мой новый логический анализатор может обрабатывать 8 каналов, давайте просто подключим каждый провод.
Такому электронному сейфу нужен 5-значный код, поэтому для первого захвата я просто нажму клавишу «1» 5 раз.
Результат: только сигнал зелёного провода начал меняться. Чёрный всегда низкий, жёлтый и красный всегда высокие (значит, цветам можно доверять).
На захваченном сигнале мы видим 5 повторений одной и той же фигуры подряд, поэтому можно сделать вывод, что эта фигура соответствует нажатию клавиши «1» (так как именно её мы и нажимали 5 раз). Чтобы декодировать полный сигнал, мы должны найти используемый протокол.
Этот сейф не относится к открытому аппаратному или программному обеспечению, поэтому мы не знаем, как он работает. Нужно копаться.
Давайте рассмотрим чипы на платах. На каждой из них только один микроконтроллер.
Согласно техническому описанию, основными протоколами связи, используемыми с этим микроконтроллером, являются SPI и I²C. Но не в этот раз, потому что им обоим нужен тактовый сигнал, а на других проводах нет никакого движения. Так что это скорее всего наиболее часто используемый протокол асинхронной шины: UART.
Хорошие новости: ПО с открытым исходным кодом для просмотра импульсов содержит множество декодеров, включая UART.
Но какая частота используется?
Чтобы узнать частоту, я начинаю с измерения времени между каждой фигурой, которая, как мы предполагаем, соотносится с нажатой клавишей.
Для передачи всего ключа потребовалось 2,1 мс, а самый короткий пик занял примерно 0,2 мс. Обычно UART использует 1 стартовый бит, 8 бит данных и 1 стоповый бит. Итого 10 бит.
2,1 мс / 10 = 0,21 мс
Это значение соответствует нашему самому короткому пику.
10 бит за 2,1 мс. Таким образом (1000 мс / 2,1 мс) * 10 = количество бит, которое можно передать за секунду, примерно равно 4762.
Частота UART должна соответствовать 9600 делениям. Значение 4762 очень близко к 4800, что соответствует 9600/2, обычной скорости для UART.
Поэтому мы пытаемся установить эту частоту в нашем декодере.
Работает! Мы можем прочитать наши 5x "1" ключей.
После некоторых попыток с разными кодами можно сделать следующие наблюдения о разных частях сигнала:
сигнал всегда начинается с формы пробуждения с низким состоянием 2,7 мс, затем высоким 0,25 мс (не является частью протокола UART);
после пробуждения сигнал всегда отправляет 0x0 байт;
после этого отправляется фиксированное значение 0x71, похоже это командный байт (0x71 = попытка разблокировать);
затем отправляются 5 цифр введённого кода;
наконец, последний байт меняется в зависимости от кода, похоже, это кастомная контрольная сумма (Checksum, строка чисел и букв, используемая для уникальной идентификации).
Вот данные:
Байт команды | Пробный код | Контрольная сумма |
0x71 | 11111 | 0x76 |
0x71 | 22222 | 0x7B |
0x71 | 12345 | 0x80 |
Мы видим, что контрольная сумма равна байту команды, к которому добавили каждый байт кода.
Теперь у нас есть вся информация, необходимая для автоматизации этого процесса с помощью короткой функции Arduino.
void send_command(int command, int a, int b, int c, int d, int e) {
int checksum = (command + a + b + c + d + e);
// Wake-up signal shape
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
delayMicroseconds(2750);
digitalWrite(pin, HIGH);
delayMicroseconds(200);
// Data
Serial.begin(4800);
Serial.write(0x0);
Serial.write(command);
Serial.write(a);
Serial.write(b);
Serial.write(c);
Serial.write(d);
Serial.write(e);
Serial.write(checksum);
Serial.end();
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH);
}
Но даже если каждый вариант кода можно попробовать очень быстро, в сейфе есть защита от брутфорса. Поэтому я пытаюсь зафиксировать сигнал во время изменения кода, чтобы увидеть, что добавляется.
Чтобы изменить код:
Нажмите кнопку «P».
Введите заводской код.
Введите новый код.
Когда мы смотрим на сигнал:
Некоторые странные кастомные формы отправляются во время нажатия «P».
Плата клавиатуры отправляет заводской код с командным байтом 0x74.
Чип внутри отвечает, действителен заводской код или нет (заводской код печатается в руководстве, генерируется случайным образом и не может быть изменен)
Клавиатура отправляет новый код с командным байтом 0x75
Я также фиксирую обмен сигналами во время загрузки, так что теперь мы можем сопоставить некоторые функции:
Байт команды | Функция | Предоставленный код |
0x71 | Попытка разблокировки | Код, чтобы попробовать |
0x74 | Попытка инициировать изменение кода | Заводской код |
0x75 | Завершить процесс изменения кода | Новый код |
0x78 | Загрузка | 00000 (ноль) |
Но что произойдёт, если вы напрямую пошлёте новый кодовый сигнал, пропустив шаг заводского кода?
...код перезаписывается!!! Таким образом, мы можем сбросить код, не зная об этом.
Теперь мы можем открыть любой электронный сейф Sentry Safe & Master lock за секунду.
Доказательство
В качестве доказательства концепции я создам карманный инструмент.
Возьму микроконтроллер Atmega328, 8бит AVR на 8МГц (без кварца). Залив программу на свою флешку, припаиваю две батарейки CR2032, кнопку и два пина.
Программа просто отправит сигнал сброса, чтобы установить фиктивный код, а затем отправит сигнал разблокировки, чтобы открыть сейф.
И всё это устройство я поместил в ручку! В итоге у меня получился настоящий инструмент для пентеста! (здесь у нас непереводимая игра слов, потому что ручка "pen" стала инструментом для пентеста "pen-test'')
Как это использовать:
Снимите крошечный винт у сейфа.
Прикоснитесь к черному и зеленому проводам двумя кончиками ручки.
Нажмите кнопку.
Сейф открыт!
Демонстрация
Как исправить
Чтобы устранить эту уязвимость, проверьте другой мой репозиторий.
Спасибо за внимание!
Что ещё интересного есть в блоге Cloud4Y
→ Малоизвестный компьютер SWTPC 6800
→ Сделайте Linux похожим на Windows 95
→ Как распечатать цветной механический телевизор на 3D-принтере
→ WD-40: средство, которое может почти всё
→ Quantel Paintbox — устройство, изменившее мир телевизионных передач
Подписывайтесь на наш Telegram-канал, чтобы не пропустить очередную статью. Пишем только по делу.