Bezpieczeństwo aplikacji Windows
description
Transcript of Bezpieczeństwo aplikacji Windows
![Page 1: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/1.jpg)
Bezpieczeństwo aplikacji Windows
Krzysztof SumowskiPiotr WarzochaRafał Zarębski
Toruń, 07.01.2011
![Page 2: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/2.jpg)
Plan prezentacji
Część I Krzysztof Sumowski, Rafał Zarębski
1. Podstawowe zagadnienia2. Podstawowe błędy i sposoby ochrony3. Narzędzia testujące
Część II Rafał Zarębski
4. Bezpieczeństwo w WinApi - program
Część III Piotr Warzocha
5. Różne metody zabezpieczania programów6. Techniki kryptograficzne
![Page 3: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/3.jpg)
CZĘŚĆ I
![Page 4: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/4.jpg)
1. Podstawowe zagadnienia
• Podstawowe pojęcia
• Znaczenie i rola bezpieczeństwa
• Dlaczego i jak powinniśmy się bronić?
• Oprogramowanie Open Source vs oprogramowanie komercyjne
• Konsekwencje błędów bezpieczeństwa w kodzie
![Page 5: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/5.jpg)
Podstawowe pojęcia
Bezpieczny program to taki, który zachowuje narzucone granice bezpieczeństwa podczas przetwarzania danych, dostarczonych ze źródła objętego innymi uprawnieniami niż sam program.
Bezpieczeństwo to zdolność do sprawowania nadzoru nad wykorzystywaniem przez innych naszych zasobów komputerowych, czyli zdolność do powiedzenia ludziom nie (lub tak) i umiejętność wsparcia tego odpowiednim działaniem.
Bezpieczne programowanie polega w takim samym stopniu na wiedzy o tym, czego nie robić, jak i na wiedzy o tym, co zrobić.
![Page 6: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/6.jpg)
Podstawowe pojęcia
• Poufność• Dostępność• Integralność – informacja nie zmienia się bez naszej wiedzy• Kontrola dostępu – możliwość kontrolowania dostępu poprzez
identyfikacje i uwierzytelnienia• Uwierzytelnianie – zapewnienie autentyczności informacji i
osób• Nienaruszalność - zapewnia integralność komunikacji• Niezaprzeczalność – niemożność zaprzeczania faktowi
wysyłania/odebrania informacji• Dyspozycyjność – ograniczanie skutków ataków
![Page 7: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/7.jpg)
Znaczenie i rola bezpieczeństwa
• Ogromna rola w dzisiejszym zinformatyzowanym świecie• Wiele czynności w naszym życiu uzależnionych od użycia
komputera/Internetu. Sklepy internetowe, banki, dane poufne – konieczność obrony, zadbania o bezpieczeństwo.
• Wyróżniamy bezpieczeństwo na poziomie:funkcjonalnym - silna autentykacja i uwierzytelnienie do zasobówkonfiguracji – odpowiednie opcje, wartości domyślne programu i ich interpretacjakodu – odporność kodu na specyficzne dane czy ataki złośliwych użytkowników
![Page 8: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/8.jpg)
Znaczenie i rola bezpieczeństwa
Kod programu i dane znajdują się w tym samym obszarze w pamięci – udogodnienie dla programistów jak i złośliwych użytkowników.
Najważniejsze z punktu widzenia bezpieczeństwa jest wejście programu (przetwarzanie danych wejściowych).
Brak lub niewystarczająca walidacja danych wejściowych jest główną przyczyną problemów z bezpieczeństwem aplikacji.
![Page 9: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/9.jpg)
Dlaczego i jak powinniśmy się bronić?
Złośliwi użytkownicy, atakujący:
• dla przyjemności
• dla zdobycia wiedzy, sprawdzenia się
• dla pieniędzy
Mimo iż spora część napastników używa prostych narzędzi, przed którymi łatwo się obronić, nie powinniśmy bagatelizować zagrożenia ze strony najgroźniejszych z nich.
![Page 10: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/10.jpg)
Dlaczego i jak powinniśmy się bronić?
Atak następuje, gdy zysk z niego jest większy bądź równy kosztom ataku.
Powinniśmy dążyć do tego, aby koszt przeprowadzenia ataku stale wzrastał = przewyższał korzyści i zniechęcał atakującego.
Nie istnieje całkowicie bezpieczny kod, możemy jedynie obniżać prawdopodobieństwo zajścia ataku.
![Page 11: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/11.jpg)
Dlaczego i jak powinniśmy się bronić?• Fakt, iż nigdy nie zostaliśmy zaatakowani i nie przeczuwamy
takiej sytuacji, nie powinien nas skłaniać do rezygnacji z dbałości o bezpieczeństwo naszych aplikacji.
• Nie ma narzędzia, które kompleksowo ochroni nas przed wszystkimi typami ataków. Defence in depth obrona na wielu warstwach (firewall, obrona samej aplikacji).
• Rewizja kodu naszego programu wtedy przynosi skutki, gdy jest dokonywana przez osoby, które go nie pisały (członek zespołu).
• Narzędzia administracyjne (np. użytkownika root) –nigdy nie powinny ufać danym, na które mogą mieć wpływ nieautoryzowani użytkownicy.
• Zawsze zakładamy możliwość podania złośliwych danych.
![Page 12: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/12.jpg)
Dlaczego i jak powinniśmy się bronić?
Projektowanie bezpiecznej aplikacji wymaga określenia wymagań bezpieczeństwa, stawianych projektowanej aplikacji.
• Jakie jest środowisko bezpieczeństwa pracy programu?
• Jakie są zagrożenia i na ile poważne?
• Komu nie można ufać?
• Jaka sieć/system operacyjny ?
• Jaka jest polityka bezpieczeństwa firmy/organizacji?
• Jakie dane będą chronione?
• Jakie wymagania bezpieczeństwa stawiane są programowi?
![Page 13: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/13.jpg)
Oprogramowanie Open Source vs oprogramowanie komercyjne
Oprogramowanie, którego kod jest ogólnodostępny umożliwia lepsze jego uszczelnienie. Dostęp do kodu mają zarówno intruzi jak i potencjalne ofiary – każdy może zabezpieczyć się najlepiej jak potrafi.
Oprogramowanie komercyjne – nie udostępnianie kodu/ nie informowanie o dziurach nie czyni go bezpieczniejszym. Stworzenie uaktualnienia nie jest takie łatwe.
Fakt udostępnienia kodu źródłowego czyni oprogramowanie bezpieczniejszym.
![Page 14: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/14.jpg)
Konsekwencje błędów bezpieczeństwa w kodzie
• Niestabilne działanie systemu
• Zmiana uprawnień dostępu do plików
• Kradzież poufnych danych
• Straty finansowe, intelektualne, moralne
• Podmiana autorstwa
• Załamanie aplikacji/systemu
• Modyfikacja działania programu
• Przejęcie kontroli nad systemem operacyjnym
• Nieuprawnione użycie programu
![Page 15: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/15.jpg)
Konsekwencje błędów bezpieczeństwa w kodzie
Rodzaje ataków
robaki
ataki Dos, DDos
exploit
backdoor
![Page 16: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/16.jpg)
2. Podstawowe błędy i sposoby ochrony
• Dlaczego powstają dziury w programach?
• Przepełnienie bufora.
• Błąd ciągów formatujących.
• Wycieki pamięci.
• Błędy dostępu do pliku.
• Podsumowanie.
![Page 17: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/17.jpg)
Dlaczego powstają dziury w programach?
• Brak odpowiedniej edukacji, mało dostępna literatura traktująca o pisaniu bezpiecznego kodu.
• Używanie prostych, ale niezabezpieczonych funkcji (np. języka C operujących na łańcuchach znaków).
• Programiści nie pamiętają, iż program pracuje w trybie „multiuser”,
• Programiści zamiast pisać od razu bezpieczny kod, piszą go byle jak, wmawiając sobie, że poprawią go później.
• Większość programistów nie potrafi myśleć jak intruz.• Aktualizacja napisanego już kodu, pod kątem zwiększenia
bezpieczeństwa jest trudna.• Bezpieczne podejście wymaga większych nakładów czasowych,
czyli większych nakładów finansowych.
![Page 18: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/18.jpg)
Przepełnienie bufora
Co to jest przepełnienie bufora?
Bufor to blok pamięci, zazwyczaj w formie tablicy. Jeśli przy zapisywaniu do bufora nie zostanie sprawdzony rozmiar tablicy, możliwe jest zapisanie danych poza zaalokowanym obszarem pamięci (buforem). Zdarzenie, w którym dane zapisywane są pod adresem wyższym niż zaalokowany bufor, nazywa się przepełnieniem bufora (buffer overflow).
Generalnie chodzi o sytuację w której program otrzymuje dane z
zewnątrz. Gdy zaalokowaliśmy bufor o stałej długości, nie sprawdzamy, czy dane przesyłane z zewnątrz nie zajmują więcej miejsca niż na nie przeznaczyliśmy.
![Page 19: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/19.jpg)
Przepełnienie bufora
Przyczyny, umożliwiające włamanie się do programu:
źle deklarowane wartości tablic, nieodpowiednio przekazywane parametry funkcji, nieprawidłowy znak, przepełnienie licznika, brak lub nieodpowiednia kontrola danych wejściowych.
Szczególnie narażone programy napisane w C/C++ (które pozwalają na swobodę programiście)
![Page 20: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/20.jpg)
Przepełnienie bufora
Zagrożenia
• Załamanie aplikacji
• Atak Dos na aplikację
• Wykonanie dowolnego kodu w systemie (z coraz większymi uprawnieniami uruchamianej aplikacji wiąże się większe zagrożenie)
Przepełnienie stosu i sterty (trudniejsze do uzyskania i wykorzystania)
![Page 21: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/21.jpg)
Przepełnienie bufora
Budowa stosu w architekturze x86
Stos jest liniową strukturą danych, w której dane dokładane są na wierzch stosu i z wierzchołka stosu są pobierane (bufor typu LIFO, Last In, First Out; ostatni na wejściu, pierwszy na wyjściu). W architekturze x86 stos rośnie w dół, co oznacza, że nowsze dane są zapamiętywane pod adresami niższymi niż elementy wstawione na stos wcześniej.
![Page 22: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/22.jpg)
Przepełnienie bufora
Każde wywołanie funkcji powoduje utworzenie nowej ramki stosu o następującej budowie (należy pamiętać, że lista uporządkowana jest w kolejności malejących adresów):
• parametry funkcji,
• adres powrotu funkcji,
• wskaźnik ramki,
• ramka procedur obsługi wyjątków,
• lokalnie zadeklarowane zmienne i bufory,
• rejestry zachowane przez funkcję wywołaną.
![Page 23: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/23.jpg)
Przepełnienie bufora
Z budowy stosu widać, że przepełnienie bufora może nadpisać: inne zmienne zaalokowane przed buforem, ramkę obsługi wyjątków, wskaźnik ramki, adres powrotu oraz parametry funkcji. Aby przejąć kontrolę nad programem, wystarczy umieścić odpowiednią wartość w danych, które później zostaną załadowane do rejestru. Jedną z takich wartości jest adres powrotu funkcji. Typowe wykorzystanie przepełnienia bufora polega na nadpisaniu adresu powrotu funkcji i pozwoleniu instrukcjom powrotnym funkcji na załadowanie zmienionego adresu do rejestru.
![Page 24: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/24.jpg)
Przepełnienie bufora
![Page 25: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/25.jpg)
Przepełnienie bufora
Osoby, które wykorzystują tego typu luki działają w taki sposób, że podstawiają własny adres powrotu, który jest podawany do programu. Możliwe jest to dzięki prostej funkcji łańcuchowej, kopiującej wartości w stosie z jednego adresu do drugiego. Nie ma w trakcie tego automatycznego sprawdzenia, czy pod adresem docelowym jest wystarczająca ilość miejsca.
![Page 26: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/26.jpg)
Przepełnienie bufora
![Page 27: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/27.jpg)
Przepełnienie bufora
Przykłady. Stos wywołania funkcji FUN
#include<stdio.h>void FUN(int a, int b, int c){ char bufor[5]; char bufor2[10]; int *ret; ret = &a - 1; (*ret) += 10;}
void main(){ int x; x = 0; FUN(1,2,3); x = 1; printf("%d\n",x);}
![Page 28: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/28.jpg)
Przepełnienie bufora
Wykorzystanie Shellcodu
Shellcode oznacza prosty, niskopoziomowy program prezentowany najczęściej w postaci kodu maszynowego, odpowiedzialny za wywołanie powłoki systemowej. Często wykorzystywany w ostatniej fazie wykorzystywania wielu błędów zabezpieczeń przez exploity.
Dostarczany jest on zwykle wraz z innymi danymi wejściowymi użytkownika. Na skutek wykorzystania luki w atakowanej aplikacji, procesor rozpoczyna wykonywanie shellcode, pozwalając na uzyskanie nieautoryzowanego dostępu do systemu komputerowego lub eskalację uprawnień.
![Page 29: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/29.jpg)
Przepełnienie bufora
Shellcode składa się z instrukcji asemblera zapisanych już w formie binarnej, w której wszystkie adresy muszą być zakodowane na stałe. Aby uniknąć bezwzględnych odwołań do pamięci generujących błąd naruszenia segmentacji programu. Większość adresów uzyskuje się ze stosu a skoki są wykonywane nie do konkretnego miejsca w pamięci tylko o konkretną ilość instrukcji procesora w przód, bądź w tył.
![Page 30: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/30.jpg)
Przepełnienie bufora
Zapobieganie przepełnieniom bufora
Aby zapobiegać przepełnieniom bufora, należy zwracać uwagę na funkcje, których używamy w naszych programach.
Najczęstszą przyczyną problemów jest niewłaściwe stosowanie funkcji związanych z obsługą łańcuchów tekstowych. Dlatego też przyjrzymy się im bliżej, aby zobaczyć, jak można zabezpieczyć się przed niepożądanym działaniem.
![Page 31: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/31.jpg)
Przepełnienie bufora
Niebezpieczne konstrukcje języka C
![Page 32: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/32.jpg)
Przepełnienie bufora
Funkcja strcpy
Wywołanie funkcji: char *strcpy( char *strDestination, const char *strSource );
Istnieje bardzo wiele sytuacji, w której działanie funkcji zakończy się z błędem. Najpopularniejsze z nich to między innymi: gdy bufor źródłowy i docelowy są puste, jeżeli bufor źródłowy nie jest zakończony znakiem null i największy z problemów – gdy rozmiar ciągu źródłowego jest większy niż bufor docelowy.
![Page 33: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/33.jpg)
Przepełnienie bufora
Funkcja strncpy Wywołanie funkcji: char *strncpy( char *strDest, const char *strSource, size_t count );
Jest bezpieczniejsza niż strcpy, ale i tutaj nadal mogą pojawiać się problemy, szczególnie w przypadku przekazywania wartości null jako ciągu źródłowego lub docelowego. Dodatkowo problemem może być zła wartość licznika. Jedna z różnic pomiędzy tą funkcją a poprzednią to fakt, że jeśli bufor źródłowy nie jest zakończony null, to funkcja nie zakończy się z błędem.
![Page 34: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/34.jpg)
Przepełnienie bufora
Funkcja sprintf Wywołanie funkcji: int snprintf( char *buffer, size _ t count, const char *format [, argument] ... );
Jest to jedna z bezpieczniejszych funkcji. Jedyna rzecz, na którą należy zwrócić uwagę to bufor docelowy jest zakończony znakiem null.
Funkcja _snprintf Wywołanie funkcji: int _snprintf( char *buffer, size _ t count, const char *format [, argument] ... );
Jest to jedna z bezpieczniejszych funkcji. Jedyna rzecz, na którą należy zwrócić uwagę, to sprawdzenie, czy bufor docelowy jest zakończony znakiem null.
![Page 35: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/35.jpg)
Przepełnienie bufora
Address Space Layout Randomization (ASLR)implementacja w Windows Vista I Windows 7rozmieszczenie bibliotek i aplikacji pod losowymi adresamiszansa na powodzenie ataku maleje 256 razymoże powodować problemy kompatybilnościoweStack Defender – IPS- uniemożliwia uruchomienie kodu napastnika z obszaru pamięci stosuData Execution Prevention (DEP)- uniemożliwia wykonanie kodu pochodzącego z niewykonywalnego obszaru pamięci- ochrona programowa - można skonfigurować ją dla systemu lub dla aplikacji- ochrona sprzętowa - wymagane „rozumienie” technologii przez procesor
![Page 36: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/36.jpg)
Przepełnienie bufora
Przepełnienie bufora to poważny problem. Każdy programista powinien mieć świadomość tego rodzaju zagrożenia. Zanim zacznie tworzyć kod, powinien wziąć pod uwagę podobne problemy i dużo wcześniej przemyśleć architekturę kodu. Z drugiej strony, programista powinien mieć pomoc ze strony narzędzi programistycznych – tak, aby to one mogły sprawdzić i rozwiązać takie problemy (przynajmniej częściowo). Po analizie tekstu możemy zadać następujące pytanie jak samemu wyrobić sobie nawyk nie popełniania takich błędów, jak przepełnienie bufora? O ile nigdy nie doświadczymy na własnej skórze problemu z włamaniem i nie stracimy przez to jakichś istotnych danych, to pewnie trudno nam będzie o tym pamiętać. A na poważnie – warto zrobić sobie listę wszystkich kroków, które musimy wykonać, i sprawdzić, czy wśród nich jest sprawdzenie możliwości wystąpienia przepełnienia bufora.
![Page 37: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/37.jpg)
Błąd ciągów formatujących
Format string attack - atak informatyczny, będący stosunkowo nową techniką wykorzystywania błędów programistycznych w aplikacjach. Błędnie napisana aplikacja może być przy wykorzystaniu tej techniki usunięta z listy procesów przez system operacyjny (tzw. crash) lub zmuszona do wykonania kodu dostarczonego przez napastnika.
![Page 38: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/38.jpg)
Błąd ciągów formatujących
Przez wiele lat niewłaściwe wykorzystanie funkcji operujących na ciągach formatujących było uważane za błąd, jednak nie brano uwagę, iż umożliwia on przejęcie kontroli nad aplikacją. W 2000 roku po raz pierwszy przedstawiono exploity wykorzystujące błędy tego typu w szeroko stosowanym serwerze usługi FTP. Kod źródłowy exploita pokazywał technikę umożliwiającą przejęcie kontroli nad aplikacją przy wykorzystaniu błędnego wywołania funkcji vsnprintf() wewnątrz własnej funkcji, odpowiedzialnej za formułowanie odpowiedzi (lreply()).
![Page 39: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/39.jpg)
Błąd ciągów formatujących
Atak wykorzystuje fakt, iż funkcje ze zmienną ilością argumentów takie jak printf() określają ilość tych argumentów na podstawie podanego ciągu znaków. Podczas jego interpretowania korzysta z dodatkowych parametrów podanych do funkcji, przedstawiając je w czytelnej dla człowieka formie.
Podatność na atak ma miejsce gdy atakujący może dostarczyć do takiej funkcji ciąg formatujący. W ten sposób można zmienić zachowanie aplikacji, i przejąć nad nią kontrolę.
![Page 40: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/40.jpg)
Błąd ciągów formatujących
Najprostszy przykład gdzie podanie ciągu formatującego jest możliwe:
int funkcja (char *nazwa)
{
printf (nazwa);
}
W języku C jest dużo funkcji formatujących. Na kolejnym slajdzie wymieniono niektóre z podstawowych funkcji, na których bazowane są inne bardziej złożone, zaś niektóre z nich nie należą do standardu, lecz są ogólnodostępne.
![Page 41: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/41.jpg)
Błąd ciągów formatującychfprintf — drukuje do pliku
printf — drukuje do strumienia standardowego wyjścia
sprintf — drukuje do zmiennej typu string
snprintf — drukuje do zmiennej typu string kontrolując długość
vfprintf — drukuje do pliku ze struktury va_arg
vprintf — drukuj from a va_arg structure
vsprintf — drukuje do strumienia standardowego wyjścia ze struktury va_arg
vsnprintf — drukuje do zmiennej typu string kontrolując długość ze struktury va_arg
Pokrewne:
setproctitle, syslog, inne err*, verr*, warn*, vwarn*
![Page 42: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/42.jpg)
Błąd ciągów formatujących
Aby zrozumieć skąd bierze się podatność na ataki wymienionych funkcji trzeba zbadać jaki jest cel funkcji formatujących.
Zastosowania:
• są używane do konwertowania prostych typów C do postaci ciągu znaków
• pozwalają określić format reprezentacji danych
• przetworzyć go (wyjście do stderr, stdout, syslog etc. )
![Page 43: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/43.jpg)
Błąd ciągów formatujących
Jak działa funkcja formatująca?
• ciąg formatujący kontroluje zachowanie funkcji
• określa typ danych jakie mają być wydrukowane
• parametry są wepchnięte na stos
• zapisane albo przez wartość albo przez referencję
Podstawowe parametry określające typ danych:
%d – liczba całkowita
%u – liczba całkowita bez znaku
%x – liczba w systemie szesnastkowym
%s – ciąg znaków
%n – do argumentu zapisywana jest liczba dotychczas zapisanych znaków
![Page 44: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/44.jpg)
Błąd ciągów formatujących
Przykład:
printf ("liczba %d , liczba %d o adresie: %08x\n", a, b, &c);
Z perspektywy prtintf stos wygląda następująco:
![Page 45: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/45.jpg)
Błąd ciągów formatujących
Funkcja przetwarza ciąg formatujący po jednym znaku. Jeśli znak ten nie jest '%' zostaje przekopiowany do wyjścia w przeciwnym wypadku następny znak/znaki określa typ zmiennej.
![Page 46: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/46.jpg)
Błąd ciągów formatujących
Zawieszenie programu
Jest to najprostszy z ataków za pomocą ciągu formatującego. Bez problemu można wywołać błąd, próbując odczytać pamięć z niedozwolonego adresu. Dokonuje się tego za pomocą podania ciągu „%s%s%s%s%s%s%s”.
![Page 47: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/47.jpg)
Błąd ciągów formatujących
Odczytanie danych ze stosu
Podając ciąg taki jak np: „%08x %08x %8x” każemy funkcji printf odczytać ze stosu 3 argumenty i wyświetlić je jako ośmiocyfrowe liczby w systemie szesnastkowym. Zależnie od wielkości bufora przeznaczonego na ciąg formatujący i na wielkość bufora wyjściowego, można odtworzyć mniejsze lub większe obszary pamięci. Można w ten sposób dowiedzieć się więcej o działaniu programu, odczytać zmienne lokalne, znaleźć przedziały pamięci, które chce się zaatakować.Dodatkowo umieszczając ręcznie adres na stosie można odczytać pamięć pod tym adresem poleceniem %s.
![Page 48: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/48.jpg)
Błąd ciągów formatujących
Pisanie do pamięci za pomocą %n
Tak jak w przypadku czytania z dowolnego miejsca, tyle ze %n w tym wypadku wpisze liczbę całkowita do argumentu wskazywanego przez podstawiony adres.
Używając tych metod można znaleźć i nadpisać kod powrotu funkcji tak aby wskazywał na spreparowany szkodliwy kod.
![Page 49: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/49.jpg)
Błąd ciągów formatujących
Jak się bronić:
Zamiast printf (string);pisać: printf („%s”,str);
Ostrożność przy używaniu funkcji typu
fprintf (STDOUT,strFormat,arg1,arg2,arg3);
Testowanie kodu:• Narzędzie RATS• Dedykowane narzędzie pscan (Cygwin)
![Page 50: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/50.jpg)
Wycieki pamięci
Zjawisko wycieku pamięci szczególnie znane jest osobom programującym w językach nie posiadających odśmiecania/śmieciarza (ang. Garbage Collector), takich jak C/C++. Na pozór, nazwa tego zjawiska niejako odnosi się do wadliwego działania pamięci, w rzeczywistości jednak winę ponosi niewłaściwie napisany kod. Aby zobrazować na czym polega cały problem, warto przeanalizować przykład z kolejnego slajdu.
![Page 51: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/51.jpg)
Wycieki pamięci
Przykład programu powodującego wyciek pamięci#include <stdio.h>#include <stdlib.h>int main(void){ int **p; // Deklarujemy wskaźnik na wskaźnik na zmienną typu całkowitego do obszaru pamięci p = (int**) malloc ( sizeof(int*) );
// Rezerwujemy miejsce na 1 element typu wskaźnik na int pod tym wskaźnikiem *p = (int*) malloc ( sizeof(int) );
// Rezerwujemy miejsce na 1 element typu int pod wskaźnikiem na wskaźnik free(p); // Zwalniamy obszar pamięci, wskazywany przez wskaźnik p return 0;}
![Page 52: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/52.jpg)
Wycieki pamięci
Na początku została zaalokowana pamięć pod wskaźnik p, a następnie pod wskaźnik na wskaźnik *p. Po czym, za pomocą funkcji free został zwolniony obszar pamięci wskazywany przez wskaźnik.Na pozór wszystko działa jak należy, a kompilacja nie wykazuje żadnych błędów. W rzeczywistości, każde wywołanie powyższego programu spowoduje wyciek 4 bajtów (bo tyle zazwyczaj wynosi rozmiar zmiennej typu int) pamięci. Nietrudno zauważyć dlaczego tak się dzieje. Wszystko spowodowane jest tym, że pamięć alokowana była dwa razy, a funkcja zwalniająca pamięć free została wywołana tylko raz.
![Page 53: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/53.jpg)
Wycieki pamięci
Ponieważ język C pozbawiony jest tzw. "odśmieciacza", dlatego każdemu wywołaniu jednej z funkcji alokujących pamięć, takich jak: malloc, calloc lub realloc, musi odpowiadać wywołanie funkcji free.Cały błąd w powyższym kodzie polega wiec na tym, że zwolniony został wskaźnik p, ale nie został zwolniony wskaźnik na ten wskaźnik. Problem jest o tyle skomplikowany, że po zwolnieniu wskaźnika p, nie mamy dostępu do wskaźnika *p, więc nie możemy zwolnić obszaru pamięci przezeń wskazywanego.
![Page 54: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/54.jpg)
Wycieki pamięci
Poniższy kod został pozbawiony tego błędu:Przykład programu potencjalnie pozbawionego wycieku pamięci#include <stdio.h>#include <stdlib.h>int main(void){int **p; // deklarujemy wskaźnik na wskaźnik na zmienną typu całkowitego do obszaru pamięci p = (int**) malloc ( sizeof(int*) );
// rezerwujemy miejsce na 1 element typu wskaźnik na int pod tym wskaźnikiem *p = (int*) malloc ( sizeof(int) );
// rezerwujemy miejsce na 1 element typu int pod wskaźnikiem na wskaźnikfree(*p); // zwalniamy obszar pamięci, wskazywany przez wskaźnik na wskaźnik p free(p); // zwalniamy obszar pamięci, wskazywany przez wskaźnik p return 0;}
![Page 55: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/55.jpg)
Wycieki pamięci
Warto zauważyć jedną z cech dynamicznej alokacji pamięci:Bardziej skomplikowane deklaracje, jak np. alokowanie pamięci pod wskaźnik na wskaźnik, albo pod wskaźnik na strukturę, w której znajdują się wskaźniki, zazwyczaj wiąże się ze zwalnianiem poszczególnych elementów w odwrotnej kolejności, niż zostały one zaalokowane.Trzeba zwrócić uwagę na to, jakim problemem może być wyciek pamięci w programie, który dłuższy czas działa w systemie, np. serwerze, czy demonie. W takim wypadku program zajmuje coraz większą ilość pamięci, której nie może wykorzystać, ani tym bardziej zwolnić. Sam wyciek może nie tylko prowadzić do spadku wydajności, a także, w skrajnym przypadku zawieszenia się programu, ale nawet do zablokowania całego systemu.
![Page 56: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/56.jpg)
Wycieki pamięci
Sam wyciek jest najczęściej wynikiem:
• zapominalstwa
• wielu ścieżek powrotu z funkcji
• przypisania nowej wartości do wskaźnika przed wywołaniem free
• nie zwolnienia elementów struktury po zwolnieniu struktury
• nieświadomości, że funkcja wywoływana alokuje pamięć, którą funkcja wywołująca powinna zwolnić.
![Page 57: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/57.jpg)
Wycieki pamięci
Śledzenie wycieków pamięci
Jak już zostało wspomniane, mimo, że wycieki pamięci są efektem bardzo niepożądanym, tak naprawdę czasami całkiem nieświadomie możemy doprowadzić do tego, że nasza aplikacja będzie traciła pamięć przez nieudolną alokację i dealokację. Jednym ze sposobów jest staranne prześledzenie zmiennych związanych z alokacją pamięci, linia po linii, od narodzin do śmierci, jednak nie jest to ani łatwy, ani przyjemny sposób. Nie mniej jednak śledzenie wycieków może być względnie proste. Mowa tu głównie o aplikacjach śledzących wycieki pamięci, albo wykorzystaniu dyrektyw preprocesora.
![Page 58: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/58.jpg)
Błędy dostępu do pliku
Sytuacja, w której użytkownik chce otworzyć plik:
- etap I: sprawdzanie dostępności pliku
- etap II: otwarcie pliku
- pomiędzy etapami procesor może zostać wywłaszczony do innego zadania, a napastnik może podmienić plik!
Zagrożenia:
- zwiększenie praw dostępu ( jeśli podatny program działa z podwyższonymi uprawnieniami)
![Page 59: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/59.jpg)
Błędy dostępu do pliku
Ochrona:
- większość języków udostępnia odpowiednie funkcje
/*first dropping privileges…*/
FILE file = fopen(strFileName, „w+”);
If (file)
DoSomething ( file );
![Page 60: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/60.jpg)
Podsumowanie
Wskazówki podnoszące bezpieczeństwo:
• Sprawdzanie wszystkich danych wejściowych.• Unikanie możliwości przepełnienia bufora.• Uruchamianie i późniejsze działanie z jak najmniejszymi
przywilejami.• Prostota projektu i implementacji.• Domyślne opcje działania/instalacji ustawione na odmowę
dostępu (ang. deny).• Minimalizacja użycia dzielonych zasobów.• Unikanie „wyścigów po zasoby” (ang. race conditions).• Mechanizmy ochrony powinny być proste, jednolite i
zaimplementowane w najniższych warstwach systemu.
![Page 61: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/61.jpg)
Podsumowanie
• Spójne stosowanie określonych konwencji programistycznych.• Korzystanie tylko z bezpiecznych, zewnętrznych bibliotek.• Walidacja parametrów przekazywanych do zewnętrznych
programów.• Sprawdzanie wyników wywołań funkcji systemowych.• Pełne logowanie każdego zdarzenia, błędu, jednak z
zachowaniem rozsądku, tak aby np. nie dostarczać atakującemu pełnego opisu wystąpienia błędu. Użytkownik ma wiedzieć co się stało, ale niekoniecznie dlaczego się coś stało.
• Nie upublicznianie funkcji ujawniających informacje testowe.• Eliminowanie z kodu przestarzałych konstrukcji języka.
![Page 62: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/62.jpg)
3. Narzędzia testujące
• Testowanie kodu źródłowego
• Skanery kodu źródłowego
• Skanery kodu binarnego
• Opcje kompilatorów, biblioteki bezpieczeństwa
• Gotowe programy testujące
![Page 63: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/63.jpg)
Testowanie kodu źródłowego
Wielostopniowy system dbania o jakość programów. Wykonywać testy dla jak największej liczby różnych przypadków. Dokumentowanie kodu.
Wszystkie algorytmy w programie powinny zostać przetestowane przy użyciu najgorszego zestawu danych, czyli dla którego aplikacje wykonują się najdłużej.
![Page 64: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/64.jpg)
Skanery kodu źródłowego
Zalety
• Duża szybkość działania
• Możliwość uruchamiania okresowego w celu wykrycia nowych błędów lub weryfikacji usunięcia poprzednio wykrytych podatności
• Istnieje szereg narzędzi dostępnych bez opłat, jak również możliwych do samodzielnego rozszerzania
![Page 65: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/65.jpg)
Skanery kodu źródłowego
Wady
• Nie zawsze mamy dostęp do kodu źródłowego
• Wykrywają jedynie błędy najłatwiejsze do strukturalnego zdefiniowania
• Niektóre darmowe narzędzia działają nieoptymalnie, mają skomplikowany interfejs, niekompletną dokumentację
• false positives – wykrycie podatności tam, gdzie jej nie ma; false negatives – nie wykrycie podatności tam, gdzie jest.
![Page 66: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/66.jpg)
Skanery kodu źródłowego
Analiza kodu C/C++
cppcheck
RATS – Rough Auditing Tool for Security (działa także pod Windowsem)
DevPartner for Visual C++ BoundsChecker Suite
![Page 67: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/67.jpg)
Skanery kodu binarnego
Narzędzie o nazwie BFBTester służy do szybkiego testu programu binarnego. BFBTester potrafi przetestować program pod kątem długości argumentów dostarczonych jako parametry oraz sprawdzi odporność na przepełnienie zmiennych środowiskowych. Do jego możliwości można zaliczyć śledzenie wywołań funkcji systemowych, tworzących pliki tymczasowe oraz powiadamianie w przypadku, kiedy używane są niezabezpieczone funkcje. Oczywiście skaner ten nie wykrywa wszystkich błędów, ale może być użyteczny na samym początku, eliminując błędy, które w późniejszym czasie mogą okazać się katastrofalne w skutkach.
![Page 68: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/68.jpg)
Opcje kompilatorów, biblioteki bezpieczeństwa
Biblioteki
• Run-time Checks (RTC) – całkowite sprawdzenie sterty danymi niezerowymi, unikając założenia, że sterta jest zawsze pusta. Sprawdzane są granice wszystkich tablic, aby wyłapać nawet jeden bajt przepełniający bufor i znaleźć niezgodne wywołania.
• PREfast – narzędzie dla programisty, które pomaga znaleźć błędy trudne do testowania i debugowania przez identyfikację założeń, które mogą być nieprawdziwe. PREfast znajduje się w Visual Studio 2005.
![Page 69: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/69.jpg)
Opcje kompilatorów, biblioteki bezpieczeństwa
• Source Code Annotation Language (SAL) – pozwala programiście na przypisanie wartości do bufora. Kiedy kod jest skompilowany, kompilator zna warunki, które pozwalają na określenie wartości oczekiwanych i aktualnych. Funkcjonalność pozwala programiście na odkrycie błędów, które mogą trudne do znalezienia ręcznie.
![Page 70: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/70.jpg)
Opcje kompilatorów, biblioteki bezpieczeństwa
• Application Verifier – to narzędzie pakietu Visual Studio, udostępniające funkcje instrumentacji obecne w systemie operacyjnym Windows. Instrumentacja ta pozwala w czasie działania aplikacji przeprowadzić jej weryfikację w wybranych obszarach, takich, jak przydział pamięci czy użycie sekcji krytycznych i uchwytów. Application Verifier wykrywa problemy czasu wykonywania w zakresie alokacji pamięci, wyjścia poza bloki na stercie, użycia pamięci po usunięciu, podwójnego usunięcia i zanieczyszczenia sterty. W zakresie wykorzystania sekcji krytycznych wykrywa działania, które mogą prowadzić do blokowania lub wycieku zasobów. Jeśli chodzi o użycie uchwytów, wykrywa próby powtórnego użycia uchwytów, które już nie są poprawne.
![Page 71: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/71.jpg)
Opcje kompilatorów, biblioteki bezpieczeństwa
Przełącznik kompilatora Visual Studio /GS. Przełącznik /GS wstawia pomiędzy bufor a adres powrotu znacznik. Jeśli przepełnienie bufora nadpisze adres powrotu, to nadpisze także znacznik wstawiony pomiędzy adres a bufor. Nowa budowa ramki stosu jest następująca:
• parametry funkcji,
• adres powrotu funkcji,
• wskaźnik ramki, • znacznik, • ramka procedur obsługi wyjątków,
• lokalnie zadeklarowane zmienne i bufory,
• rejestry zachowane przez funkcję wywołaną.
![Page 72: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/72.jpg)
Opcje kompilatorów, biblioteki bezpieczeństwa
Przełącznik /GS
Gdy testy bezpieczeństwa są włączone, sposób wykonania funkcji ulega zmianie. Instrukcje, które mają być wykonane zaraz po wywołaniu funkcji, znajdują się w początku funkcji.
Jeżeli występuje niezgodność, aplikacja domyślnie kończy swoje wykonywanie po poinformowaniu użytkownika
![Page 73: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/73.jpg)
Opcje kompilatorów, biblioteki bezpieczeństwa
Wady /GS
- chroni tylko przed przepełnieniami stosu
- wymaga włączonej optymalizacji
- nie działa dla funkcji
- z buforami o wielkości 1-4 bajty
- o zmiennej liście argumentów
- z wstawkami w asemblerze
-kompilator może błędnie zadecydować, że funkcja nie wymaga ochrony
![Page 74: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/74.jpg)
Gotowe programy testujące
BinScope Binary Analyzer. Analizuje ono aplikacje aby sprawdzić, czy ich autorzy przestrzegali zasad pisania bezpiecznego kodu. Obejmuje to np. sprawdzenie czy nie była użyta stara wersja kompilatora oraz czy kod był kompilowany z opcją /GS, która pozwala zmniejszyć ryzyko podatności na przepełnienie bufora. Co ciekawe Microsoft wprowadził w BinScope zabezpieczenie przed używaniem go do szukania dziur w programach innych autorów.
![Page 75: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/75.jpg)
CZĘŚĆ II
![Page 76: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/76.jpg)
4. Bezpieczeństwo w WinApi
• Podstawowe pojęcia
• Struktura SECURITY_ATTRIBUTES
• Secuirty Descriptor
• Opis ACE
• Nadanie praw nowemu obiektowi
• Pobranie praw obiektu
![Page 77: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/77.jpg)
Podstawowe pojęcia
• Logując się do Windowsa, otrzymujemy od systemu access token – klucz (żeton) umożliwiający dostęp do odpowiednich obiektów (do wszystkich ma dostęp tylko administrator).
• Access token – identyfikuje użytkownika w systemie (login i grupa, do której należy) i określa jego prawa oraz uprzywilejowania (privileges).
![Page 78: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/78.jpg)
Podstawowe pojęcia
Obiektem systemu Windows nazywamy:
• Pliki
• Katalogi
• Klucze rejestracyjne
• Procesy
• Wątki
• Muteksy, Semafory
• Potoki nazywane, nienazwane
![Page 79: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/79.jpg)
Podstawowe pojęcia
Security Descriptor
Używany, aby zabezpieczyć obiekt, dodawany przy każdej funkcji Create dowolnego obiektu Windows (użycie wartości NULL – dodanie domyślnego deskryptora bezpieczeństwa).
Security Descriptor zawiera:
• Identyfikator właściciela deskryptora
• Identyfikator głównej grupy deskryptora
• SACL – systemowa lista kontroli dostępu
• DACL – zdyskretyzowana lista kontroli dostępu
![Page 80: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/80.jpg)
Podstawowe pojęcia
Czym jest ACL (access control list)?ACL jest listą elementów ACE.
ACE (access control entries) – wskazuje na użytkownika bądź grupę, którego/której mają tyczyć się uprawnienia (allow/deny).
DACL – zawiera ACL z określeniem konkretnych praw dla każdego ACE.
SACL – zwiera ACL z określeniem, do którego ACE będzie się odnosił audyt i w jakim celu.
![Page 81: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/81.jpg)
Struktura SECURITY_ATTRIBUTES
Struktura ta zawiera deskryptor bezpieczeństwa i informacje o jego dziedziczeniu oraz rozmiar struktury.
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength;
LPVOID lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES;
![Page 82: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/82.jpg)
Security Descriptor
typedef PVOID PSECURITY_DESCRIPTOR;
InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
Inicjalizacja deskryptora bezpieczeństwa określonego przez sd.
![Page 83: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/83.jpg)
Security Descriptor
Ustawienie właściciela i grupy Deskryptora Bezpieczeństwa
BOOL SetSecurityDescriptorOwner(
PSECURITY_DESCRIPTOR pSecurityDescriptor, // address of security descriptor PSID pOwner, // address of SID for owner BOOL bOwnerDefaulted // flag for default );
BOOL SetSecurityDescriptorGroup(
PSECURITY_DESCRIPTOR pSecurityDescriptor, // address of security descriptor PSID pGroup, // address of SID for group BOOL bGroupDefaulted // flag for default );
![Page 84: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/84.jpg)
Security Descriptor
Ustawienie DACL w Deskryptorze Bezpieczeństwa (skojarzenie z isteniejącym ACL).
BOOL SetSecurityDescriptorDacl(
PSECURITY_DESCRIPTOR pSecurityDescriptor, // address of security descriptor
BOOL bDaclPresent, // flag for presence of discretionary ACL
PACL pDacl, // address of discretionary ACL
BOOL bDaclDefaulted // flag for default discretionary ACL
);
![Page 85: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/85.jpg)
Opis ACE
Każde ACE zawiera:
SID – security identifier – wartość w rejestrze jednoznacznie określająca użytkownika bądź grupę
32 bitową maskę praw
Nagłówek ACE – access denied / access allow
![Page 86: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/86.jpg)
Opis ACE
Maska praw
Prawa dla plików w Windows
Uprawnienia do plików i katalogów
![Page 87: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/87.jpg)
Opis ACESkojarzenie SID (security identifier) z podaną nazwą użytkownika.
Funkcja odwrotna - LookupAccountSidBOOL LookupAccountName(
LPCTSTR lpSystemName, // address of string for system name
LPCTSTR lpAccountName, // address of string for account name
PSID Sid, // address of security identifier
LPDWORD cbSid, // address of size of security identifier
LPTSTR ReferencedDomainName, // address of string for referenced domain
LPDWORD cbReferencedDomainName, // address of size of domain string
PSID_NAME_USE peUse // address of SID-type indicator
);
![Page 88: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/88.jpg)
Opis ACE
Inicjalizacja ACL
BOOL InitializeAcl(
PACL pAcl, // address of access-control list
DWORD nAclLength, // size of access-control list
DWORD dwAclRevision // revision level of access-control list
);
![Page 89: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/89.jpg)
Opis ACE
Dodanie i odebranie prawBOOL AddAccessAllowedAce(
PACL pAcl, // pointer to access-control list
DWORD dwAceRevision, // ACL revision level
DWORD AccessMask, // access mask
PSID pSid // pointer to security identifier
);
Definicja AddAccessDeniedAce identyczna
![Page 90: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/90.jpg)
Nadanie praw nowemu obiektowi
1. Inicjalizacja Deskryptora Bezpieczeństwa
2. Inicjalizacja ACL
3. Ustawienie praw dla konkretnych użytkowników AddAccessAllowedAce / AddAccessDeniedAce dla konkretnego Sid. (skojarzenie Sid z nazwą użytkownika LookupAccountName).
4. Ustawienie właściciela i grupy Deskryptora Bezpieczeństwa
5. Dodanie DACL do Deskryptora Bezpieczeństwa
![Page 91: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/91.jpg)
Nadanie praw nowemu obiektowi
6. Określenie wszystkich elementów struktury SECURITY_ATTRIBUTES
sa.nLength= sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = &sd;
7. Dodanie struktury SECURITY_ATTRIBUTES do nowotworzonego obiektu (funkcja CreateSth)
![Page 92: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/92.jpg)
Pobranie praw obiektu
Pobranie deskryptora bezpieczeństwa obiektu:
GetFileSecurity, GetKernelObjectSecurity.
Pobranie właściciela i grupy Deskryptora Bezpieczeństwa:
GetSecurityDescriptorOwner, GetSecurityDescriptorGroup
Pobranie DACL Deskryptora Bezpieczeństwa:
GetSecurityDescriptorDacl
![Page 93: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/93.jpg)
Pobranie praw obiektu
Pobranie informacji o ACL:BOOL GetAclInformation(
PACL pAcl, // pointer to access-control list
LPVOID pAclInformation, // pointer to ACL information
DWORD nAclInformationLength, // size of ACL information
ACL_INFORMATION_CLASS dwAclInformationClass // class of requested information
);
Struktura ACL_SIZE_INFORMATIONtypedef struct _ACL_SIZE_INFORMATION {
DWORD AceCount; //number of ACEs
DWORD AclBytesInUse; //number of bytes in used
DWORD AclBytesFree; //number unused bytes
} ACL_SIZE_INFORMATION;
![Page 94: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/94.jpg)
Pobranie praw obiektu
Pobranie informacji o ACL:BOOL GetAclInformation(
PACL pAcl, // pointer to access-control list
LPVOID pAclInformation, // pointer to ACL information
DWORD nAclInformationLength, // size of ACL information
ACL_INFORMATION_CLASS dwAclInformationClass // class of requested information
);
Struktura ACL_SIZE_INFORMATIONtypedef struct _ACL_SIZE_INFORMATION {
DWORD AceCount; //number of ACEs
DWORD AclBytesInUse; //number of bytes in used
DWORD AclBytesFree; //number unused bytes
} ACL_SIZE_INFORMATION;
![Page 95: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/95.jpg)
Prezentacja programu
![Page 96: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/96.jpg)
CZĘŚĆ III
![Page 97: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/97.jpg)
5. Różne metody zabezpieczania programów
• Prezentacja wybranych programów
• Proste metody zabezpieczania programów
• Kompresowanie plików wykonywalnych
• Zabezpieczenia przed debugerami
• Algorytmy wyznaczające sygnatury danych
• Problem generatorów liczb pseudolosowych
• Końcowe wskazówki
![Page 98: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/98.jpg)
Prezentacja wybranych programów
Edycja plików binarnych
• Hex Workshop (shareware) – dodatkowo wyznaczanie sumy kontrolnej plików, porównywanie plików. Dla Linuksa – kHexEdit.
• Free Hex Editor Neo - darmowy
![Page 99: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/99.jpg)
Prezentacja wybranych programów
Edycja zasobów (kursory, ikony, bitmapy, menu, okna dialogowe itp) plików wykonywalnych
• Resource Hacker –obsługuje typy: exe, dll, ocx, cpl, scr. Darmowy
• ResEdit - darmowy
• ExeScope – shareware, wyświetla z jakich funkcji API korzysta program
• PE Resource Explorer – shareware
![Page 100: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/100.jpg)
Prezentacja wybranych programów
Debugery
• Olly Debug
• SoftICE – nie rozwijany – wiele programów zabezpieczonych przed tym debugerem
• Visual Studio
Debugery umożliwiają zastawianie pułapek w zadanych miejscach kodu, przeglądanie stosu wywołań, niektóre pozwalają na modyfikację kodu, który ma zostać wykonany. Często wykorzystywane przez włamywaczy.
![Page 101: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/101.jpg)
Proste metody zabezpieczania programów
Zabezpieczanie przed modyfikacjami pliku binarnego:
• sprawdzanie rozmiaru pliku (zabezpieczenie przed nieuprawnioną modyfikacją)
• sprawdzenie daty i czasu modyfikacji
Metody nie zapewniają dostatecznej ochrony, mało skuteczne, łatwo zedytować plik binarny, aby jego wielkość pozostała taka sama; podmienianie starej daty modyfikacji.
![Page 102: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/102.jpg)
Proste metody zabezpieczania programów
Zastosowanie numeru seryjnego (zabezpieczenie przed nieuprawnionym kopiowaniem).
• Powinien być unikatowy pomiędzy wszystkimi egzemplarzami oprogramowania.
• Powinien być wygenerowany przez generator liczb pseudolosowych o takim algorytmie, aby kolejne numery miały jak najmniejszy związek ze sobą, najlepiej żaden.
• Powinien zawierać numer kontrolny (czy został wygenerowany przez właściwy algorytm)
• Powinien być jak najdłuższy, aby trudniej go było złamać, a jednocześnie powinien być jak najkrótszy, aby zmniejszyć uciążliwość wprowadzania go przez użytkownika.
![Page 103: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/103.jpg)
Proste metody zabezpieczania programów
Prezentacja programu.
Wykorzystanie debugera OllyDbg i edytora plików binarnych Hex Workshop
![Page 104: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/104.jpg)
Proste metody zabezpieczania programów
Wnioski:
• Łamanie kodu polegającego na wplecionym gdzieś jednostkowym teście jest proste.
• Wielkość programu nie ma znaczenia, kraker uderza w krytyczne punkty aplikacji.
• Procedury weryfikacyjne powinny udostępniać jak najmniej punktów zaczepienia dla krakera (nie dawać wskazówek lecz zaskakiwać).
• Wymagana większa ilość procedur weryfikacji – w różnych losowych miejscach, użycie różnych algorytmów generacji wzorca.
![Page 105: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/105.jpg)
Proste metody zabezpieczania programów
Idea kluczy rejestracyjnych przypisanych do użytkownika.
Stworzenie klucza seryjnego przy użyciu informacji ze środowiska pracy, w którym uruchamiany jest program.
Informacje te mogą tworzyć klucz odblokowujący program. Uniemożliwia to przekazywanie kluczy innym użytkownikom, umieszczania w Internecie, stworzenia keygena, pozostaje ryzyko złamania procedury weryfikującej. Wady – użytkownik zmienia konfigurację środowiska pracy – niezbędne ponowne wygenerowanie klucza.
![Page 106: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/106.jpg)
Proste metody zabezpieczania programów
Techniki:
• Odczyt fragmentu pamięci BIOS.
• Odczyt numeru seryjnego dysku twardego
• Odczyt numeru MAC
Stworzenie kilku alternatywnych kluczy (będą działać, jeśli co najwyżej jeden podzespół zostanie zmieniony – wymiana całego zestawu wymusi generowanie nowego klucza).
![Page 107: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/107.jpg)
Proste metody zabezpieczania programów
Gotowe systemy zabezpieczania aplikacji przed nieuprawnionym użyciem:
SecuROM, StarForce - ochrona przed kopiowaniem programów
Themida – utrudnia debugowanie, zrzuty aplikacji z pamięci, szyfrowanie fragmentów kodu.
ASProtect
Wszystkie te rozwiązania są drogie, konieczność częstych aktualizacji, gdyż każda nowa wersja jest/zostanie złamana przez krakerów (prędzej czy później). Rozwiązania dobre dla firm.
![Page 108: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/108.jpg)
Kompresowanie plików wykonywalnych
Kompresja plików wykonywalnych pozwala na zmniejszenie ich rozmiaru, utrudnia debugowanie i modyfikacje programu, uniemożliwia edycję zasobów i plików binarnych. Kompresor zmniejsza rozmiar kodu binarnego i dołącza procedurę dekompresującą, która rozpakowuje kod do pamięci.
![Page 109: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/109.jpg)
Kompresowanie plików wykonywalnych
Programy kompresujące:
• UPX – freeware, opcja dekompresowania. Program dostępny na wielu platformach. W Windowsie rozpakowuje skompresowany plik bezpośrednio do pamięci i w pamięci uruchamia plik.
• AsPack –shareware, istnieją programy, które dekompresują pliki wykonywalne spakowane AsPackiem, jak np. Adpackdie. AsPack kompresuje także pliki dll.
• PkLite – shareware, dokładny raport kompresji.
• Pe-Pack – kompresuje i dekompresuje
• AsProtect – shareware – kompresuje pliki wykonywalne, chroni zasoby programu, ochrona przed debugerami, weryfikacja sum kontrolnych (dobre algorytmy), stworzenie wersji trial.
![Page 110: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/110.jpg)
Kompresowanie plików wykonywalnych
Wady:
Praktycznie dla każdego programu kompresującego istnieje program dekompresujący. Niektóre z nich same posiadają taką opcję (UPX, Pe-Pack).
Za pomocą edytorów plików binarnych możemy odczytać w nagłówkach takich plików nazwę programów kompresujących. Istnieją narzędzia, które sprawdzają jakimi programami został skompresowany dany plik binarny.
![Page 111: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/111.jpg)
Kompresowanie plików wykonywalnych
Jeśli skompresowany program jest całkowicie rozpakowany w trakcie działania, to wystarczy użyć programu ProcDump, aby otrzymać rozpakowaną wersję.
Memory dump – zrzut programu z pamięci. Zatrzymanie działania programu przez debuger po deszyfracji lub dekompresji w celu zapisu wypakowanego kodu do pamięci operacyjnej.
![Page 112: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/112.jpg)
Zabezpieczenia przed debugerami
Wykrywanie aktywnych debugerów czy programów zrzucających fragment pamięci typu ProcDump jest wyjątkowo trudną czynnością. Istnieje wiele wyrafinowanych sztuczek, które wykrywają tylko określone programy lub nawet tylko konkretne wersje. Dodatkowym utrudnieniem jest fakt, iż debugery są stale udoskonalane – rozszerzenia zabezpieczające przed wykryciem debugerów. Procedury kontrolujące działanie takich programów – zadanie dla zaawansowanych.
Płatne środki ochrony przed debugerami: Themida, AsProtect.
![Page 113: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/113.jpg)
Zabezpieczenia przed debugerami
Wykrywanie Debugera VS
if(IsDebuggerPresent())
//dzialanie
Debuger SoftIce nie jest już rozwijany – opracowano różne testy (wstawki w asemblerze) wykrywające jego działanie.
Test sprawdzający, czy uruchomiony został program SoftICE poprzez wykrywanie sterownika debugera systemowego:
mov ah, 43h
int 68h
cmp eax, 0F386h
jz mamy_debuger
![Page 114: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/114.jpg)
Zabezpieczenia przed debugerami
Utrudnienie debugowania – wstawki niskopoziomowe. Makra preprocesora w C/C++. Makra zaciemniające kod programu, opłacalne szczególnie, gdy użyte w krytycznych fragmentach programu. Utrudnienie pracy krakera, śledzenie programu w debugerze. Wstawki wydłużają kod i nieznacznie spowalniają jego wykonanie.
![Page 115: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/115.jpg)
Zabezpieczenia przed debugerami
Przykładjmp_buf env;
#define AD(kod, numer) if (setjmp(env) == 0) \
{ \
goto skok_ad_##numer; \
} \
else \
{ \
kod; \
} \
goto koniec_ad_##numer; \
skok_ad_##numer: \
longjmp(env,1); \
koniec_ad_##numer: \
;
![Page 116: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/116.jpg)
Zabezpieczenia przed debugerami
Makro wstawia kod:if(setjmp(env)==0)
{
goto_skok_ad_1;
}
else
{
//wlasciwy kod
}
goto koniec_ad_1;
skok_ad_1:
longjmp(env,1);
koniec_ad_1;
Aby wstawka była skuteczna, powinna zostać użyta wiele razy w kodzie.
![Page 117: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/117.jpg)
Zabezpieczenia przed debugerami
Fragment programu:while(warunek) {
for (i=1;i<tysiac;i++)
cos tam;
miliard innych rzeczy
}
Po zaciemnieniu:AD(
while(warunek) {
for (i=1;i<tysiac;i++)
AD(
cos tam;
,1)
AD( miliard innych rzeczy, 2);
},0)
![Page 118: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/118.jpg)
Zabezpieczenia przed debugerami
Innym sposobem ochrony przed debugerami jest kontrola czasu wykonania procedury. Może być stosowana tylko w najbardziej krytycznych fragmentach kodu, ponieważ jej użycie może spowolnić działanie programu.
Zapamiętujemy czas systemowy i co kilkanaście linii kodu porównujemy ją z bieżącym stanem zegara systemowego. Jeśli ich wykonanie trwało za długo, daje nam to sygnał, iż możemy mieć styczność z debugerem.
![Page 119: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/119.jpg)
Zabezpieczenia przed debugerami
Przykład:#include <time.h>
int main()
{
time_t sekundy, biezacy;
sekundy = time (NULL);
//WAZNY KOD
biezacy = time(NULL);
if(biezacy -1 > sekundy)
{
printf(“Mamy debugger\n”);
exit(1);
}
return 0;
}
![Page 120: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/120.jpg)
Algorytmy wyznaczające sygnatury danych
Funkcja mieszająca (ang hash function) – dla pewnej danej wejściowej tworzy znacznie krótszą od niej informację, stanowiącą tzw. sygnaturę danej wejściowej (skrót danych).
Jej głównym zastosowaniem jest możliwość sprawdzenia integralności danych – tego, czy dane nie zostały zmodyfikowane po wyznaczeniu skrótu, przy zachowaniu jednocześnie niewielkich rozmiarów skrótu.
![Page 121: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/121.jpg)
Algorytmy wyznaczające sygnatury danych
Cechy idealnej sygnatury:
• Brak możliwości wygenerowania dwóch różnych wiadomości o tym samym skrócie.
• Zmiana nawet jednego bitu wiadomości powinna modyfikować średnio połowę bitów skrótu – dzięki temu z charakteru zmiany skrótu nie powinno dać się odczytać charakteru zmiany treści wiadomości i vice versa.
• Brak możliwości odtworzenia wiadomości wyłącznie na podstawie skrótu.
![Page 122: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/122.jpg)
Algorytmy wyznaczające sygnatury danych
Kod CRC – cykliczny kod nadmiarowy – suma kontrolna danych. CRC jest dość łatwe do sfałszowania. Ze względu na szybkość i prostotę wyznaczania oraz niewielki narzut do długości danych jest on powszechnie stosowany wszędzie tam, gdzie trzeba wykryć przypadkowe błędy, na przykład powstałe w wyniku transmisji radiowej lub stratnej kompresji. Nie powinien być stosowany jako metoda zabezpieczenia danych przed złośliwą modyfikacją. Kod CRC wyznacza się poprzez binarne dzielenie z resztą ciągu danych z pewnym dzielnikiem zwanym generatorem lub wielomianem CRC. Zazwyczaj są to wielomiany o długości 17 lub 33 bitów dające kod 16- 32- bitowy.
http://www.atmel.com/dyn/resources/prod_documents/DOC1143.PDF
![Page 123: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/123.jpg)
Algorytmy wyznaczające sygnatury danych
MD5 to jeden z najpopularniejszych algorytmów do wyznaczania sygnatury wiadomości. Przez wiele lat uznawany za całkowicie bezpieczny. W 2004 roku znaleziono słabość algorytmu pozwalającą na wyznaczenie wiadomości różnej od zadanej, która ma taki sam skrót jak ona. Obecnie nie stosuje się tej funkcji do zabezpieczania najbardziej wrażliwych z punktu widzenia bezpieczeństwa danych – wciąż jednak może ona być używana do wielu zastosowań - podpisywanie plików pobieranych z Internetu bądź w celu kontroli integralności kodu programu.
http://informa.ovh.org/art/pdf/md5.pdf
![Page 124: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/124.jpg)
Algorytmy wyznaczające sygnatury danych
SHA-1 opublikowany w 1993 roku, w 2004 opublikowano jego wady, przez wiele lat uznawany za bezpieczniejszy od MD5. Podpisywanie wiadomości o szczególnym znaczeniu – zaleca się stosowanie SHA-2.
http://e-handel.mm.com.pl/crypto/opis_algorytmu_sha.htm
![Page 125: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/125.jpg)
Problem generatorów liczb pseudolosowych
Generatory liczb pseudolosowych – zastosowanie w grach komputerowych, w kryptografii (tworzenie trudnych do przewidzenia kluczy). Komputery nie potrafią tworzyć liczb prawdziwe losowych. Liczby pseudolosowe – zestawy liczb, które dają dość dobre przybliżenie prawdziwie losowego ciągu. Generator inicjowany jest pewną wstępną informacją zwaną ziarnem. Idealnie powinno ono pochodzić z losowego źródła. Każdorazowe rozpoczęcie generowania liczb pseudolosowych rozpoczyna się w innym miejscu ciągu. W praktyce dobry ziarnem jest często zmieniający się znacznik czasu, na przykład milisekundy.
![Page 126: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/126.jpg)
Problem generatorów liczb pseudolosowych
Cechy liczb pochodzących z dobrego generatora:
• Kolejne wartości są zupełnie nieprzewidywalne dla człowieka.
• Nie można ustalić ziarna nawet na podstawie długiej obserwacji kolejnych wygenerowanych liczb.
• Znajomość wszystkich do tej pory wygenerowanych bitów nie pozwala na przewidzenie kolejnego.
![Page 127: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/127.jpg)
Końcowe wskazówki
Nie należy chwalić się wykryciem włamania, nie dawać wskazówek włamywaczowi, lecz po cichu zastosować odpowiednie procedury blokujące możliwość właściwego korzystania z programu. W okolicy testów bezpieczeństwa korzystać z jak najmniejszej liczby wywołań standardowych funkcji Windows API (okienka komunikatów, okna dialogowe).
![Page 128: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/128.jpg)
Końcowe wskazówki
Lepiej użyć gotowego a nawet darmowego programu antydebugerowego niż pisać odpowiednie funkcje samodzielnie.
Dodatkowa kompresja kodu - nawet jeśli krakerzy złamią to zabezpieczenie, nie przyjdzie im to zawsze ad hoc.
Pisać skomplikowane, niebanalne i nieszablonowe wstawki antydebugerowe. Makra zaciemniające kod – nie są bariera nie do przejścia dla krakera, ale stanowić mogą duże utrudnienie i zaskoczenie.
![Page 129: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/129.jpg)
Końcowe wskazówki
Kreatywność, wyjście poza schematy. Cały czas zaskakiwać krakerów, a nie podążać za schematami, których oczekują włamywacze. Nie ma całkowicie bezpiecznych aplikacji, dlatego warto użyć wyobraźni, aby krakerzy musieli przez nas się nieźle napocić.
![Page 130: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/130.jpg)
Końcowe wskazówkiSprawdzać zabezpieczenia jak najczęściej, aby maksymalnie utrudnić pracę krakerom – jak najwięcej miejsc, które musi zmodyfikować włamywacz. Unikać pojedynczych, choćby bardzo dobrze zabezpieczonych, punktów kontrolnych, co jest uciechą dla krakerów.
Używać różnych algorytmów i różnych metod zabezpieczeń. Wklejając funkcję zabezpieczającą w wiele miejsc w kodzie, starać się, aby za każdym razem ją nieco modyfikować.
Nie uruchamiać wszystkich zabezpieczeń w tym samym momencie. Używać zabezpieczeń, które nie uruchamiają się za każdym razem, ale np tylko co pewien okres lub przy użyciu rzadkiej funkcji programu.
![Page 131: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/131.jpg)
Końcowe wskazówki
Im mniej funkcji ma program, tym lepiej z punktu widzenia bezpieczeństwa. Jeśli jakaś funkcja nie jest koniecznie potrzebna - należy się jej pozbyć. Każda nadmiarowa linia kodu może być potencjalnym źródłem błędu bezpieczeństwa. Im kod będzie prostszy i łatwiejszy w zrozumieniu, tym mniejsza szansa, że będzie zawierał krytyczny błąd.
![Page 132: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/132.jpg)
Końcowe wskazówki
Większość ataków popełniana jest przez mało doświadczonych użytkowników korzystających z gotowych programów, znanych metod. Mówimy o nich script kiddies.
Wszelakie zabezpieczenia, które wydają się nam być mało wartościowe i łatwe dla obejścia dla krakerów, mogą być dobry uzupełnieniem dla reszty zabezpieczeń i skuteczną ochroną przed script kiddies.
![Page 133: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/133.jpg)
6. Techniki kryptograficzne
• Podstawowe informacje
• Rys historyczny
• Symetryczne algorytmy szyfrowania
• Asymetryczne algorytmy szyfrowania
• Wykorzystanie kryptografii w zabezpieczaniu programów
• Końcowe wskazówki
![Page 134: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/134.jpg)
Podstawowe informacje
Kodowanie polega na zamianie pewnej informacji na tajny ciąg wyłącznie za pomocą pewnego algorytmu. Wystarczy sama znajomość algorytmu, aby odtworzyć zakodowaną informację.
Szyfrowanie – polega na ukryciu wiadomości za pomocą tajnego ciągu zwanego kluczem. Cechą dobrego algorytmu szyfrującego jest to, że ta sama wiadomość źródłowa zaszyfrowana tym samym algorytmem, ale przy użyciu dwóch różnych kluczy daje zupełnie inne ciągu wyjściowe.
![Page 135: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/135.jpg)
Podstawowe informacje
Kryptografia – proces poufnej komunikacji z użyciem szyfrów.
Kryptoanaliza – proces łamania (odszyfrowywania) zaszyfrowanych informacji.
![Page 136: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/136.jpg)
Podstawowe informacje
System kryptograficzny można nazwać bezwarunkowo bezpiecznym, jeżeli jego złamanie nie jest możliwe nawet przy wykorzystaniu nieograniczonych zasobów obliczeniowych. Przeprowadzenie kryptoanalizy nie jest możliwe. Jeśli podczas ataku zostaną wykorzystane wszystkie możliwe klucze, nie będzie możliwe ustalenie, który klucz był właściwy.
![Page 137: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/137.jpg)
Podstawowe informacje
System kryptograficzny jest uznawany za obliczeniowo bezpieczny, jeżeli najlepszy znany algorytm służący do jego złamania wymaga ogromnych zasobów obliczeniowych i czasu. Teoretycznie możliwe jest złamanie takiego szyfru, ale z praktycznego punktu widzenia nie ma to sensu, ponieważ wartość niezbędnych zasobów i czasu znaczeni przekracza maksymalną wartość chronionych danych.
![Page 138: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/138.jpg)
Podstawowe informacje
Klucz jednorazowy – klucz o długości równej lub dłuższej od treści wiadomości. Wszystkie znaki takiego klucza są losowe i nie mają związku ze sobą. Zaraz po zaszyfrowaniu klucz powinien być niszczony, odbiorca, mający kopię klucza, po odczytaniu wiadomości, powinien zniszczyć klucz.
![Page 139: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/139.jpg)
Podstawowe informacje
W praktyce używanie klucza jednorazowego bardzo trudne:
• Konieczność bezpiecznego przekazywania klucza i kolejnych, przy wysyłaniu nowych wiadomości.
• Kosztowne przesyłanie klucza- co najmniej tak długiego jak wiadomość.
• Problem generacji losowego klucza – napastnik może poznać i złamać algorytm generacji liczb pseudolosowych
• Bezpieczeństwo całej techniki szyfrowania jest zależna od dostarczenia klucza do nadawcy.
![Page 140: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/140.jpg)
Rys historyczny
Początkowo szyfry przestawieniowe (każda litera zamieniona miejscami z inną literą) i podstawieniowy (każda litera alfabetu podmieniana na inną odległą w alfabecie o pewną stałą liczbę pozycji – szyfr Cezara).
Szyfry polialfabetyczne – różne szyfry użyte do różnych fragmentów wiadomości.
![Page 141: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/141.jpg)
Rys historyczny
Zasada Kerckhoffsa
System szyfrujący jest bezpieczny tylko wtedy, gdy na jego bezpieczeństwo nie wpływa to, czy wróg zna go, czy nie. O sile systemu stanowi klucz.
![Page 142: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/142.jpg)
Symetryczne algorytmy szyfrowania
Wykorzystanie takiego samego klucza do szyfrowania i deszyfrowania wiadomości. Oba procesy szybsze niż w szyfrowaniu asymetrycznym, problem stanowić może dystrybucja kluczy.
![Page 143: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/143.jpg)
Symetryczne algorytmy szyfrowania
Szyfry blokowe działają na blokach o stałej wielkości, mających zwykle 64 lub 128 bitów. Jeżeli użyto identycznego klucza, ten sam fragment tekstu zawsze uzyska po zaszyfrowaniu taką samą postać. Przykłady: DES, AES.
Szyfry strumieniowe generując strumień pseudolosowych bitów. Jest to strumień klucza, który jest wykorzystywany do operacji XOR na operacji jawnej. Ta technika dobrze sprawdza się przy szyfrowaniu ciągłych strumieni danych. Przykład: RC4.
![Page 144: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/144.jpg)
Symetryczne algorytmy szyfrowania
DES – algorytm wynaleziony przez IBM. Oryginalny algorytm DES stosował tylko 56-bitowy klucz. Stworzono różne modyfikacje, np DESX – klucz o długości 184 bitów.
DES był wielokrotnie łamany. Dla klucza o długości 56 bitów, wszystkie kombinacje można sprawdzić w ciągu kilku tygodni metodą pełnego przeglądu.
![Page 145: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/145.jpg)
Symetryczne algorytmy szyfrowania
AES – odpowiedź na niewystarczające bezpieczeństwo algorytmu DES. Możliwe użycie kluczy o długościach 128, 192, 256 bitów. Nie jest pewne jakiej mocy obliczeniowej potrzeba, aby złamać najsilniejszą wersję algorytmu, dlatego też szyfrowanie tą metodą jest uznawane za bezpieczne.
![Page 146: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/146.jpg)
Symetryczne algorytmy szyfrowania
RC4 – popularny, do niedawna uważany za bardzo silny, obecnie nie jest zalecany (w 2000 roku opracowano atak na ten algorytm). Wykorzystywany był w systemie szyfrowania WEP stosowanym do szyfrowania wiadomości w sieciach bezprzewodowych. Przydatny, gdy stanowi dodatkową ochronę danych czy kodu źródłowego. Jest relatywnie prosty.
Do szyfrowania danych używane są dwa algorytmy: algorytm generowania kluczy wewnętrznych i generator liczb pseudolosowych. Oba algorytmy wykorzystują skrzynkę S o rozmiarach 8x8, która jest tablicą zawierającą 256 wartości od 0 do 255. W tabeli znajdują się wszystkie liczby od 0 do255 ale rozmieszczone w sposób losowy.
![Page 147: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/147.jpg)
Symetryczne algorytmy szyfrowania
Algorytm RC4:Tablica skrzynki S zostaje zapełniona kolejnymi wartościami od 0 do 255. Kolejna 256 bajtowa tablica, oznaczana jako K, jest zapełniana wartościami ziarna (o maksymalnej długości 256 bitów). Mieszanie tablicy S:j=0;for i=0 to 255{ j = ( j + S[i] + K[i]) mod 256; zamiana S[i] i S[j];}
Po tej operacji wszystkie wartości w skrzynce S zostaną wymieszane zgodnie z wartością ziarna. Koniec algorytmu generowania kluczy wewnętrznych.
![Page 148: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/148.jpg)
Symetryczne algorytmy szyfrowania
Kolejny krok: uzyskanie danych strumienia klucza za pomocą generatora liczb pseudolosowych. Dla każdego bajtu strumienia klucza wykonywany jest następujący pseudokod:
i = ( i + 1 ) mod 256;j = ( j + S[i] ) mod 256;zamiana S[i] i S[j];t = ( S[i] + S[j] ) mod 256;Przekazanie wartosci S[t];
Przekazana wartość S[t] sanowi pierwszy bajt strumienia klucza. Algorytm jest powtarzany dla kolejnych bajtów w strumieniu.
![Page 149: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/149.jpg)
Asymetryczne algorytmy szyfrowania
Szyfry asymetryczne wykorzystują dwa klucze – klucz publiczny i klucz prywatny. Klucz publiczny jest dostępny dla wszystkich, należy natomiast zapewnić poufność klucza prywatnego. Każda wiadomość zaszyfrowana za pomocą klucza publicznego może zostać odszyfrowana tylko poprzez użycie klucza prywatnego. Rozwiązuje to problem dystrybucji kluczy. Wyznaczenie jednego z klucza na podstawie drugiego jest bardzo trudne i w praktyce niewykonalne.
![Page 150: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/150.jpg)
Asymetryczne algorytmy szyfrowania
RSA – najpopularniejszy system używający szyfrowania asymetrycznego. Jego bezpieczeństwo opiera się na problemie faktoryzacji dużych liczb, która jest bardzo złożona obliczeniowo.
![Page 151: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/151.jpg)
Asymetryczne algorytmy szyfrowania
Generacja klucza RSA:Losowanie dużych liczb pierwszych p i q oraz liczby e względnie pierwszej z φ(n), gdzie n=p*q, φ (p*q)=(p-1)*(q-1). φ – funkcja Eulera.Obliczenie d=e-1 mod φ(n)Kluczem publicznym jest para (e,n), kluczem prywatnym para (d,n).Liczby p i q powinny zostać zniszczone i nigdy nie powinny być podawane publicznie.Szyfrowanie wiadomości m polega na wykonaniu operacji:c=me mod nDeszyfrowanie polega na podniesieniu zaszyfrowanej wiadomości do potęgi d. Zgodnie z twiedzeniem Eulera : cd= med = m mod n
![Page 152: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/152.jpg)
Asymetryczne algorytmy szyfrowania
Jeśli nie znamy d, to nie odtworzymy łatwo wiadomości. Nie znając sposobu faktoryzacji n na p i q, nie odtworzymy łatwo d na podstawie znanego e.
Bezpieczeństwo metody RSA zależy od długości klucza. Najdłuższy klucz, jaki do tej pory udało się skutecznie złamać, to 600 bitów. Typowe klucze mają długość 1024 bitów, zalecane stosowanie kluczy o długości 2048 bitów.
![Page 153: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/153.jpg)
Wykorzystanie kryptografii w zabezpieczaniu programów
Testowanie integralności danych programu
Mamy pliki ‘ok.txt’ i ‘ok2.txt’, chcemy zweryfikować integralność pliku ‘ok.txt’. Wyznaczamy MD5 z zawartości pliku ‘ok.txt’. Szyfrujemy zawartość pliku ‘ok2.txt’, używając jako klucza wartości otrzymanej powyżej. (Metoda RC4).
Dostarczamy plik ‘ok.txt’ w postaci normalnej i ‘ok2.txt’ w postaci zaszyfrowanej.
W trakcie działania programu wyznaczmy MD5 z zawartości pliku ‘ok.txt’.
Za pomocą powyższej wartości deszyfrujemy plik ‘ok2.txt’.
Próbujemy użyć w programie pliku ‘ok2.txt’ jeśli plik został zmodyfikowany, nie uda nam się to.
![Page 154: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/154.jpg)
Wykorzystanie kryptografii w zabezpieczaniu programów
Weryfikacja pliku wykonywalnego
Jeden program wylicza sumę kontrolną drugiego i wkleja w wyznaczone jego miejsce sumę kontrolną (sygnatura jest wyznaczana z pominięciem tego fragmentu). Jeśli sygnatura pliku wykonywalnego się zmieni, można to łatwo porównać z wklejonym wzorcem.
Podczas używania tego zabezpieczenia nie możemy korzystać z programów kompresujących. Weryfikacja integralności pliku wykonywalnego powinna odbywać się jak najczęściej. Aby utrudnić ataki, gdyż włamywacz może wyznaczyć MD5 zmienionego pliku i wprowadzić go w odpowiednie miejsce, możemy wyznaczać skrót danych nie dla całego pliku, ale dla wybranych fragmentów (pierwsze 200 znaków, co 13 linia).
![Page 155: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/155.jpg)
Wykorzystanie kryptografii w zabezpieczaniu programów
Zaciemnianie kodu – sprawienie, by stał się nieczytelny dla człowieka. Szyfrowanie fragmentów kodu i deszyfrowanie ich w trakcie działania programu – samo modyfikujący się program.
![Page 156: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/156.jpg)
Wykorzystanie kryptografii w zabezpieczaniu programów
Klucz programowy – klucz zawierający fragmenty kodu programu. Bez jego dostępności program nie zadziała poprawnie. Im dłuższy klucz programowy – tym trudniejsze złamanie programu – staje się niemal zadaniem napisania kodu od nowa. Kod może zawierać niektóre fragmenty programu – określone funkcje, linie kodu.
![Page 157: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/157.jpg)
Wykorzystanie kryptografii w zabezpieczaniu programów
Przykład. Mamy program A zabezpieczony kluczem programowym. Jego działanie polega na próbie wczytania klucza programowego i wprowadzenie otrzymanych bajtów w odpowiednie fragmenty pamięci. Do stworzenia klucza będzie potrzebny program B.
Program A uruchomiony z parametrem będącym poprawnym hasłem, utworzy plik ‘klucz’, do którego zapisze aktualną postać fragmentu kodu. Plik zostanie użyty przez program B, który wyszukuje zawartość pliku ‘klucz’ w programie A i nadpisuje ją zerami.
Program A uruchomiony z parametrem klucz odczytuje klucz programowy z pliku ‘klucz’ i odpowiednie fragmenty pamięci zostaną nadpisane danymi z klucza.
![Page 158: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/158.jpg)
Wykorzystanie kryptografii w zabezpieczaniu programów
Deszyfrowanie fragmentów programu w trakcie jego działania – ochrona przed zrzutem zawartości pamięci (oczywiście nie jest 100% skuteczna – kraker nadal może robić zrzuty pamięci – nie wiadomo, czy w odpowiednim momencie). Procedury zabezpieczeń powinny wykonywać się w najróżniejszych miejscach programu i w różnych odstępach czasu. Każda procedura powinna być deszyfrowana innym kluczem.
![Page 159: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/159.jpg)
Wykorzystanie kryptografii w zabezpieczaniu programów
Przykład. Mamy program A. Program użyty z parametrem klucz produkuje plik ‘klucz’ z zawartością kodu programowego. Program B zabezpieczający program A, uruchamiany jako:
B A klucz kod. Plik ‘klucz’ zostanie zniszczony, a program A zaszyfrowany podanym kodem.
Użycie programu A z podanym jako parametrem kodem – odszyfrowanie.
![Page 160: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/160.jpg)
Wykorzystanie kryptografii w zabezpieczaniu programów
CryptoAPI – interfejs programistyczny aplikacji, który umożliwia szyfrowanie, wyznaczanie sygnatur – zadania związane z kryptografią.
Plik nagłówkowy Wincrypt.h
![Page 161: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/161.jpg)
Wykorzystanie kryptografii w zabezpieczaniu programów
CSP - Cryptographic Service Provider
Zawiera implementacje standardów i algorytmów kryptograficznych. W wariancie minimalnym, CSP składa się z biblioteki DLL (implementacje funkcji CryptoSPI) .
CryptAcquireContext - Funkcja pozyskuje uchwyt do pojemnika klucza wewnątrz CSP. Uchwyt może być użyty do różnorakich funkcji dla wybranego CSP. CryptReleaseContext - Zwalnia uchwyt do CSP i pojemnika klucza.
![Page 162: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/162.jpg)
Wykorzystanie kryptografii w zabezpieczaniu programów
HCRYPTPROV Uchwyt do CSP (cryptographic service provider). typedef unsigned long HCRYPTPROV;
HCRYPTHASH Uchwyt do obiektów hashtypedef unsigned long HCRYPTHASH;
Obiekt Hash - obiekt używany do haszowania (wyznaczania sygnatury) wiadomości. Jest tworzony poprzez CryptCreateHash.
CryptGetHashParam - Funkcja odzyskuje dane, które operują na obiekcie hash oraz aktualną wartość sygnatury.
CryptHashData Function - Dodaje dane do obiektu hash.
![Page 163: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/163.jpg)
Końcowe wskazówki
Klucze programowe
Jeśli klucz zawiera fragmenty kodu programu, to ciężko jest go złamać, bo bez klucza program po prostu nie zadziała. Różne fragmenty programu powinny otrzymywać różne klucze.
Klucze szyfrujące fragment kodu
Bez podania poprawnego klucza uruchomienie programu nie będzie możliwe. Każdy fragment programu powinien zawierać inny klucz. Deszyfracja powinna odbywać się w trakcie działania programu.
![Page 164: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/164.jpg)
Końcowe wskazówki
Wrażliwe dane zabezpieczać bardziej niż kod. Szyfrowanie ich, sprawdzanie, czy nikt ich nie uszkodził lub zmodyfikował bez pozwolenia.
![Page 165: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/165.jpg)
Końcowe wskazówki
Nigdy nie polegajmy na tym, że zaciemnianie sposobu działania programu bądź kodu spowoduje, że będzie on bezpieczniejszy, ale o ile to możliwe powinniśmy zakrywać przed niepowołanymi użytkownikami informacje, które ich nie dotyczą.
![Page 166: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/166.jpg)
Łańcuch a sieć bezpieczeństwa
• Łańcuch – kilka zabezpieczeń polega na sobie w taki sposób, że unieszkodliwienie dowolnego z nich powoduje, iż pozostałe nie działają.
• Sieć – wiele niezależnych zabezpieczeń, które mogą testować to samo lub nawet zabezpieczać siebie nawzajem. Jeśli włamywacz pokona jedno zabezpieczenie, jest szansa, że zostanie zatrzymany przez inne. Wspólne działanie zabezpieczeń.
• Niech zabezpieczenia nie polegają jedne na drugim, ale niech kontrolują się wzajemnie – aby system był bezpieczny, wystarczy aby jedno działało.
![Page 167: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/167.jpg)
Źródła
• Hart Johnson M., Windows System Programming, Pearson Education, 2010.
• Brain Marshall, Reeves Ron, Win32 System Services, Prentice Hall, 2000.
• Erickson Jon, Hacking. Sztuka penetracji, Helion, Gliwice, 2004.
• Ross Jacek, Bezpieczne Programowanie. Aplikacje hakeroodporne, Helion, Gliwice, 2009.
• Centrum Innowacji Microsoft w Poznaniu http://mic.psnc.pl/• MSDN Library – Security
http://msdn.microsoft.com/en-us/library/aa969178.aspx
![Page 168: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/168.jpg)
Źródła
Artykuły i prezentacje w Internecie:• http://nfsec.pl/hakin9/b0f.pdf
• http://download.microsoft.com/download/7/0/e/70e1166e-b9c6-4d43-878c-75ee69ec7c75/Testowanie%20bezpieczenstwa%20kodu.doc
• http://www.proidea.org.pl/media/materialy/przemek_skowron_isaca.pdf
Artykuły i prezentacje w Internecie:• http://nfsec.pl/hakin9/b0f.pdf
• http://download.microsoft.com/download/7/0/e/70e1166e-b9c6-4d43-878c-75ee69ec7c75/Testowanie%20bezpieczenstwa%20kodu.doc
• http://www.proidea.org.pl/media/materialy/przemek_skowron_isaca.pdf
• http://students.mimuw.edu.pl/SO/Projekt06-07/temat5-g3/index.pdf
• http://aragorn.pb.bialystok.pl/~wkwedlo/OS1-12.pdf
• http://students.mimuw.edu.pl/SO/Projekt02-03/temat5-g1/pkoziol/ref.pdf
• http://cygnus.et.put.poznan.pl/~junior/skisr/prezentacje/s22.pdf
• http://4programmers.net/Assembler/FAQ/Wykrywanie_debuggera_%28SoftICE%29
![Page 169: Bezpieczeństwo aplikacji Windows](https://reader036.fdocuments.net/reader036/viewer/2022062314/56814781550346895db4b289/html5/thumbnails/169.jpg)
Dziękujemy za uwagę