Desativar proteção de pilha no Ubuntu para estouro de buffer sem sinalizadores de compilador C

9

Gostaria de testar alguns códigos de shell e quero desativar as proteções do Linux.

Eu sei que eu poderia compilar usando flags, mas eu sei que existe outra maneira de desativar essas proteções em geral, eu não consigo me lembrar. Você pode me ajudar?

    
por Phate 04.03.2013 / 12:01

2 respostas

6

A proteção de pilha é feita pelo compilador (adicione alguns dados extras à pilha e guarde alguns em chamada, verifique a integridade ao retornar). Não é possível desativar isso sem recompilar. Faz parte do ponto, realmente ...

    
por 04.03.2013 / 12:06
24

Para expandir o que vonbrand tem (corretamente, +1), há duas partes na proteção de pilha do Linux.

Stack canaries

Os canários de pilha são o recurso imposto pelo compilador ao qual a vonbrand se refere. Estes não podem ser desativados sem uma recompilação.

Para provar isso para você mesmo e ver como eles funcionam, use o seguinte código:

#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]);
}

Agora compile isso ( gcc -fstack-protector -masm=intel -S test.c ) em algo do gnu, pois ficaria feliz em montar e ler a saída. O ponto importante é que, ao sair da função mybadfunction , há esse pequeno código:

    mov edx, DWORD PTR [ebp-12]
    xor edx, DWORD PTR gs:20
    je  .L2
    call    __stack_chk_fail

Como você pode imaginar, isso é pegar um cookie de pilha de [ebp-12] e compará-lo com o valor em gs:20 . Não corresponde? Em seguida, chama uma função __stack_chk_fail in glibc que mata seu programa ali mesmo.

Existem maneiras de contornar isso em termos de exploração de exploits, mas a maneira mais fácil de criar um caso de teste de shellcode é compilar seu programa com -fno-stack-protector .

Páginas não executáveis

Existem algumas outras considerações sobre os sistemas Linux modernos. Se você pegar o stub usual de teste de shellcode:

char buffer[] = {...};

typedef void (* func)(void);

int main(int argc, char** argv)
{
    func f = (func) buffer;
    f();
    return 0;
}

O GCC / Linux moderno mapeará a seção .rodata do arquivo PE somente com permissões de execução. Você precisa desativá-lo, o que pode ser feito usando o exemplo de código de este post do blog . Idéia básica: você usa mprotect para adicionar as permissões que deseja às páginas nas quais os dados do shellcode residem.

pilhas não executáveis

Se você for testar um cenário de exploração tradicional, por exemplo meu código ruim acima, com seu shellcode, você também precisa garantir que a pilha seja executável para os casos simples. O formato de arquivo PE contém um campo para determinar se a pilha é executável - você pode consultar e controlar isso com execstack . Para ativar uma pilha executável, execute

execstack -s /path/to/myprog

Isso pode ser feito em programas arbitrários sem precisar de uma recompilação, mas não desabilitará automaticamente os canários da pilha, já que eles são compilados na compilação.

Bônus adicionado: aslr:

Para desativar isso, echo 0 > /proc/sys/kernel/randomize_va_space .

Você acabou de dizer a alguém como explorar meu precioso pinguim?

Não. Qualquer exploit deve trabalhar em torno de canários de pilha (muito não triviais) e encontrar um programa com execstack set ou configurá-lo (o que significa que já pode executar comandos arbitrários) ou usar técnicas mais difíceis, como retornar à libc / retornar a programação orientada.

    
por 05.03.2013 / 11:07