none
IL-Disassembler - kann man .NET-Quellcode schützen? RRS feed

  • Frage

  • Hallo zusammen,

      ich komme aus der Borland/CodeGear-Welt und arbeite mich in C# ein, komme schon einigermaßen zurecht, auch mit Hilfe dieses Forums (vielen Dank dafür!).

      Jetzt bin ich aber auf etwas gestoßen, was mich einigermaßen schockiert hat. Sehe ich das richtig, dass jedes C#- bzw. .NET-Programm quasi Open Source ist? Wenn ich meine EXEs oder DLLs mit dem IL-Disassembler öffne, sehe ich vieles, was bei der Weitergabe eines Programmes eigentlich nicht zu sehen sein sollte.

      Beispielsweise habe ich für Datenbank-Zugriffe Passwörter im Quellcode hinterlegt, was mir bei einer Borland-Exe auch einigermaßen sicher erschien. Unter .NET kann ich diese mit dem IL-Disassembler sichtbar machen.

      Wie handhabt ihr das? Kann man .NET-Quellcode schützen? Wenn ja, wie?

    Gruß,

    Matthias
    Montag, 29. November 2010 15:53

Antworten

  • hallo Matthias,

    Beispielsweise habe ich für Datenbank-Zugriffe Passwörter im Quellcode hinterlegt, was mir bei einer Borland-Exe auch einigermaßen sicher erschien.

    Das ist absolut unsicher... mit IDA Pro bekommt man es relativ leicht raus.

    Generell gilt: Es gibt keinen wirksamen Schutz, denn letztendlich muss es ja einen lesbaren Maschinencode für den Prozessor geben.

    http://msdn.microsoft.com/de-de/library/bb979521.aspx

    Man kann zwar Obfusctoren verwenden, jedoch sind diese aus der Sicht von TDD ein K.O.: Denn es wird eine komplett ungetestete Assembly erzeugt.


    Microsoft MVP Office Access
    https://mvp.support.microsoft.com/profile/Stefan.Hoffmann
    Montag, 29. November 2010 16:29
  • Hallo Matthias,

    man kann bereits normale exe decompilieren, es dauert nur länger (etwas aufwändiger).

    Während man mit Obfuskatoren, die normal in Visual Studio jetzt bereits beinhaltet sind, schon einen einfachen Schutz erreichen kann, gibt es für .NET zwar einen wirksamen Schutz durch Drittanbieter-Software:

    [.NET Reactor - .NET Protection, .NET Obfuscator and Licensing]
    http://www.eziriz.com/dotnet_reactor.htm 

    aber Passwörter gehören normal (best practice) nicht in den Code. Es gibt da viele einfache Tools (zum Teil von Microsoft) die gerade zur Laufzeit hier einhaken und Dinge auslesen können. Man nutzt zum Teil auch Windows-Konten (Integrierte Authentifizierung), die nach einer Installion angegeben werden, (sodass das Programm passwortlos arbeitet) und nur z.B. über Kerberos die Authentifikation prüft o.ä..

    Das einzige wäre noch, das Du einen verschlüsselten Windows-Speicher über DPAPI benutzt.

    [DPAPI unter C#]
    http://dzaebel.net/DPAPI.htm

    Siehe auch den Thread: [Passwort sicher im Quelltext hinterlegen]


    ciao Frank
    Montag, 29. November 2010 16:49
  • Hallo Matthias,

    Ich schließe mich Stefan an was die Speicherung von sicherheitsrelevanten Informationen in eine .NET-Assembly oder in einer unverwalteten Anwendung angeht. Das sollte man gar nicht erst versuchen. Das wirft ja nicht nur Security- sondern auch Maintenability-Probleme auf.

    Wenn es Dir aber hauptsächlich um die Speicherung von Zugriffsinformationen geht, würde ich Dir als Einstieg in die Thematik folgenden Link empfehlen:

    Verschlüsseln von Konfigurationsdateiabschnitten mit geschützter Konfiguration in:
    Verbindungszeichenfolgen und Konfigurationsdateien (ADO.NET)
    http://msdn.microsoft.com/de-de/library/ms254494.aspx

    s.a. Passwort sicher im Quelltext hinterlegen:
    http://social.msdn.microsoft.com/Forums/de-DE/dotnetframeworkde/thread/18e825f6-ba08-4e11-8be8-72b487ca7baa

    Gruß
    Marcel

    Montag, 29. November 2010 16:58
    Moderator
  • Hallo Matthias

    > die entsprechende Assembly in sein Projekt einbinden und das GradientPanel verwenden, oder?

    ja, Default 'by design' haben mit Visual Studio erstellte (pure managed) Assemblies keinerlei Schutz gegen fremde Nutzung/Decompiling.
    Es gibt einige 'kostenlose' Obfuscators, die dagegen einen minimalsten Schutz durch Verschleierung bieten, aber alles was darüber hinausgeht kostet etliches an Geld für Tools von _sehr_ kleinen Firmen, denen du dann blind vertrauen musst und abhängig bist.
    Andernfalls nimmst du besser gar nicht .NET (sondern nächstbesser: C++), oder akzeptierst den Default ohne Schutz.


    Montag, 29. November 2010 18:03
  • Hallo Matthias,

       > kann ich eine Assembly gegen "unberechtigten" Aufruf schützen?

    Für Komponenten werden standardmäßig Dinge wie:

    [Gewusst wie: Lizenzieren von Komponenten und Steuerelementen]
    http://msdn.microsoft.com/de-de/library/fe8b1eh9.aspx

    [LicenseProvider-Klasse (System.ComponentModel)]
    http://msdn.microsoft.com/de-de/library/system.componentmodel.licenseprovider.aspx

    eingesetzt. Zu den heutigen CAS-Möglichkeiten/Vorgehensweisen sind u.a. hier aufgeführt:

    [Codezugriffssicherheit]
    http://msdn.microsoft.com/de-de/library/c5tk9z76.aspx

    [Exploring the .NET Framework 4 Security Model]
    http://msdn.microsoft.com/en-us/magazine/ee677170.aspx


    ciao Frank
    Montag, 29. November 2010 18:17
  • Hallo Matthias,

    Aber was mir noch nicht ganz klar ist - kann ich eine Assembly gegen "unberechtigten" Aufruf schützen? Nicht dass ich was gegen Open Source hätte, aber ich habe einen Arbeitgeber, und der erzählt mir was von Knowhow-Schutz [...] Wenn nun eines dieser Projekte weitergegeben (verkauft) wird, kann ja jemand, der ein wenig von .NET versteht, die entsprechende Assembly in sein Projekt einbinden und das GradientPanel verwenden, oder?

    Gelegenheitsangreifer kannst Du das Handwerk legen, indem Du die verwendeten Assemblies obfuszierst und mittels starkem Namen und InternalsVisibleToAttribute schützst. Dabei gibst Du an, dass die zunächst als intern deklarierten Klassen nur für Assemblies nach außen sichtbar sein sollen, die den angegebenen PublicKey aufweisen. Dann können Deine Bibliotheken nicht mehr so einfach von Fremdanwendungen referenziert werden. Reverse Engineering ist theoretisch noch immer möglich, aber das Kosten-Nutzen-Verhältnis ist doch derart gestaltet, dass sich für gewöhnlich ein Angriff auf dieser Ebene nicht mehr lohnt.

    InternalsVisibleToAttribute-Klasse:
    http://msdn.microsoft.com/de-de/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx

    Auch wenn unter .NET 4.0 Code Access Security nicht mehr den Stellenwert von früher hat, kann man weiterhin benutzerdefinierte Permissions verwenden, um den Zugriff auf den eigenen Code zu schützen:

    Is CAS dead in .NET 4?
    http://blogs.msdn.com/b/shawnfa/archive/2010/02/24/so-is-cas-dead-in-net-4-or-what.aspx

    Ferner kannst Du bei der Installation Dateisystem-ACLs so setzen, dass unbefugte Benutzer keinen Zugriff mehr auf die Assemblies haben, z.B. um Reflection-Attacken zu vermeiden.

    File.SetAccessControl-Methode
    http://msdn.microsoft.com/de-de/library/system.io.file.setaccesscontrol.aspx

    Gruß
    Marcel

    Montag, 29. November 2010 18:30
    Moderator

Alle Antworten

  • hallo Matthias,

    Beispielsweise habe ich für Datenbank-Zugriffe Passwörter im Quellcode hinterlegt, was mir bei einer Borland-Exe auch einigermaßen sicher erschien.

    Das ist absolut unsicher... mit IDA Pro bekommt man es relativ leicht raus.

    Generell gilt: Es gibt keinen wirksamen Schutz, denn letztendlich muss es ja einen lesbaren Maschinencode für den Prozessor geben.

    http://msdn.microsoft.com/de-de/library/bb979521.aspx

    Man kann zwar Obfusctoren verwenden, jedoch sind diese aus der Sicht von TDD ein K.O.: Denn es wird eine komplett ungetestete Assembly erzeugt.


    Microsoft MVP Office Access
    https://mvp.support.microsoft.com/profile/Stefan.Hoffmann
    Montag, 29. November 2010 16:29
  • Hallo Matthias,

    man kann bereits normale exe decompilieren, es dauert nur länger (etwas aufwändiger).

    Während man mit Obfuskatoren, die normal in Visual Studio jetzt bereits beinhaltet sind, schon einen einfachen Schutz erreichen kann, gibt es für .NET zwar einen wirksamen Schutz durch Drittanbieter-Software:

    [.NET Reactor - .NET Protection, .NET Obfuscator and Licensing]
    http://www.eziriz.com/dotnet_reactor.htm 

    aber Passwörter gehören normal (best practice) nicht in den Code. Es gibt da viele einfache Tools (zum Teil von Microsoft) die gerade zur Laufzeit hier einhaken und Dinge auslesen können. Man nutzt zum Teil auch Windows-Konten (Integrierte Authentifizierung), die nach einer Installion angegeben werden, (sodass das Programm passwortlos arbeitet) und nur z.B. über Kerberos die Authentifikation prüft o.ä..

    Das einzige wäre noch, das Du einen verschlüsselten Windows-Speicher über DPAPI benutzt.

    [DPAPI unter C#]
    http://dzaebel.net/DPAPI.htm

    Siehe auch den Thread: [Passwort sicher im Quelltext hinterlegen]


    ciao Frank
    Montag, 29. November 2010 16:49
  • Hallo Matthias,

    Ich schließe mich Stefan an was die Speicherung von sicherheitsrelevanten Informationen in eine .NET-Assembly oder in einer unverwalteten Anwendung angeht. Das sollte man gar nicht erst versuchen. Das wirft ja nicht nur Security- sondern auch Maintenability-Probleme auf.

    Wenn es Dir aber hauptsächlich um die Speicherung von Zugriffsinformationen geht, würde ich Dir als Einstieg in die Thematik folgenden Link empfehlen:

    Verschlüsseln von Konfigurationsdateiabschnitten mit geschützter Konfiguration in:
    Verbindungszeichenfolgen und Konfigurationsdateien (ADO.NET)
    http://msdn.microsoft.com/de-de/library/ms254494.aspx

    s.a. Passwort sicher im Quelltext hinterlegen:
    http://social.msdn.microsoft.com/Forums/de-DE/dotnetframeworkde/thread/18e825f6-ba08-4e11-8be8-72b487ca7baa

    Gruß
    Marcel

    Montag, 29. November 2010 16:58
    Moderator
  • Hallo zusammen,

      hatte vergessen zu erwähnen, dass es um Datenbank-Passwörter geht. Für den Client-Server-Bereich (MSSQL) werde ich das auf Windows-Authentifizierung umstellen, da habt ihr mich überzeugt. Ich habe aber noch eine "portable" Anwendung, die auf eine verschlüsselte SQL-CE-Datenbank zugreift, da erscheint mir das Passwort im Quellcode *einigermaßen* sinnvoll.

      Danke für die Antworten! Werde mich mal durch die Links lesen.

      Aber was mir noch nicht ganz klar ist - kann ich eine Assembly gegen "unberechtigten" Aufruf schützen? Nicht dass ich was gegen Open Source hätte, aber ich habe einen Arbeitgeber, und der erzählt mir was von Knowhow-Schutz...

      Einfaches Beispiel: Mit Hilfe dieses Forums habe ich ein GradientPanel erstellt und dieses in eine Assembly ausgelagert, um es in verschiedenen meiner Projekte nutzten zu können. Wenn nun eines dieser Projekte weitergegeben (verkauft) wird, kann ja jemand, der ein wenig von .NET versteht, die entsprechende Assembly in sein Projekt einbinden und das GradientPanel verwenden, oder?

      Natürlich geht es mir nicht um den Schutz von sowas *einfachem* wie einem mit Internet-Hilfe erstellten GradientPanel, aber es könnte ja auch komplexere Funktionalitäten geben, die man (ein Arbeitgeber) nicht einfach so veröffentlichen möchte.

    Gruß,

    Matthias

    Montag, 29. November 2010 17:52
  • Hallo Matthias

    > die entsprechende Assembly in sein Projekt einbinden und das GradientPanel verwenden, oder?

    ja, Default 'by design' haben mit Visual Studio erstellte (pure managed) Assemblies keinerlei Schutz gegen fremde Nutzung/Decompiling.
    Es gibt einige 'kostenlose' Obfuscators, die dagegen einen minimalsten Schutz durch Verschleierung bieten, aber alles was darüber hinausgeht kostet etliches an Geld für Tools von _sehr_ kleinen Firmen, denen du dann blind vertrauen musst und abhängig bist.
    Andernfalls nimmst du besser gar nicht .NET (sondern nächstbesser: C++), oder akzeptierst den Default ohne Schutz.


    Montag, 29. November 2010 18:03
  • Hallo Matthias,

       > kann ich eine Assembly gegen "unberechtigten" Aufruf schützen?

    Für Komponenten werden standardmäßig Dinge wie:

    [Gewusst wie: Lizenzieren von Komponenten und Steuerelementen]
    http://msdn.microsoft.com/de-de/library/fe8b1eh9.aspx

    [LicenseProvider-Klasse (System.ComponentModel)]
    http://msdn.microsoft.com/de-de/library/system.componentmodel.licenseprovider.aspx

    eingesetzt. Zu den heutigen CAS-Möglichkeiten/Vorgehensweisen sind u.a. hier aufgeführt:

    [Codezugriffssicherheit]
    http://msdn.microsoft.com/de-de/library/c5tk9z76.aspx

    [Exploring the .NET Framework 4 Security Model]
    http://msdn.microsoft.com/en-us/magazine/ee677170.aspx


    ciao Frank
    Montag, 29. November 2010 18:17
  • Hallo Matthias,

    Aber was mir noch nicht ganz klar ist - kann ich eine Assembly gegen "unberechtigten" Aufruf schützen? Nicht dass ich was gegen Open Source hätte, aber ich habe einen Arbeitgeber, und der erzählt mir was von Knowhow-Schutz [...] Wenn nun eines dieser Projekte weitergegeben (verkauft) wird, kann ja jemand, der ein wenig von .NET versteht, die entsprechende Assembly in sein Projekt einbinden und das GradientPanel verwenden, oder?

    Gelegenheitsangreifer kannst Du das Handwerk legen, indem Du die verwendeten Assemblies obfuszierst und mittels starkem Namen und InternalsVisibleToAttribute schützst. Dabei gibst Du an, dass die zunächst als intern deklarierten Klassen nur für Assemblies nach außen sichtbar sein sollen, die den angegebenen PublicKey aufweisen. Dann können Deine Bibliotheken nicht mehr so einfach von Fremdanwendungen referenziert werden. Reverse Engineering ist theoretisch noch immer möglich, aber das Kosten-Nutzen-Verhältnis ist doch derart gestaltet, dass sich für gewöhnlich ein Angriff auf dieser Ebene nicht mehr lohnt.

    InternalsVisibleToAttribute-Klasse:
    http://msdn.microsoft.com/de-de/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx

    Auch wenn unter .NET 4.0 Code Access Security nicht mehr den Stellenwert von früher hat, kann man weiterhin benutzerdefinierte Permissions verwenden, um den Zugriff auf den eigenen Code zu schützen:

    Is CAS dead in .NET 4?
    http://blogs.msdn.com/b/shawnfa/archive/2010/02/24/so-is-cas-dead-in-net-4-or-what.aspx

    Ferner kannst Du bei der Installation Dateisystem-ACLs so setzen, dass unbefugte Benutzer keinen Zugriff mehr auf die Assemblies haben, z.B. um Reflection-Attacken zu vermeiden.

    File.SetAccessControl-Methode
    http://msdn.microsoft.com/de-de/library/system.io.file.setaccesscontrol.aspx

    Gruß
    Marcel

    Montag, 29. November 2010 18:30
    Moderator