Odpowiedzi:
Ochrona stosu jest wykonywana przez kompilator (dodaj dodatkowe dane do stosu i ukryj niektóre podczas połączenia, sprawdź zdrowie psychiczne po powrocie). Nie można tego wyłączyć bez ponownej kompilacji. To część tego, naprawdę ...
Aby rozwinąć to, co powiedział vonbrand (poprawnie +1), ochrona stosu Linuksa składa się z dwóch części.
Kanarki stosowe to wymuszona przez kompilator funkcja, o której mówi vonbrand. Nie można ich wyłączyć bez ponownej kompilacji.
Aby to sobie udowodnić i zobaczyć, jak działają, pobierz następujący kod:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
int mybadfunction(char* a_bad_idea)
{
char what[100];
strcpy(what, a_bad_idea);
printf("You passed %s\n", what);
}
int main(int argc, char** argv)
{
printf("Tralalalaala\n");
mybadfunction(argv[1]);
}
Teraz skompiluj to ( gcc -fstack-protector -masm=intel -S test.c
) w coś gnu, co chętnie skompletuje i przeczyta wynik. Ważną kwestią jest to, że przy wyjściu z mybadfunction
funkcji jest ten mały fragment kodu:
mov edx, DWORD PTR [ebp-12]
xor edx, DWORD PTR gs:20
je .L2
call __stack_chk_fail
Jak można się domyślić, bierze się plik cookie stosu [ebp-12]
i porównuje go z wartością at gs:20
. Nie pasuje Następnie wywołuje funkcję __stack_chk_fail
w glibc, która zabija twój program właśnie tam.
Istnieją sposoby na obejście tego w zakresie pisania exploitów, ale najłatwiejszym sposobem na zbudowanie testowego kodu powłoki jest kompilacja programu -fno-stack-protector
.
Istnieje kilka innych uwag na temat nowoczesnych systemów Linux. Jeśli weźmiesz zwykły kod testowy powłoki:
char buffer[] = {...};
typedef void (* func)(void);
int main(int argc, char** argv)
{
func f = (func) buffer;
f();
return 0;
}
nowoczesny GCC / Linux zamapuje .rodata
sekcję pliku PE tylko do odczytu bez uprawnień do wykonywania. Musisz to wyłączyć, co można zrobić za pomocą próbki kodu z tego postu na blogu . Podstawowy pomysł: mprotect
dodajesz odpowiednie uprawnienia do stron, na których znajdują się dane kodu powłoki.
Jeśli zamierzasz przetestować tradycyjny scenariusz wykorzystania, np. Mój zły kod powyżej, z twoim kodem powłoki, musisz także upewnić się, że stos jest wykonywalny dla prostych przypadków. Format pliku PE zawiera pole do określania, czy stos jest wykonywalny - możesz to sprawdzać i kontrolować za pomocą execstack . Aby włączyć plik wykonywalny, uruchom
execstack -s /path/to/myprog
To może być wykonane na dowolnych programów bez konieczności ponownej kompilacji, ale nie będzie się automatycznie wyłączać kanarki stos jak te są pieczone w na kompilacji.
Aby to wyłączyć, echo 0 > /proc/sys/kernel/randomize_va_space
.
Nie. Każdy exploit musi obejść kanary stosów (bardzo mało trywialne) i albo znaleźć program z execstack
setem, albo ustawić go (co oznacza, że i tak może już wykonywać dowolne polecenia), albo użyć trudniejszych technik, takich jak powrót do libc / return programowanie zorientowane.
Za pomocą tych opcji można wyłączyć niektóre zabezpieczenia (wykrywanie zniszczenia stosu i uczynienie stosu wykonywalnym).
--z execstack
-f no-stack-protector
Możesz także wyłączyć ASLR (randomizacja układu przestrzeni adresowej) za pomocą Bash za pomocą polecenia:
echo 0 > /proc/sys/kernel/randomize_va_space