RFID Mifare Classic 공격 방법 및 카드 복제
Table of contents
보고서 목적
최근 IoT가 발전하면서, 개폐 잠금장치에 출입키 카드를 이용하면 자동으로 문이 열리는 시대에 들어섰다. 이러한 카드들은 RFID(Radio-Frequency Identification) 기술을 사용하며 전 세계 시장의 80% 이상을 점유하고 있는 NXP사의 Mifare 태그가 적용되어 있다. Mifare 태그 기반 RFID 태그 중 Mifare Classic 태그는 하드웨어적 연산이 제한적인 저가용 태그로 국내외 간단한 출입 통제와 교통카드 등 다양한 용도로 사용된다.
하지만, Mifare Classic 태그는 제한적인 하드웨어 연산을 기반으로 보안이 제공됨에 따라, 2008년 하드웨어 역공학, 부채널 공격, 난수 일치 공격 등 다양한 방법을 이용한 공격을 통해, 해당 카드의 암호화 스킴(Scheme) 및 통신 프로토콜이 여러 논문을 통해 노출되었다(강정호 외, 2013). 이러한 점과 더불어 시중에 RFID 카드를 단시간에 복제할 수 있는 기기와 모바일 기기를 이용하여 복제할 수 있는 앱 등이 공개가 되면서 RFID 카드를 이용한 범죄도 늘고 있다. 따라서 본 보고서는 RFID 공격 방법들에 관해 서술하고, Golang을 통해 RFID 카드 복제 자동화 툴을 제작하여 실제 출입 통제 역할을 하는 RFID 카드들을 대상으로 적용해 보고 오늘날 쓰이는 RFID 카드 태그 종류와 보안 상태에 관한 결과를 서술하려고 한다.
이론적 배경
RFID 기술 개요
RFID(Radio-Frequency Identification) 시스템은 RFID 태그(Tag)와 리더(Reader), 안테나, 호스트로 구성된다. RFID 태그에는 물체의 고유 식별 정보가 저장되어 있으며, 리더가 안테나를 통해 태그에 무선 신호를 보내면 태그는 태그의 정보를 응답으로 안테나에게 전송하고 안테나는 전송 받은 데이터를 디지털 신호로 바꿔 리더에게 전송한다. 리더는 전송받은 데이터를 해독하여 호스트로 보내어 분산된 리더들을 관리 할 수 있다. RFID 기술은 다양한 분야에서 활용되고 있다. 보안 시스템과 출입 통제 시스템에서는 출입 권한을 관리하는 데 활용된다. RFID는 장거리 통신이 가능하여, RFID 태그와 리더가 전파를 이용하여 무선 통으로 데이터를 송수신한다. 이 점을 이용하여 공격자는 도청, 위치추적, 스니핑 공격 등을 수행할 수 있으므로 기술이 발전함에 따라 RFID 보안은 더욱 중요시되고 있다.
RFID Mifare Classic 태그
NXP사의 Mifare Classic 태그는 국제 표준 ISO/IEC 14443A에 따라 비접촉식 스마트카드에 사용할 수 있도록 만들어져 있다.
NXP사의 공식 문서에 따르면, Mifare Classic 태그 메모리 크기에 따라 1k와 4k의 두 가지 유형으로 나눌 수 있다. EEPROM 인터페이스를 사용하며 1kB의 경우, 블록(Block) 4개로 구성된 섹터(Sector) 16개로 구성된다. 한 블록은 16바이트로 구성되며, 각 섹터의 마지막 블록을 트레일러(Trailer)라고 한다. 이 트레일러에는 두 개의 비밀 키(Key A and Key B)와 이 섹터의 각 블록에 대해 다양한 액세스 가능 조건이 포함된다. 그리고 암호화 유닛(Crypto unit)은 CRYPTO1 스트림 암호를 사용하고 있으며 CRYPTO1 암호는 데이터 교환의 인증 및 암호화에 사용된다.
[그림 1] MIFARE Classic command flow diagram
통신 과정은 [그림 1]과 같다. Power-On Reset(POR) 후에 카드는 요청 코드에 대한 응답과 함께 REQA(Request A) 또는 WUPA(WakeUp A) 명령에 응답한다. Anticollision Loop Get Identifier는 여러 장의 카드가 있는 경우 리더의 충돌을 방지하기 위해서 충돌 방지 루프(Anticollision Loop)에서 카드의 식별자를 읽어 카드를 구분하고, 카드를 하나만 선택하고 나머지 카드는 IDLE 상태로 전환되고 새 요청 명령을 기다리게 된다. Select Card는 리더가 인증 및 메모리 관련 작업을 위해 개별 카드 하나를 선택하는 과정이며 카드가 SAK(Select AcKnowledge) 코드를 반환한다. 3 Pass Authentication specific sector는 카드를 선택한 후 리더는 다음 메모리 액세스를 위한 메모리 위치를 지정하고 3단계 인증 절차에 해당하는 키를 사용한다. 인증에 성공하면 모든 명령과 응답이 암호화되며 Read Block, Write Block, Decrement, Increment, Restore, Halt, Transfer와 같은 메모리 작업을 수행할 수 있다.
3단계 인증 절차는 첫 번째로 리더가 액세스하려는 섹터를 지정하고 Key A 또는 B를 선택한다. 두 번째로 카드는 섹터 트레일러에서 비밀 키와 액세스 조건을 읽고 카드가 리더에게 과제와 같은 숫자를 보낸다. 이 과정이 1단계이다. 세 번째로 리더는 비밀 키와 추가 입력을 사용하여 응답을 계산한 후 리더의 무작위 과제와 함께 응답이 카드로 전송된다. 이 과정이 2단계이다. 카드는 리더의 응답을 자신의 과제와 비교하여 확인한 다음 리더가 전송한 과제에 대한 응답을 계산하여 리더에게 보내며 이 과정이 3단계이다. 네 번째로 리더는 자신의 과제와 카드의 응답을 비교하며 인증한다.
[그림 2] Memory organization
1024 x 8 bit EEPROM 메모리는 블록 4개로 구성된 섹터 16개로 구성된다. 한 블록에는 16바이트가 포함된다. 메모리 구성은[그림 2]과 같다.
처음 섹터 0의 첫 번째 데이터 블록 0은 Manufactuer block으로 IC칩의 제조사 측 데이터가 포함되어 있다. 이 블록은 제조 과정에서 프로그래밍 되고, 쓰기(Write) 방지된다. [그림 3]과 [그림 4]는 각각 4바이트 NUID 및 7바이트 UID 버전의 Manufacturer Block을 나타낸 것이다.
[그림 3] Manufacturer block for MF1S503yX with 4-byte NUID
[그림 4] Manufacturer block for MF1S500yX with 7-byte UID
섹터 0을 제외한 모든 섹터에는 데이터 저장을 위한 16바이트로 구성된 데이터 블록 3개가 포함되어 있다. 이 데이터 블록은 액세스 비트를 이용하여 읽기/쓰기 블록과 값(Value) 블록으로 구성할 수 있다. 값 블록은 저장된 값을 직접 제어하기 위해 증가 및 감소와 같은 추가 명령이 제공되는 전자 지갑 애플리케이션에 활용된다. 이 메모리 작업을 허용하려면 인증이 성공적으로 수행되어야 한다.
[그림 5] Value blocks
값 블록은 [그림 5]와 같이 구성되어 있다. 값 블록을 사용하면 앞서 말한 것과 같이 전자 지갑 기능을 수행할 수 있다. (읽기, 쓰기, 증가, 감소, 복원, 전송 명령이 사용할 수 있다) 값 블록에는 오류 감지 및 수정, 백업 관리가 가능한 고정 데이터 형식이 있다. 값 블록은 값 블록 형식의 쓰기 작업을 통해서만 생성할 수 있다.
값 블록의 value는 부호화된 4바이트 값을 나타낸다. value의 최하위 유효 바이트는 최하위 주소 바이트에 저장이 된다. 음수 값은 표준 2의 보수를 취하여 저장되며 데이터 무결성과 보안을 위해 값은 반전되지 않은 상태로 두 번, 반전된 상태로 한 번, 총 세 번 저장된다.
Adr은 강력한 백업 관리를 구현할 때 블록의 저장 주소를 저장하는 데 사용할 수 있는 1바이트 주소를 나타낸다. 주소 바이트는 반전된 주소와 반전되지 않은 주소를 두 번 저장하여 총 네 번 저장된다. 증가, 감소, 복원, 전송 작업은 변경되지 않은 상태를 유지한다. 이는 오직 쓰기 명령을 통해서만 변경할 수 있다.
[그림 6] Value block format example
10진수 값 1234567d와 블록 주소 17d에 대한 유효한 값 블록 형식 예가 [그림 6]에 나와 있다. 먼저 10진수 값을 16진수 표현으로 변환하면 0012D687h가 된다. 16진수 값의 LSByte(Least Significant Bit)는 Byte Number 0에 저장되고, MSByte(Most Significant Bit)는 Byte Number 3에 저장된다. 16진수 표현의 비트 반전한 값의 LSByte는 Byter Number 4에, MSByte는 바이트 7에 저장된다. 이 예제에서 주소의 16진수 값은 11h이고 비트가 반전된 16진수 값은 EEh이다.
[그림 7] Sector trailer
섹터 트레일러는 [그림 7]과 같이 구성되어 있으며 한 섹터의 마지막 블록이다. 각 섹터에는 섹터 트레일러에 읽을 때 논리 “0”을 반환하는 비밀키 A(필수) 및 B(선택)와 바이트 단위로 저장되는 해당 섹터의 블록에 대한 액세스 비트가 있다. 액세스 비트는 데이터 블록의 유형(데이터 또는 값)도 지정한다. 키 B가 선택되지 않은 경우, 섹터 트레일러의 마지막 6바이트를 데이터 바이트로 사용할 수 있다. 섹터 트레일러의 액세스 비트는 정해진 규칙에 따라 구성해야 한다. 섹터 트레일러의 바이트 9는 사용자 데이터에 사용할 수 있다. 이 바이트에는 바이트 6, 7, 8과 같은 액세스 권한이 적용된다. 섹터 트레일러를 읽으면 키 바이트는 논리 0을 반환하여 공백으로 처리한다. 만약 키 B를 읽을 수 있도록 구성하면 10~15바이트에 저장된 데이터가 반환된다. 칩 전달 시 모든 키는 FFFF FFFF FFFFh로 설정되고 바이트 6, 7, 8은 FF0780h로 설정된다.
공격 방법
다양한 공격 방법 제시 후, 툴을 이용해 UID 태그 복사한다는 방법론 쓰기
개요
앞 이론적 배경에서 언급했듯이, Mifare Classic의 주요 보안 요소는 CRYPTO 1 암호이다. CRYPTO 1 암호는 Filter 함수와 Filter 함수에 대한 입력 상태로 구성되어 있다. 이 암호화 알고리즘을 이용하여 세션 키와 같은 민감한 데이터를 암호화하는데 사용한다. 또한, 매 클록 주기마다 난수(Nonce)를 생성하는 난수 생성기(RNG)를 활용한다.
Mifare Classic은 스트림 암호 Crypto 1을 사용하여 인증데이터의 기밀성과 무결성을 보장하며, 앞서 말한 것과 같은 3단계 인증 절차를 통하여 Challenge-Response 인증을 사용한다. 언뜻 보기에 이러한 기술은 완벽한 보안을 보장하는 것처럼 보이지만 의도하지 않은 민감한 정보, 전반적이거나 부분적인 세션 키가 유출되어 UID, Card 난수, 인증 데이터 및 일부 오류 메시지를 분석하여 섹터 키를 검색할 수 있다.
Mifare Classic의 공격은 Crypto 1 암호의 취약점에 의해서 발생한다. Crypto 1 암호는 몇 가지 결함이 존재한다. 1) 프로토콜이 시작될 때 섹터 키가 초기 상태에 있고, 2) 최상위 9비트는 출력 계산에 사용되지 않으며, 3) 홀수 상태 비트만 출력과 관련이 있고, 4) 그 결과는 엔트로피가 낮다. 위의 결함들을 종합하면 Crypto 1의 입력과 일부 출력을 통해 초기 상태를 쉽게 복구할 수 있다. 구체적으로 공격자는 리더와 카드의 인증 데이터를 보호하는데 사용되는 UID, Card 난수 및 모든 세션 키를 알고 있는 섹터 키를 알아낼 수 있다.
기존 Mifare Classic 카드는 각 클록 주기마다 16bit LSFR(Liner feedback shift register)를 기반으로 하는 특정한 RNG을 가지고 있다. 인증 절차에서는 16bit 엔트로피만 가진 16bit LSFR에 의해 생성된 32bit 난수가 사용된다. 이때 엔트로피가 상당히 낮기 때문에 짧은 시간 내에 동일한 난수를 생성할 수 있다. 따라서 공격자는 클록 주기에 따른 난수가 생성이 되므로 클록 주기를 이용하여 생성된 난수값을 예측 가능하다.
Default Key Search
NXP는 Mifare Classic 카드를 제조할 때, 액세스 통제 시스템을 통합하기 위해 테스트를 가능하게 하기 위해서 기본 키를 설정한다. 이러한 기본 키 들은 잘 연구되어 있으며 [표 1]은 잘 알려진 기본 키 후보이다. 따라서 공격자는 알려진 기본 키 후보들을 사용하여 대상 카드의 모든 섹터에 대한 인증을 반복적으로 시도 함으로써 기본 키를 사용하는 취약한 섹터를 찾을 수 있다. 이 취약한 섹터는 일반적으로 데이터 블록이 비어있기 때문에 카드를 공격할 때 섹터 키를 무시할 수 있다. 하지만 이 섹터 키는 기본 키가 아닌 사용자 지정 섹터 키를 복구하는 둥지 공격(Nested Attack)에 중요한 정보를 제공한다.
[표 1] Well-researched default key candidates.
Dark Side Attack
홀수 패리티 비트 메커니즘은 데이터 송수신 과정에서 데이터의 오류를 검출하는데 사용된다. 카드가 리더의 암호화된 인증 데이터를 수신하면 데이터를 해독하고 패리티 비트의 유효성을 식별한다. 만약 패리티 비트는 올바르지만 리더의 인증 데이터가 유효하지 않은 경우 카드가 세션 키를 사용하여 {NACK}으로 표시되는 보호된 4비트 NACK(Acknowledge) 값을 생성한다. 이 경우 NACK은 0x5와 동일하다. {NACK}을 보호 하는 데 사용 된 4비트 세션키는 노출된 NACK 상수 값으로 xor 연산을 통해 복구가 된다.
공격자는 리더의 인증 데이터 전송 단계까지 합법적인 카드로 인증을 스푸핑한다. 마지막으로, 공격자는 인증을 연속적으로 시도하여 다음과 같은 정보를 얻는다. 고정된 카드 난수로 가능한 8개의 모든 리더의 답변에 따라 {NACK}과 적절한 패리티 비트를 얻기 위해 연속적으로 인증을 시도한다. 이에 따라 획득한 정보(UID, Card Nonce, {NACK})에 대한 8개의 세션 키, 8개의 패리티 비트) 에서 섹터 키는 CRYPTO 1 취약점에 따라 유도된다.
Varying The Card Nonce Attack
이전 공격 방법과 달리 공격자는 카드 난수를 변경할 수 있다. 즉, 이 공격은 카드 난수를 고정하거나 예측할 필요가 없다. 공격을 수행하기 전에 공격자는 두 개의 4바이트 인증 데이터가 동일하고 0일 때 {NACK}에 대한 8비트 패리티 비트 및 4비트 세션 키가 모두 0이 되도록 48비트 상태로 구성된 미리 계산된 테이블을 만든다. 이 상태는 리더의 인증 데이터를 보호하는 첫 번째 세션 키 비트를 생성하는 데 사용 된다. 미리 계산된 테이블에는 약 2^36 요소가 포함되어 있다.
공격자는 리더의 응답이 두 개의 4바이트 데이터와 8비트 패리티 비트로 구성되므로 모든 0을 전송하여 대상 카드에 인증을 반복적으로 시도한다. 0x5의 {NACK}이 포함된 카드 난수를 수신하면 공격자는 시도를 중단한다. 세션 키가 {NACK}과 동일하고 모두 0이면 {NACK}의 값은 0x5이기 때문이다. 이 조건에서는 올바른 카드 난수와 섹터 키에 따라 {NACK}에 대한 적절한 8비트 패리티 비트와 4비트 세션 키가 결정된다. 따라서 공격자는 평균적으로 2^12 회 인증을 시도한 후 적절한 카드 난수를 얻게 된다.
그런 다음 공격자는 적절한 카드 난수와 UID를 입력으로 사용하여 미리 계산된 테이블에 롤백 체계를 적용하여 약 2^36 초기 상태를 재구성하고 전체 초기 상태에 대해 성공할 때까지 카드에 대한 인증을 시도한다.
이 공격에는 384GB의 ROM 스토리지와 약 2^36 인증 시도가 필요하다. 따라서 이 엄청난 메모리 요구량과 통신 횟수는 이 방법의 가장 단점이라고 할 수 있다.
Nested Attack
리더가 카드의 한 섹터에 대한 인증을 이미 완료한 경우, 다른 섹터에 대한 새로운 인증은 암호화된 카드 난수와 함께 시작되며 수행된다. 카드 난수는 후속 섹터의 섹터 키에서 유도된 세션 키로 보호된다. 공격자가 만약 난수를 알고 있는 경우 해당 세션 키를 복구한다. 마지막으로, 섹터 키는 CRYPTO 1 취약점을 통해 세션 키에서 유도된다.
PRNG는 매 클록 주기마다 난수를 생성한다. 따라서 후속 인증을 위한 두 번째 카드 난수는 첫 번째 난수 값과 첫 번째 카드 난수 요청 명령의 시간에 의해 결정된다. 따라서 적어도 하나의 섹터 키를 알고 있다면 다른 섹터 키를 복구할 수 있다. 이 공격은 온라인 단계에서 세 번의 인증 시도가 필요하며 오프라인 단계에서 키를 유출 위해 두 번의 시도가 필요하다.
Genuine Reader Attack
위의 네 가지 공격과 달리 이 방법은 카드가 아닌 정품 리더를 대상으로 한다. MIFARE CLASSIC 통신 과정에서 시간 초과가 발생하면 세션 키에 의한 보호와 함께 32비트 HLAT 명령이 전송된다. HLAT는 ISO/IEC 14443A-3 표준에 정의된 상수 값이다. 공격자는 다음과 같을 때 올바른 카드 인증 데이터를 전송 할 수 없는 경우, {HALT} 명령을 받고, 그리고 HALT 명령에는 세션키가 포함되어 있다. HALT는 카드의 인증 데이터 전송 단계에서 0x500057CD와 동일하다. 또한 카드 난수를 사용하여 리더의 인증 데이터에서 또 다른 세션 키가 공개된다. 두 세션 키 모두 CRYPTO 1 취약점에 따라 섹터 키가 생성된다.
Successful Authentication Data Attack
이 공격은 성공적인 인증 데이터가 필요하다는 점을 제외하면 위의 Genuine Reader Attack과 유사하다. 성공적인 Mifare Classic 통신 과정은 UID, 카드 난수, 리더와 카드의 인증 데이터 등 섹터 키를 복구할 수 있는 충분한 정보가 포함된다. 두 인증 데이터에서 서로 다른 세 개의 세션 키가 유도된다는 점을 고려하면 위의 공격과 매우 유사한 방식을 섹터 키 복구가 쉽게 수행된다. 이 공격은 기본 통신 과정을 방해하지 않고 키를 알아내는 데 많지 않은 계산이 필요하기 때문에 매우 강력하다. 하지만, 공격자는 무선 트래픽을 도청할 수 있어야한다.
Mifare Classic 카드 복제
Help
명령어는 SecuCard 툴의 도움말을 출력한다.
Copy
명령어는 자동으로 UID와 Type (1 OR 4)를 추출하여 새로운 카드에 복사한다.
Chk
명령어는 현재 카드 정보에 대한 데이터를 제공한다.
HwChk
명령어는 현재 하드웨어의 정보를 제공한다.
MfChk
명령어는 보안 취약점인 MIFARE Classic 1k인지 확인한다.
이로써, Golang 언어를 활용하여 자동화 툴을 직접 제작하면서 RFID 태그 복사가 자동으로 할 수 있는 도구를 제작 완료했습니다.
결론
직접 제작한 자동화 툴을 통해 실제 Mifare Classic 카드들을 복제하면서 대다수 카드가 기본 키를 사용하여 쉽게 복제할 수 있었다. 2023년 10월 10일 국회 과학기술정보방송통신위원회 소속 국민의힘 박성중 의원이 과기정통부 소관 70개 기관으로부터 제출받은 자료에 따르면 RFID 출입증 제작 과정에 보안 규격을 요구한 곳은 26개에 불과했다. 나머지 기관은 복제가 가능할 수도 있는 RFID 출입증을 사용하고 있는 셈이다. 최상의 보안을 유지해야 하는 ’가급 국가 보안시설’인 원자력연구원과 ‘나급 보안시설’ 한국핵융합에너지연구원도 추가 보안 규격이 전혀 없는 RFID 출입증을 사용하고 있었다. 기술이 발전하면서 RFID 카드키 사용도 늘고 있으므로 사소한 것에도 보안을 집중하는 능력이 필요하다.
감사의 말
이 보고서를 함께 작성하고, 내용이 더 완성도 있게 다듬어질 수 있도록 많은 도움을 주신 @is07king 님께 진심으로 감사드립니다. 블로그에 이 보고서를 업로드할 수 있도록 흔쾌히 허락해 주신 점 또한 깊이 감사드립니다.
참고 문헌
[1] NXP product data sheet, “MIFARE Classic EV 1K – Mainstream contactless smart card IC for fast and easy solution development Rev. 3.2,” https://www.nxp.com/docs/en/data-sheet/MF1S50YYX_V1.pdf
[2] Hyunjin Ahn, Yerim Lee, Su-Jin Lee, Dong-Guk Han. (2016). Optimal MIFARE Classic Attack Flow on Actual Environment. 전기학회논문지, 65(12), 2240-2250.
[3] 김운주, 김지현, 서필성, 정유민, 김종민. (개최날짜). RFID 취약점 보안을 위한 기술 제안. 한국정보통신학회 종합학술대회 논문집, 개최지.
[4] RFID 기술 개요 ”[세상을 바꾸는 무선통신기술] 제 2탄. 무선주파수기술의 장거리선수! ‘RFID’” https://news.samsungsemiconductor.com/kr/세상을-바꾸는-무선통신기술-제-2탄-무선주파수기술
[5] 관련 뉴스 “최상급 보안시설인데…‘5초 만에 복제되는 RFID 키’ 사용” https://www.yna.co.kr/view/AKR20231008022800017