Nicolas RUFF – Analyse d`une backdoor .NET
Transcription
Nicolas RUFF – Analyse d`une backdoor .NET
Une backdoor chinoise en .NET Nicolas RUFF nicolas.ruff(à)eads.net Historique ??? 6 décembre 2011 16 décembre 2011 10 janvier 2012 • Attaques ciblées dans la nature • Publication de l'avis de sécurité APSA11-04 • http://www.adobe.com/support/security/advisories/apsa11-04.html • Publication du correctif Adobe Reader 9.4.7 • Publication du correctif Adobe Reader 10.1.2 Historique Principe général de l'attaque 2 1 4 Le shellcode extrait un fichier exécutable embarqué (en général chiffré par un XOR) Un PDF malveillant est transmis par email Le shellcode "nettoie" le PDF et l'ouvre à nouveau 3 Le fichier exécutable s'installe en tant que résident (backdoor) Backdoor(s) • Poison Ivy: la plus courante • http://www.poisonivy-rat.com/ • Mais chaque "équipe" a ses techniques/outils C:\> file scvhost.exe scvhost.exe: PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows Backdoor(s) • Ca s'annonce long et pénible … Format .NET • Format PE + métadonnées .NET – Logées dans l'ancienne "COM Directory" – Très peu documentées pendant fort longtemps • http://www.ntcore.com/files/dotnetformat.htm – Encore très peu d'outils capables de les manipuler pefile, metasm, miasm … CFF Explorer, Phoenix Framework?, … Format .NET Format .NET Format .NET Format .NET Protections en .NET • Techniques anti-analyse "statique" – – – – – Renommage des méthodes / classes / variables de classe / … Obfscuation des constantes / chaines de caractères / … Obfuscation du flot de contrôle Code / objets sérialisés … • Techniques anti-analyse "dynamique" – – – – – Vérification du contexte d'exécution Vérification de type Réflexion Signature … Protections en .NET • Techniques plus avancées – – – – – Code natif Cryptographie Activation en ligne … Cf. protecteurs commerciaux • Xenocode, 9Rays, … • Un binaire .NET reste plus difficile à protéger qu'un binaire natif – Note: la compilation native est possible avec NGEN.EXE Protection statique en .NET • Renommage – Une table contient tous les noms en instance unique • Cf. format DEX utilisé par Android – Il serait possible de renommer "à la main" • … mais il est ardu de renommer si la taille des chaines change – Rebel.NET est un "PoC" • Il faut créer un ".H" qui contient tous les renommages • http://www.ntcore.com/rebelnet.php – Note: une fois le code importé dans Visual Studio, il est très simple de le "refactoriser" • … même s'il ne compile pas Protection statique en .NET • Manipulation d'une assembly – "System.Reflection" ne semble pas fait pour ça • Difficulté à modifier du code existant • Difficulté à sauvegarder le code modifié – "Mono.Cecil" est beaucoup plus puissant pour cette tâche • http://www.mono-project.com/Cecil – … surtout lorsqu'il est combiné avec Reflexil • http://reflexil.net/ Protection statique en .NET • Cheat sheet pour Mono.Cecil + Reflexil ad = Mono.Cecil.AssemblyDefinition.ReadAssembly(...) md = Mono.Cecil.ModuleDefinition.ReadModule(...) foreach td in md.Types foreach fd in td.Fields foreach md in td.Methods foreach pd in md.Parameters mb = md.Body foreach vd in mb.Variables – Note: Mono.Cecil n'a aucune documentation officielle • Fonctionne bien avec: – Classe, méthodes, variables de classe • Mais beaucoup plus de plomberie pour: – Manipuler les variables locales Protection statique en .NET • La preuve qu'on peut faire partie du problème et de la solution Protection statique en .NET • Obfuscation des constantes Protection statique en .NET • Code masqué – Se trouve dans une ressource "chiffrée" – La clé est fournie par un "générateur de constantes" fortement obfusqué – Dans ce cas, l'analyse dynamique est plus simple Stream manifestResourceStream = executingAssembly.GetManifestResourceStream("Resources.binary.resources"); Protection dynamique en .NET • Vérification de type dynamique if (Assembly.GetCallingAssembly() == typeof(ProtectedClass.c000016).Assembly)) ... Protection dynamique en .NET • Vérification que l'assembly n'est pas utilisée comme référence depuis un projet tiers Assembly executingAssembly = Assembly.GetExecutingAssembly(); Assembly callingAssembly = Assembly.GetCallingAssembly(); ... Protection dynamique en .NET • Vérification de la hauteur de pile d'appel StackTrace trace = ... StackFrame frame = MethodBase base2 = Type type = (base2 ... new StackTrace(skipFrames, false); trace.GetFrame(skipFrames); (frame == null) ? null : frame.GetMethod(); == null) ? null : base2.DeclaringType; Protection dynamique en .NET • Utilisation de la clé de signature publicKeyToken = assemblyName.GetPublicKeyToken(); ... Protection dynamique en .NET • Aucun test booléen – Trop facile à "patcher" – Au contraire, les résultats sont intégrés dans le calcul d'une constante "magique" Revue des outils • Il existe 3 possibilités: – System.Reflection – Mono.Cecil • Capable d'ouvrir une assembly sans l'exécuter – http://www.monoproject.com/Cecil#Differences_with_other_alternatives – Librairie "maison" • En général non maintenu / non publique Revue des outils • Analyse statique Outil Avis ILDASM / ILASM Fourni avec Visual Studio - ultrabasique Spices.NET Commercial - peu adapté aux codes obfusqués Reflector Commercial - basé sur System.Reflection - peu adapté aux codes obfusqués dotPeek Successeur de Reflector - à suivre JustDecompile Successeur de Reflector - à suivre ILSpy Bien mais la 2.0 est encore mieux Phoenix Framework Statut du projet chez Microsoft ? SAE Parfait pour les codes obfusqués de4dot Orienté "protections commerciales" … … Revue des outils • Analyse dynamique Outil Avis mDBG Basé sur ICorDbg* - PoC non maintenu Outils Foundstone & al. Basé sur les API de performance - peut être intéressant dans certains cas - SAE offre globalement la même fonctionnalité WinDbg + SOS.DLL Puissant mais inutilisable avec du code obfusqué ILSpy 2.0 Très prometteur PE Browse Dbg Logique de la GUI ... ? DILE Non maintenu … .. Conclusion • Faire une backdoor en .NET n'était pas une mauvaise idée • Les compétences et les outils sont plus rares que dans le monde natif