The English version: https://glitch0ne.com/2023/10/12/lf-rfid-shenanigans/
Disclaimer: Atacul și tehnicile despre care vă povestesc aici trebuie încercate doar pe dispozitive personale sau dispozitivele unor persoane care și-au dat acordul explicit pentru asta. Nu sunt responsabil pentru modul în care alte persoane folosesc informațiile prezentate mai jos. Mulțumesc!
Fiind un mare fan al motto-ului surorii lui Dexter, “Uuu! La ce e bun acest butoon?”, mă găsesc deseori în situații în care cunoștințele mele deja existente mă ajută doar până la un punct. Astfel, într-o zi fatidică de vară, am decis să-ncerc să copiez un RFID de frecvență joasă pe care-l aveam, ca să-mi pot da seama dacă-l pot salva și emula cu Flipperul. Și deși părea să fi mers, cipul fiind recunoscut ca un EM4100, un tip clasic de cip care poate fi ușor emulat, cititorul nu-mi recunoștea încercările de emulare. Neavând mai multe informații, am decis să-ncerc asta mai târziu, odată ce voi fi avut acces la ceva unelte mai puternice.
După ceva vreme au ajuns și jucăriile. În sfârșit reușisem să obțin acces la un Proxmark 3, o unealtă clasică pentru cercetare și dezvoltare în domeniul RFID, și cu aceasta am reînceput încercările de a emula cipul care nu a mers din prima. Și-am rămas doar cu încercarea, eșuând o a doua oară. Cu toate astea, Proxmark-ul avea capabilități mult mai puternice decât Flipper-ul și mi-a permis să analizez mai îndeaproape datele pe care le primeam de la sistemul pe care încercam să-l simulez. Și de-aici începe cu adevărat povestea.
Pentru context, EM4100 este un cip RFID destul de cunoscut, folosit în multe sisteme de control al accesului. Acesta stochează și transmite date folosind un format specific, care arată așa:
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | Header de 9 biți setați pe 1 |
| 8 biți pentru numărul versiunii sau identificatorul de client | D00 | D01 | D02 | D03 | P0 | Fiecare grup de 4 biți e urmat de un bit de paritate par | |||
| D04 | D05 | D06 | D07 | P1 | |||||
| 32 biți de date | D08 | D09 | D10 | D11 | P2 | ||||
| D12 | D13 | D14 | D15 | P3 | |||||
| D16 | D17 | D18 | D19 | P4 | |||||
| D20 | D21 | D22 | D23 | P5 | |||||
| D24 | D25 | D26 | D27 | P6 | |||||
| D28 | D29 | D30 | D31 | P7 | |||||
| D32 | D33 | D34 | D35 | P8 | |||||
| D36 | D37 | D38 | D39 | P9 | |||||
| 4 biți de paritate pe coloană | PC1 | PC2 | PC3 | PC4 | S0 | Un bit de stop, întotdeauna 0 | |||
Am aruncat o privire peste datele binare pe care le-am primit de la cipul nostru misterios și am încercat să văd dacă avea un format similar, și am descoperit că așa era. Sau cel puțin, o parte din el urmărea același format. Vezi tu, majoritatea biților transmiși se aliniau cum trebuie cu formatul la care mă așteptam, ceea ce înseamnă că un cititor simplu ar fi văzut asta ca pe un cip clasic EM4100
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | Header de 9 biți setați pe 1 | |||
| 8 biți pentru numărul versiunii sau identificatorul de client | 0 | 0 | 0 | 0 | 0 | Fiecare grup de 4 biți e urmat de un bit de paritate par | ||||||
| 0 | 0 | 1 | 1 | 0 | ||||||||
| 32 biți de date | 1 | 1 | 1 | 0 | 1 | |||||||
| 1 | 0 | 0 | 0 | 1 | ||||||||
| 1 | 0 | 1 | 1 | 1 | ||||||||
| 0 | 1 | 0 | 1 | 0 | ||||||||
| 1 | 1 | 1 | 0 | 1 | ||||||||
| 1 | 1 | 0 | 0 | 0 | ||||||||
| 0 | 1 | 0 | 1 | 0 | ||||||||
| 1 | 0 | 1 | 1 | 1 | ||||||||
| 4 biți de paritate pe coloană | 0 | 1 | 1 | 1 | 0 | Un bit de stop, întotdeauna 0 | ||||||
| Date în plus? | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | ||||
| 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | |||||
| 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | |||||
| 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | |||||
Cu toate astea, după formatul clasic de EM4100 mai erau niște bucăți în plus. Mai exact, 4 biți de date pe care de acum îi voi scrie în format hexadecimal pentru că biții-s greu de citit și nu cred că un procesor o să-mi citească articolul prea curând: 0x7E1EAAAA.
În principiu, motivul pentru care încercările mele inițiale de a citi și emula cardul au eșuat, este că jucăriile mele au presupus că ceva ce arată ca o rață și măcăne ca o rață e cu siguranță o rață. Din păcate, rața asta avea o coadă curios de lungă, și n-avea cum să încapă în cuibul pe care i-l pregătisem. Cum aș putea să pun datele de pe cipul meu, pe un alt suport?
T5577 intră-n schemă
T5577 este un cip care are potențialul de a emula o groază de tipuri diferite de cipuri RFID de frecvență joasă, împreună cu protocoalele folosite, în timp ce are și spațiu mai mult de stocare. Atâta timp cât e configurat cum trebuie, și datele sunt scrise corect în memoria sa, ar trebui să funcționeze și să se comporte ca orice alt cip RFID LF. Formatul în cauză arată cam așa:
| Pagina 1 | L | Configurare opțiune pentru front-end analogic | Bloc 3 | |||
| 1 | Date de trasabilitate | Bloc 2 | ||||
| 1 | Date de trasabilitate | Bloc 1 | ||||
| L | Date de configurare pentru pagina 0 | Bloc 0 | ||||
| Pagina 0 | L | Date utilizabile sau parolă | Bloc 7 | |||
| L | 32 biți de date | Bloc 6 | ||||
| L | 32 biți de date | Bloc 5 | ||||
| L | 32 biți de date | Bloc 4 | ||||
| L | 32 biți de date | Bloc 3 | ||||
| L | 32 biți de date | Bloc 2 | ||||
| L | 32 biți de date | Bloc 1 | ||||
| L | Date de configurare | Bloc 0 | ||||
Bun, deci ce știm pân-acuma? Avem un cip necunoscut de frecvență joasă, care se comportă cam ca un EM4100, dar care ține date în plus fix după bitul de stop. În teorie, am putea configura un T5577 să arate și să măcăne ca rața noastră, scriind datele următoare pe primul bloc din prima pagină:
0x00148060
Datele astea în principiu configurează cipul să funcționeze la o rată de transfer de 64 de cicluri, folosind encodare Manchester, și oferind datele până la al treilea bloc, blocuri care în total conțin 96 de biți de date. 64 de biți pe care îi întâlnim pe un EM4100 clasic, și 32 de biți de date misterioase, super securizate.
Imediat după, scriem în memoria cipului datele pe care vrem să le ofere, în blocuri de 32 de biți, care în hexadecimal ar arăta cam așa:
0xFF80DD8D
0xD5DC2AEE
0x7E1EAAAA
Astfel, am configurat T5577-le să transmită toate datele care erau inițial pe cipul nostru misterios, acesta putând fi recunoscut de cititoarele pe care le foloseam la testare. Sfârșit!
Totuși, ce însemnau datele alea misterioase? Mno, aș putea face niște presupuneri, cea principală fiind că producătorul a vrut să adauge puțină „securitate” cardurilor sale, pentru a nu permite încercări triviale de copiere sau emulare. Și deși asta a funcționat pentru un moment în cazul meu, imediat ce am pus mâna pe ceva unelte mai performante, misterele au fost demistificate, și-au fugit cu tot cu securitatea lor. Umblă vorba că datele alea de la final sunt la fel pentru mai multe cipuri de la acel producător (ca un fel de semnătură) ceea ce înseamnă că pentru moment nu semnifică mare lucru.
Morala poveștii ar fi că, dacă sunteți un producător care consideră să folosească acest tip de securitate prin obscuritate, ar trebui să știți că cineva, undeva, o să vadă direct prin tertipurile de genul ăsta.
Referințe
- Descrierea protocolului EM4100: https://www.priority1design.com.au/em4100_protocol.html
- Ghid T5577: https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/T5577_Guide.md
- Flipper Zero: https://flipperzero.one/
- Proxmark 3: https://proxmark.com/proxmark-3-hardware/proxmark-3-rdv4