
CVE-2022-27499
Ceci est la démo originale de l’attaque par snapshot non anticipée que nous avons découverte. Merci à Intel pour l’avis de sécurité.
Tout d’abord, toute personne souhaitant exécuter la démo doit installer le SDK Intel SGX et Occlum (vous pouvez choisir d’utiliser notre SDK SGX modifié). Nous fournissons un Dockerfile pour une installation rapide d’Occlum et du SDK. Le SDK SGX modifié est destiné à aider l’attaquant à décider du timing.
Vous pouvez également installer Occlum sur la machine hôte. (Veuillez vous référer à https://github.com/occlum/occlum pour plus de détails d’installation.) Dans les deux cas, vous devrez d’abord installer le pilote Intel SGX sur votre hôte, ou utiliser un pilote SGX intégré au noyau.
(sudo) docker build -t $Your_Image_Name .
Une fois l’image construite, exécutez
(sudo) docker run -it --privileged -p $Redis_Server_Port:6379 -v $Host_SGX_Driver_Path:/dev/sgx --name "snapshot-demo" $Your_Image_Name
Ici, $Redis_Server_Port est le numéro de port de l’hôte que vous souhaitez exposer pour le serveur Redis dans le conteneur, tandis que $Host_SGX_Driver_Path est le chemin du périphérique susmentionné de votre pilote SGX installé.
Le programme cible se trouve dans le dossier bash_redis.
Le programme victime exécute un script bash (occlum_bash.sh). Il récupère d’abord un mot de passe provisionné pour générer un fichier de configuration Redis personnalisé, avec l’entrée « requirepass » remplie. Il lance ensuite un serveur Redis, conformément au fichier de configuration personnalisé.
Pour construire le programme de génération de configuration, exécutez make. Pour construire le serveur Redis, exécutez les commandes suivantes.
cd bash_redis
./download_and_build_redis_glibc.sh
Ouvrez un terminal pour la victime. Exécutez run_redis.sh, en vérifiant que le serveur Redis fonctionne correctement.
Utilisez la commande redis-cli -h $Redis_Server_IP -p $Redis_Server_Port -a admin123456 pour vérifier si le mot de passe (admin123456) a été défini dans le fichier de configuration.
Appuyez sur ctrl + C pour terminer le serveur Redis.
Préparez 2 terminaux, un pour la victime et un pour l’attaquant. Vous ne pouvez ouvrir qu’un seul terminal supplémentaire (pour l’attaquant) si un terminal a déjà été ouvert pour la victime.
Exécutez à nouveau run_redis.sh sur le terminal de la victime. Ce script démarrera le programme cible.
L’attaquant doit prendre un snapshot (en utilisant ./take_snapshot_step-1.sh) lorsqu’il peut déterminer que le snapshot est en cours d’écriture. Dans la démo, l’attaquant peut obtenir un avertissement clair depuis le terminal de la victime comme suit.
...
Run ./take_snapshot_step-1.sh NOW!
line 4522: # passwords, then flags, or key patterns. However note that the additive
line 4523: # and subtractive rules will CHANGE MEANING depending on the ordering.
line 4524: # For instance see the following example:
...
Lancez le script ./take_snapshot_step-1.sh sur le terminal de l’attaquant.
Si vous construisez Occlum avec notre SDK SGX modifié, vous verrez davantage de messages d’indication. Cela est dû au fait que nous avons modifié la partie non fiable du SDK Intel SGX, qui imprime des messages d’aide pour faciliter la décision du timing par l’attaquant. Pour la commodité de l’attaquant, nous réservons des intervalles de temps pour permettre à l’attaquant d’exécuter ./take_snapshot_step-1.sh. En fait, l’attaquant disposant du privilège root sur l’hôte pourrait intercepter l’exécution de l’enclave et capturer n’importe quel snapshot en modifiant la partie non fiable du SDK SGX.
Une fois que le serveur Redis est opérationnel et en cours d’exécution, exécutez ./take_snapshot_step-2.sh pour terminer la collecte du snapshot.
L’attaquant exécute replay_redis.sh pour rejouer l’enclave en utilisant le snapshot que nous avons collecté. N’importe quel client peut se connecter au serveur Redis sans authentification.
Exemple de commande pour le client Redis :
redis-cli -h $Redis_Server_IP -p $Redis_Server_Port
keys *
Si un message (error) NOAUTH Authentication required. s’affiche, cela signifie que vous aurez besoin d’un mot de passe pour accéder au serveur Redis. Tapez auth $Your_Password pour réussir l’authentification. Dans cette démo, utilisez auth admin123456.
Si un message (empty array) s’affiche, cela signifie que vous n’avez pas besoin de mot de passe pour accéder au serveur Redis.
Parfois, la démo échoue en raison du contrôle d’intégrité d’Occlum. Vous verrez probablement le message suivant.
Replaying ...
~/snapshot-demo/bash_redis_replay/occlum_instance ~/snapshot-demo/bash_redis_replay
In: writing meta-data in write_all_changes_to_disk
In: writing meta-data in write_all_changes_to_disk
Error: Os { code: 22, kind: InvalidInput, message: "Invalid argument" }
[ERROR] occlum-pal: The init process exit with code: 1 (line 59, file src/pal_api.c)
[ERROR] occlum-pal: Failed to run the init process: EINVAL (line 129, file src/pal_api.c)
Exécutez simplement la démo à nouveau (à partir de la phase d’enregistrement), puis l’erreur disparaîtra définitivement.
Bonne chance et amusez-vous bien !