Praktyczna analiza plików binarnych

Zbuduj własne narzędzia na platformie Linux do instrumentacji binarnej, analizy i deasemblacji

1 opinia

Format:

epub, mobi

RODZAJ DOSTĘPU

93,60  104,00

Format: epub, mobi

Cena początkowa: 104,00 zł (-10%)

Najniższa cena z 30 dni: 62,40 zł  


93,60

w tym VAT

Nowoczesne złośliwe oprogramowanie coraz częściej zaciemnia swój kod i uniemożliwia analizę przez co potrzebujemy coraz wymyślniejszych metod, aby podnieść tę ciemną kurtynę wiedzy. Może pomóc w tym analiza binarna, której celem jest ustalenie prawdziwych własności programów binarnych, aby zrozumieć, co naprawdę robią. Inżynieria wsteczna i deasemblacja, stanowią kluczowe, pierwsze kroki, jednak zakres analizy binarnej jest znacznie większy i pozostaje jeszcze wiele do nauczenia.
Ten praktyczny przewodnik napisany dla inżynierów bezpieczeństwa i hakerów porusza fascynujące tematy związane z analizą i instrumentacją binarną. Zalecana jest praktyczna znajomość C / C++ oraz asemblera x86-64 (Dodatek A książki wprowadza w błyskawiczny kurs asemblera x86). Po zapoznaniu się z podstawowymi pojęciami i formatami, przeanalizujesz pliki binarne przy użyciu takich technik jak np. deasemblacja czy wstrzykiwanie kodu oraz poznasz narzędzia do analizy binarnej GNU / Linux. Następnie zaimplementujesz narzędzia do profilowania za pomocą Pin, zbudujesz własne narzędzia do dynamicznej analizy taint z libdft i nie tylko. Nauczysz się:
• Analizować pliki binarne ELF i PE i tworzyć program ładujący pliki binarne przy użyciu libbfd
• Modyfikować pliki binarne ELF za pomocą takich metod jak wstrzykiwanie kodu i edycja heksadecymalna
• Budować dostosowane narzędzia do deasemblacji za pomocą Capstone
• Używać instrumentacji binarnej, aby obejść popularne sztuczki anty-analityczne
• Stosować analizę taint, aby wykryć atak przejęcia przepływu sterowania i wycieki informacji
• Używać wykonywania symbolicznego, aby zbudować automatyczne narzędzia do eksploitacji
Ćwiczenia zawarte na końcu każdego rozdziału pomagają przejść od zrozumienia podstaw do wykonywania zaawansowanych analiz binarnych i instrumentacji. Praktyczna analiza plików binarnych pomoże Ci osiągnąć biegłość na poziomie eksperckim.


Rok wydania2020
Liczba stron480
KategoriaBezpieczeństwo
WydawcaWydawnictwo Naukowe PWN
TłumaczenieGrzegorz Frelik
ISBN-13978-83-01-21224-7
Numer wydania1
Język publikacjipolski
Informacja o sprzedawcyePWN sp. z o.o.

Ciekawe propozycje

Spis treści

  SŁOWO WSTĘPNE XVII
  PRZEDMOWA XXI
  PODZIĘKOWANIA XXIII
  WSTĘP    1
  Czym jest analiza binarna i dlaczego jej potrzebujesz?     2
  Dlaczego analiza binarna stanowi wyzwanie?    3
  Kto powinien przeczytać tę książkę?    4
  Co jest w tej książce?    4
  Jak korzystać z tej książki?    6
    Model programowy procesora    6
    Składnia asemblera    6
    Format binarny i platforma systemowa    7
    Przykładowy kod i maszyna wirtualna    7
  CZĘŚĆ I FORMATY BINARNE    9
  1. ANATOMIA PLIKU BINARNEGO 11
    1.1. Proces kompilacji    12
      1.1.1. Faza preprocesowania    12
      1.1.2. Faza kompilacji     14
      1.1.3. Faza asemblacji    16
      1.1.4. Faza konsolidacji (linkowania)     16
    1.2. Symbole i okrojone pliki binarne    18
      1.2.1. Podgląd symboli w pliku     18
      1.2.2. Kolejny plik binarny przechodzi na ciemną stronę: „okrajanie” pliku     20
    1.3. Deasemblacja pliku binarnego    20
      1.3.1. Zaglądanie do wnętrza pliku obiektowego    20
      1.3.2. Badamy kompletny wykonywalny plik binarny    22
    1.4. Ładowanie i wykonywanie pliku binarnego    26
    1.5. Podsumowanie    28
  2. FORMAT ELF 29
    2.1. Nagłówek pliku    31
      2.1.1. Tablica e_ident    31
      2.1.2. Pola e_type, e_machine i e_version    33
      2.1.3. Pole e_entry    33
      2.1.4. Pola e_phoff i e_shoff    34
      2.1.5. Pole e_flags    34
      2.1.6. Pole e_ehsize    34
      2.1.7. Pole e_*entsize i e_*num    34
      2.1.8. Pole e_shstrndx    35
    2.2. Nagłówki sekcji    35
      2.2.1. Pole sh_name    36
      2.2.2. Pole sh_type    37
      2.2.3. Pole sh_flags    37
      2.2.4. Pola sh_addr, sh_offset oraz sh_size    38
      2.2.5. Pole sh_link    38
      2.2.6. Pole sh_info    38
      2.2.7. Pole sh_addralign    38
      2.2.8. Pole sh_entsize    38
    2.3. Sekcje    38
      2.3.1. Sekcje .init i .fini    40
      2.3.2. Sekcja .text    40
      2.3.3. Sekcje .bss, .data i .rodata    41
      2.3.4. Wiązanie leniwe symboli i sekcje .plt, .got oraz .got.plt    42
      2.3.5. Sekcje .rel.* i .rela.*    45
      2.3.6. Sekcja .dynamic    46
      2.3.7. Sekcje .init_array i .fini_array    48
      2.3.8. Sekcje .shstrtab, .symtab, .strttab, .dynsym i .dynstr    48
    2.4. Nagłówki programów    49
      2.4.1. Pole p_type    50
      2.4.2. Pole p_flags    51
      2.4.3. Pola p_offset, p_vaddr, p_paddr, p_filesz i p_memsz    51
      2.4.4. Pole p_align    51
    2.5. Podsumowanie    52
  3. FORMAT PE: KRÓTKIE WPROWADZENIE    53
    3.1. Nagłówek MS-DOS i stub MS-DOS    54
    3.2. Sygnatura, nagłówek i nagłówek opcjonalny pliku PE    54
      3.2.1. Sygnatura pliku PE    57
      3.2.2. Nagłówek pliku PE    57
      3.2.3. Nagłówek opcjonalny pliku PE    58
    3.3. Tablica nagłówków sekcji    58
    3.4. Sekcje    59
      3.4.1. Sekcje .edata i .idata    59
      3.4.2. Wyrównywanie w sekcjach kodu PE    60
    3.5. Podsumowanie    61
  4. TWORZENIE PROGRAMU ŁADUJĄCEGO PLIKI BINARNE PRZY UŻYCIU LIBBFD    63
    4.1. Czym jest libbfd?    64
    4.2. Prosty interfejs do ładowania plików binarnych    64
      4.2.1. Klasa Binary    67
      4.2.2. Klasa Section    67
      4.2.3. Klasa Symbol    67
    4.3. Implementacja loadera plików binarnych    67
      4.3.1. Inicjalizacja libbfd i otwieranie pliku binarnego    69
      4.3.2. Parsowanie podstawowych właściwości pliku binarnego     71
      4.3.3. Ładowanie symboli    73
      4.3.4. Ładowanie sekcji    76
    4.4. Testowanie loadera binarnego    78
    4.5. Podsumowanie    81
  CZĘŚĆ II PODSTAWY ANALIZY BINARNEJ 83
  5. PODSTAWOWA ANALIZA BINARNA W LINUKSIE    85
    5.1. Rozwiązywanie kryzysów tożsamości przy użyciu file    86
    5.2. Użycie ldd do badania zależności    89
    5.3. Oglądanie zawartości pliku w xxd    90
    5.4. Parsowanie ekstrahowanego ELF za pomocą readelf    92
    5.5. Parsowanie symboli za pomocą nm    94
    5.6. Szukanie wskazówek za pomocą strings    97
    5.7. Śledzenie wywołań systemowych i bibliotecznych za pomocą strace i ltrace    100
    5.8. Badanie zachowań na poziomie instrukcji przy użyciu objdump    104
    5.9. Zrzut dynamicznego bufora łańcucha za pomocą gdb    106
    5.10. Podsumowanie    108
  6. DEASEMBLACJA I PODSTAWY ANALIZY BINARNEJ    109
    6.1. Deasemblacja statyczna    110
      6.1.1. Deasemblacja liniowa    111
      6.1.2. Deasemblacja rekurencyjna    112
    6.2. Deasemblacja dynamiczna    116
      6.2.1. Przykład: śledzenie wykonywania pliku binarnego za pomocą gdb    116
      6.2.2. Strategie pokrycia kodu    119
    6.3. Strukturyzacja deasemblowanego kodu i danych    123
      6.3.1. Strukturyzowanie kodu    123
      6.3.2. Strukturyzacja danych    130
      6.3.3. Dekompilacja    132
      6.3.4. Reprezentacje pośrednie    133
    6.4. Podstawowe metody analizy    135
      6.4.1. Własności analizy binarnej    135
      6.4.2. Analiza przepływu sterowania    139
      6.4.3. Analiza przepływu danych    141
    6.5. Wpływ ustawień kompilatora na deasemblację    145
    6.6. Podsumowanie    146
  7. PROSTE METODY WSTRZYKIWANIA KODU DLA ELF    147
    7.1. Najprostsze modyfikacje binarne przy użyciu edycji hex     147
      7.1.1. Obserwowanie błędu off-by-one w akcji    148
      7.1.2. Naprawienie błędu off-by-one 151
    7.2. Modyfikacja zachowania biblioteki współdzielonej przy użyciu LD_PRELOAD    154
      7.2.1. Zagrożenie przepełnieniem sterty    155
      7.2.2. Wykrywanie przepełnienia sterty    157
    7.3. Wstrzykiwanie sekcji kodu    160
      7.3.1. Wstrzykiwanie sekcji ELF: przegląd wysokiego poziomu    161
      7.3.2. Użycie elfinject do wstrzykiwania sekcji ELF    163
    7.4. Wywołanie wstrzykniętego kodu    166
      7.4.1. Modyfikacja adresu startowego    167
      7.4.2. Przejęcie konstruktorów i destruktorów    170
      7.4.3. Przejęcie wpisów w GOT    173
      7.4.4. Przejęcie wpisów PLT    176
      7.4.5. Przekierowanie wywołań bezpośrednich i pośrednich    177
    7.5. Podsumowanie    178
  CZĘŚĆ III ZAAWANSOWANA ANALIZA BINARNA 179
  8. DOSTOSOWYWANIE DEASEMBLACJI DO POTRZEB 181
    8.1. Dlaczego pisać własny program do deasemblacji    182
      8.1.1. Sprawa dla dostosowania deasemblacji: zaciemniony kod    182
      8.1.2. Inne powody, by napisać dostosowany deasembler     185
    8.2. Wprowadzenie do Capstone’a    186
      8.2.1. Instalacja Capstone’a    186
      8.2.2. Deasemblacja liniowa z Capstone'a    187
      8.2.3. Eksploracja API C Capstone’a    192
      8.2.4. Deasemblacja rekurencyjna z Capstone    193
    8.3. Implementacja skanera gadżetów ROP    202
      8.3.1. Wprowadzenie do programowania zorientowanego na powrót (ROP)    202
      8.3.2. Wykrywanie gadżetów ROP    204
    8.4. Podsumowanie    210
  9. INSTRUMENTACJA BINARNA 213
    9.1. Czym jest instrumentacja binarna?    214
      9.1.1. API instrumentacji binarnej    214
      9.1.2. Statyczna kontra dynamiczna instrumentacja binarna    215
    9.2. Statyczna instrumentacja binarna    216
      9.2.1. Podejście int 3    216
      9.2.2. Podejście z użyciem trampolin    218
    9.3. Dynamiczna instrumentacja binarna    223
      9.3.1. Architektura systemu DBI    223
      9.3.2. Wprowadzenie do Pin    225
    9.4. Profilowanie za pomocą Pin    226
      9.4.1. Struktury danych profilera i kod instalacyjny    226
      9.4.2. Parsowanie symboli funkcji    229
      9.4.3. Instrumentacja bloków podstawowych    230
      9.4.4. Instrumentacja instrukcji przepływu sterowania    232
      9.4.5. Liczenie instrukcji, transferów sterowania i wywołań systemowych    235
      9.4.6. Testowanie profilera    236
    9.5. Automatyczne rozpakowywanie plików binarnych z Pin    240
      9.5.1. Wprowadzenie do programów pakujących    240
      9.5.2. Struktury danych i kod instalacyjny programu rozpakowującego    242
      9.5.3. Instrumentowanie zapisów do pamięci    244
      9.5.4. Instrumentowanie instrukcji przepływu sterowania    245
      9.5.5. Śledzenie zapisów do pamięci    245
      9.5.6. Wykrywanie pierwotnego punktu wejścia i zrzucanie rozpakowanego pliku binarnego    247
      9.5.7. Testowanie programu rozpakowującego    248
    9.6. Podsumowanie    252
  10. ZASADY DYNAMICZNEJ ANALIZY TAINT    255
    10.1. Czym jest DTA?    256
    10.2. DTA w trzech krokach: źródła taint, taint sinks i propagacja taint     256
      10.2.1. Definiowanie źródeł taint    256
      10.2.2. Definiowanie taint sinks    257
      10.2.3. Śledzenie propagacji taint    257
    10.3. Użycie DTA do wykrycia błędu Heartbleed    258
      10.3.1. Krótki przegląd podatności na Heartbleed    258
      10.3.2. Wykrywanie Heartbleed przez taint    259
    10.4. Czynniki w projektowaniu DTA: ziarnistość taint, kolory taint i zasady propagacji taint    261
      10.4.1. Ziarnistość taint    261
      10.4.2. Kolory taint    262
      10.4.3. Zasady propagacji taint    263
      10.4.4. Nadmierne i niedostateczne pokrycie taint    264
      10.4.5. Zależności sterowania    264
      10.4.6. Shadow memory    265
    10.5. Podsumowanie    267
  11. PRAKTYCZNA DYNAMICZNA ANALIZA TAINT Z LIBDFT 269
    11.1. Wstęp do libdft    269
      11.1.1. Organizacja wewnętrzna libdft    270
      11.1.2. Zasady taint    272
    11.2. Wykorzystanie DTA do wykrywania zdalnego przechwycenia sterowania    273
      11.2.1. Sprawdzanie informacji o taint    276
      11.2.2. Źródła taint: taintowanie otrzymywanych bajtów    277
      11.2.3. Taint sinks: sprawdzanie argumentów execve    279
      11.2.4. Wykrywanie próby przejęcia przepływu sterowania    280
    11.3. Obejście DTA za pomocą przepływów niejawnych    285
    11.4. Detektor eksfiltracji danych oparty na DTA    286
      11.4.1. Źródła taint: śledzenie taint dla otwartych plików    289
      11.4.2. Taint sinks: monitorowanie przesyłów sieciowych w poszukiwaniu eksfiltracji danych    292
      11.4.3. Wykrywanie próby eksfiltracji danych    293
    11.5. Podsumowanie    296
  12. PODSTAWY WYKONYWANIA SYMBOLICZNEGO    297
    12.1. Przegląd wykonywania symbolicznego    298
      12.1.1. Wykonywanie symboliczne kontra konkretne    298
      12.1.2. Rodzaje i ograniczenia wykonywania symbolicznego    302
      12.1.3. Zwiększanie skalowalności wykonywania symbolicznego    307
    12.2. Rozwiązywanie ograniczeń za pomocą Z3    309
      12.2.1. Dowodzenie osiągalności instrukcji    309
      12.2.2. Dowodzenie nieosiągalności instrukcji    312
      12.2.3. Dowodzenie poprawności formuły    313
      12.2.4. Upraszczanie wyrażeń    314
      12.2.5. Modelowanie ograniczeń dla kodu maszynowego za pomocą wektorów bitowych    315
      12.2.6. Rozwiązywanie nieprzejrzystego kodu warunkowego za pomocą wektorów bitowych    317
    12.3. Podsumowanie    318
  13. PRAKTYCZNE WYKONYWANIE SYMBOLICZNE Z TRITONEM 321
    13.1. Wprowadzenie do Tritona    322
    13.2. Utrzymywanie stanu symbolicznego przy użyciu drzew składniowych (AST)    323
    13.3. Slicing wsteczny z Tritonem    325
      13.3.1. Pliki nagłówkowe i konfigurowanie Tritona    328
      13.3.2. Plik konfiguracji symbolicznej    328
      13.3.3. Emulowanie instrukcji    329
      13.3.4. Konfigurowanie architektury Tritona    331
      13.3.5. Obliczanie „wycinka wstecznego”    332
    13.4. Wykorzystanie Tritona do zwiększenia pokrycia kodu    333
      13.4.1. Tworzenie zmiennych symbolicznych    335
      13.4.2. Znajdowanie modelu dla nowej ścieżki    336
      13.4.3. Testowanie narzędzia pokrycia kodu    339
    13.5. Automatyczna eksploitacja podatności    342
      13.5.1. Podatny program    342
      13.5.2. Znajdowanie adresu podatnego miejsca wywołania    346
      13.5.3. Budowanie generatora exploita    348
      13.5.4. Uzyskiwanie dostępu do powłoki administratora    354
    13.6. Podsumowanie    356
  CZĘŚĆ IV DODATKI    359
  A. BŁYSKAWICZNY KURS ASEMBLERA X86    361
    A.1. Zarys programu w języku asemblera    362
      A.1.1. Instrukcje języka asemblera, dyrektywy, etykiety i komentarze    362
      A.1.2. Rozdzielenie kodu od danych    363
      A.1.3. Składnia AT&T i Intela    364
    A.2. Struktura instrukcji x86    364
      A.2.1. Reprezentacja instrukcji x86 na poziomie języka asemblera    364
      A.2.2. Instrukcje x86 na poziomie kodu maszynowego    364
      A.2.3. Operandy rejestru    365
      A.2.4. Operandy pamięci    367
      A.2.5. Operandy bezpośrednie    368
    A3. Częste instrukcje x86    368
      A.3.1. Porównywanie operandów i ustawianie flag stanu    370
      A.3.2. Implementacja wywołań systemowych    370
      A.3.3. Implementacja skoków warunkowych    370
      A.3.4. Ładowanie adresów pamięci    371
    A.4. Częste konstrukcje kodu w języku asemblera    371
      A.4.1. Stos    371
      A.4.2. Wywołania funkcji i ramki funkcji    372
      A.4.3. Instrukcje warunkowe    376
      A.4.4. Pętle    378
  B. IMPLEMENTACJA NADPISYWANIA PT_NOTE PRZY UŻYCIU LIBELF 379
    B.1. Wymagane pliki nagłówkowe    380
    B.2. Struktury danych używane w elfinject    380
    B.3. Inicjalizacja libelf    381
    B.4. Uzyskiwanie nagłówka pliku wykonywalnego    385
    B.5. Znajdowanie segmentu PT_NOTE    386
    B.6. Wstrzykiwanie bajtów kodu    387
    B.7. Dopasowanie adresu ładowania dla wstrzykiwanej sekcji    388
    B.8. Nadpisanie nagłówka sekcji .note.ABI-tag    388
    B.9. Ustawienie nazwy dla wstrzykniętej sekcji    393
    B.10. Nadpisanie nagłówka programu PT_NOTE    395
    B.11. Modyfikacja adresu startowego    397
  C. SPIS NARZĘDZI ANALIZY BINARNEJ    399
    C.1. Deasemblery    399
    C.2. Debuggery    401
    C.3. Platformy deasemblerów    401
    C.4. Platformy analizy binarnej    402
  D. DALSZA LEKTURA 403
    D.1. Standardy i źródła    403
    D.2. Artykuły i raporty techniczne    404
    D.3. Książki    406
  INDEKS    407
RozwińZwiń