Respostas:
A proteção da pilha é feita pelo compilador (adicione alguns dados extras à pilha e esconda alguns fora de chamada, verifique a sanidade ao retornar). Não é possível desativar isso sem recompilar. É parte do ponto, realmente ...
Para expandir o que vonbrand disse (corretamente, +1), existem duas partes na proteção de pilha do Linux.
Canários de pilha são o recurso imposto pelo compilador ao qual vonbrand se refere. Eles não podem ser desativados sem uma recompilação.
Para provar isso a si 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 que o gnu gostaria de montar e ler a saída. O ponto importante é que, ao sair da mybadfunction
função, existe este pequeno pedaço de 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 [ebp-12]
e compará-lo com o valor em gs:20
. Não combina? Em seguida, ele chama uma função __stack_chk_fail
na glibc que mata seu programa ali mesmo.
Existem maneiras de contornar isso em termos de exploração de gravação, mas a maneira mais fácil em termos de criação de um caso de teste de código de shell é compilar seu programa -fno-stack-protector
.
Existem outras considerações nos sistemas Linux modernos. Se você usar o stub habitual de teste de código de shell:
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 .rodata
seção do arquivo PE somente para leitura, sem permissões de execução. Você precisa desativar isso, o que pode ser feito usando o exemplo de código desta postagem do blog . Ideia básica: use mprotect
para adicionar as permissões desejadas às páginas nas quais os dados do código do shell residem.
Se você for testar um cenário de exploração tradicional, por exemplo, meu código incorreto acima, com seu código de shell, também será necessário garantir que a pilha seja executável nos casos simples. O formato do arquivo PE contém um campo para determinar se a pilha é executável - você pode consultar e controlar isso com execstack . Para habilitar uma pilha executável, execute
execstack -s /path/to/myprog
Isso pode ser feito em programas arbitrários sem a necessidade de uma recompilação, mas não desabilita automaticamente os canários de pilha, pois eles são incorporados na compilação.
Para desligar isso echo 0 > /proc/sys/kernel/randomize_va_space
.
Não. Qualquer exploração deve contornar canários de pilha (muito não triviais) e encontrar um programa com execstack
set ou configurá-lo (o que significa que ele já pode executar comandos arbitrários de qualquer maneira) ou usar técnicas mais difíceis, como retornar à libc / return programação orientada.
Você pode desativar algumas proteções (detecção de quebra de pilha e execução da pilha) com essas opções.
--z execstack
-f no-stack-protector
Você também pode desativar o ASLR (randomização do layout do espaço de endereço) com o Bash com o comando:
echo 0 > /proc/sys/kernel/randomize_va_space