Présentation du problème

Un problème intéressant a été soumis, concernant un message ViewState chiffré dans les journaux d’application Windows. Le message faisait 1316 caractères et contenait probablement du code malveillant, mais était chiffré. Le seul élément disponible était une image disque de l’hôte, à partir de laquelle le fichier web.config du site affecté a été extrait. Les clés auto-générées ont été trouvées dans le registre Windows, mais il n’était pas clair comment les utiliser pour déchiffrer le message ViewState.

Complexité du déchiffrement

La complexité du déchiffrement d’un message ViewState varie de triviale pour les configurations héritées (il suffit de supprimer le hash de validation à la fin du tampon, puis de déchiffrer en utilisant la bonne clé et l’algorithme symétrique) à complexe pour les configurations modernes, qui ont historiquement impliqué l’utilisation de la réflexion pour « tromper » IIS et déchiffrer les valeurs pour nous. Les outils tels que CyberChef et Blacklist3r sont généralement utilisés pour déchiffrer les messages ViewState, mais peuvent être difficiles à utiliser.

Génération des clés auto-générées

Les clés auto-générées sont des blobs de données de 1024 octets qui contiennent les clés de validation et de déchiffrement de la machine IIS à des emplacements spécifiques. La génération de ces clés se fait dans la méthode System.Web.HttpRuntime::SetAutogenKeys().

internal static byte[] s_autogenKeys = new byte[1024];
   private static void SetAutogenKeys()
   {
       byte[] randBytes = new byte[HttpRuntime.s_autogenKeys.Length];
       byte[] autogenKey = new byte[HttpRuntime.s_autogenKeys.Length];
       bool existingKeyLoaded = false;
       RNGCryptoServiceProvider rngcryptoServiceProvider = new RNGCryptoServiceProvider();
       rngcryptoServiceProvider.GetBytes(randBytes);
       if (!existingKeyLoaded)
       {
           existingKeyLoaded = UnsafeNativeMethods.EcbCallISAPI(IntPtr.Zero, UnsafeNativeMethods.CallISAPIFunc.GetAutogenKeys, randBytes, randBytes.Length, autogenKey, autogenKey.Length) == 1;
       }
       if (existingKeyLoaded)
       {
           Buffer.BlockCopy(autogenKey, 0, HttpRuntime.s_autogenKeys, 0, HttpRuntime.s_autogenKeys.Length);
           return;
       }
       Buffer.BlockCopy(randBytes, 0, HttpRuntime.s_autogenKeys, 0, HttpRuntime.s_autogenKeys.Length);
   }

Dérivation des clés de machine

La clé de validation principale est simplement les 64 premiers octets de la clé auto-générée, tandis que la clé de déchiffrement principale est les 24 octets suivants. Ces clés sont utilisées pour déchiffrer les messages ViewState.