Если после прочтения статьи про чтение кода ключа-таблетки iButton, Вам в голову пришла мысль, что можно сделать и обратную комбинацию – значит мы мыслим в одинаковом направлении :)
Сразу хочу сказать, что эта идея далеко не новая, и воспользовавшись поиском можно найти различные решения – примеры можно найти в конце статьи в ссылках.
Итак, что же нам нужно?
А нужно нам всего-навсего произвести симуляцию 1-Ware slave-устройства, выдавая себя за iButton :)
Для этого нужно вспомнить, что происходит в линии 1-Wire:
Сначала происходит 1. инициализация – ведущее устройство (домофон) подаёт импульс RESET, после него ведомое устройство (это мы) должно дать ответ PRESENCE (прижать линию к земле на 60 — 240 микросекунд)
Далее происходит сам обмен информации: 2. домофон выдает команду на чтение ПЗУ (ROM) – это должно быть 33h.
Информация, как мы помним, передаётся побайтно, бит за битом.
При этом «0» передаётся прижиманием линии к земле в течении всего тайм-слота (60 — 120 микросекунд)
А «1» передаётся кратковременным прижиманием (на 1-15микросекунд) и последующим отпусканием линии. 3. домофон выдерживает некоторое время и начинает посылать импульсы приема информации.
Т.к. в ответ ожидается 8 байт информации – будет 64 импульса (по одному импульсу для передачи каждого бита информации от нас).
Если мы хотим передать «0» — мы удерживаем линию на логическом нуле, а если хотим передать «1», то можем ничего не делать :)
Эмулируя ключ, мы должны сначала передать номер серии устройства 01h.
Затем собственно 6 байт номера ключа (начиная с младшего байта) и в самом конце – байт CRC-кода предыдущей информации.
Для ключа, рассмотренного в статье про iButton – это будет последовательность байт:
01h 41h
CEh
67h
0Fh
00h
00h
B6h
Попробуем это дело запрограммировать :)
Чтобы не бегать постоянно к домофону – начальную проверку можно попробовать сделать в протеусе :)
Поместим в проект две ардуины – в одну загрузим скетч работы с iButton, а во вторую будем грузить код нашего эмулятора :)
Кроме того, при симуляции схемы можно воспользоваться виртуальным инструментарием. Например, подключив в Протеусе на линию 1-Wire виртуальный осциллограф – можно вживую понаблюдать – как происходит обмен информацией :)
блок-схема скетча для эмуляции iButton будет такой
А если мы не знаем ключ – сможем ли мы его подобрать перебором?
Оценочно прикинем – сколько времени понадобится на подбор ключа :)
У моего ключа-таблетки номер
00000F67CE41
, что даёт нам возможность предположить, что пока для нумерации iButton-ов используются первые 4 байта номера :)
Вне всяких сомнений — это меньше 281 биллиона, которые можно спрятать в шести байтах :)
И даёт нам всего 4 миллиарда вариантов :)
0xFFFFFFFF = 4294967295
Прикинем — сколько времени займёт проверка одного ключа:
PRESENCE ~ 480 мкс
8 бит команды 120 мкс * 8
64 бита данных 120 мкс *64
Итого ~ 10 мс => 100 ключей в секунду (в датащите упоминается про 75 ключей в секунду)
Получается, что на полный перебор потребуется 497 дней :( Что-то долго :)
В интернете упоминается, что такой брутфорс (brute force) на домофонах не сработает и после трёх неправильных ключей домофон загудит и впадёт в ступор на 5 минут :)
Однако выход есть – дело в том, что на некоторых моделях домофонов в новой чистой памяти домофона (предназначенной для хранения ключей жильцов) все биты установлены в 1 (т.е. забиты FF-ами).
И если ключ будет выдавать тоже единицы, то программа подумает, что в чистой памяти тоже хранятся коды ключей и они совпадают с тем, что записано в нашем универсальном ключе и дверь откроется :)))
Это действительно дыра в программном обеспечении контроллера и есть во всех дешёвых контроллерах. Причём простая до смеху. Контроллер проверяет ключ (причём обычно только последнии 4 байта — контроллер то дешёвый) с записаными в ЭСПЗУ. А как выглядят пустые ячейки? То есть если записать ключ вида FFFFFF......FFFFFF что будет? Правильно, он уже везде прописан :) Подверженны все домофоны типа Цифрал ТС, Визит, Метаком
А где же скетч эмулятора?
Дело в том, что мы решили устроить небольшой конкурс :) Первый приславший работоспособный ардуиновский скетч эмулятора iButton-а получит Protoshield в подарок!
Ниже приводится набросок такого скетча – вам остаётся только освежить в памяти – что происходит на линии 1-Wire и наполнить кодом функции:
void wire_send_byte(byte dsbyte)
byte wire_read_byte()
void wire_write0(void)
void wire_write1(void)
или же полностью переписать скетч самостоятельно ;)
Условия конкурса:
— скетч должен быть написан на Wiring-е
— код ключа должен храниться в статическом массиве
— скетч должен быть опробован в работе ;)
Ваши варианты скетча присылайте по адресу admin@robocraft.ru с пометкой Конкурс iButton!
Набросок скетча (ВНИМАНИЕ – СКЕТЧ НЕ ДОПИСАН ДО КОНЦА):
/*
* Эмулируем работу ключа-таблетки iButton типа DS1990A
*
*
*
* http://robocraft.ru
*/
int onepinio = 10; // порт для подключения 1-Wire
// данные ключа - номер серии, 6 байт номера, байт CRC
byte key_data[8] = {0x1, 0x41, 0xCE, 0x67, 0x0F, 0x00, 0x00, 0xB6};
void setup()
{
Serial.begin(9600);
}
void loop()
{
// считываем импульс RESET из линии
//
wire_read_RESET();
//
// выдаём в линию импульс PRESENCE
//
wire_PRESENCE();
//
// считываем команду от домофона
//
int b = wire_read_byte();
//
// что за команду считали? :)
//
if(b==0xF0) // SEARCH ROM
{
//
// начинаем двубитную передачу :(
//
wire_send_duos_bits();
}
else
{
if(b==0x33) // READ ROM
{
//
// отправляем данные iButton :)
//
wire_send_data();
}
}
delay(300);
}
//
// ждём пока линия не прижмётся к земле
//
void wire_wait()
{
pinMode(onepinio, INPUT);
while(digitalRead(onepinio))
{
delayMicroseconds(1);
}
}
//
// двубитное общение с ведущим устройством - см. AN187
//
void wire_send_duos_bits()
{
}
//
// считываем импульс RESET из линии
//
void wire_read_RESET()
{
pinMode(onepinio, INPUT);
while(digitalRead(onepinio))
{
delayMicroseconds(1);
}
while(!digitalRead(onepinio))
{
delayMicroseconds(1);
}
}
//
// выдаём в линию 1-Wire сигнал PRESENCE
// для этого нужно прижать линию к земле на 60-240 микросекунд, а затем отпустить
//
void wire_PRESENCE()
{
pinMode(onepinio, OUTPUT);
digitalWrite(onepinio,LOW); // прижимаем линию к земле
delayMicroseconds(120); // 60-240 микросекунд
pinMode(onepinio, INPUT); // отключаемся
delayMicroseconds(450);
}
//
// выдача в линию данных iButton
//
void wire_send_data()
{
for(int i=0;i<8;i++)
wire_send_byte(key_data[i]);
}
//
// выдача в линию байта данных
//
void wire_send_byte(byte dsbyte)
{
}
//
// считываем байт данных из линии
//
byte wire_read_byte()
{
}
//
// пишем бит "0" в линию
//
void wire_write0(void)
{
}
//
// пишем бит "1" в линию
//
void wire_write1(void)
{
}
Вот ответы на все, заданные здесь вопросы (чтение, запись, EEPROM на 63 ключа, дублирование, эмуляция):
PS Библиотеку(OneWireSlave2) немного подкорректировал. Там где оболочка ругалась(она четко пишет в каком файле, какая строка, функция...) на несовпадение типов изменял в библиотеке char на byte. Комменты делал для себя. Так что не пинайте.
Бонус: коды «универсальных ключей» для домофонов (как записать их в EEPROM разбереесь :) Исходник и библиотека
Комментарии (13)
RSS свернуть / развернутьx0wl
noonv
x0wl
x0wl
x0wl
x0wl
Sicness
admin
gori-gori
Продаются же перезаписываемые ключи, значит можно их как-то прошить
saniks
PS Библиотеку(
Бонус: коды «универсальных ключей» для домофонов (как записать их в EEPROM разбереесь :)
GAD
olegsis32
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.