Skip to Content
Neue Version 12 verfügbar 🎉
ObfuscatorNuGet-PaketDefense in Depth

Defense in Depth: jede Schutzebene in einem Build

Starker Schutz entsteht nicht durch einen einzelnen Trick, sondern durch Schutzebenen. Dieses Beispiel schaltet jede Schutzfunktion des NuGet-Pakets von Babel Obfuscator für eine kleine Assembly ein. So sehen Sie die vollständige Ultimate-Konfiguration in einer einzigen Projektdatei und können sie an Ihre eigene Anwendung anpassen.

Für dieses Beispiel brauchen Sie eine Standortlizenz für Babel Obfuscator (Edition Ultimate, Server oder Data Center). Der Quellcode ist auf GitHub verfügbar:

git clone https://github.com/babelfornet/defense-in-depth-nuget-example.git

Die Anwendung ist eine kleine Funktionsfreischaltung (src/LicenseGate/FeatureGate.cs). Sie enthält genau das, was die einzelnen Schutzebenen schützen, nämlich Zeichenfolgen, numerische Gewichte, ein Array und Verzweigungslogik:

internal static class FeatureGate { private static readonly int[] Weights = { 3, 7, 11, 13, 17, 19, 23, 29, 31, 37 }; private static readonly string Pepper = "d3f3ns3-1n-d3pth-pepper"; public static GateReport Evaluate(string edition, int tokens, double budget) { bool allowed = edition is "PRO" or "ENTERPRISE" && tokens > 0 && budget >= 100.0; double score = 0.0; for (int i = 0; i < Weights.Length; i++) score += Weights[i] * (tokens + 1) * 0.5; return new GateReport(edition, allowed, Math.Round(score / budget, 4), Digest(edition, tokens)); } // Digest … }

Das Konsolenprojekt LicenseGate schichtet die Schutzebenen in Release übereinander:

<PropertyGroup Condition="'$(Configuration)' == 'Release'"> <!-- Rename & restructure --> <FlattenNamespaces>true</FlattenNamespaces> <OverloadedRenaming>true</OverloadedRenaming> <VirtualFunctions>true</VirtualFunctions> <!-- Hide data --> <StringEncryption>stream</StringEncryption> <ValueEncryption>int32=true;int64=true;single=true;double=true;array=true;true</ValueEncryption> <ResourceEncryption>true</ResourceEncryption> <!-- Obscure logic --> <ControlFlowObfuscation>if=true;switch=true;case=true;chain=true;true</ControlFlowObfuscation> <ControlFlowIterations>3</ControlFlowIterations> <DynamicProxy>external=true;true</DynamicProxy> <!-- Detect & deter runtime attacks --> <TamperingDetection>true</TamperingDetection> <DebuggingProtection>true</DebuggingProtection> <SuppressIldasm>true</SuppressIldasm> <!-- Strip metadata --> <CleanAttributes>true</CleanAttributes> <SealClasses>true</SealClasses> <BabelWarningsAsErrors>W00000</BabelWarningsAsErrors> </PropertyGroup>

Jede Eigenschaft fügt eine Schutzebene hinzu: Umbenennung und Abflachung der Namespaces verbergen die Absicht. Zeichenfolgen-, Wert- und Ressourcenverschlüsselung verbergen Daten. Kontrollflussverschleierung und Dynamic Proxy verbergen die Logik. Manipulationserkennung und Debugging-Schutz schrecken Angriffe zur Laufzeit ab. Die Bereinigung der Metadaten entfernt, was die laufende Anwendung nicht braucht. Weil das Paket eine reine Buildabhängigkeit ist (PrivateAssets=all), gelangt nichts davon in den Abhängigkeitsgraphen der Anwendung selbst, und die späteren Schritte des SDK arbeiten mit der bereits geschützten Assembly.

Ein Build des Beispiels in Release wendet all das bei identischer Programmausgabe an. Öffnen Sie das Ergebnis in einem Decompiler und vergleichen Sie es mit dem Debug-Build, um den Unterschied zu sehen. Das entspricht den Empfehlungen unter Codesicherheit verbessern: Gehen Sie von dieser Konfiguration aus und lassen Sie die Schutzebenen weg, die Sie nicht brauchen.

Last updated on