Piratage et protection des lecteurs de chiffrement LUKS


Le chiffrement du disque est conçu pour protéger les données de votre ordinateur contre tout accès physique non autorisé. Il existe une idée fausse très répandue selon laquelle le chiffrement du disque répond vraiment à cette tâche, et les scénarios dans lesquels cela ne semble pas trop exotique et irréaliste. Cet article montre que l'extraction de la clé principale d'un volume LUKS chiffré est facilement réalisable dans la pratique, et une méthode de protection (il y a longtemps) est proposée.

L'essence du problème


Nous devons également nous attarder sur l'objectif du chiffrement du disque. En effet, lorsque l'accès physique est impossible et que le système en cours d'exécution détient les données, il n'y a aucun problème. Il peut y avoir des problèmes avec la sécurité du système lui-même, mais le chiffrement du disque n'aidera pas ici. Le chiffrement de disque doit protéger les données lorsqu'une personne curieuse a la possibilité d'accéder aux disques sans passer par le système, par exemple en connectant physiquement des disques à leur système ou en chargeant leur système d'exploitation sur un ordinateur inspecté. Un scénario d'accès physique est le seul scénario dans lequel le chiffrement de disque a un sens.

Le problème est que l'attaquant peut intervenir discrètement dans la chaîne de démarrage du système d'exploitation et forcer le système à émettre des clés de chiffrement dès qu'il les reçoit au prochain démarrage.

Une telle attaque ne nécessite qu'un seul accès à l'ordinateur: les données du disque peuvent être copiées avec la substitution du circuit de démarrage, puis décryptées par eux jusqu'à ce que la clé apparaisse. Par rapport aux disques non chiffrés, le seul inconvénient est que vous devez prendre soin de la façon dont la clé est transmise et attendre qu'elle démarre.

Ensuite, nous passons à la démonstration d'une telle technique dans la pratique. Il peut s'avérer que pour sa mise en œuvre, l'attaquant aura besoin de moins d'efforts que le propriétaire du système a dépensé pour configurer certaines de ses méthodes exotiques de déverrouillage de disques (par exemple, à distance).

Démonstration pratique


Je ferai une démonstration sur l'exemple d'une machine virtuelle avec Debian 9, sur laquelle le chiffrement de disque a été activé lors de l'installation du système.

L'installation de Debian 9 avec chiffrement crée une partition de démarrage et une partition avec LVM chiffré. Capture d'écran du système installé demandant le mot de passe de déchiffrement pour plus de clarté:



Tout est prêt, vous pouvez continuer. Éteignez la voiture, copiez le disque. Dans mon cas, cela ressemble à ceci:

 [root @ dt1 ~] # virsh détruit debian9-boothack 
 Le domaine debian9-boothack est détruit

 [root @ dt1 ~] # cp -v /var/lib/libvirt/images/debian9-boothack.qcow2 ~
 '/var/lib/libvirt/images/debian9-boothack.qcow2' -> '/root/debian9-boothack.qcow2'


Montez le lecteur de la machine, extrayez l'initramdrive:

 [root @ dt1 ~] # mkdir / guest
 [root @ dt1 ~] # guestmount -a /var/lib/libvirt/images/debian9-boothack.qcow2 -m / dev / sda1 / guest
 [root @ dt1 ~] # cp -v /guest/initrd.img-4.9.0-9-amd64 ~ user / tmp
 '/guest/initrd.img-4.9.0-9-amd64' -> '/home/user/tmp/initrd.img-4.9.0-9-amd64'


Déballez initramdrive:

 [utilisateur @ dt1 tmp] $ mkdir décompressé
 [utilisateur @ dt1 tmp] $ cd décompressé /
 [utilisateur @ dt1 décompressé] $ zcat ../initrd.img-4.9.0-9-amd64 |  cpio -idm
 [utilisateur @ dt1 décompressé] $ ls
 bin conf etc init lib lib64 exécuter des scripts sbin

Terminé, vous pouvez modifier initramdrive. Sachant que la machine dispose d'une connexion réseau permanente, je souhaite organiser l'envoi crypté de la clé principale après ouverture des disques. Pour ce faire, il me faudra:

  1. Utilitaire pour l'envoi crypté sur le réseau . Ajoutez-le à /sbin
  2. Script shell pour l'extraction et l'envoi de clés . Envoyé à /scripts/local-top et ajouté à la liste /scripts/local-top/ORDER après cryptoroot .
  3. Le script de traitement d'événement udhcpc natif manquant pour démarrer le réglage automatique du réseau directement dans ramdrive, à l'aide des outils intégrés. Sa place légitime est dans /etc/udhcpc/default.script

L'exécutable secsend est construit statiquement pour éliminer les dépendances sur toutes les bibliothèques. Dans des conditions normales, l'assemblage produit un fichier de sortie de 2,7 Mo, ce qui est assez notable par rapport à la taille du ramdrive - 62 mégaoctets sous forme décompressée et 20 en format compressé. Cependant, lors de la construction de toutes les bibliothèques et de l'exécutable avec une libl musl minimale, la taille du fichier de sortie est ~ 250 Ko et 120 Ko après la compression UPX. Secsend lui-même lit simplement l'entrée standard, la crypte avec cryptobox depuis libsodium en utilisant la clé publique spécifiée Curve25519 et envoie des données à l'adresse spécifiée via TCP. Son utilisation est sans principes dans le but principal de la démonstration, cela montre plutôt que l'attaquant est essentiellement illimité: vous pouvez exécuter du code qui fait ce que l'attaquant veut et comment il le veut.

Après avoir ajouté ces trois fichiers et en avoir édité un autre, vous pouvez tout replacer et remettre le fichier modifié à sa place:

 [utilisateur @ dt1 décompressé] $ find.  |  cpio -o -c |  gzip -9> ../initrd.img-4.9.0-9-amd64
 125736 blocs
 [utilisateur @ dt1 décompressé] $ sudo cp -v ../initrd.img-4.9.0-9-amd64 / guest
 '../initrd.img-4.9.0-9-amd64' -> '/guest/initrd.img-4.9.0-9-amd64'
 [utilisateur @ dt1 décompressé] $ sudo guestunmount / guest

Il faudra un certain serveur pour recevoir une clé principale chiffrée, comme celle- ci (Python 3.5.3+). En le lançant avec la partie secrète de la paire de clés, on attend que la victime conditionnelle allume son ordinateur:



Lorsque vous allumez une machine virtuelle avec un disque chiffré, tout semble comme d'habitude, rien n'a changé:



Mais du côté de l'écouteur de connexion, une clé principale secrète est apparue:



A partir de ce moment, la machine virtuelle avec des données et son utilisateur connaissant le mot de passe de chiffrement ne présentent plus d'intérêt pour l'attaquant. Je souligne que la modification d'une phrase secrète ne modifie pas la clé principale avec laquelle le volume entier est chiffré. Même si un changement de phrase secrète se déroule d'une manière ou d'une autre entre la création d'une copie et l'envoi de la clé, ce n'est pas un obstacle. Nous utiliserons la clé principale pour ouvrir le volume. Pour ce faire, nous convertissons son entrée de journal à 16 décimales en un fichier binaire:

 [root @ dt1 ~] # echo 'fa0c53 *********** 4bd8c' |  xxd -r -p> master.key

Montez les disques avec une copie:

 [root @ dt1 ~] # modprobe nbd max_part = 8
 [root @ dt1 ~] # qemu-nbd --connect = / dev / nbd0 /root/debian9-boothack.qcow2 
 [root @ dt1 ~] # ls / dev / nbd0 *
 / dev / nbd0 / dev / nbd0p1 / dev / nbd0p2 / dev / nbd0p5
 [root @ dt1 ~] # fichier -s / dev / nbd0p5
 / dev / nbd0p5: fichier chiffré LUKS, ver 1 [aes, xts-plain64, sha256] UUID: fb732477-ef98-40b5-86a2-8526c349f031
 [root @ dt1 ~] # cryptsetup --master-key-file = master.key luksOpen / dev / nbd0p5 crackeddisk
 [root @ dt1 ~] # pvs
   PV VG Fmt Attr PSize PFree
   / dev / mapper / crackeddisk debian9-boothack-vg lvm2 a-- 19.75g 0 
   / dev / sda3 dt1 lvm2 a-- <215.01g 8.00m
 [root @ dt1 ~] # lvs
   LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy% Sync Convert
   racine debian9-boothack-vg -wi-a ----- 18,75 g                                                    
   swap_1 debian9-boothack-vg -wi-a ----- 1,00g                                                    
   racine dt1 -wi-ao ---- 215.00g                                                    
 [root @ dt1 ~] # mkdir / hackedroot
 [root @ dt1 ~] # mount / dev / mapper / debian9 - boothack - vg-root / hackedroot /
 [root @ dt1 ~] # ls / hackedroot /
 bin boot dev etc home initrd.img initrd.img.old lib lib64 perdu + média trouvé mnt opt ​​proc root run sbin srv sys tmp usr var vmlinuz vmlinuz.old
 [root @ dt1 ~] # cat / hackedroot / etc / hostname 
 debian9-boothack

Les données sont récupérées.

Mesures de protection


Comme vous pouvez le conclure, la racine du problème est le lancement de code non fiable. Voici un bref aperçu des techniques qui devraient être envisagées dans le contexte de ce numéro.

Chiffrement de la partition de démarrage


Certaines distributions offrent également cette fonctionnalité lors de l'installation (par exemple, OpenSuSE). Dans ce cas, la partition de démarrage est déchiffrée par le chargeur de démarrage, puis le noyau et initramdrive sont chargés à partir de celui-ci. Cette approche n'a pas beaucoup de sens pour les raisons suivantes:

  • Le problème le plus important avec l'usurpation de code reste toujours ouvert. Ce n'est que maintenant que le chargeur de dĂ©marrage devra ĂŞtre remplacĂ©.
  • Pour une partition de dĂ©marrage, l'intĂ©gritĂ© des donnĂ©es n'est pas plus importante, mais l'intĂ©gritĂ© des donnĂ©es. LUKS Basic Encryption ne fournit pas une telle garantie. Un avantage ici rĂ©side uniquement dans le fait qu'il est difficile de former une substitution significative sur une telle partition chiffrĂ©e.
  • Et le chiffrement LUKS2 avec vĂ©rification d'intĂ©gritĂ© (dm-intĂ©gritĂ©) ne protège pas non plus contre les interfĂ©rences, car il ne donne aucune garantie contre les attaques liĂ©es Ă  la relecture du secteur. Par exemple, en ayant un vidage d'une telle partition et une configuration du chargeur de dĂ©marrage, vous pouvez toujours prendre et restaurer le noyau Ă  l'Ă©tat copiĂ© prĂ©cĂ©demment. Cela ne donne pas d'avantages spĂ©cifiques dans la question de l'extraction de clĂ©s (sauf si l'ancien noyau Ă©tait vulnĂ©rable et peut ĂŞtre utilisĂ© d'une manière ou d'une autre), c'est plutĂ´t un argument en faveur de l'inutilitĂ© de chiffrer la partition de dĂ©marrage.

Utilisation de TPM pour stocker une clé de chiffrement et valider un environnement de démarrage sécurisé


Le TPM est essentiellement un processeur cryptographique qui agit comme une enclave sécurisée ou une carte à puce dans le système. Les données secrètes chiffrées avec elles ne peuvent être déchiffrées qu'en les utilisant et uniquement à leurs conditions - lorsque les valeurs PCR du système convergent, qui dépendent de l'état de la plate-forme et du code qui y est exécuté. La technologie est assez prometteuse et peut vous permettre d'implémenter un cryptage sécurisé dans le système sans nécessiter de clé (par exemple, en entrant avec une empreinte digitale ou des méthodes d'authentification sans rapport avec le cryptage). Idéalement, il devrait fonctionner en conjonction avec le démarrage sécurisé UEFI, interdisant le déchiffrement lorsque la configuration ne converge pas.

Cependant, sous Linux, la prise en charge du TPM en est encore à ses balbutiements. Le chargeur de démarrage TrustedGRUB2 (un chargeur de démarrage adapté pour travailler avec TPM) ne prend pas en charge UEFI et tout l'intérêt de l'idée disparaît de cela. De plus, la présence d'un TPM 2.0 fonctionnel commence à peine à apparaître dans le matériel, souvent avec les mises à jour du BIOS. La plupart des cartes mères n'ont pas de module TPM discret; au lieu de cela, le TPM est un logiciel implémenté dans Intel ME . Pour toutes ces raisons, je ne considère pas encore qu'une telle configuration fonctionne et convienne à une utilisation généralisée.

Utilisation de UEFI Secure Boot pour couvrir entièrement la chaîne de démarrage avec une signature électronique


Il existe des distributions (Fedora, OpenSuSE) et des solutions uniques qui vous permettent d'utiliser Secure Boot sous Linux. Cependant, les solutions en boîte ne fournissent souvent pas l'intégrité du code dans la chaîne de charge. Ils sont principalement conçus pour garantir que Linux démarre simplement lorsque le démarrage sécurisé est activé. Habituellement, il suffit d'utiliser une cale EFI, signée par un certificat Microsoft, qui exécute ensuite n'importe quoi. Par conséquent, lors de l'utilisation d'une certification externe, il est tout simplement impossible de couvrir la signature d'un lecteur sur disque généré directement dans le système installé.

Il existe des articles sur le hub qui suggèrent d'utiliser votre propre PKI pour signer le code. Cela vous permet de signer tout ce dont vous avez besoin par vous-même et de couvrir ainsi l'ensemble de la chaîne UEFI → bootloader → noyau et intramdrive.

  1. Apprivoiser UEFI SecureBoot - le premier article sur le hub sur ce sujet, très détaillé.
  2. Nous utilisons Secure Boot sous Linux au maximum - il est particulièrement bien expliqué ici pourquoi Secure Boot avec des certificats Microsoft installés est équivalent à son absence.

Le résultat recherché est obtenu dans le deuxième article. Une signature intramdrive est obtenue en fusionnant le ramdrive et le noyau en une seule application EFI, sans utiliser de chargeur, et UEFI vérifie directement la signature immédiatement en bloc. Les deux manuels nécessitent beaucoup de travail manuel sur chaque système protégé.

Solution abordable


J'ai proposé une approche pour la mise en œuvre complète de Secure Boot, compatible avec le schéma de démarrage généralement accepté et ne nécessitant pas d'intervention sérieuse dans le système: un chargeur de démarrage séparé, un lecteur RAM séparé, un noyau séparé. UEFI ne vérifie que la signature du chargeur de démarrage GRUB2, le chargeur de démarrage a une configuration filaire avec la clé pour vérifier la signature et le mot de passe administrateur, puis vérifie le noyau et le ramdrive. Le chargeur de démarrage signé est installé en parallèle avec l'ancien et, si nécessaire, il reste possible de démarrer de la manière habituelle en désactivant le démarrage sécurisé. Bien sûr, cette fonction doit être fermée par le mot de passe administrateur dans le menu des paramètres UEFI.

J'ai décidé d'automatiser le processus de déploiement Secure Boot avec ma propre PKI et de le rendre aussi simple et indépendant de la distribution que possible. Le résultat est exactement un tel ensemble de la recette Makefile et des utilitaires: https://github.com/Snawoot/linux-secureboot-kit . Pour debian, ubuntu, fedora et centos, l'ensemble du processus ne nécessite que quelques commandes.

Plus précisément, avec l'exemple de Debian 9, l'installation ressemble à ceci (en supposant que UEFI est déjà en mode configuration):

 apt update && apt install -y unzip make sbsigntool wget https://gist.github.com/Snawoot/1937d5bc76d7b0a29f2039aa679c0449/raw/74a63c99be07ec93cfc1df47d2e98e54920c97b7/efitools-1.9.2-static.tar.xz && \ tar xpJf efitools-1.9.2-static.tar.xz -C / wget https://github.com/Snawoot/linux-secureboot-kit/archive/master.zip unzip master.zip cd linux-secureboot-kit-master/ make debian9-install 

Ici, toutes les commandes sont entrées au nom du superutilisateur. Par conséquent, il ne reste plus qu'à vérifier que le démarrage sécurisé est activé dans le menu BIOS et à protéger les paramètres du BIOS avec un mot de passe administrateur.

Et voici la tentative de remplacer le ramdrive sur une telle installation:



Remplacement du chargeur de démarrage (l'apparence dépend de la plate-forme):



Résumé


Le chiffrement du disque seul ne suffit pas pour garantir la confidentialité des données. La signature de toute la chaîne de démarrage à l'aide de UEFI Secure Boot et GPG vous permet d'obtenir un bon niveau de protection contre l'usurpation de code exécutable, à condition que l'opérateur informatique soit capable de reconnaître une réinitialisation ou une usurpation de la carte système, ou même de tout l'ordinateur. Sinon, il est extrêmement difficile d'offrir des méthodes de protection adéquates si l'utilisateur est prêt à saisir le mot de passe / à transférer la clé sur une machine qui se retrouve accidentellement sur la table ou dans la salle des serveurs.

Source: https://habr.com/ru/post/fr457542/


All Articles