Как стать автором
Обновить
213.79
Бастион
Проводим пентесты, проектируем защищенные системы

Ключ от всех дверей: MITM-атака на протокол Wiegand с помощью самодельной платы

Уровень сложностиСредний
Время на прочтение9 мин
Количество просмотров9.4K

Представьте: вы выложили кучу денег на крутые замки и карты доступа, а какой-то парень с крошечной штуковиной в кармане открывает их за пару минут. Похоже на сцену из киберпанк-фильма? Но это наша реальность. В сердце множества СКУД скрывается протокол, разработанный в 70-х годах прошлого века без шифрования и защиты от перехвата данных.

Сегодня расскажу, как мы спаяли крохотную платку, которая наглядно показывает уязвимость Wiegand. Наш имплант легко перехватывает данные из СКУД, копирует карты доступа и эмулирует их, когда вам это нужно.

Мы делимся этим материалом не чтобы научить вас обходить системы безопасности (кто хотел, тот уже давно все нагуглил), а чтобы показать: пора что-то менять. Серьезно, нельзя же в 2025 году полагаться на технологию, которая старше многих безопасников, обслуживающих эти системы.


Ископаемый протокол

Помните нашу прошлую статью о взломе биометрической СКУД? Тогда мы показали, как обойти защиту, которая на первый взгляд кажется неприступной. Но неудачный дизайн многих таких систем — только вершина айсберга. Погружаясь глубже в архитектуру, мы столкнулись с протоколом Wiegand — настоящим динозавром в мире систем контроля доступа.

Карта Wiegand-26
Карта Wiegand-26

История этого стандарта началась в 70-х годах с любопытной технологии — пластиковых карт с вплавленными отрезками проволоки из сплава железа, кобальта и ванадия. Этот материал назвали в честь изобретателя Джона Виганда (John R. Wiegand).

Карты Виганда были удивительно простыми, так как работали за счет физических свойств материала. Не нужно батареек, не боятся влаги, не размагничиваются. Проведите такой картой мимо считывателя, и проволочки внутри одна за другой сгенерируют последовательность электрических импульсов.

В наиболее распространенном формате — Wiegand-26, данные передаются по двум линиям: нули по одной линии, единицы по другой. Всего 26 бит, которые включают 2 бита контроля четности и 24 бита самих данных. Никакого шифрования, никакой защиты от перехвата — все как в те времена, когда самым сложным вычислительным устройством в офисе был калькулятор.

Временная диаграмма протокола Wiegand. Обратите внимание на задержки, 200 и 2000 мкс.
Временная диаграмма протокола Wiegand. Обратите внимание на задержки, 200 и 2000 мкс.

Время шло, технологии менялись: сперва магнитные карты, потом бесконтактные RFID, затем появилась биометрия. Но сам протокол Wiegand остался практически неизменным legacy. Индустрия СКУД вцепилась в него мертвой хваткой. 

Производителей можно понять: во-первых, Wiegand невероятно прост в реализации — всего три провода (DATA0, DATA1 и земля), а во-вторых, зачем менять то, что вроде бы функционирует, если замена потребует миллионов на новое оборудование?

Упрощенная принципиальная электрическая схема подключения считывателя и контроллера СКУД по протоколу Wiegand
Упрощенная принципиальная электрическая схема подключения считывателя и контроллера СКУД по протоколу Wiegand

И вот мы обнаружили технологию из 70-х в биометрической СКУД нашего собственного офиса в 2025 году. Мы сидели в переговорке, обсуждая безопасность, и кто-то из команды сказал: «Погодите, если этот протокол такой примитивный... мы же можем просто подслушать его?»

Мы решили проверить эту гипотезу на практике. Если ваша навороченная система в итоге передает данные в открытом виде по двум проводам — какая разница, считала она отпечаток пальца, лицо или карточку? В конце пути все сводится к тем же самым незащищенным битам.

И если Wiegand — это просто два провода с импульсами, то теоретически нам нужно всего лишь подключиться к ним, записать эти импульсы, а потом воспроизвести их в нужный момент.

Микроконтроллер, две кнопки и немного магии

Так родилась идея нашего импланта — мини-устройства, которое просто подключается к проводам и тихонько собирает идентификаторы всех, кто проходит через дверь. А когда надо — воспроизводит их. Главный фокус тут в том, чтобы контроллер даже не подозревал о подмене и думал, что общается со своим родным считывателем.

Мы сразу решили, что устройство должно быть компактным, в идеале размером с монету. Это сильно ограничило выбор деталей — только самое миниатюрное и доступное, никаких лишних элементов.

Начали с проектирования. Буквально за пару вечеров накидали принципиальную схему и развели плату. Параллельно определились с компонентной базой. Учитывая простоту протокола, нам должно было хватить самого базового микроконтроллера. Остановились на STM32 серии F0 с минимальной обвязкой — хороший компромисс между доступностью и функциональностью.

Аппаратная платформа

Прототип действительно получился миниатюрным — всего 25×25 мм, причем значительную часть места съедают разъемы. Если заменить их на припаянные проводки и использовать двустороннюю плату, габариты уменьшатся еще сильнее.

Общий вид платы импланта, лицевая сторона
Общий вид платы импланта, лицевая сторона

А теперь давайте рассмотрим малютку поближе. Для подключения к линиям Wiegand мы используем обычные клеммники: два сигнальных провода и общий провод для возвратного тока.

Чтобы общаться с компьютером, мы добавили порт UART с простеньким трехконтактным разъемом (RX, TX, GND). К нему подключается обычный USB-TTL преобразователь.

Общий вид платы импланта, оборотная сторона
Общий вид платы импланта, оборотная сторона

Управляется вся эта прелесть двумя кнопками: нажал одну — устройство эмулирует записанные идентификаторы, нажал другую — память очищается. Мы даже добавили перемычку, которая запускает процесс эмуляции отправки идентификаторов. По сути, это аналог того самого реле с магнитом, о котором мы рассказывали в прошлой статье.

ПО импланта

Прошивку разрабатывали на языке C в среде Cube IDE — стандартном инструментарии для микроконтроллеров STM32. Но тут мы столкнулись с первой сложностью — памяти и ресурсов у нашего малыша не так много, пришлось крепко задуматься над оптимизацией кода. Несколько раз мы переписывали код полностью, так как не оставалось места под хранение номеров карт.

Алгоритм работы устройства построен на точном соблюдении временных характеристик протокола. Когда на линии появляется импульс, устройство проверяет его длительность — по правилам Wiegand она должна быть около 200 микросекунд. 

Если импульс правильный, устройство начинает собирать биты в пакет — как пазл, кусочек за кусочком. Собрав все биты, оно проверяет биты четности, и если все ОК — сохраняет идентификатор в памяти. Места там хватит на 100 разных номеров.

Когда же приходит время притвориться считывателем, процесс идет задом наперед. Устройство формирует точные копии импульсов DATA0 и DATA1, как по нотам воспроизводя сохраненные идентификаторы. И контроллер СКУД даже не подозревает о подмене — он уверен, что общается с легитимным считывателем.

// фрагмент кода передачи битов

if(bit_level_state == LEVEL_HIGH) // если уровень сигнала на линии высокий
{
	bit_delay++;

	if(bit_delay > 9) // делаем задержку 2000 мкс. между началом первого и второго бита
	{
    	bit_delay = 0;

    	if(transfer_bit_counter > 0) // если счетчик бит на передачу еще не обнулился
    	{
        	if( ( (rfid_number_wiegand_transfer >> (transfer_bit_counter-1)) & 0x01 ) == 0x01 ) // если бит на передачу равен 1
        	{
            	HAL_GPIO_WritePin(PORT_WRITE_1, PIN_DATA_WRITE_1, GPIO_PIN_SET); // выставляем в низкое состояние на порту W1
            	transfer_bit_counter--; // уменьшаем счетчик передачи битов
            	bit_level_state = LEVEL_LOW; // выставляем низкое состояние на линии
        	}
        	else // если бит на передачу равен 0
        	{
            	HAL_GPIO_WritePin(PORT_WRITE_0, PIN_DATA_WRITE_0, GPIO_PIN_SET); // выставляем в низкое состояние на порту W0
            	transfer_bit_counter--; // уменьшаем счетчик передачи битов
            	bit_level_state = LEVEL_LOW; // выставляем низкое состояние на линии
        	}


    	}
	}
}
else if(bit_level_state == LEVEL_LOW) // если уровень сигнала на линии низкий
{
	HAL_GPIO_WritePin(PORT_WRITE_0, PIN_DATA_WRITE_0, GPIO_PIN_RESET); // выставляем в высокое состояние на порту W0
	HAL_GPIO_WritePin(PORT_WRITE_1, PIN_DATA_WRITE_1, GPIO_PIN_RESET); // выставляем в высокое состояние на порту W1
	bit_level_state = LEVEL_HIGH;
	if(transfer_bit_counter == 0)
	{
    	data_transfer_state = DATA_TRANSFER_END; // передача окончена
	}
}

Самое интересное, что вся эта магия — буквально несколько сотен строк кода. Я добавил пример, чтобы показать, насколько это все просто устроено. Конечно, в прошивке платы еще много нюансов и оптимизаций, но базовый принцип именно такой.

Стандарт, который никто не соблюдает

Мы решили подойти к делу основательно и собрали набор измерительного оборудования: осциллограф Rigol DS1052E для анализа сигналов, мультиметр Fluke 28-II (не самый дешевый, между прочим) для проверки уровней напряжения и логический анализатор Saleae Logic для детального разбора протокола.

Логический анализатор и осциллограф, использованные в проекте
Логический анализатор и осциллограф, использованные в проекте

Тестировали имплант поэтапно, как заправские инженеры. Сначала проверяли каждый компонент устройства по отдельности — что-то вроде unit-тестов, но для железа. «Работает микроконтроллер? Отлично! А кнопки? Тоже хорошо!» Потом начали соединять компоненты вместе, и тут понеслось...

Знаете, как обычно в таких историях — теория теорией, а практика преподносит сюрпризы. Вот и у нас на этапе общей функциональности начали вылезать забавные неожиданности. Оказалось, что в реальном мире все работает чуть иначе, чем пишут в учебниках.

С кодом пришлось попотеть не на шутку. Нам требовалось запихнуть уйму функций в крошечную память микроконтроллера и при этом выдержать идеальную точность таймингов. Чуть промахнулся с длительностью импульса — и контроллер просто не распознает отправленные данные.

И тут выяснилось, что производители СКУД трактуют стандарт Wiegand кто во что горазд! У одних импульсы длиннее, у других короче, третьи вообще меняют паузы между битами. Такое ощущение, что они соревнуются, кто дальше уйдет от изначальной спецификации. 

Сперва мы работали только с самым распространенным форматом Wiegand-26, но в процессе тестирования добавили поддержку других вариантов — 34, 42, 48 бит и более.

Осцилограмма Wiegand
Осцилограмма Wiegand

Пришлось погрузиться в документацию с головой. Представляете, сколько времени уходит на изучение нескольких десятков разных спецификаций? Особенно когда в каждой второй встречаются формулировки вроде «рекомендуемое значение, которое может отличаться в зависимости от реализации».

Для полноты эксперимента мы собрали целую коллекцию считывателей. Все они были построены на основных принципах Wiegand, но каждый новый образец норовил выкинуть что-нибудь этакое. Чаще всего встречались отклонения в длительности битов и пауз в большую или меньшую сторону. В итоге мы вычислили среднее значение, которое отлично работало во всех случаях.

СКУД на обеденном столе 

После всех этих испытаний мы соорудили тестовый стенд, который выглядел как типичная точка доступа в офис. 

В центре композиции красовался компактный контроллер (производства компании Bastion — забавное совпадение, да?). К нему подключили настоящий электромагнитный замок с кнопкой выхода и навесили считыватель RFID-карт. Для полного комплекта добавили немного ретро — считыватель для iButton, тех самых металлических «таблеток».

Тестовый стенд, имитирующий типичную точку доступа СКУД
Тестовый стенд, имитирующий типичную точку доступа СКУД

А чтобы добавить зрелищности, установили на стенде большую красную лампу. Она дублирует индикацию считывателя и загорается каждый раз, когда происходит успешный перехват или эмуляция кода. В реальных условиях такая иллюминация, конечно, не нужна, но для демонстрации — самое то!

Но самое интересное началось, когда мы добрались до финальных испытаний на настоящих, действующих СКУД. Огромное спасибо моим коллегам с предыдущей работы, которые первыми рискнули своими системами и позволили нам использовать их в качестве подопытных кроликов.

Тут мы окончательно убедились, насколько всё просто. Хотите взломать систему безопасности за миллионы рублей? Всего-то и нужно найти на считывателе четыре провода! Два питания (плюс и минус 12 вольт) и два провода данных (обычно зеленый W0 и белый W1). Даже цвета стандартные.

А дальше сценарий использования такой простой, что даже смешно. Аккуратно снимаем считыватель с крепления (часто это всего пара винтов), подключаем наш «имплант» к проводам и возвращаем всё на место. Теперь каждый, кто приложит свою карту к этому считывателю, невольно «дарит» нам свой идентификатор — устройство тихонько его перехватывает и сохраняет в памяти.

Потом возвращаемся, достаем наше устройство и используем сохраненные коды. Каждое замыкание перемычки на плате — и «имплант» отправляет в систему очередной идентификатор, будто кто-то поднес карту к считывателю. Для контроллера СКУД это совершенно неотличимо от легитимного использования. Дверь открывается, и никаких следов взлома или подозрительной активности в логах — идеальное преступление, если бы мы были злоумышленниками.

И ведь для создания такого устройства не нужно быть гением, только немного смекалки, плата с компонентами и несколько вечеров свободного времени.

Вместо заключения: тревожный звоночек для индустрии

Создание этого импланта — это только начало истории. Мы уже прикинули, куда двигаться дальше. Сейчас копаем в сторону более продвинутых протоколов.

У нашей маленькой платы есть потенциал для апгрейдов. Можно добавить полноценный RFID-ридер с отдельной платой и антенной или прикрутить беспроводную связь через LoRa — это позволит собирать данные удаленно, не подходя к считывателю. 

А если вам нужен вывод из нашего эксперимента, то он прост как дважды два: Wiegand на серьезных объектах в 2025 году — это как запирать сейф на замок от почтового ящика. 

Можно, конечно, попытаться защититься — спрятать провода поглубже, налепить камер, регулярно проверять оборудование на наличие лишних деталей. Но реальное решение требует комплексного подхода: производителям пора оставить доисторические протоколы в покое, а пользователям нужно привыкать оценивать безопасность СКУД в комплексе, а не по отдельным красивым компонентам и рекламным буклетам.

Надеюсь, наш маленький взлом заставит хотя бы пару человек в индустрии задуматься о рисках использования старых технологий в современных системах и подтолкнет к переменам.

А вы уже проверили свою СКУД на уязвимости? Уверены, что ваша навороченная система не сдастся перед платой размером с монетку?

PURP — телеграм-канал, где кибербезопасность раскрывается с обеих сторон баррикад

t.me/purp_sec — инсайды и инсайты из мира этичного хакинга и бизнес-ориентированной защиты от специалистов Бастиона

Теги:
Хабы:
+36
Комментарии50

Публикации

Информация

Сайт
bastion-tech.ru
Дата регистрации
Дата основания
2014
Численность
101–200 человек
Местоположение
Россия
Представитель
Игорь Santry