Skip to content
← Alle Beiträge
· Delta1 Labs Nebula.NETObfuskierungSicherheit

Report-home: erfahren, wann ein geschützter .NET-Build im Feld angegriffen wird

Anti-Tamper- und Anti-Debug-Wächter reagieren auf der Maschine des Nutzers — aber Sie erfahren nie, dass sie ausgelöst haben. Das Report-home von Nebula.NET (tamperReportUrl, Pro) POSTet ein minimales Ereignis an Ihren eigenen Endpunkt in dem Moment, in dem ein Wächter auslöst, sodass ein Angriff auf einen ausgelieferten Build zu einem verwertbaren Signal wird. So funktioniert es und so bauen Sie den Empfänger.

Sie härten einen .NET-Build gut. Kontrollfluss-Verflachung, String- und Methodenverschlüsselung, Anti-Tamper, Anti-Debug, Umgebungsprüfungen — das volle Programm. Sie liefern ihn aus. Und dann hören Sie nichts, was Sie sich als gute Nachricht einreden. Aber „Stille” und „niemand greift meine Software an” sind nicht dasselbe. Jeder dieser Wächter löst auf der Maschine des Kunden aus, reagiert dort und hinterlässt keine Spur, die Sie je sehen. Ein Cracker verbringt ein Wochenende damit, Ihre Lizenzprüfung in einem Debugger durchzusteppen, Ihr Anti-Debug-Wächter löst ein Dutzend Mal aus, und Sie erfahren davon genau nichts.

Das Report-home von Nebula.NET (tamperReportUrl, eine Pro-Funktion) schließt diese Lücke. Wenn ein Wächter auslöst, POSTet die geschützte App auch ein winziges Ereignis an einen Endpunkt, den Sie betreiben — sodass ein Angriff auf einen Build im Feld zu einem Signal auf Ihrer Seite wird statt zu einem Schulterzucken. Dieser Beitrag ist ein tiefer Einstieg darin, was er sendet, was er bewusst nicht sendet, und wie Sie den Empfänger bauen, der diese Ereignisse in etwas verwandelt, auf das Sie reagieren.

Der blinde Fleck der clientseitigen Schutzmaßnahmen

Seien wir ehrlich, was ein Laufzeitwächter ist. Anti-Tamper berechnet beim Laden einen SHA-256 des geschriebenen Images und reagiert, wenn die Datei nach der Obfuskierung verändert wurde. Anti-Debug fragt die verwaltete und native Laufzeit, ob ein Debugger angehängt ist. Die Umgebungsprüfungen suchen nach einem CLR-Profiler (CORECLR_ENABLE_PROFILING) oder dem Harmony-Laufzeit-Patcher. Jeder ist ein wirklich nützlicher Stolperdraht — aber ein Stolperdraht, dessen einzige Ausgabe eine lokale Reaktion ist: beenden, werfen, aussteigen oder eine von Ihnen benannte Methode aufrufen.

Diese Reaktion schützt die eine Maschine, auf der sie läuft. Was sie nicht tut, ist, Ihnen irgendetwas zu sagen. Der Wächter und der Angreifer sind allein in einem Raum auf dem Computer eines anderen. Sie erfahren, dass Ihre Software gecrackt wird, wenn ein Keygen in einem Forum auftaucht — nicht, wenn der erste antiDebug-Wächter auslöst.

Ohne Report-homeWächter löst aus (Nutzermaschine)reagiert lokal → Anbieter blindAnbieter: sieht nichtsMit Report-homeWächter löst aus → POST{"event":"antiDebug"} dann reagiertIhr Endpunkt (tamperReportUrl)Angriff wird verwertbares Signal

Was Report-home tatsächlich tut

Setzen Sie einen Konfigurationsschlüssel, und jeder injizierte Wächter erhält eine zweite Aktion: Bevor er seine Reaktion ausführt, POSTet er ein minimales Ereignis an Ihre URL.

{
  "obfuscate": true,
  "controlFlow": true,
  "stringEncryption": true,
  "antiTamper": true,
  "antiDebug": true,
  "environmentChecks": true,
  "tamperReportUrl": "https://telemetry.example.com/nebula-events"
}

Der Rumpf ist bewusst winzig — nur der Ereignisname:

{ "event": "antiTamper" }

Vier Eigenschaften definieren das Verhalten, und jede ist eine Entwurfsentscheidung, die es zu verstehen lohnt:

  • Es geht an Ihren Endpunkt, niemals an uns. Der POST trifft die URL, die Sie in tamperReportUrl setzen. Delta1 Labs empfängt ihn nie. Das ist Ihre Telemetrie auf Ihrem Server.
  • Nur der Ereignisname verlässt die Maschine. Keine Quelle, keine Assembly-Bytes, keine Dateipfade, keine persönlichen oder Gerätedaten — nur, welcher Wächter ausgelöst hat. Es gibt nichts Sensibles abzufangen und nichts, was eine Datenschutzprüfung verärgern würde.
  • Es ist begrenzt und selbstschluckend. Der Versand kann Ihre App nicht blockieren und nicht in sie werfen. Wenn Ihr Endpunkt langsam oder unerreichbar ist, wird der Bericht verworfen und die Reaktion des Wächters läuft unverändert weiter. Report-home wird nie zu einem neuen Fehlermodus.
  • Es ist getrennt von Nebulas eigener Analytik. Nebula hat einen anonymen Tool-Nutzungskanal zur Build-Zeit, den Sie mit NEBULA_NO_TELEMETRY stummschalten können. Report-home hat damit nichts zu tun — es ist ein Laufzeitkanal von Ihrer App an Ihren Server, gesteuert allein dadurch, ob tamperReportUrl gesetzt ist.

Da es ausgehenden Verkehr aus der geschützten App hinzufügt, ist Report-home nicht für abgeschottete Bereitstellungen gedacht. Lassen Sie die URL dort ungesetzt, und die Wächter reagieren trotzdem lokal — sie können nur nicht nach Hause telefonieren.

Welche Wächter melden, und was jeder bedeutet

Jeder Laufzeitwächter, den Nebula injiziert, meldet unter seinem eigenen Ereignisnamen, was das Signal nützlich macht statt zu einem einzigen, undifferenzierten „etwas ist passiert”:

EreignisWächterWas es üblicherweise bedeutet
antiTamperImage-Integrität zur Ladezeit (SHA-256 des geschriebenen Images)Das Binary wurde nach der Obfuskierung verändert — eine gepatchte/gecrackte Kopie oder ein beschädigter Download
antiDebugVerwaltete + native Debugger-ErkennungJemand hat einen Debugger angehängt — der klassische erste Zug des dynamischen Reverse Engineering
environmentCLR-Profiler- / Harmony-Patcher-ErkennungEin Profiler oder der Harmony-Laufzeit-Patcher ist vorhanden — automatisiertes Hooking Ihrer Methoden
expiryAblauf- / Zeitbomben-WächterEin Beta-, Evaluierungs- oder gesperrter Build läuft über sein expiryUtc hinaus

Einen antiDebug-Ausschlag auf einer einzelnen Build-Version zu sehen, sagt Ihnen etwas ganz anderes als ein stetiges Rinnsal von antiTamper von den Maschinen einer einzigen Kunden-ID. Das eine ist aktives Reverse Engineering; das andere könnte eine beschädigte Installation oder ein Weiterverteilungsring sein. Sie zu unterscheiden ist der ganze Sinn davon, jedem Wächter seinen eigenen Namen zu geben.

Das Signal lauter machen: kontinuierliche Prüfungen

Report-home ist am nützlichsten in Kombination mit Prüfungen, die mehr als einmal laufen. Standardmäßig sind environmentChecks und antiDebug Wächter zur Ladezeit — sie lösen beim Start aus. Ein geduldiger Angreifer hängt sich einfach nach dem Start an. Das Einschalten der kontinuierlichen Prüfungen ändert das:

{
  "antiTamper": true,
  "antiDebug": true,
  "environmentChecks": true,
  "environmentChecksContinuous": true,
  "environmentChecksIntervalSeconds": 45,
  "autoProtectLicensing": true,
  "tamperReportUrl": "https://telemetry.example.com/nebula-events"
}

Mit environmentChecksContinuous läuft die Erkennung nicht mehr nur beim Start. Sie abonniert AppDomain.AssemblyLoad, sodass ein Profiler oder Patcher, der sich nach dem Start anhängt, in dem Moment erwischt wird, in dem er geladen wird; sie prüft erneut am Eintritt der Methoden, die Ihr Lizenzierungs-SDK aufrufen (dieselben, die autoProtectLicensing findet und schützt); und mit environmentChecksIntervalSeconds prüft sie erneut auf einem Hintergrund-Timer mit Jitter. Jede dieser zusätzlichen Auslösungen kann nach Hause melden — statt eines Ereignisses beim Start erhalten Sie also ein Bild eines Angriffs, wie er sich über eine Sitzung entfaltet.

Den Empfänger bauen

Der Endpunkt ist gewöhnlich. Er nimmt einen kleinen JSON-POST entgegen und zeichnet ihn auf; alles Interessante geschieht darin, wie Sie aggregieren, nicht im Handler. Ein minimaler ASP.NET-Core-Empfänger:

app.MapPost("/nebula-events", async (HttpContext ctx, TamperEvent evt) =>
{
    // Attribute the hit to a build/customer using signals you already have:
    // the User-Agent you set, a header you add at your CDN/gateway, or the
    // source address. The body itself carries only the event name by design.
    var record = new TamperHit(
        Event:   evt.Event,                       // "antiTamper" | "antiDebug" | "environment" | "expiry"
        AtUtc:   DateTime.UtcNow,
        Source:  ctx.Connection.RemoteIpAddress?.ToString(),
        Agent:   ctx.Request.Headers.UserAgent.ToString());

    await _hits.AppendAsync(record);              // your store of choice
    return Results.NoContent();                   // keep it cheap; the client ignores the response anyway
});

record TamperEvent(string Event);
record TamperHit(string Event, DateTime AtUtc, string? Source, string? Agent);

Zwei Dinge auf der Empfangsseite im Hinterkopf behalten. Erstens ignoriert der Client Ihre Antwort und wiederholt nie — es ist von Haus aus Feuern-und-Vergessen — also sollte Ihr Handler billig sein und darf nie ein Bestätigungsprotokoll erwarten. Zweitens behandeln Sie den Rumpf als nicht vertrauenswürdige Eingabe: Er kommt von Software, die auf einer Maschine läuft, die ein Angreifer kontrollieren kann, also validieren Sie den Ereignisnamen gegen Ihre bekannte Menge, begrenzen Sie die Rate pro Quelle und lassen Sie eine unerwartete Nutzlast nie etwas anderes tun, als protokolliert und verworfen zu werden. Der Wert von Report-home liegt im Aggregat — ein Sprung bei antiDebug nach einem Release, ein Cluster von antiTamper aus einer Region — nicht im Vertrauen auf ein einzelnes Ereignis.

Was Report-home ist und was nicht

Report-home stoppt keinen Crack. Die Wächter erledigen das Stoppen — Anti-Tamper weigert sich, ein verändertes Binary auszuführen, Anti-Debug und die Umgebungsprüfungen reagieren auf dynamische Angriffe — und nichts davon ist absolut, denn jeder clientseitige Schutz läuft letztlich auf einer Maschine, die der Angreifer kontrolliert. Was Report-home ändert, ist Ihre Sichtbarkeit. Heute ist ein Angriff auf einen ausgelieferten Build für Sie unsichtbar; mit gesetztem tamperReportUrl ist er ein datiertes, benanntes Ereignis auf Ihrem eigenen Server, einem Build und oft einem Kunden zuordenbar. Das verwandelt Reverse Engineering von etwas, das Sie Monate später entdecken, in etwas, das Sie geschehen sehen — und worauf Sie reagieren, indem Sie einen härteren Build ausliefern, eine geleakte Lizenz widerrufen oder einen Kunden kontaktieren, dessen Maschinen aufleuchten.

Setzen Sie es in einer Zeile, richten Sie es auf einen Endpunkt, den Sie kontrollieren, und lassen Sie es für abgeschottete Ziele ungesetzt. Siehe Konfiguration → Anti-Tamper & Anti-Debug für den vollständigen Satz an Wächter- und Reaktionsoptionen, Deobfuskierung widerstehen dafür, wie die Wächter in die größere Härtungsgeschichte passen, oder die Nebula.NET-Produktseite für das Gesamtbild.

Nebula.NET testen

Härten Sie Ihren .NET-Code in wenigen Minuten — starten Sie mit der kostenlosen Edition.