Bezpieczne programowanie.
Aplikacje hakeroodporne
Autor: Jacek Ross
ISBN: 978-83-246-2405-8
Format: 158×235, stron: 312
WyobraŸ sobie sytuacjê, w której poœwiêcasz mnóstwo czasu na stworzenie nowego,
ciekawego rozwi¹zania w œwiecie informatyki. Kosztuje Ciê to wiele dni i nocy ogromnego
wysi³ku. Dok³adnie w momencie opuszczenia Twojego bezpiecznego komputera,
udostêpniony œwiatu, Twój pomys³ zostaje wystawiony na ciê¿k¹ próbê – w sieci
dzia³aj¹ krakerzy, którzy za wszelk¹ cenê bêdê próbowali z³amaæ Twoje zabezpieczenia
lub wykorzystaæ luki w Twojej aplikacji. Jak tego unikn¹æ? Jak tworzyæ oprogramowanie
odporne na ich ataki?
Proste i przejrzyste odpowiedzi na podobnie skomplikowane pytania znajdziesz w³aœnie
w tej ksi¹¿ce! Podczas lektury poznasz zagro¿enia, na jakie nara¿ony jest programista,
oraz proste sposoby utrudniania krakerom zadania. Dodatkowo zdobêdziesz wiedzê na
temat metod szyfrowania danych i wyznaczania sygnatur. Jednak, co najwa¿niejsze,
zobaczysz, jak wykorzystaæ tê wiedzê w praktyce! W publikacji „Bezpieczne programowanie.
Aplikacje hakeroodporne” znajdziesz równie¿ sporo ciekawych informacji na temat
zabezpieczania aplikacji sieciowych oraz zaawansowane metody, gwarantuj¹ce
podniesienie bezpieczeñstwa Twojego produktu do wysokiego poziomu. To jeszcze
nie wszystko! W kolejnych rozdzia³ach autor prezentuje sposoby ochrony przed
debugerami, patenty na bezpieczne tworzenie kodu na platformie .NET oraz
psychologiczne aspekty tworzenia hakeroodpornych aplikacji!
• Przegl¹d zagro¿eñ, rodzaje oszustw i naruszeñ bezpieczeñstwa
• Zabezpieczenie programu przy u¿yciu numeru seryjnego
• Dostêpne na rynku systemy zabezpieczania aplikacji
• Algorytmy szyfruj¹ce
• Tworzenie skrótów wiadomoœci
• Wykorzystanie szyfrowania przy zabezpieczaniu oprogramowania
• Zabezpieczenia aplikacji wykorzystuj¹cych PHP i .NET
• Ochrona przed atakami typu: wstrzykiwanie SQL, XSS, DOS i DDOS
• U¿ywanie zaawansowanych metod ochrony oprogramowania
• Sposoby zaciemniania programu
• Ochrona kodu przed debugerami
• Zastosowanie kluczy sprzêtowych i technik biometrycznych
• Psychologiczne aspekty ochrony oprogramowania
Dowiedz siê, jak tworzyæ aplikacje odporne na ataki!
Spis tre"ci
Wst"p .............................................................................................. 9
Rozdzia# 1. Zagro$enia czyhaj%ce na programistów ........................................... 11
1.1. Dawno, dawno temu w !wiecie gier ........................................................................... 11
1.2. Moje przygody z gr# Metal Knights ........................................................................ 14
1.3. Niebezpieczny edytor map, czyli s$abe punkty ........................................................ 16
1.4. A jak to robi# w Diablo... czyli co! o bezpiecze%stwie aplikacji sieciowych .......... 19
1.5. Rodzaje oszustw i narusze% bezpiecze%stwa ........................................................... 21
1.5.1. Nieuprawnione u&ycie b#d' kopiowanie programu ........................................ 21
1.5.2. Nielegalna podmiana autorstwa kodu ............................................................. 23
1.5.3. Nieuprawniona modyfikacja kodu .................................................................. 23
1.6. Pirat, Robin Hood, kraker? ...................................................................................... 24
1.7. Czy ja tak&e mam my!le) o zabezpieczeniach? ....................................................... 25
1.8. Czym si* ró&ni kraker od z$odzieja samochodów? .................................................. 27
Zadania do samodzielnego wykonania ........................................................................... 30
Pytania kontrolne ............................................................................................................ 31
Rozdzia# 2. Proste metody zabezpieczenia programów ......................................... 33
2.1. Wst*p ....................................................................................................................... 33
2.2. Numer seryjny ......................................................................................................... 33
2.3. CrackMe — przyk$ady s$abo!ci prostych zabezpiecze%
przed nieuprawnionym u&ytkowaniem programu ................................................. 35
2.3.1. CrackMe1 ....................................................................................................... 35
2.3.2. CrackMe2 ....................................................................................................... 42
2.4. Gotowe systemy zabezpieczania aplikacji przed nieuprawnionym u&yciem ........... 44
Przegl#d systemów zabezpieczaj#cych dost*pnych na rynku ................................... 47
2.5. Zako%czenie ............................................................................................................. 50
Zadania do samodzielnego wykonania ........................................................................... 51
Pytania kontrolne ............................................................................................................ 51
Rozdzia# 3. Teoria szyfrowania. Algorytmy szyfruj%ce w praktyce ....................... 53
3.1. Wst*p ....................................................................................................................... 53
3.2. Szyfrowanie i kodowanie informacji ....................................................................... 53
3.3. Historyczne algorytmy szyfrowania i kodowania .................................................... 54
3.3.1. Pocz#tki .......................................................................................................... 54
3.3.2. Szyfry przestawieniowe i podstawieniowe, szyfr Cezara ............................... 55
3.3.3. Szyfry polialfabetyczne .................................................................................. 55
3.3.4. Zasada Kerckhoffsa ........................................................................................ 56
4
Bezpieczne programowanie. Aplikacje hakeroodporne
3.4. Wspó$czesne algorytmy szyfrowania ................................................................... 56
3.4.1. Rozwój algorytmów szyfrowania ................................................................... 56
3.4.2. Algorytmy symetryczne. Algorytm RC4 ........................................................ 57
3.4.3. Szyfrowanie symetryczne, algorytm DES ...................................................... 61
3.4.4. Szyfrowanie symetryczne, algorytm AES ...................................................... 61
3.4.5. Szyfrowanie asymetryczne, algorytm RSA .................................................... 61
3.4.6. Podpis cyfrowy ............................................................................................... 63
3.4.7. Szyfr z kluczem jednorazowym ...................................................................... 63
3.5. Algorytmy wyznaczaj#ce sygnatury (skróty) danych .............................................. 64
3.5.1. Algorytm wyznaczania CRC .......................................................................... 64
3.5.2. Algorytm MD5 ............................................................................................... 65
3.5.3. Algorytm SHA-1 ............................................................................................ 65
3.6. Generatory liczb pseudolosowych ........................................................................... 69
3.7. Do czego mo&e s$u&y) szyfrowanie w zabezpieczaniu programów? ....................... 70
Zadania do samodzielnego wykonania ........................................................................... 71
Pytania kontrolne ............................................................................................................ 71
Rozdzia# 4. Zabezpieczanie programów sieciowych na przyk#adzie j"zyka PHP ... 73
4.1. Wst*p ....................................................................................................................... 73
4.2. Obs$uga danych z zewn#trz ..................................................................................... 74
4.3. Przekazywanie danych mi*dzy skryptami ............................................................... 75
4.4. Uwierzytelnianie w PHP .......................................................................................... 76
4.5. Niebezpieczne konstrukcje j*zyka ........................................................................... 79
4.5.1. Konstrukcja include ($plik) ............................................................................ 80
4.5.2. eval($code), konstrukcja $$ ............................................................................ 81
4.5.3. fopen($url) ...................................................................................................... 82
4.6. Bezpieczna obs$uga b$*dów ..................................................................................... 83
4.7. Bezpiecze%stwo systemu plików ............................................................................. 84
4.8. Cross site scripting ................................................................................................... 85
4.9. Wstrzykiwanie kodu SQL ........................................................................................ 86
4.9.1. Wstrzykiwanie kodu SQL — przyk$ad 1. ....................................................... 87
4.9.2. Wstrzykiwanie kodu SQL — przyk$ad 2. ....................................................... 90
4.9.3. U&ycie PDO .................................................................................................... 91
4.9.4. Ataki wielofazowe .......................................................................................... 92
4.9.5. Sposoby ochrony ............................................................................................ 92
4.10. Wstrzykiwanie polece% systemowych (shell injection) ......................................... 93
4.11. Wstrzykiwanie zawarto!ci e-mail (e-mail injection) .............................................. 94
4.12. Cross site request forgery ...................................................................................... 95
4.13. Przej*cie kontroli nad sesj# (session fixation) ....................................................... 97
4.14. Session poisoning ................................................................................................ 101
4.14.1. Przechowywanie stanu aplikacji w niezabezpieczonych miejscach ........... 101
4.14.2. Przypisanie warto!ci do zmiennej sesyjnej
o nazwie stworzonej na podstawie danych od u&ytkownika ................... 104
4.14.3. Podmiana sekwencji wywo$a% przez w$amywacza. Problem wy!cigu ....... 105
4.14.4. U&ywanie tych samych zmiennych sesyjnych do ró&nych celów ............... 106
4.14.5. Zmienne sesyjne nie s# gwarancj# bezpiecze%stwa .................................... 108
4.15. Ataki typu DOS i DDOS ..................................................................................... 110
4.16. Dyrektywa register_globals ................................................................................. 112
4.17. Narz*dzie zaciemniaj#ce kod 'ród$owy j*zyka PHP ........................................... 114
Zako%czenie .................................................................................................................. 116
Zadania do samodzielnego wykonania ......................................................................... 116
Pytania kontrolne .......................................................................................................... 116
Spis tre&ci
5
Rozdzia# 5. Zaawansowane metody zabezpieczania programów ....................... 121
5.1. Wst*p ..................................................................................................................... 121
5.2. Klucze rejestracyjne przypisane do u&ytkownika .................................................. 122
5.2.1. Idea kluczy rejestracyjnych przypisanych do u&ytkownika .......................... 122
5.2.2. Typowe techniki ........................................................................................... 124
5.2.3. Tworzenie kluczy rejestracyjnych w aplikacjach sieciowych ....................... 125
5.3. Samotestuj#cy si* program .................................................................................... 126
5.3.1. Testowanie integralno!ci programu gwarancj# jego oryginalno!ci .............. 126
5.3.2. Przyk$ad — weryfikacja integralno!ci pliku wykonywalnego ..................... 127
5.3.3. Przyk$ad — weryfikacja integralno!ci kodu programu ................................ 132
5.4. Sprawdzanie integralno!ci danych ......................................................................... 135
5.4.1. Ukryj moje dane ........................................................................................... 136
5.4.2. Testowanie integralno!ci danych ulegaj#cych zmianom .............................. 137
5.4.3. Wersje czasowe oprogramowania — k$opoty z shareware ........................... 138
5.4.4. Bezpieczne przechowywanie danych — przyk$ad ........................................ 140
5.5. Samomodyfikuj#cy si* program ............................................................................ 144
5.5.1. Samomodyfikuj#cy si* program.
Brzydka sztuczka czy eleganckie zabezpieczenie? ................................. 144
5.5.2. Sabota&, czyli jak ukara) krakera? ................................................................ 146
5.5.3. „Za 5 sekund ten program ulegnie samozniszczeniu”
— automatyczna deinstalacja programu ................................................. 147
5.5.4. „Kod o ograniczonej przydatno!ci do wykonania” ............................................ 148
5.6. Klucz programowy ................................................................................................ 150
5.6.1. Klucz programowy — przyk$ad ................................................................... 151
5.6.2. Deszyfrowanie fragmentów programu w trakcie jego dzia$ania ................... 156
5.6.3. Przyk$ad programu deszyfruj#cego si* w trakcie dzia$ania .......................... 158
5.7. Zaciemnianie kodu i danych programu .................................................................. 161
5.7.1. Czy to wci#& open source? Zaciemnianie kodu jako metoda obronna .......... 161
5.8. Zabezpieczenia. Jak to w praktyce wprowadzi) w &ycie .................................... 163
5.8.1. Zabezpieczenia a etapy produkcji ................................................................. 163
5.8.2. Generator zabezpiecze% ................................................................................ 164
Zadania do samodzielnego wykonania ......................................................................... 165
Pytania kontrolne .......................................................................................................... 166
Rozdzia# 6. Zabezpieczenie programów przed debugerami ............................... 167
6.1. Wst*p ..................................................................................................................... 167
6.2. Wykrywanie debugerów ........................................................................................ 168
6.3. Utrudnianie debugowania ...................................................................................... 169
6.3.1. Wstawki kodu utrudniaj#ce debugowanie .................................................... 169
6.3.2. Generator wstawek kodu utrudniaj#cych debugowanie ................................ 172
Zadania do samodzielnego wykonania ......................................................................... 175
Pytania kontrolne .......................................................................................................... 175
Rozdzia# 7. Wykorzystanie internetu do zabezpieczania programów .................. 177
7.1. Wst*p ..................................................................................................................... 177
7.2. Rejestracja programu przez internet ...................................................................... 178
7.3. Aktywacja numeru seryjnego przez internet .......................................................... 179
7.4. Kontrola u&ytkowania aplikacji z cz*!ciowym dost*pem do internetu .................. 180
7.5. Weryfikacja prawid$owej pracy aplikacji przez sie) .............................................. 181
7.6. Przechowywanie poufnych danych u&ytkownika .................................................. 182
7.7. Deszyfrowanie programu w trakcie dzia$ania a internet ........................................ 183
7.8. Fragmentaryczne dane pobierane z internetu ......................................................... 185
7.9. Przesy$anie informacji o programie do centralnego serwera .................................... 186
6
Bezpieczne programowanie. Aplikacje hakeroodporne
7.9.1. Totalna inwigilacja? Rejestrowanie informacji
o zachowaniu programu i u&ytkownika ..................................................... 186
7.9.2. Zdalne sprawdzanie to&samo!ci u&ytkownika .............................................. 188
7.9.3. Zdalne i lokalne blokowanie dzia$ania programu
sterowanego danymi z centralnego serwera ............................................... 191
7.10. Wirtualne wybory ................................................................................................ 192
Zadania do samodzielnego wykonania ......................................................................... 196
Pytania kontrolne .......................................................................................................... 196
Rozdzia# 8. Zabezpieczanie programów przy u$yciu kluczy sprz"towych
oraz technik biometrycznych ......................................................... 197
8.1. Wst*p ..................................................................................................................... 197
8.2. Zabezpieczenie aplikacji za pomoc# kluczy sprz*towych ..................................... 198
8.2.1. Karty magnetyczne i elektroniczne .............................................................. 198
8.2.2. Podpis cyfrowy na trwa$ym no!niku ............................................................ 199
8.2.3. Klucze sprz*towe w zabezpieczaniu oprogramowania ................................. 200
8.3. Technologie GPS i RFID, geolokalizacja .............................................................. 201
8.3.1. Technologie GPS i RFID .............................................................................. 201
8.3.2. Problemy etyczne i moralne post*pu technicznego
zwi#zanego z lokalizacj# i kontrol# u&ytkowników ................................... 202
8.4. Weryfikacja to&samo!ci za pomoc# technik biometrycznych ................................... 203
8.4.1. Techniki biometryczne ................................................................................. 203
8.4.2. Indywidualne oprogramowanie .................................................................... 204
8.5. Szpiegostwo elektroniczne .................................................................................... 204
8.5.1. W$amania do sieci bezprzewodowych .......................................................... 204
8.5.2. Przechwytywanie fal elektromagnetycznych ................................................ 205
Pytania kontrolne .......................................................................................................... 206
Rozdzia# 9. Tworzenie bezpiecznych aplikacji w &rodowisku .NET ..................... 207
9.1. Wst*p ..................................................................................................................... 207
9.2. Autoryzacja oparta na uprawnieniach i rolach (Role-Based Authorization) .......... 208
9.2.1. Uprawnienia, interfejs IPermission, klasa Principal ..................................... 209
9.2.2. Autoryzacja nakazowa oparta na rolach (Imperative Role-Based Security) ........ 210
9.2.3. Autoryzacja deklaracyjna oparta na rolach (Declarative Role-Based
Security) ............................................................................................................... 213
9.3. Zabezpieczenie dost*pu kodu do zasobów (Code Access Security) ......................... 215
9.3.1. Nakazowe zabezpieczenie dost*pu kodu do zasobów
(Imperative Code Access Security) ............................................................... 215
9.3.2. Deklaracyjne zabezpieczenie dost*pu kodu do zasobów
(Declarative Code Access Security) .............................................................. 219
9.3.3. Poziomy regu$ bezpiecze%stwa (Security Policy Level) ............................... 220
9.3.4. Narz*dzie The Code Access Security Policy Utility — caspol.exe .............. 221
9.4. Bezpiecze%stwo ASP.NET .................................................................................... 222
9.4.1. Metody uwierzytelniania w ASP.NET ......................................................... 222
9.4.2. Dost*p anonimowy ....................................................................................... 223
9.4.3. Uwierzytelnianie systemu Windows ............................................................ 223
9.4.4. Uwierzytelnianie przy u&yciu formularza ..................................................... 226
9.4.5. Uwierzytelnianie za pomoc# .NET Passport ................................................ 228
9.4.6. Bezpieczna komunikacja za pomoc# SSL .................................................... 228
9.5. Tworzenie silnych nazw podzespo$om .................................................................. 230
Zadania do samodzielnego wykonania ......................................................................... 231
Pytania kontrolne .......................................................................................................... 232
Spis tre&ci
7
Rozdzia# 10. Bezpieczny Program ..................................................................... 235
10.1. Wst*p ................................................................................................................... 235
10.2. Opis programu ..................................................................................................... 236
10.3. Przegl#d kodu 'ród$owego ................................................................................... 238
10.3.1. BezpiecznyProgram.exe ............................................................................. 238
10.3.2. ZabezpieczBP.exe ...................................................................................... 245
10.3.3. StwórzKluczBP.exe .................................................................................... 246
10.4. Wnioski ............................................................................................................... 247
Zadania do samodzielnego wykonania ......................................................................... 249
Rozdzia# 11. Psychologiczna strona bezpiecze'stwa ......................................... 251
11.1. Wst*p ................................................................................................................... 251
11.2. Wp$yw architektury programu na jego bezpiecze%stwo ...................................... 251
11.3. „Tylne wej!cia” i kod tymczasowy ......................................................................... 253
11.4. U&ycie gotowego kodu ........................................................................................ 254
11.5. Open source ......................................................................................................... 256
11.6. Ta%cz#ce !winki kontra bezpiecze%stwo ............................................................. 257
11.7. Security by obscurity — zabezpieczanie przez zaciemnianie .............................. 258
11.8. Karanie w$amywacza ........................................................................................... 260
11.9. Brzytwa Ockhama ............................................................................................... 261
11.10. U&ycie socjotechniki .......................................................................................... 261
11.11. Nie poprawiaj w$amywacza ............................................................................... 262
11.12. Walka ze script kiddies ...................................................................................... 263
11.13. Ochrona przed automatami ................................................................................ 264
11.14. Ataki z wewn#trz ............................................................................................... 267
11.15. Ya%cuch a sie) zabezpiecze% ............................................................................. 267
11.16. Ca$o!ciowe spojrzenie na problem bezpiecze%stwa ........................................... 268
Pytania kontrolne .......................................................................................................... 270
Podsumowanie ............................................................................. 273
Odpowiedzi do pyta' kontrolnych .................................................. 281
S#owniczek poj") ......................................................................... 293
Skorowidz .................................................................................... 301
Rozdzia 6.
Zabezpieczenie programów
przed debugerami
6.1. Wst3p
Wykrywanie aktywnych debugerów oraz programów zrzucaj#cych fragment pami*ci
typu
ProcDump
to czynno!), która mo&e by) op$acalna, jednak nie jest tak prosta, jak
si* wydaje. Istnieje wiele wyrafinowanych sztuczek wykrywaj#cych te programy, jednak
zdecydowana wi*kszo!) z nich wykrywa dok$adnie okre!lone programy, jak na przyk$ad
SoftIce czy OllyDbg, i w dodatku cz*sto tylko okre!lone ich wersje. Najgorsz# infor-
macj# jest jednak to, &e istnieje mnóstwo $atek i rozszerze% popularnych debugerów,
które zabezpieczaj# si* przed wykryciem. Programy te po modyfikacjach (wykona-
nych cz*sto przez samych krakerów dla siebie) ukrywaj# si* i stosuj# techniki myl#ce.
Dlatego wykrywanie debugerów jest zadaniem cz*sto skazanym na pora&k*. Zwykle
jest si* pó$ kroku do ty$u, a nawet je!li uda nam si* poprzez zaimplementowanie
wielu technik jednocze!nie wykry) skutecznie wszystkie istniej#ce debugery, to i tak
jest to tylko chwilowe zwyci*stwo, bo za chwil* powstan# takie, których nie wykry-
jemy. Jest to wi*c typowe leczenie objawów, a nie przyczyn choroby.
Nie oznacza to, &e nie nale&y w ogóle przejmowa) si* problemem i nie stosowa) &adnych
zabezpiecze%. Jednak je!li Czytelnik nie jest geniuszem assemblera, powinien zostawi)
to zadanie innym i u&y) do tego celu programu pobranego z internetu. Jest ich wiele,
zarówno darmowych, jak i p$atnych. Do tych drugich nale&# m.in. opisane w rozdziale
drugim TheMida czy AsProtect. Dzi*ki temu zaoszcz*dzimy sobie czasu na próby,
których wyniki mog# by) w#tpliwe, a co wi*cej, których rezultat ci*&ko b*dzie nam
zweryfikowa), poniewa& nie b*dziemy dysponowa) odpowiedni# ilo!ci# wersji debuge-
rów. Procedury kontroluj#ce dzia$anie takich programów nie musz# by) niestandar-
dowe i dlatego warto pozostawi) je fachowcom.
168
Bezpieczne programowanie. Aplikacje hakeroodporne
Z tych w$a!nie powodów w rozdziale tym nie znajdziecie wielu wyrafinowanych sztuczek
blokuj#cych debugery. Opisz* jedynie kilka najprostszych, aby ka&dy móg$ sobie wy-
robi) opini* na ten temat i w razie potrzeby poszuka) bardziej zaawansowanych in-
formacji w innych 'ród$ach. Zamiast tego skupi* si* na ogólnych metodach utrudniania
debugowania, które mog# by) u&yteczne niezale&nie od stosowania funkcji wykry-
waj#cych debugery lub komercyjnych systemów zabezpiecze%, które równie& takowe
funkcje posiadaj#.
6.2. Wykrywanie debugerów
Najprostszym sposobem wykrywania debugerów jest wstawienie do kodu po prostu:
if(IsDebuggerPresent())
// wykonaj jaki' kod, np. zamknij program;
Mo&na to $atwo przetestowa), wpisuj#c w miejsce komentarza na przyk$ad polecenie
wy!wietlenie jakiego! komunikatu i uruchamiaj#c aplikacj* krok po kroku w Visual
Studio. Debuger VS zostanie wykryty i program wy!wietli komunikat. Uruchamiaj#c
program z pliku wykonywalnego, nie zobaczymy komunikatu.
Tego typu zabezpieczenie b*dzie jednak ca$kowicie nieskuteczne w przypadku za-
awansowanych debugerów u&ywanych przez krakerów, takich jak SoftIce czy OllyDbg.
W$amywacze u&ywaj# zmodyfikowanych wersji tych programów, które s# zabezpie-
czone nie tylko przed opisan# powy&ej weryfikacj#, ale tak&e przed wieloma bardziej
zaawansowanymi metodami. Twój program musia$by mie) naprawd* szerok# gam*
testów, aby mo&na by$o mie) pewno!) wykrycia wi*kszo!ci mutacji tych debugerów.
Dlatego w$a!nie lepiej jest u&y) gotowego narz*dzia wykonanego przez specjalistów,
a samemu skupi) si* na innych zabezpieczeniach. Jako ciekawostk* podam jeszcze
przyk$ady dwóch rozwi#za% tego typu:
mov ah,43h
int 68h
cmp eax,0F386h
jz mamy_debugger
W tym te!cie próbujemy zbada), czy uruchomiony zosta$ program SoftIce poprzez
wykrywanie sterownika debugera systemowego. Kolejny przyk$ad opiera si* na wy-
krywaniu
int 41h
u&ywanego przez debugery:
xor ax,ax
mov es,ax
mov bx, cs
lea dx, int41handler
xchg dx, es:[41h*4]
xchg bx, es:[41h*4+2]
in al, 40h
xor cx,cx
int 41h
xchg dx, es:[41h*4]
xchg bx, es:[41h*4+2]
Rozdzia# 6. Zabezpieczenie programów przed debugerami
169
cmp cl,al
jnz si_jest
int41handler PROC
mov cl,al
iret
int41handler ENDP
Obydwa powy&sze przyk$ady wykrywania debugera SoftIce pochodz# ze strony:
http://4programmers.net/Assembler/FAQ/Wykrywanie_debuggera_(SoftICE)
1
.
6.3. Utrudnianie debugowania
6.3.1. Wstawki kodu utrudniaj%ce debugowanie
Utrudnienie debugowania mo&na wykona), wklejaj#c w wiele miejsc kodu 'ród$owego
programu relatywnie nieskomplikowane wstawki. Je!li u&ywamy j*zyka C/C++, sprawa
jest prosta, mo&emy bowiem wykorzysta) makra preprocesora, co w po$#czeniu z twór-
czym u&yciem instrukcji skoku bezwarunkowego (tak oczerniane przez wszystkich
goto
), wstawek assemblerowych czy konstrukcji takich jak
setjmp
czy
longjmp
, mo&e
solidnie skomplikowa) !ledzenie programu w debugerze. Wa&ne jest, aby tego typu
wstawki pozostawa$y neutralne dla kodu.
Oto przyk$ad:
jmp_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:
\
;
Powy&sze makro wstawia kod wygl#daj#cy mniej wi*cej tak:
if( setjmp(env) == 0 )
{
goto skok_ad_1;
}
else
1
Tre!) udost*pniona na zasadach licencji Creative Commons Attribution:
http://creativecommons.org/licenses/by/2.0/pl/legalcode.
170
Bezpieczne programowanie. Aplikacje hakeroodporne
{
// WAABCIWY FRAGMENT KODU
}
goto koniec_ad_1;
skok_ad_1:
longjmp(env, 1);
koniec_ad_1:
W trakcie wykonania instrukcja
setjmp(env) == 0
wywo$ana po raz pierwszy ustawi
punkt powrotu dla skoku
longjmp
na miejsce swojego wywo$ania oraz zwróci warto!)
TRUE
. W zwi#zku z tym kolejn# wykonywan# instrukcj# b*dzie
goto skok_ad_1
. Nast*pnie
wykona si*
longjmp(env,1)
, które spowoduje przesuni*cie wykonania z powrotem do
pierwszej linii kodu. Tym razem jednak warunek nie b*dzie ju& spe$niony i wykonany
zostanie ci#g instrukcji oznaczony jako
WLAMCIWY FRAGMENT KODU
. Na koniec instrukcja
goto koniec_ad_1
zapewni prawid$owe opuszczenie tego bloku kodu. Ca$a konstrukcja
ma wple!) w kod kilka dziwnych i zaciemniaj#cych sens skoków wyd$u&aj#cych
i utrudniaj#cych !ledzenie wykonania w debugerze. Oczywi!cie powinna by) u&yta
w programie wiele razy, aby by) naprawd* skuteczn#.
U&ycie makra jest nast*puj#ce. Kod, który zaciemniamy, otacza si* wywo$aniem makra:
AD(kod, x)
. Pewn# wad# tego makra jest to, &e trzeba go wywo$ywa) z dodatkowym
parametrem, który za ka&dym razem musi by) inny. To, co przed zaciemnieniem wy-
gl#da tak:
for( int i = 0; i < 10; i++)
for( int j = 0; j < i; j++)
if( x[i] < x[j])
{
int tmp = x[i];
x[i] = x[j];
x[j] = tmp;
}
po — b*dzie wygl#da) tak:
AD(
for( int i = 0; i < 10; i++)
for( int j = 0; j < i; j++)
AD(if( x[i] < x[j])
{
int tmp = x[i];
AD(x[i] = x[j] ,2);
AD(x[j] = tmp ,3);
}
, 1)
, 0)
Inne makra mog# korzysta) wprost ze wstawek assemblerowych:
#define WSTAWKA_START_ASM __asm PUSH EAX __asm PUSH EBX __asm PUSH ECX __asm PUSHF
#define WSTAWKA_STOP_ASM __asm POPF __asm POP ECX __asm POP EBX __asm POP EAX
#define WSTAWKA_PUSTA_1 WSTAWKA_START_ASM __asm MOV EAX, ECX __asm MOV EAX, 0 __asm
ADD EAX, 0xD007 _asm MOV EBX, EAX WSTAWKA_STOP_ASM
Rozdzia# 6. Zabezpieczenie programów przed debugerami
171
#define WSTAWKA_PUSTA_2 WSTAWKA_START_ASM MAKE_DUMMY_1 __asm TEST EAX, EAX __asm
PUSHF __asm POP EAX __asm MOV EAC, EAX MAKE_STOP_ASM
#define WSTAWKA_PUSTA_3 WSTAWKA_START_ASM __asm MOV EAX, EBX __asm ADD EAX, 0x01ac
__asm PUSH EAX __asm MOV EAX, EBX __asm POP EBX WSTAWKA_STOP_ASM
Powy&sze kody nie maj# &adnego sensu, natomiast nie zmieniaj# stanu rejestrów ani
flag (dzi*ki u&yciu makr
WSTAWKA_START_ASM
i
WSTAWKA_STOP_ASM)
. U&ycie jest proste:
wywo$anie makra wstawia si* po prostu do kodu.
for( int i = 0; i < 10; i++)
for( int j = 0; j < i; j++)
if( x[i] < x[j])
{
WSTAWKA_PUSTA_3
int tmp = x[i];
WSTAWKA_PUSTA_3 WSTAWKA_PUSTA_2
x[i] = x[j];
WSTAWKA_PUSTA_3 WSTAWKA_PUSTA_1 WSTAWKA_PUSTA_3
x[j] = tmp;
WSTAWKA_PUSTA_2
}
Prawda, &e proste? Polecam obejrzenie kodu assemblerowego wygenerowanego przez
kompilator dla ka&dej z trzech powy&szych wersji kodu. Po!wi*ciwszy 3 – 4 godziny,
mo&na wyprodukowa) kilkana!cie czy nawet kilkadziesi#t podobnych fragmentów
kodu i u&y) ich w setkach miejsc, wykonuj#c po prostu prac* typu kopiuj/wklej. Nie
powstrzyma to samo w sobie &adnego krakera, ale utrudni mu nieco prac*. Oczywi-
!cie takie wstawki wyd$u&aj# kod oraz nieznacznie spowalniaj# jego wykonanie. Je!li
jednak b*dziemy u&ywa) ich wy$#cznie w najbardziej krytycznych fragmentach pro-
gramu, dotycz#cych zabezpiecze%, to jest to op$acalne. Zw$aszcza &e przy dzisiej-
szych pr*dko!ciach procesorów tych kilkadziesi#t instrukcji maszynowych nie b*dzie
du&ym obci#&eniem.
Powy&sze makra s# banalne i maj# wy$#cznie pos$u&y) jako przyk$ad tego, co mo&na
robi). W prawdziwym systemie warto posiedzie) nieco d$u&ej i doda) nast*puj#ce
elementy:
Wstawki assemblerowe z du&# ilo!ci# skoków wymieszanych bez $adu, na
przyk$ad:
WSTAWKA_START_ASM
__asm JMP skok_1x;
skok_1x: __asm TEST EAX,EBX;
__asm JMP skok_3x;
skok_5x:
__asm MOV EAX, EBX;
__asm JMP skok_4x;
skok_2x: __asm MOV EAX, ECX;
__asm JMP skok_5x;
skok_4x: __asm POPF;
__asm JMP skok_6x;
skok_3x: __asm MOV EAX, 0;
__asm PUSH EAX;
__asm MOV EAX, EBX;
172
Bezpieczne programowanie. Aplikacje hakeroodporne
__asm TEST EAX, EAX;
__asm JNZ skok_4x;
__asm JMP skok_2x;
skok_6x: __asm MOV EAX,EBX;
WSTAWKA_STOP_ASM
U&ycie nie tylko skoków bezwzgl*dnych, ale tak&e du&ej ilo!ci zagnie&d&onych
funkcji oraz skoków warunkowych (jak w powy&szym przyk$adzie skok
JNZ
).
Wstawianie instrukcji, które nie b*d# nigdy wykonane, w pobli&e w$a!ciwego
kodu. Mo&na tego dokona) poprzez skoki. Ciekaw# instrukcj#, któr# mo&na
w takie miejsce wstawi), jest
__asm int 3
, czyli instrukcja przerwania
programowego.
Mo&na nawet pokusi) si* o sterowanie przep$ywem wykonania za pomoc#
wyj#tków.
Przez ca$y czas powinni!my mie) jednak na uwadze to, &e jest to tylko dodatek, i uwa&a),
aby nie zaciemni) sobie kodu nadmiernie.
6.3.2. Generator wstawek kodu utrudniaj%cych
debugowanie
Makra, o których pisa$em powy&ej, to interesuj#ca technika, ale maj# one kilka wad:
Nie ka&dy j*zyk posiada makra preprocesora. Mo&na jeszcze ratowa) si* u&yciem
funkcji rozwijanych w miejscu wywo$ania (
inline
), ale nie zawsze i nie
wszystko uda si* nimi zast#pi).
Makra pisane r*cznie s# zazwyczaj schematyczne. Ci*&ko je sparametryzowa)
czy zmienia) im dynamicznie tre!).
Nawet najwygodniejsze w u&yciu widniej# w kodzie 'ród$owym, zmniejszaj#c
jego czytelno!) oraz utrudniaj#c testowanie (i debugowanie, ale w ko%cu po to
zosta$y napisane).
Lepszym rozwi#zaniem b*dzie wi*c zostawienie wersji deweloperskiej kodu w stanie
czystym i wstawianie kodu antydebugowego przez automat dopiero w procesie pro-
dukcji oprogramowania. Dzi*ki u&yciu zautomatyzowanych systemów produkcji
oprogramowania takich jak na przyk$ad CruiseControl .NET, systemów kontroli wer-
sji takich jak CVS czy SVN oraz narz*dzi skryptowych takich jak NANT, Python czy
Ruby proces ten nie powinien by) skomplikowany. Wygl#da on nast*puj#co:
Prace deweloperskie wykonywane s# przez programistów. Programista,
ko%cz#c prace, wysy$a kod 'ród$owy do repozytorium systemu kontroli wersji.
Automat pobiera zmodyfikowane 'ród$a do swojej lokalnej kopii.
Prekompilacja — wygenerowanie przez automat wstawek antydebugowych
i wstawienie ich do kodu.
Kompilacja zmodyfikowanego kodu.
Wykonanie testów automatycznych.
Rozdzia# 6. Zabezpieczenie programów przed debugerami
173
Automat taki mo&e generowa) wstawki losowo spo!ród zbioru elementów w miejsca
oznaczone w kodzie w specyficzny sposób. Dzi*ki temu jedyne, co musi zrobi) pro-
gramista, to wstawi) takie oznaczenia wsz*dzie, gdzie chce. Mo&e to by) na przyk$ad
specyficzny komentarz:
// ZABEZPIECZ
for( int i = 0; i < 10; i++)
for( int j = 0; j < i; j++)
if( x[i] < x[j])
{
// ZABEZPIECZ
int tmp = x[i];
// ZABEZPIECZ
x[i] = x[j];
// ZABEZPIECZ
x[j] = tmp;
// ZABEZPIECZ
}
// ZABEZPIECZ
Na p$ycie CD znajduje si* kod 'ród$owy programu GenerujZabezpieczenia napisanego
w j*zyku C#. Jest to program uruchamiany z linii polece%, którego jedynym parametrem
jest !cie&ka do pliku 'ród$owego (w j*zyku C++), w którym wstawki
// ZABEZPIECZ
maj# zosta) zmienione na wstawki antydebugowe. Czytelnik mo&e rozbudowa) i zmody-
fikowa) go wed$ug w$asnych potrzeb. Mo&na zmieni) go w nast*puj#cy sposób:
Dodanie wi*kszej ilo!ci elementów s$u&#cych do generowania wstawek.
Dodanie generacji wstawek dla ró&nych j*zyków programowania.
Dodanie generacji kilku rodzajów wstawek, w tym parametryzowanych.
Stworzenie bardziej skomplikowanych wstawek.
Stworzenie mniej schematycznych wstawek.
Nale&y przy tym pami*ta) o tym, &e program po prostu wstawia wstawk* tam, gdzie
zobaczy stosowny tekst. Mo&e wi*c si* zdarzy), &e kod 'ród$owy po modyfikacji nie
b*dzie si* kompilowa) lub w ogóle nie b*dzie dzia$a). Zale&y to od sposobu u&ycia
oznakowania wstawek. Je!li ich tre!) pojawi si* w nietypowym miejscu, na przyk$ad
w ci#gu znaków do wy!wietlenia na konsoli itp., to dzia$anie programu mo&e zmieni)
si* na nieprawid$owe.
Kod programu jest do!) prosty. Podstawow# funkcj# jest
ModyfikujPlik
, która odczytuje
plik, wyszukuje frazy
// ZABEZPIECZ
i podmienia je na losowo wygenerowane wstawki
assemblerowe. Generowane s# dwa typy wstawek:
Statyczna — od 1 do 9 rozkazów assemblera wylosowanych z tablicy
statyczneWstawki
.
Fa$szywe skoki — trzy przeplataj#ce si* fragmenty kodu (wylosowane jak wstawka
statyczna).
174
Bezpieczne programowanie. Aplikacje hakeroodporne
Oto g$ówna funkcja:
static void ModyfikujPlik(string aMcie`ka)
{
// odczyt pliku
TextReader reader = new StreamReader(aMcie`ka,
System.Text.Encoding.Default);
string zawartocf = reader.ReadToEnd();
reader.Close();
// modyfikacja zawarto'ci
int ile = 0;
while (zawartocf.IndexOf(oznaczenieWstawki) != -1)
{
int indeksWstawki = zawartocf.IndexOf(oznaczenieWstawki);
string wstawka = UtwórzWstawkp();
zawartocf = zawartocf.Substring(0, indeksWstawki) + wstawka +
zawartocf.Substring(indeksWstawki + oznaczenieWstawki.Length);
ile++;
}
// zapis pliku
TextWriter writer = new StreamWriter(aMcie`ka, false,
System.Text.Encoding.Default);
writer.Write(zawartocf);
writer.Close();
Console.WriteLine(aMcie`ka + " zostav zmodyfikowany "
+ ile.ToString() + " razy");
}
Pojedyncz# wstawk* tworzy funkcja
UtwórzWstawkp()
:
static string UtwórzWstawkp()
{
string cizgPodmiany = poczztekWstawki;
int ile = rd.Next(1, 3);
for (int i = 0; i < ile; i++)
{
if(rd.Next(0,2) == 0)
cizgPodmiany += UtwórzSztuczneSkoki();
else
cizgPodmiany += UtwórzStatycznzWstawkp();
}
return cizgPodmiany + koniecWstawki;
}
T* funkcj* zmodyfikuj, je!li chcesz mie) wi*cej typów wstawek. Po prostu nie losuj
liczb z zakresu <0; 2), lecz wi*kszego, i zast#p warunek instrukcj#
switch
. Funkcje
UtwórzSztuczneSkoki
i
UtwórzStatycznzWstawkp
wygl#daj# nast*puj#co:
static string UtwórzStatycznzWstawkp()
{
int ile = rd.Next(1, 10);
string retWart = "";
for (int i = 0; i < ile; i++)
{