RFID модуль PN532: как я домофонный ключ скопировал

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

Ладно, мы люди не гордые, идем в ближайший «Дом быта», просим сделать копию. Там берут, прикладывают к своей шайтан-машине и возвращают. Правда без копии. Потому что копию сделать нельзя. Потому что безопасность должна быть безопасной и ключик зашифрован. Не унываем, идем в другую мастерскую… в третью… после пятой приходит понимание, что мы в жопе и спасение утопающих — дело рук самих утопающих. Беглое сканирование показало, что мы имеем дело с ключом стандарта Mifare Classic.

Disclaimer
Товарищ майор, данная статья носит исключительно образовательный характер и не преследует целей по взлому транспортных карт и иных устройств, основанных на Mifare Classic. Автор не поддерживает и осуждает любые киберпреступления.

1. Железо
Из оборудования понадобится купить только RFID-модуль PN532 (я использовал версию V3). На июнь 2021 года стоит платка менее 500 рублей. Остальное скорее всего у вас есть: компьютер и usb-uart преобразователь. В качестве последнего я использовал многострадальный Pinboard с ft232 на борту, вы можете использовать любой другой, но народ жаловался, что модуль на cp2102 почему-то работает не всегда корректно.



Работать будем по UART — и тут есть подвох. На некоторых платах RX- и TX-выводы не обозначены. В таком случае, поступаем просто: смотрим на 4-пиновый разъем: после пина VCC идет TXD (на месте SDA), а следом — RXD. Подключаемся к компу, запускаем свой любимый терминал, выставляем скорость 115200, открываем нужный порт и посылаем следующую HEX-последовательность:

55 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 03 FD D4 14 01 17 00

Модуль должен ответить:

00 00 FF 00 FF 00 00 00 FF 02 FE D5 15 16 00

На скриншоте ниже представлен вывод на примере программы Terminal v1.9b.



Если все прошло успешно, отключаемся, идем дальше. Если нет — проверяем питание модуля, пробуем менять местами RX и TX, перезагружаем компьютер, переустанавливаем винду, протираем экран тряпочкой… Ну и так далее, пока не заработает.

2. Ставим Linux на виртуалку
КЭП, но если у вас уже линух, то эту часть можно пропустить. С остальными продолжим. Ставить будем Ubuntu Server 16.04. Описывать установку на VirtualBox я не буду — там все стандартно:

  • качаем торрент-файл по официальной ссылке
  • скачиваем образ
  • создаем виртуалку (гигов 10 диска, гига 4 ОЗУ), в сетевых настройках виртуалки выставляем «сетевой мост»
  • подцепляем образ в качестве загрузочного диска
  • запускаем виртуалку
  • выбираем английский язык
  • нажимаем Install Ubuntu

Дальше стандартная установка по типу next-next-ok (везде все выбираем по дефолту). В результате будет создана виртуалка. Заходите под своим логином/паролем, который указали на этапе установки.



Далее набираете:

sudo su -

Еще раз введите пароль. Теперь, когда вы под рутом, установите ssh (если не сделали этого на этапе установки системы):

apt install -y ssh

Далее узнайте свой ip:

ip a



Если вы не забыли указать сетевой мост в начальных настройках, и ваш роутер поддерживает DHCP, то будет назначен ip из подсети вашего роутера.

Сворачиваем окно виртуалки, открываем putty, вбиваем адрес, который только что узнали, попадаем в консоль:



Все, теперь удобно копипастить команды из браузера на сервер :-)

Возвращаемся в окно виртуалки, нажимаем ПКМ на значок USB и пробрасываем uart-порт в виртуалку, как на скрине ниже.



Сворачиваем виртуалку, идем в putty, дальше работаем уже там.

3. Внутри Linux
Итак, мы сделали проброс usb-порта из винды в убунту. Если же у вас изначально Linux, то просто вытащите-воткните usb-uart переходник. Набираем в консоли команду:

dmesg



В моем случае обнаружилось два rs232 порта: ttyUSB0 и ttyUSB1. Пробуем подключиться. Отключаем UART-переходник от PN532, на переходнике закорачиваем RX и TX, в консоли заходим под рута:

sudo su -

Запускаем команду:

screen /dev/ttyUSB0 115200

Вместо "/dev/ttyUSB0" должен быть ваш порт. Экран очистится и на нем будет отображаться только курсор. Пробуем набирать любой текст с клавиатуры.



Если текст набирается успешно, значит выбран правильный rs232-интерфейс и он работает корректно. Если же терминал молчит, то попробуйте выбрать другой порт (например, /dev/ttyUSB1). Должно заработать — ведь как-то у вы прошли тест из первой главы? Получилось? Отлично, продолжаем.

Нажмите Ctrl+A, затем Shift + K, затем Y — так вы выйдете из терминала.


Небольшое (но полезное) дополнение, которое можно пропустить

Наберите (находясь все так же под рутом) команду:

echo "termcapinfo xterm ti@:te@" >> /etc/screenrc

Выходим из putty и подключаемся заново. Теперь набираем

screen

Далее нажмите Enter и войдите под рутом:

sudo su -

Выполните, например, команду:

ls -lh /

Получите список файлов и директорий:



Теперь закройте окно putty, подключитесь заново и наберите:

screen -rd



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

Ctrl + A , затем Esc

Теперь вы можете перемещаться выше-ниже по предыдущему экрану (курсором, либо PgUP/PgDown). Для выхода из этого режима нажмите еще два раза Esc. Можно и просто записать все что выводилось на экран в файл (разумеется, в пределах размера буфера, который указывается через переменную defscrollback в файле /etc/screenrc):

Ctrl + A, затем двоеточие, затем hardcopy -h /tmp/filename.txt

Все это очень удобно, если у вас прервалась putty-сессия во время какого-то процесса (например, ребутнулся роутер во время подбора ключей) и нужно подключиться в состояние «как было».

4. Установка nfc-tools
Подключаем обратно PN532. Дальше все довольно стандартно. Находясь под рутом, набираем:

apt install -y autoconf libtool libpcsclite-dev libusb-dev git pkg-config
mkdir /dist
cd /dist
git clone https://github.com/nfc-tools/libnfc.git
cd ./libnfc
autoreconf -vis
./configure --with-drivers=pn532_uart
make install clean
ldconfig
mkdir /usr/local/etc/nfc

Создаем файл конфигурации:

nano /usr/local/etc/nfc/libnfc.conf

Вместо nano можете заюзать любой удобный редактор (я предпочитаю vim). В файле прописываем:

allow_autoscan = true
allow_intrusive_scan = false
log_level = 1
device.name = "PN532_UART"
device.connstring = "pn532_uart:/dev/ttyUSB0"

  • log_level — уровень логирования (если не работает, увеличьте до 3, будет более подробный вывод команды)
  • device.connstring — тут после двоеточия указываем путь до порта, полученный на этапе dmesg.

Сохраняем, прикладываем пустой ключик (идет в комплекте с платой PN532), набираем команду:

nfc-list

Если ошибок не появилось (скрин ниже), ключик успешно считан, можно продолжать.



Иногда модуль может подвисать (причем подвисание сохраняется и при перезагрузке):

error   libnfc.driver.pn532_uart        pn53x_check_communication error
nfc-list: ERROR: Unable to open NFC device: pn532_uart:/dev/ttyUSB0

В этом случае отключаем проброс USB (убираем галку).



Далее выполняем тест через терминал из п.1 статьи и делаем проброс USB обратно. Должно заработать.

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

cd /dist
git clone https://github.com/nfc-tools/mfoc.git
cd ./mfoc
autoreconf -vis
./configure
make

Для теста приложите болванку из комплекта PN532 к модулю и выполните:

/dist/mfoc/src/mfoc -O /dist/dump.mfd



Чтение ключа должно пройти без ошибок, а на выходе получится дамп. Теперь попробуйте приложить свой домофонный ключ и запустить заново. Программа будет долго пытаться использовать стандартные криптоключи, но в итоге у нее ничего не получится и она выдаст ошибку: «No sector encrypted with the default key has been found, exiting..»



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

6. Darkside Attack: установка mfcuk
Mfcuk является реализацией атаки Mifare Classic «Dark Side» Key Recovery, основанной на статье Nicolas T. Courtois The dark side of security by obscurity, которая использует уязвимости ГПСЧ и ответов об ошибках Mifare карт. Для нас это лишь означает, что эта тулза может выломать криптоключ опорного (как правило, нулевого) сектора, а остальные ключи уже можно будет получить через подборщик mfoc. Ликбез окончен, начинаем установку!

Сначала все стандартно:

cd /dist
git clone https://github.com/nfc-tools/mfcuk.git
cd ./mfcuk
autoreconf -vis
./configure

А дальше нужно применить небольшой патч. Дело в том, что согласно вот этой статье, существуют «weaker» ключи, а в mfcuk не существует логики по данному типу. В результате тулза крутится сутками, а результата нет. Впрочем, статья 2016 года и может уже починили (последний коммит mfcuk от 2018 года), но мы рисковать не будем и сделаем проще: скопируем пропатченные исходники с гитхаба автора статьи:

wget "https://raw.githubusercontent.com/unixpapers/mfcuk/master/mfcuk.c" -O src/mfcuk.c
wget "https://raw.githubusercontent.com/unixpapers/mfcuk/master/crapto1.c" -O src/crapto1.c

И если вы подумали, что это все, то нет. Автор упомянутой статьи, поправив один баг, наплодил другой. Хорошо, что есть комменты :) Цитата: «В авторском фиксе файлов crapto1.c/mfcuk.c есть нюанс — там sleepmillis заменено на sleep. На win* системах оно работает корректно, а в unix-like — нет, в 1000 раз медленнее». Ну что же, исправим это досадное недоразумение:

sed -i "s/sleep(/sleepmillis(/g" src/mfcuk.c

Проверяем:

cat src/mfcuk.c | grep "sleepmillis(" > /dev/null && echo OK

Должно выдать ОК. Теперь можно и компилировать:

make

Далее прикладываем домофонный ключик к плате (желательно приклеить скотчем, чтобы не сполз), переходим в папку src и набираем команду:

cd src
./mfcuk -C -R 0:A -s 250 -S 250








Через некоторое время (примерно через час) начинают вылезать первые результаты. На строчки ERROR не обращайте внимание. Ваша задача — дождаться, пока пара ключей maxhii/maxloi начнут от вывода к выводу повторяться. Однако, не спешите прерывать сканирование. На скрине выше показан пример ложного срабатывания. Далее можно видеть пример правильного ключа, обычно он начинает появляться на maxhi/maxlo равным 5-6.

В конце скриншота можно наблюдать ошибку: «Segmentation fault (core dumped)». Причину ошибки выяснить так и не удалось, а возникать она может уже на первых итерациях, когда ключ еще не найден, тогда приходится начинать все заново. После того, как я заменил металлическую подставку под платой на картонную коробку, ошибка стала вылетать гораздо реже. Возможно, возникали какие-то наводки и программе сносило крышу.

Если вы прождали пару часов, а программа так ничего и не выводит, то шансов уже меньше, некоторые ключи просто не поддаются копированию. Например, у меня получилось натравить эту тулзу только на оригинальный ключик. На копию не было никакой реакции. Как вариант, оставьте сканироваться на ночь. Не помогло? Попробуйте собрать оригинальный mfcuk, может он у вас сработает.

Получилось? Теперь нужно собрать криптоключик. Берем последние 6 цифр maxhii (включая начальные нули, если они есть), аналогично 6 цифр maxloi, в нашем случае получается: be33fef612ae. Теперь можно начинать подбор остальных ключей.

7. И снова mfoc
Заходим в папку /dist и запускаем переборщик с нашим криптоключом (сразу укажем количество попыток -P 20000).

cd /dist
/dist/mfoc/src/mfoc -O /dist/dump.mfd -P 20000 -k be33fef612ae

Если вместо скрина ниже будет ошибка «No sector encrypted...», то это означает, что вы поспешили остановить работу mfcuk и следует повторить последние действия из предыдущей главы.



На скрине можно видеть, что для нулевого сектора ключ подошел и mfoc начинает подбор остальных ключей. Это может занять довольно продолжительное время. Причем, иногда один ключ подбирается несколько часов (особенно, первый), а иногда за час может прилететь два-три ключа. У меня на подбор оставшихся 15 ключей ушло где-то часов 8. Кроме того, эта тулза так же может выдавать ошибку «Segmentation fault (core dumped)». После чего ее нужно запускать снова, указывая последовательно все найденные ключи:

/dist/mfoc/src/mfoc -O /dist/dump.mfd -P 20000 -k be33fef612ae -k 0d57fd3aafa5

Лучше всего это автоматизировать. Я для этого заюзал два простейших скрипта. Скрипт перебора: mloop.sh

#!/bin/bash
while :
do
cat key.log | xargs ./mfoc -O /dist/dump.mfd -P 20000
done

И скрипт добавления найденных ключей в файл key.log, а также оповещения в телеграм: mtest.sh

#!/bin/bash
while :
do
cat mfoc.log | grep "Found Key" && echo -k $(cat mfoc.log | grep "Found Key" | grep -oE "\[.*\]" | tr -d "[" | tr -d "]") >> key.log && cat key.log && echo && echo > mfoc.log && curl "https:
//api.telegram.org/bot12345678:ANYTOKEN/sendMessage?chat_id=-123456654321&text=key_found$(cat key.log | wc -l)" > /dev/null 2>/dev/null
sleep 10
done
Вместо «bot12345678:ANYTOKEN» следует вставить токен своего телеграм-бота, а вместо "-123456654321" — ID чата, куда будет отправляться сообщение.

Эти скрипты следует создать в папке /dist/mfoc/src/. В той же папке нужно создать файл key.log, куда прописать найденные ключи (как минимум, один) в следующем формате

-k be33fef612ae
-k 0d57fd3aafa5

Да, я знаю, что mfoc умеет полноценно работать с файлами ключей, но обнаружил я это уже потом, а переписывать скрипт было лень.

Теперь запускаем:

cd /dist/mfoc/src/
bash mloop.sh >> mfoc.log &
bash mtest.sh &

Вывод mfoc можно мониторить командой:

tail -f mfoc.log

Этот лог затирается после каждого найденного ключа. В результате вам будет периодически капать сообщение:



Кроме того, автоматом будет пополняться файл key.log, а так же в консоль будут выводиться сообщения:

Found Key: A [fb5162d7c339]
-k be33fef612ae
-k 0d57fd3aafa5
-k fb5162d7c339

Так что найденные ключи не потеряются, даже если у вас нет телеграм бота. Когда будет найден 16-й ключ, работу скриптов следует прекратить:

fg
Ctrl + C
fg
Ctrl + C

Проверьте, что скрипты больше не выполняются:

ps -ax | grep [m]test
ps -ax | grep [m]loop

Если по какой-то причине они еще висят, то их следует убить командой kill. Теперь можете попробовать сделать дамп:

cd /dist
cat /dist/mfoc/src/key.log | xargs /dist/mfoc/src/mfoc -O /dist/dump.mfd

В результате должно получиться следующее:



И вот у вас на руках дамп dump.mfd, который вы можете теперь при наличии ключей заливать куда угодно и использовать. Так что же, победа?! Как бы не так…

8. Заливка дампа и несколько последних рывков
Первое, что приходит в голову, это залить дамп на ключик, который шел в комплекте с PN532. Ну что же, попробуем это сделать. Для этого сначала нужно получить его дамп. Прикладываем пустой ключ к плате и запускаем mfoc:

/dist/mfoc/src/mfoc -O /dist/dump_empty.mfd

Запускаем само копирование:

nfc-mfclassic w A  /dist/dump_empty.mfd /dist/dump.mfd




Успешно! Теперь идем к домофону, дрожащей рукой прикладываем ключик и… Облом! Домофон даже не пискнул. В чем же дело?

Возвращаемся обратно, прикладываем этот ключ к PN532, делаем отдельный дамп:

cat /dist/mfoc/src/key.log | xargs /dist/mfoc/src/mfoc -O /dist/dump_new.mfd

Теперь сравниваем два дампа:

cmp -l /dist/dump.mfd /dist/dump_new.mfd | gawk '{printf "%08X %02X %02X\n", $1, strtonum(0$2), strtonum(0$3)}'




А вот и косяк! Первый (нулевой) сектор ключа оказался не перезаписан! А он чуть ли не самый главный, ведь там хранится ID, который вносится в память домофона. Пробуем записать еще раз. Форматируем китовый ключ:

nfc-mfclassic f A u /dist/dump_new.mfd /dist/dump_new.mfd

Делаем дамп:

/dist/mfoc/src/mfoc -O /dist/dump_empty.mfd

Теперь запишем дамп, но с ключом -W, который указывает, что нужно писать в нулевой сектор тоже.

nfc-mfclassic W a /dist/dump_empty.mfd /dist/dump.mfd




FAIL!

Так что же делать? Где взять подходящий ключ? Самый простой вариант — купить ключ Mifare Zero, стоит рублей 30-40 и у него нулевой сектор можно записать сколько угодно раз. Что же, пробуем:

/dist/mfoc/src/mfoc -O /dist/dump_empty.mfd
nfc-mfclassic W a /dist/dump_empty.mfd /dist/dump.mfd




Успешно!

Теперь бежим и… хотя нет, мы теперь умные, сначала сравниваем дампы:

cat /dist/mfoc/src/key.log | xargs /dist/mfoc/src/mfoc -O /dist/dump_new.mfd
cmp -l /dist/dump.mfd /dist/dump_new.mfd | gawk '{printf "%08X %02X %02X\n", $1, strtonum(0$2), strtonum(0$3)}'

Успешно! Ни одного выпавшего байта, для верности сделаем даже сравнение md5-сумм:

md5sum /dist/dump.mfd /dist/dump_new.mfd




Идеальное совпадение с оригинальным ключом. Идем теперь к домофону, прикладываем наш новый ключ и… слышим в ответ презрительное молчание. Да в чем теперь-то дело?! Ключи ведь идентичны!

Успокоившись, мы узнаем, что хотя содержимое ключей и совпадает, почти все современные домофоны научились фильтровать Mifare Zero. На смену им пришли One-Time Programmable (OTP) ключи, у которых нулевой сектор можно записать только один раз, но они гораздо лучше маскируются под оригинал. Большинство домофонов (в том числе и мой) спокойно проглатывают MF OTP-2.0, но для более привередливых существуют MF OTP-3.0. Стоят они обычно раза в полтора дороже, но они работают!

Покупаем такой ключик, делаем дамп, записываем…

/dist/mfoc/src/mfoc -O /dist/dump_empty.mfd
nfc-mfclassic W a /dist/dump_empty.mfd /dist/dump.mfd

Уже без особого энтузиазма идем к домофону и… Бинго!!! Оно заработало! =)

Статья, на которую опирался в этом нелегком пути:

https://mysku.ru/blog/ebay/41849.html

Во вложении пропатченные mfcuk файлы — на случай недоступности (не забудьте заменить sleep на sleepmillis, как описано в статье).
Так же добавил архивы с оригинальными nfc-tools, mfcuk, mfoc — на случай, если их на гите забанят.

За сим всё!

Файлы в топике: mfcuk_patched.tar, mfcuk.tar, libnfc.tar, mfoc.tar

Комментарии (14)

RSS свернуть / развернуть
MIFARE Classic и его знаменитое очень надёжное шифрование *CRAP*TO-1 :-)
0
Кстати, если перехватить общение оригинального ключа и домофона, то ключи вытаскиваются все и мгновенно. Там очень, очень плохо с безопасностью.
0
а чем оно перехватывается? Сниффер какой-то?
0
Да, есть снифферы. Антенна, такая же как в карточке, физически помещается между карточкой (ключом, тегом) и считывателем (домофоном).
+1
Автору за труды от меня плюс. Но все же легенда с ключом мне кажется мало правдоподобной.
Когда у нас потерялся один из ключей, то было достаточно позвонить в обслуживающую фирму и договориться о времени прибытия их сотрудника. Приехал на следующий день их сотрудник в условленное время и на моих глазах провел манипуляцию между домофоном и чипом посредством набора некоего кода на самом домофоне. Всего по времени это заняло около пяти минут. По деньгам я заплатил 30 молдавских Лей за чип, и столько же за вызов. Вот и все пляски с бубном.
0
Ну возможно и правда было бы логичней обратиться напрямую в обслуживающую компанию (если она есть :)), но как до нее достучаться никто не знал, а ключик был очень нужен, впрочем… водная часть — она на то и водная, сколько там правды, каждый решает сам :)
0
Все очень просто. Достаточно заглянуть внимательно в платежку, там как правило указаны телефонные контакты с любой компанией предоставляющей услуги, будь то: вода, газ, телефон, электричество или тот же домофон.
Вот как то так.
0
Мысль интересная, попробую — отпишусь )
0
С безопасностью в этих системах действительно все обстоит плохо. По видимому такие устройства как и обычные дверные замки рассчитаны лишь на честных людей.
0
Нормально обстоит, если не экономить. DESFire так просто не скопируешь, особенно если использовать SAM'ы нормальные (чипы с ключевым материалом в ридере) а не базовые чипы ридеров. Но стоит не $0.1 а $5 за ключ и не $1 а $20 за домофон. Вот и делают то, что делают.
MIFARE Classic очень старая система. И правда не очень удачная. Но просто самая дешёвая.
0
Также прошел путь описанный ТС в вводной части. Также около 5 мастерских просто отказали, но во одной сделали 2 «копии» — с условием, что если ключи не подойдут то вернут деньги. Деньги вернули. Но ключ то нужен. Оказывается что в Нерезиновой этот бизнес подгребла под себя ОДНА компания. Она ставит домофоны и барыжит брелками. На ее сайте можно ввести адрес и получить информацию по Вашему домофону и стоимости копии. Там же есть адрес мастерской. Не сказать что бы большая очередь, но народ шел постоянно. Мастер спрашивал документ, подтверждающий ваше право на «вход в подъезд» — прописка в паспорте или иной документ и оперативно копировал или просто выпускал по значению адреса новые брелки за денежку. И да — мой брелок тоже был с такой же заморочкой — Mifare classic.
0
Любопытно…
0
Про классики инфы полно, а у нас УК поставила визиты и просит по 600р за ключик. А в ключике ультралайт, без какого либо шифрования, но с 7 байт UID, производства отечественного микрона. И копируется всё это только на заготовки UL-3, которые купить можно, но хз как на них писать кроме как аппаратным девайсом для копирования за много денег, ибо в открытом доступе никакой инфы и софта под эти заготовки найти не удалось.
0
У нас тоже визит, но видимо повезло — классик. А у вас точно ультралайт? Проверьте NFC-сканером (если в тлф. есть такая функция).

У меня по модели домофона, что я нагуглил, ключ тоже должен быть 7-байтный (VIZIT-RF3), а по факту оказался 4-байтный классик.
0
Проверял конечно. UID 34D70881519CB7 ATQA 0044 SAK 00
Я даже нашёл где её смогли скопировать, причём в копии скопированы только первые 7 страниц, а в оригинале ещё страницы 16, 20 и 24 содержат одну и ту же отличную от нуля запись. Но копия работает.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.