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