2008-11-21 7 views
16

Kann überprüft werden, ob eine dynamisch geladene Assembly mit einem bestimmten starken Namen signiert wurde?Überprüfen einer Assembly auf einen starken Namen

Ist es genug/sicher, um die Werte zu vergleichen, die von AssemblyName.GetPublicKey() Methode zurückgegeben werden?

Assembly loaded = Assembly.LoadFile(path); 

byte[] evidenceKey = loaded.GetName().GetPublicKey(); 

if (evidenceKey != null) 
{ 
    byte[] internalKey = Assembly.GetExecutingAssembly().GetName().GetPublicKey(); 

    if (evidenceKey.SequenceEqual(internalKey)) 
    { 
     return extension; 
    } 
} 

Kann dies nicht verfälscht werden? Ich bin mir nicht sicher, ob die Methode SetPublicKey() irgendeine Auswirkung auf eine gebaute Assembly hat, aber selbst die MSDN-Dokumentation zeigt, wie Sie dies auf einer dynamisch generierten Assembly (Reflection) verwenden können Host-Anwendung und injizieren Sie es in eine eigene Assembly und mallicious Code ausführen, wenn das oben genannte die Sicherheit war, oder fehle ich etwas?

Gibt es einen korrekteren und sichereren Ansatz? Ich weiß, wenn die umgekehrte Situation das Szenario war, das heißt, wo ich wollte, dass die Assembly nur von signierten Hosts aufgerufen wird, dann könnte ich die Assembly mit dem Attribut StrongNameIdentityPermission taggen.

Antwort

14

Es gibt keinen verwalteten Weg, um die Signatur einer Assembly zu prüfen, und die Prüfung des öffentlichen Schlüssels macht Sie anfällig für Spoofing. Sie müssen P/Invoke verwenden und rufen Sie die StrongNameSignatureVerificationEx Funktion der Signatur

[DllImport("mscoree.dll", CharSet=CharSet.Unicode)] 
static extern bool StrongNameSignatureVerificationEx(string wszFilePath, bool fForceVerification, ref bool pfWasVerified); 
+1

Was immer Sie tun, kann Sie zum Spoofing veranlassen, da der Angreifer leicht die Überprüfung in Ihrer Assembly umgehen und die modifizierte IL wieder zusammenbauen und die Assembly mit seiner eigenen aufgeben kann Schlüssel. –

+0

Wenn Sie sagen, dass es keinen verwalteten Weg gibt, meinen Sie, dass es technisch nicht möglich ist, oder dass es keine Standard-Bibliothek/-Routine dafür gibt? – ohw

13

Es hat wenig Sinn, den starken Namen zu testen, nachdem die Baugruppe geladen wurde. Ein Angreifer könnte einfach einen Modulkonstruktor in die Assembly einfügen und den gewünschten Code ausführen. Die .NET 3.5 SP1-Version des Frameworks folgte und überprüft nicht mehr den starken Namen von Assemblys, die von vertrauenswürdigen Speicherorten geladen werden. Startzeiten verbessern sich um ca. 40%.

Der entscheidende Punkt ist: Sobald ein Angreifer die Maschine zu einem Punkt kompromittiert, an dem er in der Lage ist, eine Baugruppe in den Prüfpfad Ihrer Anwendung zu injizieren, wird er sich nicht die Mühe machen. Er würde nur Ihre EXE-Datei ersetzen.

+0

Eigentlich ist das eine Situation, wo Erweiterungen (in Form von Baugruppen) können zur Anwendung hinzugefügt werden, das heißt, sie aus einem Verzeichnis geladen werden mit Assembly.LoadFile und ich möchte nur Erweiterungen laden können, die mit dem gleichen starken Namen wie die Host-Anwendung signiert wurden. – TheCodeJunkie

+0

Es geht also nicht darum, ein ganzes System oder eine Anwendung zu schützen, sondern zu beschränken, wer in der Lage ist, Erweiterungen für die Anwendung selbst zu schreiben. Kein starker Name, tut mir leid, Ihre Erweiterung wird nicht geladen – TheCodeJunkie

+0

@Hans Passant Ich denke, die Prüfung starken Namen ist immer noch nützlich. Wenn exe A dll B referenziert und beide stark benannt sind und die starke Namensvalidierung in app.config aktiviert ist, kann ein Hacker den starken Namen in beiden Dateien einfach durch Überschreiben der Datei auf Hacker-Ebene (Byte) entfernen. Wir können den Programmstart einchecken, wenn die Assembly einen starken Namen hat (zB signiert) – Alireza

7

prüfen starken Namen von mscoree.dll mit StrongNameSignatureVerificationEx zu überprüfen, wird unter .NET veraltet 4 nach http://msdn.microsoft.com/pl-pl/library/ms232579.aspx.

.NET 4 Art und Weise, es zu tun ist:

var clrStrongName = (IClrStrongName)RuntimeEnvironment.GetRuntimeInterfaceAsObject(new Guid("B79B0ACD-F5CD-409b-B5A5-A16244610B92"), new Guid("9FD93CCF-3280-4391-B3A9-96E1CDE77C8D")); 
bool verificationForced; 
int result = clrStrongName.StrongNameSignatureVerificationEx(@"PATH\TO\ASSEMBLY.DLL", true, out verificationForced); 
if (result == 0) 
{ 
    Console.WriteLine("Valid."); 
} 



[ComConversionLoss, Guid("9FD93CCF-3280-4391-B3A9-96E1CDE77C8D"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), SecurityCritical] 
[ComImport] 
internal interface IClrStrongName 
{ 
    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int GetHashFromAssemblyFile([MarshalAs(UnmanagedType.LPStr)] [In] string pszFilePath, [MarshalAs(UnmanagedType.U4)] [In] [Out] ref int piHashAlg, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] [Out] byte[] pbHash, [MarshalAs(UnmanagedType.U4)] [In] int cchHash, [MarshalAs(UnmanagedType.U4)] out int pchHash); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int GetHashFromAssemblyFileW([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzFilePath, [MarshalAs(UnmanagedType.U4)] [In] [Out] ref int piHashAlg, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] [Out] byte[] pbHash, [MarshalAs(UnmanagedType.U4)] [In] int cchHash, [MarshalAs(UnmanagedType.U4)] out int pchHash); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int GetHashFromBlob([In] IntPtr pbBlob, [MarshalAs(UnmanagedType.U4)] [In] int cchBlob, [MarshalAs(UnmanagedType.U4)] [In] [Out] ref int piHashAlg, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] [Out] byte[] pbHash, [MarshalAs(UnmanagedType.U4)] [In] int cchHash, [MarshalAs(UnmanagedType.U4)] out int pchHash); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int GetHashFromFile([MarshalAs(UnmanagedType.LPStr)] [In] string pszFilePath, [MarshalAs(UnmanagedType.U4)] [In] [Out] ref int piHashAlg, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] [Out] byte[] pbHash, [MarshalAs(UnmanagedType.U4)] [In] int cchHash, [MarshalAs(UnmanagedType.U4)] out int pchHash); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int GetHashFromFileW([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzFilePath, [MarshalAs(UnmanagedType.U4)] [In] [Out] ref int piHashAlg, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] [Out] byte[] pbHash, [MarshalAs(UnmanagedType.U4)] [In] int cchHash, [MarshalAs(UnmanagedType.U4)] out int pchHash); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int GetHashFromHandle([In] IntPtr hFile, [MarshalAs(UnmanagedType.U4)] [In] [Out] ref int piHashAlg, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] [Out] byte[] pbHash, [MarshalAs(UnmanagedType.U4)] [In] int cchHash, [MarshalAs(UnmanagedType.U4)] out int pchHash); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    [return: MarshalAs(UnmanagedType.U4)] 
    int StrongNameCompareAssemblies([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzAssembly1, [MarshalAs(UnmanagedType.LPWStr)] [In] string pwzAssembly2, [MarshalAs(UnmanagedType.U4)] out int dwResult); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int StrongNameFreeBuffer([In] IntPtr pbMemory); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int StrongNameGetBlob([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzFilePath, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] [Out] byte[] pbBlob, [MarshalAs(UnmanagedType.U4)] [In] [Out] ref int pcbBlob); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int StrongNameGetBlobFromImage([In] IntPtr pbBase, [MarshalAs(UnmanagedType.U4)] [In] int dwLength, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] [Out] byte[] pbBlob, [MarshalAs(UnmanagedType.U4)] [In] [Out] ref int pcbBlob); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int StrongNameGetPublicKey([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzKeyContainer, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] [In] byte[] pbKeyBlob, [MarshalAs(UnmanagedType.U4)] [In] int cbKeyBlob, out IntPtr ppbPublicKeyBlob, [MarshalAs(UnmanagedType.U4)] out int pcbPublicKeyBlob); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    [return: MarshalAs(UnmanagedType.U4)] 
    int StrongNameHashSize([MarshalAs(UnmanagedType.U4)] [In] int ulHashAlg, [MarshalAs(UnmanagedType.U4)] out int cbSize); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int StrongNameKeyDelete([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzKeyContainer); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int StrongNameKeyGen([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzKeyContainer, [MarshalAs(UnmanagedType.U4)] [In] int dwFlags, out IntPtr ppbKeyBlob, [MarshalAs(UnmanagedType.U4)] out int pcbKeyBlob); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int StrongNameKeyGenEx([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzKeyContainer, [MarshalAs(UnmanagedType.U4)] [In] int dwFlags, [MarshalAs(UnmanagedType.U4)] [In] int dwKeySize, out IntPtr ppbKeyBlob, [MarshalAs(UnmanagedType.U4)] out int pcbKeyBlob); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int StrongNameKeyInstall([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzKeyContainer, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] [In] byte[] pbKeyBlob, [MarshalAs(UnmanagedType.U4)] [In] int cbKeyBlob); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int StrongNameSignatureGeneration([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzFilePath, [MarshalAs(UnmanagedType.LPWStr)] [In] string pwzKeyContainer, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] [In] byte[] pbKeyBlob, [MarshalAs(UnmanagedType.U4)] [In] int cbKeyBlob, [In] [Out] IntPtr ppbSignatureBlob, [MarshalAs(UnmanagedType.U4)] out int pcbSignatureBlob); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int StrongNameSignatureGenerationEx([MarshalAs(UnmanagedType.LPWStr)] [In] string wszFilePath, [MarshalAs(UnmanagedType.LPWStr)] [In] string wszKeyContainer, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] [In] byte[] pbKeyBlob, [MarshalAs(UnmanagedType.U4)] [In] int cbKeyBlob, [In] [Out] IntPtr ppbSignatureBlob, [MarshalAs(UnmanagedType.U4)] out int pcbSignatureBlob, [MarshalAs(UnmanagedType.U4)] [In] int dwFlags); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int StrongNameSignatureSize([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] [In] byte[] pbPublicKeyBlob, [MarshalAs(UnmanagedType.U4)] [In] int cbPublicKeyBlob, [MarshalAs(UnmanagedType.U4)] out int pcbSize); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    [return: MarshalAs(UnmanagedType.U4)] 
    int StrongNameSignatureVerification([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzFilePath, [MarshalAs(UnmanagedType.U4)] [In] int dwInFlags, [MarshalAs(UnmanagedType.U4)] out int dwOutFlags); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    [return: MarshalAs(UnmanagedType.U4)] 
    int StrongNameSignatureVerificationEx([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzFilePath, [MarshalAs(UnmanagedType.I1)] [In] bool fForceVerification, [MarshalAs(UnmanagedType.I1)] out bool fWasVerified); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    [return: MarshalAs(UnmanagedType.U4)] 
    int StrongNameSignatureVerificationFromImage([In] IntPtr pbBase, [MarshalAs(UnmanagedType.U4)] [In] int dwLength, [MarshalAs(UnmanagedType.U4)] [In] int dwInFlags, [MarshalAs(UnmanagedType.U4)] out int dwOutFlags); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int StrongNameTokenFromAssembly([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzFilePath, out IntPtr ppbStrongNameToken, [MarshalAs(UnmanagedType.U4)] out int pcbStrongNameToken); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int StrongNameTokenFromAssemblyEx([MarshalAs(UnmanagedType.LPWStr)] [In] string pwzFilePath, out IntPtr ppbStrongNameToken, [MarshalAs(UnmanagedType.U4)] out int pcbStrongNameToken, out IntPtr ppbPublicKeyBlob, [MarshalAs(UnmanagedType.U4)] out int pcbPublicKeyBlob); 

    [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)] 
    int StrongNameTokenFromPublicKey([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] [In] byte[] pbPublicKeyBlob, [MarshalAs(UnmanagedType.U4)] [In] int cbPublicKeyBlob, out IntPtr ppbStrongNameToken, [MarshalAs(UnmanagedType.U4)] out int pcbStrongNameToken); 
} 
+0

Fantastische Hilfe. Funktioniert gut für mich. Vielen Dank – bgx

Verwandte Themen