Praktyczna analiza plików binarnych - Helion
Tłumaczenie: Grzegorz Frelik
ISBN: 9788301212247
stron: 480, Format: ebook
Data wydania: 2020-07-23
Księgarnia: Helion
Cena książki: 79,20 zł (poprzednio: 99,00 zł)
Oszczędzasz: 20% (-19,80 zł)
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.
Osoby które kupowały "Praktyczna analiza plików binarnych", wybierały także:
- Learning Java Lambdas 373,75 zł, (29,90 zł -92%)
- The DevOps 2.1 Toolkit: Docker Swarm 332,22 zł, (29,90 zł -91%)
- Securing Network Infrastructure 199,33 zł, (29,90 zł -85%)
- Mastering Linux Security and Hardening 186,88 zł, (29,90 zł -84%)
- Blockchain Development with Hyperledger 175,88 zł, (29,90 zł -83%)
Spis treści
Praktyczna analiza plików binarnych eBook -- spis treści
- Okładka
- Strona tytułowa
- Strona redakcyjna
- Spis treści
- Słowo wstępne
- Przedmowa
- Podziękowania
- Wstęp
- Czym jest analiza binarna i dlaczego jej potrzebujesz?
- Dlaczego analiza binarna stanowi wyzwanie?
- Kto powinien przeczytać tę książkę?
- Co jest w tej książce?
- Jak korzystać z tej książki?
- Model programowy procesora
- Składnia asemblera
- Format binarny i platforma systemowa
- Przykładowy kod i maszyna wirtualna
- CZĘŚĆ I. FORMATY BINARNE
- 1. Anatomia pliku binarnego
- 1.1. Proces kompilacji
- 1.1.1. Faza preprocesowania
- 1.1.2. Faza kompilacji
- 1.1.3. Faza asemblacji
- 1.1.4. Faza konsolidacji (linkowania)
- 1.2. Symbole i okrojone pliki binarne
- 1.2.1. Podgląd symboli w pliku
- 1.2.2. Kolejny plik binarny przechodzi na ciemną stronę: okrajanie pliku
- 1.3. Deasemblacja pliku binarnego
- 1.3.1. Zaglądanie do wnętrza pliku obiektowego
- 1.3.2. Badamy kompletny wykonywalny plik binarny
- 1.4. Ładowanie i wykonywanie pliku binarnego
- 1.5. Podsumowanie
- 1.1. Proces kompilacji
- 2. Format ELF
- 2.1. Nagłówek pliku
- 2.1.1. Tablica e_ident
- 2.1.2. Pola e_type, e_machine i e_version
- 2.1.3. Pole e_entry
- 2.1.4. Pola e_phoff i e_shoff
- 2.1.5. Pole e_flags
- 2.1.6. Pole e_ehsize
- 2.1.7. Pole e_*entsize i e_*num
- 2.1.8. Pole e_shstrndx
- 2.2. Nagłówki sekcji
- 2.2.1. Pole sh_name
- 2.2.2. Pole sh_type
- 2.2.3. Pole sh_flags
- 2.2.4. Pola sh_addr, sh_offset oraz sh_size
- 2.2.5. Pole sh_link
- 2.2.6. Pole sh_info
- 2.2.7. Pole sh_addralign
- 2.2.8. Pole sh_entsize
- 2.3. Sekcje
- 2.3.1. Sekcje .init i .fini
- 2.3.2. Sekcja .text
- 2.3.3. Sekcje .bss, .data i .rodata
- 2.3.4. Wiązanie leniwe symboli i sekcje .plt, .got oraz .got.plt
- 2.3.5. Sekcje .rel.* i .rela.*
- 2.3.6. Sekcja .dynamic
- 2.3.7. Sekcje .init_array i .fini_array
- 2.3.8. Sekcje .shstrtab, .symtab, .strttab, .dynsym i .dynstr
- 2.4. Nagłówki programów
- 2.4.1. Pole p_type
- 2.4.2. Pole p_flags
- 2.4.3. Pola p_offset, p_vaddr, p_paddr, p_filesz i p_memsz
- 2.4.4. Pole p_align
- 2.5. Podsumowanie
- 2.1. Nagłówek pliku
- 3. Format PE: krótkie wprowadzenie
- 3.1. Nagłówek MS-DOS i stub MS-DOS
- 3.2. Sygnatura, nagłówek i nagłówek opcjonalny pliku PE
- 3.2.1. Sygnatura pliku PE
- 3.2.2. Nagłówek pliku PE
- 3.2.3. Nagłówek opcjonalny pliku PE
- 3.3. Tablica nagłówków sekcji
- 3.4. Sekcje
- 3.4.1. Sekcje .edata i .idata
- 3.4.2. Wyrównywanie w sekcjach kodu PE
- 3.5. Podsumowanie
- 4. Tworzenie programu ładującego pliki binarne przy użyciu libbfd
- 4.1. Czym jest libbfd?
- 4.2. Prosty interfejs do ładowania plików binarnych
- 4.2.1. Klasa Binary
- 4.2.2. Klasa Section
- 4.2.3. Klasa Symbol
- 4.3. Implementacja loadera plików binarnych
- 4.3.1. Inicjalizacja libbfd i otwieranie pliku binarnego
- 4.3.2. Parsowanie podstawowych właściwości pliku binarnego
- 4.3.3. Ładowanie symboli
- 4.3.4. Ładowanie sekcji
- 4.4. Testowanie loadera binarnego
- 4.5. Podsumowanie
- 1. Anatomia pliku binarnego
- CZĘŚĆ II. PODSTAWY ANALIZY BINARNEJ
- 5. Podstawowa analiza binarna w Linuksie
- 5.1. Rozwiązywanie kryzysów tożsamości przy użyciu file
- 5.2. Użycie ldd do badania zależności
- 5.4. Parsowanie ekstrahowanego ELF za pomocą readelf
- 5.5. Parsowanie symboli za pomocą nm
- 5.6. Szukanie wskazówek za pomocą strings
- 5.7. Śledzenie wywołań systemowych i bibliotecznych za pomocą strace i ltrace
- 5.8. Badanie zachowań na poziomie instrukcji przy użyciu objdump
- 5.9. Zrzut dynamicznego bufora łańcucha za pomocą gdb
- 5.10. Podsumowanie
- 6. Deasemblacja i podstawy analizy binarnej
- 6.1. Deasemblacja statyczna
- 6.1.1. Deasemblacja liniowa
- 6.1.2. Deasemblacja rekurencyjna
- 6.2. Deasemblacja dynamiczna
- 6.2.1. Przykład: śledzenie wykonywania pliku binarnego za pomocą gdb
- 6.2.2. Strategie pokrycia kodu
- 6.3. Strukturyzacja deasemblowanego kodu i danych
- 6.3.1. Strukturyzowanie kodu
- 6.3.2. Strukturyzacja danych
- 6.3.3. Dekompilacja
- 6.3.4. Reprezentacje pośrednie
- 6.4. Podstawowe metody analizy
- 6.4.1. Własności analizy binarnej
- 6.4.2. Analiza przepływu sterowania
- 6.4.3. Analiza przepływu danych
- 6.5. Wpływ ustawień kompilatora na deasemblację
- 6.6. Podsumowanie
- 6.1. Deasemblacja statyczna
- 7. Proste metody wstrzykiwania kodu dla ELF
- 7.1. Najprostsze modyfikacje binarne przy użyciu edycji hex
- 7.1.1. Obserwowanie błędu off-by-one w akcji
- 7.1.2. Naprawienie błędu off-by-one
- 7.2. Modyfikacja zachowania biblioteki współdzielonej przy użyciu LD_PRELOAD
- 7.2.1. Zagrożenie przepełnieniem sterty
- 7.2.2. Wykrywanie przepełnienia sterty
- 7.3. Wstrzykiwanie sekcji kodu
- 7.3.1. Wstrzykiwanie sekcji ELF: przegląd wysokiego poziomu
- 7.3.2. Użycie elfinject do wstrzykiwania sekcji ELF
- 7.4. Wywołanie wstrzykniętego kodu
- 7.4.1. Modyfikacja adresu startowego
- 7.4.2. Przejęcie konstruktorów i destruktorów
- 7.4.3. Przejęcie wpisów w GOT
- 7.4.4. Przejęcie wpisów PLT
- 7.4.5. Przekierowanie wywołań bezpośrednich i pośrednich
- 7.5. Podsumowanie
- 7.1. Najprostsze modyfikacje binarne przy użyciu edycji hex
- 5. Podstawowa analiza binarna w Linuksie
- CZĘŚĆ III. ZAAWANSOWANA ANALIZA BINARNA
- 8. Dostosowywanie deasemblacji do potrzeb
- 8.1. Dlaczego pisać własny program do deasemblacji
- 8.1.1. Sprawa dla dostosowania deasemblacji: zaciemniony kod
- 8.1.2. Inne powody, by napisać dostosowany deasembler
- 8.2. Wprowadzenie do Capstonea
- 8.2.1. Instalacja Capstonea
- 8.2.2. Deasemblacja liniowa z Capstonea
- 8.2.3. Eksploracja API C Capstonea
- 8.2.4. Deasemblacja rekurencyjna z Capstone
- 8.3. Implementacja skanera gadżetów ROP
- 8.3.1. Wprowadzenie do programowania zorientowanego na powrót (ROP)
- 8.3.2. Wykrywanie gadżetów ROP
- 8.4. Podsumowanie
- 8.1. Dlaczego pisać własny program do deasemblacji
- 9. Instrumentacja binarna
- 9.1. Czym jest instrumentacja binarna?
- 9.1.1. API instrumentacji binarnej
- 9.1.2. Statyczna kontra dynamiczna instrumentacja binarna
- 9.2. Statyczna instrumentacja binarna
- 9.2.1. Podejście int 3
- 9.2.2. Podejście z użyciem trampolin
- 9.3. Dynamiczna instrumentacja binarna
- 9.3.1. Architektura systemu DBI
- 9.3.2. Wprowadzenie do Pin
- 9.4. Profilowanie za pomocą Pin
- 9.4.1. Struktury danych profilera i kod instalacyjny
- 9.4.2. Parsowanie symboli funkcji
- 9.4.3. Instrumentacja bloków podstawowych
- 9.4.4. Instrumentacja instrukcji przepływu sterowania
- 9.4.5. Liczenie instrukcji, transferów sterowania i wywołań systemowych
- 9.4.6. Testowanie profilera
- 9.5. Automatyczne rozpakowywanie plików binarnych z Pin
- 9.5.1. Wprowadzenie do programów pakujących
- 9.5.2. Struktury danych i kod instalacyjny programu rozpakowującego
- 9.5.3. Instrumentowanie zapisów do pamięci
- 9.5.4. Instrumentowanie instrukcji przepływu sterowania
- 9.5.5. Śledzenie zapisów do pamięci
- 9.5.6. Wykrywanie pierwotnego punktu wejścia i zrzucanie rozpakowanego pliku binarnego
- 9.5.7. Testowanie programu rozpakowującego
- 9.6. Podsumowanie
- 9.1. Czym jest instrumentacja binarna?
- 10. Zasady dynamicznej analizy taint
- 10.1. Czym jest DTA?
- 10.2. DTA w trzech krokach: źródła taint, taint sinks i propagacja taint
- 10.2.1. Definiowanie źródeł taint
- 10.2.2. Definiowanie taint sinks
- 10.2.3. Śledzenie propagacji taint
- 10.3. Użycie DTA do wykrycia błędu Heartbleed
- 10.3.1. Krótki przegląd podatności na Heartbleed
- 10.3.2. Wykrywanie Heartbleed przez taint
- 10.4. Czynniki w projektowaniu DTA: ziarnistość taint, kolory taint i zasady propagacji taint
- 10.4.1. Ziarnistość taint
- 10.4.2. Kolory taint
- 10.4.3. Zasady propagacji taint
- 10.4.4. Nadmierne i niedostateczne pokrycie taint
- 10.4.5. Zależności sterowania
- 10.4.6. Shadow memory
- 10.5. Podsumowanie
- 11. Praktyczna dynamiczna analiza taint z libdft
- 11.1. Wstęp do libdft
- 11.1.1. Organizacja wewnętrzna libdft
- 11.1.2. Zasady taint
- 11.2. Wykorzystanie DTA do wykrywania zdalnego przechwycenia sterowania
- 11.2.1. Sprawdzanie informacji o taint
- 11.2.2. Źródła taint: taintowanie otrzymywanych bajtów
- 11.2.3. Taint sinks: sprawdzanie argumentów execve
- 11.2.4. Wykrywanie próby przejęcia przepływu sterowania
- 11.3. Obejście DTA za pomocą przepływów niejawnych
- 11.4. Detektor eksfiltracji danych oparty na DTA
- 11.4.1. Źródła taint: śledzenie taint dla otwartych plików
- 11.4.2. Taint sinks: monitorowanie przesyłów sieciowych w poszukiwaniu eksfiltracji danych
- 11.4.3. Wykrywanie próby eksfiltracji danych
- 11.5. Podsumowanie
- 11.1. Wstęp do libdft
- 12. Podstawy wykonywania symbolicznego
- 12.1. Przegląd wykonywania symbolicznego
- 12.1.1. Wykonywanie symboliczne kontra konkretne
- 12.1.2. Rodzaje i ograniczenia wykonywania symbolicznego
- 12.1.3. Zwiększanie skalowalności wykonywania symbolicznego
- 12.2. Rozwiązywanie ograniczeń za pomocą Z3
- 12.2.1. Dowodzenie osiągalności instrukcji
- 12.2.2. Dowodzenie nieosiągalności instrukcji
- 12.2.3. Dowodzenie poprawności formuły
- 12.2.4. Upraszczanie wyrażeń
- 12.2.5. Modelowanie ograniczeń dla kodu maszynowego za pomocą wektorów bitowych
- 12.2.6. Rozwiązywanie nieprzejrzystego kodu warunkowego za pomocą wektorów bitowych
- 12.3. Podsumowanie
- 12.1. Przegląd wykonywania symbolicznego
- 13. Praktyczne wykonywanie symboliczne z Tritonem
- 13.1. Wprowadzenie do Tritona
- 13.2. Utrzymywanie stanu symbolicznego przy użyciu drzew składniowych (AST)
- 13.3. Slicing wsteczny z Tritonem
- 13.3.1. Pliki nagłówkowe i konfigurowanie Tritona
- 13.3.2. Plik konfiguracji symbolicznej
- 13.3.3. Emulowanie instrukcji
- 13.3.4. Konfigurowanie architektury Tritona
- 13.3.5. Obliczanie wycinka wstecznego
- 13.4. Wykorzystanie Tritona do zwiększenia pokrycia kodu
- 13.4.1. Tworzenie zmiennych symbolicznych
- 13.4.2. Znajdowanie modelu dla nowej ścieżki
- 13.4.3. Testowanie narzędzia pokrycia kodu
- 13.5. Automatyczna eksploitacja podatności
- 13.5.1. Podatny program
- 13.5.2. Znajdowanie adresu podatnego miejsca wywołania
- 13.5.3. Budowanie generatora exploita
- 13.5.4. Uzyskiwanie dostępu do powłoki administratora
- 13.6. Podsumowanie
- 8. Dostosowywanie deasemblacji do potrzeb
- CZĘŚĆ IV. DODATKI
- A. Błyskawiczny kurs asemblera x86
- A.1. Zarys programu w języku asemblera
- A.1.1. Instrukcje języka asemblera, dyrektywy, etykiety i komentarze
- A.1.2. Rozdzielenie kodu od danych
- A.1.3. Składnia AT and T i Intela
- A.2. Struktura instrukcji x86
- A.2.1. Reprezentacja instrukcji x86 na poziomie języka asemblera
- A.2.2. Instrukcje x86 na poziomie kodu maszynowego
- A.2.3. Operandy rejestru
- A.2.4. Operandy pamięci
- A.2.5. Operandy bezpośrednie
- A3. Częste instrukcje x86
- A.3.1. Porównywanie operandów i ustawianie flag stanu
- A.3.2. Implementacja wywołań systemowych
- A.3.3. Implementacja skoków warunkowych
- A.3.4. Ładowanie adresów pamięci
- A.4. Częste konstrukcje kodu w języku asemblera
- A.4.1. Stos
- A.4.2. Wywołania funkcji i ramki funkcji
- A.4.3. Instrukcje warunkowe
- A.4.4. Pętle
- A.1. Zarys programu w języku asemblera
- B. Implementacja nadpisywania PT_NOTE przy użyciu libelf
- B.1. Wymagane pliki nagłówkowe
- B.2. Struktury danych używane w elfinject
- B.3. Inicjalizacja libelf
- B.4. Uzyskiwanie nagłówka pliku wykonywalnego
- B.5. Znajdowanie segmentu PT_NOTE
- B.6. Wstrzykiwanie bajtów kodu
- B.7. Dopasowanie adresu ładowania dla wstrzykiwanej sekcji
- B.8. Nadpisanie nagłówka sekcji .note.ABI-tag
- B.9. Ustawienie nazwy dla wstrzykniętej sekcji
- B.10. Nadpisanie nagłówka programu PT_NOTE
- B.11. Modyfikacja adresu startowego
- C. Spis narzędzi analizy binarnej
- C.1. Deasemblery
- C.2. Debuggery
- C.3. Platformy deasemblerów
- C.4. Platformy analizy binarnej
- D. Dalsza lektura
- D.1. Standardy i źródła
- D.2. Artykuły i raporty techniczne
- D.3. Książki
- A. Błyskawiczny kurs asemblera x86
- O Autorze
- Przypisy