close

Kod powłoki

Skocz do nawigacji Skocz do wyszukiwania

W informatyce szelkod to program w języku asemblera , który tradycyjnie uruchamia powłokę , taką jak powłoka uniksowa '/bin/sh' lub powłoka command.com w systemach operacyjnych DOS i Microsoft Windows . Szelkod może zostać wykorzystany do wykorzystania błędu poprzez exploita , umożliwiając hakerowi lub crackerowi uzyskanie dostępu do wiersza poleceń komputera lub , bardziej ogólnie, wykonanie dowolnego kodu .

Opis

Rodzaje kodu powłoki

Istnieją dwa różne rodzaje szelkodu, lokalny i zdalny. Rozróżnienie zależy od rodzaju kontroli, jaką zapewnia wykonanie szelkodu na maszynie docelowej, która może być lokalna lub zdalna (jeśli odbywa się przez sieć).

Lokalny

Lokalny szelkod jest używany przez atakującego, który ma ograniczony dostęp do maszyny, ale wykorzystując lukę w procesie o wyższych uprawnieniach, na przykład przepełnienie bufora, może uzyskać te same uprawnienia, jeśli wykonanie szelkodu powiedzie się.

Zdalny

Zdalny szelkod jest używany zamiast tego, gdy atakujący chce wykorzystać lukę w procesie innej maszyny w sieci lokalnej lub intranecie. Jeśli Shellcode jest wykonywany poprawnie, zwraca kontrolę nad maszyną docelową przez sieć. Zdalne kody powłoki zwykle używają standardowego gniazda TCP/IP , aby umożliwić dostęp do powłoki komputera docelowego. Dalsze rozróżnienia można sklasyfikować według metody, za pomocą której ustanawiane jest połączenie. Jeśli to sam szelkod może nawiązać połączenie, nazywa się to „odwróconą powłoką” lub szelkodem typu connect-back , ponieważ kod powłoki działający na zdalnej maszynie łączy się z maszyną atakującego. Jeśli, z drugiej strony, atakujący musi utworzyć połączenie, szelkod nazywa się bindshell , ponieważ szelkod wiąże się z określonym portem, który będzie używany przez atakującego do połączenia się i kontrolowania docelowej maszyny. Trzecim, mniej popularnym typem szelkodu jest szelkod z ponownym użyciem gniazd . Ten typ szelkodu jest zwykle używany, gdy exploit nawiązuje połączenie z podatnym procesem, które nie jest zamykane przed wykonaniem szelkodu. Shellcode może ponownie wykorzystać to połączenie do komunikacji z atakującym. Ponowne użycie szelkodu Socket jest bardziej skomplikowane do zaimplementowania, ponieważ kod szelkowy musi identyfikować połączenie, z którego może korzystać (wśród możliwych połączeń otwartych na komputerze). [1] Zapora ogniowa może być używana do identyfikowania połączeń wychodzących nawiązywanych przez szelkod typu connect-back i próby połączenia przychodzącego z bindshella. Zapora może zapewnić dodatkową ochronę przed atakującym, nawet jeśli system jest podatny na ataki, zapobiegawczo uniemożliwiając dostęp do powłoki utworzonej przez wykonanie szelkodu. Jest to jeden z powodów, dla których czasami używane jest gniazdo ponownie wykorzystujące szelkod, ponieważ nietworzenie nowych połączeń jest trudniejsze do zidentyfikowania i zablokowania.

Pobierz i wykonaj

Pobierz i wykonaj to rodzaj zdalnego szelkodu, który wykonuje pobieranie i uruchamia jakąś formę złośliwego oprogramowania w systemie docelowym. Ten typ szelkodu nie tworzy powłoki, ale nakazuje maszynie pobranie określonego pliku wykonywalnego z sieci, zapisanie go na dysku, a następnie jego uruchomienie. Obecnie jest powszechnie stosowany w atakach drive-by download , gdy ofiara odwiedza złośliwą witrynę, która próbuje zainicjować pobieranie i wykonać kod powłoki w celu zainstalowania oprogramowania na zaatakowanej maszynie. Odmianą tego typu szelkodu jest „pobierz i ładuje bibliotekę”. [2] [3] Zaletą tej techniki jest to, że kod szelkodu może być mniejszy, nie wymaga tworzenia nowego procesu na maszynie docelowej oraz że szelkod nie musi implementować kodu do czyszczenia docelowego process , ale można to zrobić z biblioteki załadowanej do procesu.

Inscenizowane

Gdy ilość danych, które osoba atakująca może wstrzyknąć do procesu docelowego, jest zbyt mała, aby kod powłoki mógł działać poprawnie, można go uruchomić etapami. Najpierw wykonywany jest mały fragment kodu powłoki (etap 1). Ten kod zrzuca większy fragment kodu powłoki (faza 2) do pamięci procesu i uruchamia go.

Polowanie na jajka

Polowanie na jajka to kolejny rodzaj stopniowego szyldu. Jest używany, gdy atakujący ma możliwość wstawienia dużego szelkodu do procesu, ale nie może określić, gdzie w pamięci zostanie umieszczony. Następnie do procesu wprowadza się małe polowanie na jajka w przewidywalnej lokalizacji, a następnie wykonywane. Kod przeszukuje przestrzeń pamięci w poszukiwaniu większego kodu powłoki (jajka) i wykonuje go.

Omlet

Ten rodzaj szelkodu jest podobny do polowania na jajka, ale wyszukuje mniejsze bloki (jajka) i ponownie łączy je w większy (omlet), który jest następnie wykonywany. Ta technika jest stosowana, gdy atakujący z jakiegoś powodu jest ograniczony do wstawiania do procesu małych bloków danych. [4]

Operacja

Strategia wykonywania kodu Shellcode

Exploit często umieszcza szelkod w docelowym procesie przed lub w tym samym czasie, w którym pojawia się exploit, aby przejąć kontrolę nad licznikiem programu . Licznik programu jest skierowany do wskazywania szelkodu do wykonania. Wstrzykiwanie szelkodu często odbywa się poprzez przechowywanie kodu w danych przesyłanych przez sieć do podatnego procesu, udostępniając go w pliku, który jest odczytywany przez proces lub poprzez wiersz poleceń lub zmienne środowiskowe w przypadku lokalnych exploitów.

Kodowanie Shellcode

Ponieważ wiele procesów filtruje lub ogranicza dane, które można wprowadzić, często szelkod musi zostać napisany, aby przezwyciężyć te ograniczenia, czyniąc kod małym, wolnym od zer lub znaków alfanumerycznych. Znaleziono kilka rozwiązań pozwalających na obejście tych ograniczeń:

  • Optymalizacje projektu i implementacji w celu zmniejszenia rozmiaru kodu powłoki.
  • Zmiany implementacyjne mające na celu obejście ograniczeń w zakresie bajtów używanych w szelkodzie.
  • Samomodyfikujący się kod , który modyfikuje liczbę bajtów swojego kodu przed ich wykonaniem w celu odtworzenia bajtów, których normalnie nie można wstawić do procesu.

Ponieważ narzędzia do wykrywania włamań mogą identyfikować sygnatury prostych szelkodów wysyłanych przez sieć, są one szyfrowane i automatycznie deszyfrowane lub polimorficzne , aby uniknąć rozpoznania.

Kodowanie procentowe

Wykorzystuje przeglądarki kierujące do kierowania zwykle kodują szelkod w ciągu JavaScript za pomocą kodowania procentowego lub notacji z kodowaniem adresu URL, stosując znak ucieczki „\ uXXXX” lub używając jednostki . Niektóre exploity dodatkowo zaciemniają zakodowany ciągiem kod powłoki, aby uniknąć wykrycia przez narzędzia IDS . Na przykład w architekturze IA-32 dwie (bez operacji) instrukcje NOPmają tę formę przed zakodowaniem.

90 NOP
90 NOP

Są zakodowane w ciągu znaków z kodowaniem procentowym. (przy użyciu metody unescape() do dekodowania)

unescape ("% u9090");

Jest on następnie zakodowany w notacji „\ uXXXX”:

"\ u9090";

I wreszcie w kodowaniu encji.

"& # x9090;"

lub

"& # 37008;"

Shellcode Null-Free

Wiele szelkodów jest pisanych bez użycia null bytes , ponieważ są one przeznaczone do wstawiania do procesu docelowego za pomocą łańcucha zakończonego znakiem null. Po skopiowaniu ciągu zakończonego znakiem null kopia będzie zawierać pierwszy znak null , ale kolejne bajty nie zostaną przetworzone. Gdy kod szelkodu zawierający wartość null zostanie wprowadzony w ten sposób, tylko część kodu szelkoda zostanie wstawiona, co uniemożliwi jego późniejsze wykonanie. Aby utworzyć szelkod wolny od wartości null , rozpoczynający się od jednego, który zawiera bajty null, instrukcje maszynowe zawierające zera można zastąpić instrukcjami, które dają ten sam efekt, ale nie zawierają bajtów null. Na przykład na architekturze IA-32 to zastąpienie może być wykonane:

B8 01000000     MOV EAX, 1 // Ustaw rejestr EAX na 0x000000001

ta instrukcja zawiera zera jako część literału (1 jest interpretowana jako 0x000000001) z następującymi instrukcjami:

33C0            XOR EAX, EAX // Ustaw rejestr EAX na 0x000000000
40              INC EAX // Zwiększ wartość EAX do 0x00000001

które mają ten sam efekt, ale wymagają mniejszej liczby bajtów do kodowania i są wolne od bajtów zerowych.

Szereg kodów alfanumerycznych i drukowalnych

W pewnych okolicznościach proces docelowy może odfiltrować wszystkie bajty z wprowadzonego kodu powłoki, które nie są drukowane lub alfanumeryczne. W tych warunkach zakres instrukcji, których można użyć do napisania szelkodu, staje się bardzo ograniczony. Rozwiązanie tego problemu opublikował Rix w Phrack 57 [5] , gdzie pokazano, jak można przekonwertować dowolny rodzaj kodu na kod alfanumeryczny. Szeroko stosowaną techniką jest tworzenie samomodyfikującego się kodu, ponieważ pozwala to kodowi na modyfikowanie własnych bajtów w celu włączenia innych, które nie są uwzględnione wśród dozwolonych, oraz poszerzenia zakresu użytecznych instrukcji. Za pomocą tego rodzaju sztuczki samomodyfikujący się dekoder można początkowo utworzyć przy użyciu tylko bajtów z dopuszczalnego zakresu. Kiedy wychodzący szelkod zaczyna działać, dekoder może zmodyfikować swój kod, aby móc użyć dowolnej wymaganej instrukcji, aby umożliwić mu prawidłowe działanie i jednocześnie kontynuować dekodowanie oryginalnego szelkodu. Po wykonaniu dekodowania dekoder przekazuje kontrolę do szelkodu, aby mógł działać normalnie. Pokazano, w jaki sposób możliwe jest tworzenie szelkodów o dowolnej złożoności, które przypominają normalny tekst w języku angielskim. [6]

Shellcode odporny na znaki Unicode

Wiele nowoczesnych programów używa kodowania ciągów formatu Unicode, aby umożliwić internalizację tekstu. Często te programy konwertują wejściowe ciągi ASCII przed ich przetworzeniem. Ciągi Unicode zakodowane w UTF-16 używają dwóch bajtów do dekodowania każdego znaku (lub czterech bajtów dla niektórych znaków specjalnych). Gdy ciąg ASCII jest konwertowany na UTF-16, bajt zerowy jest wstawiany po każdym bajcie oryginalnego ciągu. Obscu pokazał w Phrack 61 [7] , że możliwe jest napisanie szelkodów, które mogą działać poprawnie nawet po tej transformacji. Istnieją programy, które mogą automatycznie zmienić każdy szelkod na kod zakodowany w UTF-16 i działają na tej samej zasadzie, co samomodyfikujący się dekoder, który dekoduje oryginalny szelkod.

Platformy

Wiele szelkodów jest pisanych w kodzie maszynowym ze względu na niski poziom, na którym można wykorzystać lukę. Shellcode jest często tworzony w celu ataku na określoną kombinację procesora, systemu operacyjnego i dodatku Service Pack, które są powszechnie określane jako platforma. W przypadku niektórych exploitów, ze względu na ograniczenia narzucone przez proces docelowy, konieczne jest stworzenie określonego szelkodu. Jednak nie zawsze jest możliwe, aby szelocde działał dla wielu exploitów, dodatków Service Pack, systemów operacyjnych i prawdopodobnie procesorów. [8] Wszechstronność można zapewnić, tworząc różne wersje szelkodu, w oparciu o różne platformy, które mają być zaatakowane, i tworząc nagłówek, który identyfikuje poprawną wersję dla używanej platformy. Po wykonaniu kod zachowuje się różnie w zależności od platformy i jest w stanie wykonać poprawną wersję szelkodu.

Notatki

  1. ^ BHA, Shellcode / Socket-reuse , na blackhatlibrary.net , 6 czerwca 2013 . Źródło 7 czerwca 2013 .
  2. ^ SkyLined, Download i LoadLibrary wydany na skypher.com 11 stycznia 2010. Pobrano 19 stycznia 2010 (archiwum z 23 stycznia 2010) .
  3. ^ SkyLined, Download and LoadLibrary shellcode dla x86 Windows , na code.google.com , 11 stycznia 2010 . Źródło 19 stycznia 2010 .
  4. ^ SkyLined, w32 SEH omlet shellcode , na skypher.com , 16 marca 2009. Pobrano 19 marca 2009 (zarchiwizowane z 23 marca 2009) .
  5. ^ Rix, Pisanie ia32 alfanumerycznych kodów szelek , phrack.org , Phrack , 8 listopada 2001 . Źródło 29 lutego 2008 .
  6. ^ Joshua Mason, Small, Sam, Monrose, Fabian i MacManus, Greg, angielski Shellcode ( PDF ), cs.jhu.edu , listopad 2009 . Źródło 10 stycznia 2010 .
  7. ^ Obscou, Building IA32 Shellcodes „Unicode-Proof” , phrack.org , Phrack , 13 sierpnia 2003 . Źródło 29 lutego 2008 .
  8. ^ Eugene, Architecture Spanning Shellcode , phrack.org , Phrack , 11 sierpnia 2001 . Źródło 29 lutego 2008 .

Powiązane pozycje

Linki zewnętrzne