2013-07-11 4 views
6

Rozważmy następujący podatny kodu/program:Wykorzystanie przepełnienie ciąg oparte na x86-64 z NX (DEP) oraz ASLR włączona

#include <string.h> 

int main(int argc, char *argv[]) { 
    char buf[16]; 
    strcpy(buf, argv[1]); 

    return 0; 
} 

Na IA-32 (x86, 32-bit) z systemem Linux NX ASLR przyczyniłoby się to, że za pomocą wykorzystania GOT nadpisywanie techniki, który zasadniczo obejmuje następujące etapy:

  1. przepełnienie bufora aż ODP
  2. nadpisywania rip adres [email protected]
  3. Użyj czystego gadżetu z .text, np. pop edi ; pop ebp ; ret, jako adres zwrotny strcpy
  4. argumentów pisać dla strcpy: &bss -address jako cel i jeden bajt /bin/sh wykorzystaniem .text
  5. powtórz kroki 2-4 aż /bin/sh jest całkowicie zapisywane &bss
  6. nadpisywania GOT wjazdu od strcpy z system (używając przesunięcia, wymaga wiedzy na temat używanej wersji Libc - zignorujmy to tutaj)
  7. Napisz [email protected] na stosie, a następnie jakiś 4-bajtowy fragment i wreszcie adres &bss whi ch wskazuje /bin/sh
  8. Profit

chcę wykorzystać to na x86-64 z tych samych środków łagodzących włączone. Ale jest to trudniejsze, niż to sobie wyobrażaliśmy. Zasadniczo z następujących powodów:

  1. x86-64 rejestru opartego na konwencji wywołania: Argumenty funkcji są przekazywane za pomocą rejestrów, nie stos. Dlatego niektóre dodatkowe gadżety ROP są wymagane do przeniesienia argumentów ze stosu do odpowiedniego rejestru. Jest to niewielki problem, ale ma również wpływ następujący problem:
  2. 64-bitowy adres zwrotny: RIP w x86-64 wskazuje na .text, który nie ma nawet długości 32-bitów. Dlatego też NULL-bajty muszą być zapisane na stosie w celu wywołania funkcji łańcuchowych. Zasadniczo można zapisać tyle bajtów NULL, ile pożądane, przy użyciu przykutych wywołań do strcpy i korzystając z kończącego znaków NULL, strcpy zawsze zapisuje. Ale można tylko raz wywołać strcpy, tylko nadpisując najmniej znaczące bajty RIP-a.

    |0x00000000|  (most significant bytes) 
    |0x00deadbe| <- RIP (least significant bytes) 
    |0x41414141| 
    |0x41414141| <- SFP 
    | ... | 
    

Są to główne problemy dostałem z wykorzystanie programu na x86-64 z NX i ASLR włączona. Czy są jakieś techniki, które rozwiązują te problemy? Czy naprawdę x86-64 naprawdę uniemożliwia działanie, exploit otwierający powłoki?

+1

Jeśli RIP ma oznaczać adres zwrotny, potrzebujesz nowej terminologii dla x86-64. Tak jak EAX jest rozszerzony do RAX, EIP (aktualny Wskaźnik Instrukcji) jest rozszerzony do RIP. Tak więc w x86-64, RIP jest nazwą rejestru i sam nie tworzy dobrej nazwy dla adresu zwrotnego, który odczyta RET. –

Odpowiedz

0

x86-64 nie zapobiega tego typu exploitom. Zobacz ten tutorial.

+1

Ponieważ to pytanie zakłada x86-64 z włączonymi ASLR i NX, twój link nie zapewnia rozwiązania: "Musiałem oszukiwać na tym trochę, wyłączając ASLR. Z powodu natury adresowania na 64-bitowym systemy, bajty zerowe stają się naprawdę dużym problemem. W tym konkretnym wyzwaniu łatwo jest nadpisać RIP, ale mogłem powrócić do pojedynczego gadżetu z powodu pustych bajtów. " – Propantriol

Powiązane problemy