2013-07-20 24 views
5

Napisałem aplikację C# .NET, która używa popularnego niezarządzanego pliku DLL jako części jego funkcjonalności. Plik DLL jest importowany przy użyciu standardowego pliku DllImport z System.Runtime.InteropServices.Jak zweryfikować podpis cyfrowy biblioteki DLL w .NET

Niestety moja aplikacja (wraz z większością aplikacji .NET wykorzystujących DllImport) jest podatna na przechwytywanie DLL. tj. osoba atakująca może umieścić złośliwą kopię zaimportowanej biblioteki DLL w tym samym katalogu, co dowolny plik otwarty przez moją aplikację. To może dać atakującemu pełną kontrolę nad maszyną użytkownika.

Aby złagodzić tę lukę, chciałbym sprawdzić, czy plik DLL jest poprawnie podpisany (z domyślnym Authenticode) przed zaimportowaniem. Wiem, że podpisy można weryfikować za pomocą narzędzi takich jak sigcheck.exe, ale nie jest to rozwiązanie opłacalne, ponieważ muszę to zrobić z poziomu mojego kodu C#.

Moje pytanie brzmi po prostu: Jak mogę sprawdzić, czy biblioteka DLL ma prawidłowy podpis Authenticode z mojego zarządzanego kodu C# przed załadowaniem biblioteki DLL?

Ograniczenia:

  • Importowany DLL nie jest opracowany przeze mnie, to od firmy zewnętrznej.
  • DLL nie jest dystrybuowany z moją aplikacją, oczekuje się, że zostanie już zainstalowany przed uruchomieniem mojej aplikacji.
  • Zaimportowana biblioteka DLL istnieje w wielu różnych wersjach (a jeszcze więcej pojawi się), więc nie mogę po prostu przed jej zaimportowaniem go ustawić jako verify an MD5 checksum of the DLL.

Nieudane podejścia:

  • Microsoft miłego writeup na preventing "DLL preloading attacks", jednak ta informacja nie ma zastosowania dla .NET za dllimport.
  • Widziałem kilka osób sugerujących korzystanie z niezarządzanej funkcji WinVerifyTrust z Wintrust.dll. Jest to oczywiście głupie rozwiązanie, ponieważ spowoduje to, że moja aplikacja będzie podatna na wstrzyknięcia DLL za pośrednictwem Wintrust.dll.
+0

Jest to najprawdopodobniej dup z http://stackoverflow.com/questions/3281057/get-timestamp-from-authenticode-signed-files-in-net, ale ponieważ nie określasz, w jaki sposób podpisano niezarządzaną bibliotekę DLL, mogę Nie bądź naprawdę pewny. –

+1

Dlaczego atakujący nie zastąpi * twojego * programu? Znacznie łatwiej zrobić. –

+0

Myślę, że nadal można użyć pliku sigcheck.exe.Możesz uruchomić proces z C# i przechwycić jego wynik: http://stackoverflow.com/a/10380353/1415732 – Alden

Odpowiedz

1

Musisz użyć weryfikatora Authenticode. Odpowiedzi na this question oferują do korzystania z P/Invoke , a jeśli potrzebujesz rozwiązania zarządzanego, możesz być zainteresowany naszą biblioteką SecureBlackbox, która między innymi oferuje podpisywanie Authenticode i weryfikację podpisu.

Mimo że można się bronić przed ładowaniem fałszywej biblioteki DLL, nie można obronić samej aplikacji przed złamaniem. Więc weryfikacja podpisu chroni cię tylko przed jednym atakiem, oczywiście.

Pozwolę sobie wskazać, że zastąpienie WinTrust.dll zależy od innego wektora ataku, który wymaga dostępu do komputera. W tym przypadku osoba atakująca może załatać swoją aplikację w całości.

+0

Aby zweryfikować podpis za pomocą "CryptQueryObject" (zgodnie z zaleceniami w tej odpowiedzi), wymagany jest DllImport z CRYPT32.DLL. Jak widzę, zamiast tego uczyniłbym moją aplikację podatną na przechwytywanie DLL przez crypt32.dll w taki sam sposób jak w przypadku WinTrust.dll. Nie martwię się też, że moja aplikacja zostanie złamana, ponieważ jest to oprogramowanie typu open source. Chcę tylko chronić moich użytkowników, aby mogli bezpiecznie otwierać pliki przy użyciu mojej aplikacji, nie będąc 0wn3d. – ErikH

+1

@EricH jeśli istnieje szansa na przejęcie DLL, to komputer użytkownika jest już zagrożony, a fałszywy program crypt32.dll zrobił już to, na co miał zamiar, na długo przed aplikacją. –