Spojrzenie na wykorzystanie luk w zabezpieczeniach

Ponieważ nie mogłem się doczekać dalszej dyskusji na ten temat, pozwól, że opowiem Ci trochę historii, teorii i praktyki w zakresie luk w zabezpieczeniach. Wszyscy już słyszeliśmy, że luki w zabezpieczeniach mogą dużo kosztować, wszyscy wiemy, że musimy aktualizować nasze oprogramowanie, wszyscy wiemy, że wiele aktualizacji jest spowodowanych błędami bezpieczeństwa. Ale dzisiaj opowiem wam trochę o tym, jak te błędy są wykrywane i wykorzystywane 🙂 Ale zanim to nastąpi, wyjaśnimy kilka szczegółów, aby uzyskać lepszy przegląd.

Zanim zaczniesz

Najpierw chcę wam powiedzieć, że skupimy się na pierwszej luce, którą nauczyłem się wykorzystywać, znanej Przepełnienia bufora, w tej luce wykorzystujemy brak weryfikacji w pamięci do robienia fajnych rzeczy 🙂 Ale wyjaśnijmy trochę więcej na ten temat.

To nie będzie prawdziwy scenariusz

Nie mogę pozwolić sobie na nauczenie ich łamania dowolnego programu, który widzą - po pierwsze, ponieważ jest to niebezpieczne dla ich komputerów, po drugie, ponieważ wymagałoby to więcej niż mój zwykły limit słów.

Wyruszamy w podróż do lat 80-tych

To, co Wam pokażę, mogę zrobić na swoim laptopie, ale nie oznacza to, że dziś da się to zrobić w prosty sposób 🙂 wiele z tych koncepcji zostało już wykorzystanych tyle razy, że nowe metody ochrony i nowe metody ominięcia pojawiły się 😛 ale to przenosi nas w to samo miejsce, nie ma miejsca, żeby to wszystko opowiedzieć 🙂

Może nie działać na twoim procesorze

Chociaż posłużę się bardzo prostym przykładem, chcę, aby od początku było jasne, że szczegółów tego jest tak wiele i tak różnorodnych, że tak jak może wyjść to samo co ja, jeśli chcesz tego spróbować , pożądany efekt też może nie zostać osiągnięty 🙂 Ale możesz sobie wyobrazić, że nie potrafię tego wyjaśnić w tej przestrzeni, tym bardziej, że tym wstępem zajęłam już ponad 300 słów, więc od razu przechodzimy do sedna.

Co to jest Przepełnienie bufora

Aby odpowiedzieć na to pytanie, musimy najpierw zrozumieć pierwszą połowę tej kombinacji.

Bufory

Ponieważ wszystko dotyczy pamięci w komputerze, logiczne jest, że musi istnieć jakiś rodzaj pojemnika na informacje. Kiedy rozmawiamy o Wejścia Wyjścia, dochodzimy bezpośrednio do koncepcji bufory. Krótko mówiąc, a bufor Jest to przestrzeń pamięci o określonym rozmiarze, w której będziemy przechowywać pewną ilość informacji, prosta 🙂

Jak sama nazwa wskazuje, przepełnienia występują, gdy bufor zapełnia się większą ilością informacji, niż może obsłużyć. Ale dlaczego jest to ważne?

Stos

Znane również jako stosy, są abstrakcyjnym typem danych, w którym możemy stos informacji, ich główną cechą jest to, że mają uporządkowanie LIFO (ostatnie weszło, pierwsze wyszło). Pomyślmy przez chwilę o stosie talerzy, kładziemy je na wierzchu jeden po drugim, a następnie wyjmujemy je jeden po drugim od góry, to sprawia, że ​​ostatnia płyta, którą włożyliśmy (ta, która jest na górze) jest pierwszą. które mamy zamiar wyjąć, oczywiście jeśli możemy wyjąć tylko jeden talerz naraz i zdecydujemy się to zrobić w takiej kolejności: P.

Teraz, gdy znasz te dwa pojęcia, musimy je uporządkować. Stosy są ważne, ponieważ każdy uruchamiany przez nas program ma swój własny stos wykonania. Ale ten stos ma szczególna cecharośnie. Jedyną rzeczą, którą musisz o tym wiedzieć, jest to, że podczas działania programu, gdy wywoływana jest funkcja, stos przechodzi od liczby X w pamięci do liczby (Xn). Ale aby kontynuować, musimy zrozumieć jeszcze jedną koncepcję.

Wskaźniki

Jest to koncepcja, która doprowadza wielu programistów do szaleństwa, kiedy zaczynają w świecie C, w rzeczywistości ogromna moc programowania w C wynika częściowo z użycia wskaźników. Mówiąc prosto, wskaźnik wskazuje na adres pamięci. Brzmi to skomplikowanie, ale nie jest skomplikowane, wszyscy mamy pamięć RAM w naszych maszynach, prawda? Cóż, można to zdefiniować jako plik kolejne ułożenie blokówlokalizacje te są zwykle wyrażane w liczbach szesnastkowych (od 0 do 9, a następnie od A do F, na przykład 0x0, 0x1, 0x6, 0xA, 0xF, 0x10). Tutaj jako ciekawostka, 0x10 NIE jest równe 10 😛, jeśli zamienimy to na porządek dziesiętny, to będzie to samo, co powiedzenie 15. To jest coś, co również wprowadza zamieszanie w więcej niż jeden na początku, ale przejdźmy do tego.

Dokumentacja

Procesory współpracują z wieloma plikami registros, które działają w celu przesyłania lokalizacji z pamięci fizycznej do procesora, dla architektur używających 64-bitów liczba rejestrów jest duża i trudna do opisania tutaj, ale żeby się zorientować, rejestry są jak wskaźniki, wskazują między innymi rzeczy, przestrzeń pamięci (lokalizacja).

Teraz ćwicz

Wiem, że do tej pory było dużo informacji do przetworzenia, ale w rzeczywistości są to dość złożone kwestie, które staram się wyjaśnić w bardzo prosty sposób, zobaczymy mały program, który używa buforów i zamierzamy przerwij to, aby zrozumieć to o przepełnieniach, oczywiście ten nie jest. To jest prawdziwy program i zamierzamy „ominąć” wiele środków zaradczych, które są dziś używane, tylko po to, aby pokazać, jak to było zrobione wcześniej 🙂 i ponieważ niektóre z nich zasady są niezbędne, aby móc uczyć się bardziej złożonych rzeczy 😉

GDB

Świetny program, który jest niewątpliwie jednym z najczęściej używanych przez programistów C. Wśród jego wielu zalet jest to, że pozwala nam zobaczyć to wszystko, o czym do tej pory rozmawialiśmy, rejestry, stos, bufory itp. 🙂 Zobaczmy program, którego użyjemy w naszym przykładzie.

retinput.c

Posiadać. Christopher Diaz Riveros

Jest to dość prosty program, będziemy korzystać z biblioteki stdio.h aby móc uzyskać informacje i wyświetlić je w terminalu. Widzimy funkcję o nazwie return_input który generuje plik bufor nazywa szyk, który ma długość 30 bajtów (typ danych char ma długość 1 bajtu).

Funkcja gets(array); żądaj informacji według konsoli i funkcji printf() zwraca zawartość tablicy i wyświetla ją na ekranie.

Każdy program napisany w C zaczyna się od funkcji main(), to będzie odpowiedzialne tylko za wywołanie return_input, teraz skompilujemy program.

Posiadać. Christopher Diaz Riveros

Przyjrzyjmy się trochę temu, co właśnie zrobiłem. Opcja -ggdb mówi gcc, aby skompilował program z informacjami dla gdb, aby mógł poprawnie debugować. -fno-stack-protector Jest to opcja, której oczywiście nie powinniśmy używać, ale której zamierzamy użyć, ponieważ w przeciwnym razie byłoby możliwe wygenerowanie przepełnienia bufora w stosie. W końcu przetestowałem wynik. ./a.out po prostu uruchamia to, co właśnie skompilowałem, prosi o informacje i zwraca je. Bieganie 🙂

Ostrzeżenia

Kolejna uwaga tutaj. Czy widzisz ostrzeżenia? oczywiście jest to coś, co należy wziąć pod uwagę podczas pracy z kodem lub kompilacją, jest to trochę oczywiste i niewiele jest programów, które dziś mają tę funkcję gets() W kodzie. Jedną z zalet Gentoo jest to, że kompilując każdy program, widzę, co może być nie tak, „idealny” program nie powinien ich mieć, ale zdziwiłbyś się, jak wiele dużych programów ma te ostrzeżenia, ponieważ są one po prostu BARDZO duże i trudno je śledzić. niebezpieczne funkcje, gdy występuje jednocześnie wiele ostrzeżeń. Teraz, jeśli będziemy kontynuować

Debugowanie programu

Posiadać. Christopher Diaz Riveros

Teraz ta część może być trochę zagmatwana, ale skoro już wystarczająco napisałem, nie mogę sobie pozwolić na wyjaśnienie wszystkiego, więc przepraszam, jeśli widzisz, że jadę za szybko 🙂

Rozbrajanie kodu

Zacznijmy od spojrzenia na nasz skompilowany program w języku maszynowym.

Posiadać. Christopher Diaz Riveros

To jest kod naszej głównej funkcji w programie Montaż, to właśnie rozumie nasz procesor, wiersz po lewej stronie to fizyczny adres w pamięci, plik <+ n> jest znany jako offset, w zasadzie odległość od początku funkcji (głównej) do tej instrukcji (znanej jako opcode). Następnie widzimy typ instrukcji (push / mov / callq…) i jeden lub więcej rejestrów. Podsumowując, możemy powiedzieć, że jest to wskazanie, po którym następuje źródło / pochodzenie i przeznaczenie. <return_input> odnosi się do naszej drugiej funkcji, spójrzmy.

return_input

Posiadać. Christopher Diaz Riveros

Jest to trochę bardziej złożone, ale chcę tylko, abyś sprawdził kilka rzeczy. Jest tam tag o nazwie <gets@plt> i wywołano ostatni kod operacji retq wskazujący koniec funkcji. Zamierzamy wstawić kilka punktów przerwania, jeden w funkcji gets i inny w retq.

Posiadać. Christopher Diaz Riveros

run

Teraz uruchomimy program, aby zobaczyć, jak zaczyna się akcja.

Posiadać. Christopher Diaz Riveros

Widzimy, że pojawia się mała strzałka wskazująca kod operacji, w którym jesteśmy, chcę, aby wzięli pod uwagę kierunek 0x000055555555469b, to jest adres po wezwaniu return_input w funkcji main , jest to ważne, ponieważ w tym miejscu program powinien powrócić po zakończeniu odbierania pliku wkład, przejdźmy do funkcji. Teraz sprawdzimy pamięć przed wejściem do funkcji gets.

Posiadać. Christopher Diaz Riveros

Utworzyłem dla ciebie kopię zapasową funkcji głównej i wyróżniłem kod, do którego się odnosiłem, jak widać, ze względu na endianizm został podzielony na dwa segmenty, chcę, abyś wziął pod uwagę kierunek 0x7fffffffdbf0 (pierwszy od lewej za komandosem x/20x $rsp) ponieważ jest to lokalizacja, której musimy użyć do sprawdzenia wyniku pobierania, kontynuujmy:

Łamanie programu

Posiadać. Christopher Diaz Riveros

Podkreśliłem je 0x44444444ponieważ reprezentują nasze Ds s teraz zaczęliśmy dodawać wkład do programu i jak widać, od naszego żądanego adresu dzieli nas tylko dwie linijki, będziemy go wypełniać, aż znajdziemy się tuż przed adresami, które zaznaczyliśmy w poprzednim kroku.

Zmiana ścieżki powrotu

Teraz, gdy udało nam się wejść do tej sekcji kodu, w której wskazuje on powrót funkcji, zobaczmy, co się stanie, jeśli zmienimy adres 🙂 zamiast iść do lokalizacji kodu operacyjnego, który jest zgodny z tym, który mieliśmy przed chwilą, co myślisz jeśli wrócimy do return_input? Ale do tego konieczne jest zapisanie adresu, który chcemy, w postaci binarnej, zrobimy to za pomocą funkcji printf od bash 🙂

Posiadać. Christopher Diaz Riveros

Teraz otrzymaliśmy tę informację dwukrotnie - zapewne program nie był do tego stworzony, ale udało nam się złamać kod i sprawić, by powtórzył coś, czego nie powinien.

Refleksje

Tę prostą zmianę można uznać za wykorzystać bardzo podstawowy managed udało mu się przerwać program i zrobić coś, na co go chcemy.

To tylko pierwszy krok na prawie nieskończonej liście rzeczy do zobaczenia i dodania, są sposoby, aby dodać więcej rzeczy niż zwykłe powtarzanie zamówienia, ale tym razem dużo napisałem i wszystko, co dotyczy kodowanie szelek To temat do pisania więcej niż artykułów, powiedziałbym, że całe książki. Przepraszam, jeśli nie udało mi się zagłębić trochę więcej w tematy, które bym mi się spodobały, ale na pewno będzie okazja 🙂 Pozdrawiam i dziękuję za przybycie.


14 komentarzy, zostaw swoje

Zostaw swój komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

*

*

  1. Odpowiedzialny za dane: Miguel Ángel Gatón
  2. Cel danych: kontrola spamu, zarządzanie komentarzami.
  3. Legitymacja: Twoja zgoda
  4. Przekazywanie danych: Dane nie będą przekazywane stronom trzecim, z wyjątkiem obowiązku prawnego.
  5. Przechowywanie danych: baza danych hostowana przez Occentus Networks (UE)
  6. Prawa: w dowolnym momencie możesz ograniczyć, odzyskać i usunąć swoje dane.

  1.   2p2 powiedział

    Bądź bardziej bezpośredni. Pisz mniej i skup się na tym, co ważne

    1.    ChrisADR powiedział

      Cześć, dzięki za komentarz.

      Prawdę mówiąc, wyciąłem sporą część pomysłów, ale mimo to wydawało mi się, że zostawiłem minimum, aby ktoś, kto nie ma wiedzy programistycznej, mógł wpaść na pomysł.

      pozdrowienia

      1.    anonimowy powiedział

        Problem w tym, że ci, którzy nie mają wiedzy programistycznej, niczego się nie dowiedzą, ponieważ jest to zbyt skomplikowane, aby zacząć od tego, ale ci, którzy potrafią programować, cenią sobie bycie bardziej bezpośrednim.

        Myślę, że nie możesz dotrzeć do wszystkich, musisz wybrać, aw tym przypadku zgrzeszyłeś, chcąc dużo ukryć.

        Nawiasem mówiąc, jako konstruktywną krytykę mówię, że uwielbiam te tematy i chciałbym, abyś kontynuował pisanie artykułów, gratuluję!

    2.    anonimowy powiedział

      Myślę, że to samo.

      1.    ChrisADR powiedział

        Bardzo dziękuję obojgu !! na pewno trudno jest zrozumieć, jak dotrzeć do grupy docelowej, gdy prawda jest taka, że ​​liczba osób z zaawansowanym poziomem programowania, które czytają te artykuły jest niewielka (przynajmniej można to wywnioskować na podstawie komentarzy)

        Z pewnością zgrzeszyłem, chcąc uprościć coś, co wymaga szerokiej bazy wiedzy, aby je zrozumieć. Mam nadzieję, że rozumiesz, że kiedy dopiero zaczynam blogowanie, nie odkryłem jeszcze dokładnego punktu, w którym moi czytelnicy wiedzą i rozumieją, co mówię. To znacznie ułatwiłoby powiedzenie prawdy 🙂

        Postaram się być krótszy, kiedy to się opłaca, bez depersonalizacji formatu, ponieważ oddzielenie sposobu pisania od treści jest nieco bardziej skomplikowane niż można by sobie wyobrazić, przynajmniej mam je dość powiązane, ale przypuszczam, że ostatecznie będę mógł dodać linie zamiast wycinania treści.

        pozdrowienia

  2.   Mario powiedział

    Gdzie możesz dowiedzieć się więcej na ten temat? Jakaś polecana książka?

    1.    ChrisADR powiedział

      Przykład został zaczerpnięty z podręcznika The Shellcoder's Handbook autorstwa Chrisa Anleya, Johna Heasmana, Felixa Lindera i Gerardo Richarte, ale aby wykonać tłumaczenie 64-bitowe, musiałem poznać moją architekturę, podręcznik programisty Intel, tomy 2 i 3 są całkiem wiarygodne źródło tego. Dobrze jest również przeczytać dokumentację GDB, która jest dostarczana z poleceniem 'info gdb', Aby nauczyć się asemblera i C jest wiele bardzo dobrych książek, z wyjątkiem tego, że książki Assembly są trochę stare, więc istnieje luka do wypełnienia innym typem dokumentacja.

      Sam szelkod nie jest już tak skuteczny w dzisiejszych czasach z różnych powodów, ale nadal interesujące jest poznanie nowych technik.

      Mam nadzieję, że to trochę pomoże 🙂 Pozdrowienia

  3.   Franz powiedział

    Buen artículo, el viejo blog desdelinux ha vuelto a renacer =)
    Kiedy mówisz, że zdalna powłoka nie jest tak skuteczna, masz na myśli środki zaradcze mające na celu złagodzenie ataków, nazywają to ofensywnymi zabezpieczeniami.
    Pozdrawiam i tak trzymaj

    1.    ChrisADR powiedział

      Dziękuję bardzo Franz - bardzo miłe słowa, właściwie miałem na myśli, że dzisiejsze kodowanie powłoki jest znacznie bardziej złożone niż to, co tutaj widzimy. Mamy ASLR (generator losowych lokalizacji pamięci), ochronę stosu, różne środki i środki zaradcze, które ograniczają liczbę rozkazów, które można wstrzyknąć do programu, a to dopiero początek.

      Pozdrawiam,

  4.   wolne oprogramowanie powiedział

    Witam, czy zrobisz kolejną część rozszerzającą temat? To interesujące

    1.    ChrisADR powiedział

      Witam, temat jest z pewnością dość interesujący, ale poziom złożoności, który byśmy przyjęli, stałby się bardzo wysoki, prawdopodobnie obejmując dużą liczbę postów, aby wyjaśnić różne warunki wstępne zrozumienia drugiego. Pewnie o tym napiszę, ale nie będą to kolejne posty, chciałbym napisać kilka tematów zanim przejdę dalej.

      Pozdrowienia i dzięki za udostępnienie

  5.   kaktus powiedział

    Bardzo dobrze! Piszesz świetne posty! Jedno pytanie. Zaczynam kwestię bezpieczeństwa IT od przeczytania książki zatytułowanej „Zapewnianie bezpieczeństwa za pomocą testów piórem”. Czy ta książka jest zalecana? Jak sugerujesz, abym zaczął dociekać w tych sprawach?

    1.    ChrisADR powiedział

      Witaj kaktusie, to cały wszechświat o podatnościach i innych, prawdę mówiąc, wiele zależy od tego, co przykuwa Twoją uwagę, a jakie masz potrzeby, menedżer IT nie musi wiedzieć tego samego co pen-tester, Albo badacz luk w zabezpieczeniach lub analityk sądowy, zespół odzyskiwania po awarii ma zupełnie inny zestaw umiejętności. Oczywiście każdy z nich wymaga innego poziomu wiedzy technicznej, polecam zacząć odkrywać dokładnie to, co lubisz i zacząć pochłaniać książki, artykuły i inne, a co najważniejsze przećwiczyć wszystko, co przeczytasz, nawet jeśli jest nieaktualne , to w końcu coś zmieni.
      Pozdrawiam,

  6.   Eizen powiedział

    Hey.
    Dziękuję bardzo za wyjaśnienie tego tematu, a także za komentarz, że dla dodatkowych informacji mamy „Podręcznik Szelkodera”. Mam już oczekujące czytanie 😉