GNU/Linux >> Znalost Linux >  >> Linux

Vypněte ochranu zásobníku na Ubuntu pro přetečení vyrovnávací paměti bez příznaků kompilátoru C

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...


Linux
  1. Fraps jako programy pro Ubuntu?

  2. 8 MacOS Like Docks pro Ubuntu

  3. Existuje F# Interactive pro Linux na .NET Core bez použití Mono?

  1. Existuje příkaz pro návrat o několik kroků zpět v adresáři bez použití cd?

  2. Existuje ekvivalent cd - pro cp nebo mv?

  3. Amazon Linux vs. Ubuntu pro Amazon EC2

  1. Zakázat uživatelské prostředí z bezpečnostních důvodů?

  2. Existuje instalační program Wubi pro verzi Ubuntu Dvd?

  3. Jak zakázat veškerou správu napájení v Ubuntu (pro serverový netbook)?