Laden...

Nur signierte Assemblies erlauben

Letzter Beitrag vor 12 Jahren 13 Posts 5.465 Views
Nur signierte Assemblies erlauben

Hallo,

ich habe ein größeres Visual Studio 2012 .NET 3.5 Projekt das in C# geschrieben wurde.
Die Solution besteht aus dem Hauptprojekt (die zu einer .exe kompiliert wird) und einer Menge zusätzlichen "DLL" Projekten.

Alle Assemblies besitzen einen Strong Name und werden per pfx Datei signiert.

Das Ergebnis vom signtool:

Index Algorithm Timestamp
========================================
0 sha1 None

Successfully verified: C:\meineSignierte.exe

Nachdem ich nun ein wenig an meiner kompilierten exe rumgespielt habe sieht das Ergebnis vom Sign Tool so aus:

Index Algorithm Timestamp
========================================
SignTool Error: No signature found.

Number of errors: 1

Nun zum eigentlichen Problem:
Ich kann meine gepatch'te exe nun weiterhin ohne Probleme starten (obwohl sie nicht mehr signiert ist). Das gleiche passiert auch wenn ich eine der referenzierten dll's ändere. Diese werden auch ohne ein Murren geladen.

Sollte die CLR nicht was dagegen haben? Übersehe ich eine Einstellung die das Laden von unsignierten Assemblies verbietet?

Ich möchte sichergehen, dass nur die von mir erstellte und signierte Assembly benutzt werden kann und keine manipulierte.
Ich habe überlegt selber einen Check dafür einzubauen. Das ganze ist natürlich Witzlos wenn man den Check einfach raus patchen kann solange unsignierte bzw. delay signed Assemblies laufen.

Für einen Tipp/Hinweis wäre ich dankbar.

Grüße,
MisterRed

Ist die DLL im GAC installiert? Wenn ich das richtig verstanden habe, wird nur dann von der CLR sichergestellt, dass die Signierung mit der übereinstimmt, die die Exe erwartet?!

Hallo!

Hallo,
Nachdem ich nun ein wenig an meiner kompilierten exe rumgespielt habe sieht das

Was genau meinst Du mit "etwas herumgespielt"? Hast Du im PE-Header rumgefummelt?

Ich möchte sichergehen, dass nur die von mir erstellte und signierte Assembly benutzt werden kann und keine manipulierte.

Was genau ist denn Deine Motivation dahinter? Ein Kopierschutz bzw. das Erkennen von "gecrackten" EXE / DLL Dateien? Wenn ja: Das ist m. E. mit 100% managed Code nicht machbar...

Bye,
Michael

Debuggers don't remove Bugs, they only show them in Slow-Motion.

Hey,

im GAC sind die DDLs vermutlich nicht, da diese ja bestandteil meiner Solution sind und jedes mal neu kompiliert werden.

Mit herumgespielt meine ich per Reflector/Reflexil den CIL Code bearbeitet und anschließend als delay signed exe gespeichert.

Meine Motivation ist erstmal einen minimal Schutz vor Codemanipulation herzustellen. Ansonsten bringt mir das Signieren ja (fast) nichts wenn sowieso jeder am Code rummachen kann.

Ich bin mir nicht sicher, ob das die CLR wirklich abfängt oder gar abfangen muss - ich denke nicht.
Bei der Assembly.Load() hast Du allerdings die Möglichkeit über den Evidence Parameter die Signierung festzustellen und kannst dann ein Laden verweigern.

Eventuell könntest Du auch einen eigenen DomainManager schreiben, der sich darum kümmert.

Und bevor das Thema aufkommt: ja man kann sich nicht wirklich 100%tig gegenüber so etwas schützen und ja man kommt auch bei einer signierten DLL jederzeit an den ILCode. Dazu gibts unzählige Themen in diesem Forum und muss hier nich nochmal an den Tag kommen 🙂

Edit: was mir da als Lösung einfällt - keine Ahnung obs klappen würde:
Beim Init der Anwendung über alle geladenen Assembly iterieren, sich über GetPublicKey() den Key holen und gegen diesen prüfen.

Das Hauptproblem ist ja, dass wenn ich schon die exe die die DLL's lädt manipulieren kann (was ich in diesem Fall gemacht habe) bringt es mir ja nichts da irgend einen Schutz einzubauen da man diesen in 10 Minuten wieder rausgepatcht hat.

Wenn zumindest die unsignierte bzw. nicht mehr signierte Exe nen Fehler werfen würde würde das enorm helfen.

Die Applikation würd übrigens per ClickOnce deployed. Ich kann die manipulierte Anwendung direkt und über ClickOnce starten ohne das irgendetwas über die nicht mehr signierte bzw. delay signierte exe beschweren würde.

Wie gesagt, eine Lücke gibts immer und das wirste auch nicht einfach so beseitigen können. Wenn sowas eine K.O.-Anforderung Deines Projekts ist, dann musst Du eigentlich .NET meiden und mit C++ arbeiten.

Und selbst da ist es heutzutage auch recht einfach da etwas zu patchen.

Wenn man SW erstellt die Hacker benutzen, kann man es ehsofort sein lassen solche sachen einzubauen, hat man normale Kunden reichen die std mechanismen.

Meine Motivation ist erstmal einen minimal Schutz vor Codemanipulation herzustellen

Und ansonsten hatten wir das Thema hier schon (gefühlte) tausend Mal.
[FAQ] NET Assembly vor Disassembling schützen (Obfuscator)

Wie gesagt, eine Lücke gibts immer und das wirste auch nicht einfach so beseitigen können.

Das geht ja sogar so weit, dass der IL-JIT gepachted werden kann und ein leicht modifizierter Code beim Assembly.Load ausgeführt wird. Das ist auf der eigenen Maschine leicht machbar. (Letztes mal mit .Net 3.5 ausprobiert, KA wie's mit den neuen Versionen ausschaut.)

As a man thinketh in his heart, so he is.

  • Jun Fan
    Es gibt nichts Gutes, außer man tut es.
  • Erich Kästner
    Krawutzi-Kaputzi
  • Kasperl

Hi!

Das Hauptproblem ist ja, dass wenn ich schon die exe die die DLL's lädt manipulieren kann (was ich in diesem Fall gemacht habe) bringt es mir ja nichts da irgend einen Schutz einzubauen da man diesen in 10 Minuten wieder rausgepatcht hat.

Die Information, ob die EXE/DLL digital signiert ist, entnimmt das Betriebssystem bzw. das .NET Framework dem Header der EXE-Datei. Man nehme sich also den Hex-Editor seiner Wahl, suche im Header der EXE/DLL diese Stelle und "nullt" diese einfach aus (das ist grob gesagt das Vorgehen, das meiner Ansicht nach funktionieren sollte - hab es aber selber noch nict probiert). Das dauert nicht einmal 10 Minuten 😁

In diesem Fall hilft nur Obfuscation und/oder dazu noch native code der EXE/DLL verschlüsselt und erst zur Laufzeit entschlüsselt. Dann dauert das Patchen definitv länger als 10 Minuten 8) Wobei "nur" Obfuscation auch nur bedingt was bringt, da es auch "de-obfucators" gibt - z. B. de4dot

Die Frage ist halt wirklich, ob das alles lohnt, da gerade das Obfuskieren ja auch deutlich Aufwand (ich meine damit die Konfiguration was obfuskiert werden darf und was nicht) bedeuten kann - man denke an Reflection....

Aber diese Diskussion hatten wir schon mehrfach....

Bye,
Michael

Debuggers don't remove Bugs, they only show them in Slow-Motion.

Hinweis von herbivore vor 12 Jahren

... weshalb wir sie hier auch nicht fortsetzen sollten, außer es gibt entscheidende neue Informationen.

Hoi,

danke für eure Antworten.

Ich hätte echt gedacht, dass Microsoft da irgendetwas mitliefert was man einfach "einschalten" kann.

Ich bin vor ein paar Wochen auf folgenden MSDN Artikel gestoßen:
How to: Disable the Strong-Name Bypass Feature

Wenn man wie dort vorgeschlagen folgendes in die App Config hinzufügt:

<configuration>
  <runtime>
     <bypassTrustedAppStrongNames enabled="false" />
  </runtime>
</configuration>

... crasht die modifizierte App beim Starten. Da sich der Eintrag allerdings in der App Config befindet und jederzeit geändert werden bzw. entfernt werden kann ist es wieder witzlos es als Lösung in Betracht zu ziehen.
Noch dazu kann man das "Sicherheitsfeature" wohl per Registry Key komplett deaktiveren.

Grüße,
MisterRed

Du wirst auf keinem Gerät ein Sicherheitsfeature finden, das man nicht deaktivieren kann.
Und wenn man etwas "einschalten" kann wirds auch immer einen Weg geben, um dieses wieder auszuschalten.

Da stellt sich eher die Frage, ob man die Ressourcen in diesem Umfang wirklich investieren will. Aber diese Frage kannst nur Du selbst Dir beantworten.

Nicht nur das.

MS hatte mal eine SecureVM für .NET entwickelt, bei der man einzelne Routinen nur mit dieser einen signierten Nativen Umgebung ausführen konnte.
Die wurde nie geknackt, aber haben wollte sie auch keiner, also wurde die wieder eingestellt.