background image

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!

background image

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

background image

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

background image

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

background image

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

background image

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

background image

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.

background image

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]

background image

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.

background image

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

background image

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;

background image

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.

background image

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).

background image

Czytaj dalej...

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++)

{