Abychom rozšířili to, co vonbrand řekl (správně, +1), ochrana zásobníku Linuxu má dvě části.
Hromadné kanárky
Stack canaries jsou kompilátorem vynucená funkce, na kterou vonbrand odkazuje. Tyto nelze zakázat bez rekompilace.
Abyste si to dokázali a viděli, jak fungují, použijte následující kód:
#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]);
}
Nyní to zkompilujte (gcc -fstack-protector -masm=intel -S test.c
) do něčeho, co by gnu rád sestavil a přečetl výstup. Důležité je, že při výstupu z mybadfunction
funkce, je zde tento malý kousek kódu:
mov edx, DWORD PTR [ebp-12]
xor edx, DWORD PTR gs:20
je .L2
call __stack_chk_fail
Jak můžete hádat, jde o přebírání souboru cookie zásobníku z [ebp-12]
a porovnáním s hodnotou gs:20
. Neodpovídá? Poté volá funkci __stack_chk_fail
v glibc, který ukončí váš program přímo tam.
Existují způsoby, jak to obejít, pokud jde o psaní exploitů, ale nejjednodušší způsob, jak vytvořit testovací případ shell kódu, je zkompilovat váš program s -fno-stack-protector
.
Nespustitelné stránky
Existují některé další úvahy o moderních systémech Linux. Pokud použijete obvyklý testovací útržek shell kódu:
char buffer[] = {...};
typedef void (* func)(void);
int main(int argc, char** argv)
{
func f = (func) buffer;
f();
return 0;
}
moderní GCC/Linux bude mapovat .rodata
část souboru PE pouze pro čtení bez oprávnění ke spuštění. Musíte to vypnout, což lze provést pomocí ukázky kódu z tohoto blogového příspěvku. Základní myšlenka:používáte mprotect
přidat oprávnění, která chcete na stránky, na kterých jsou uložena data shellkódu.
Nespustitelné zásobníky
Pokud budete testovat tradiční scénář exploitu, např. můj špatný kód výše, s vaším shell kódem pak také musíte zajistit, aby byl zásobník spustitelný pro jednoduché případy. Formát souboru PE obsahuje pole pro určení, zda je zásobník spustitelný – můžete se dotazovat a ovládat pomocí execstack. Chcete-li povolit spustitelný zásobník, spusťte
execstack -s /path/to/myprog
Toto může lze provést na libovolných programech bez nutnosti rekompilace, ale automaticky nevypne zásobníkové kanárky, protože jsou zapečeny při kompilaci.
Přidaný bonus:aslr:
Chcete-li to vypnout, echo 0 > /proc/sys/kernel/randomize_va_space
.
Právě jsi někomu řekl, jak zneužít mého drahého tučňáka?
Ne. Jakýkoli exploit musí obejít stack canaries (velmi netriviální) a buď najít program s execstack
set nebo set it (to znamená, že už stejně může provádět libovolné příkazy) nebo použít složitější techniky, jako je návrat k programování orientovanému na libc/return.
Ochranu zásobníku provádí kompilátor (přidejte do zásobníku nějaká data navíc a některá si schovejte při zavolání, při návratu zkontrolujte zdravý rozum). Bez rekompilace to nelze zakázat. Je to součást věci, opravdu...