ASLR
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Address Space Layout Randomization (ASLR) é uma técnica de segurança utilizada em sistemas operacionais para randomizar os endereços de memória usados por processos do sistema e de aplicativos. Ao fazer isso, torna-se significativamente mais difícil para um atacante prever a localização de processos e dados específicos, como a pilha, heap e bibliotecas, mitigando assim certos tipos de exploits, particularmente buffer overflows.
Para verificar o status do ASLR em um sistema Linux, você pode ler o valor do arquivo /proc/sys/kernel/randomize_va_space
. O valor armazenado neste arquivo determina o tipo de ASLR que está sendo aplicado:
0: Sem randomização. Tudo é estático.
1: Randomização conservadora. Bibliotecas compartilhadas, pilha, mmap(), página VDSO são randomizadas.
2: Randomização total. Além dos elementos randomizados pela randomização conservadora, a memória gerenciada através de brk()
é randomizada.
Você pode verificar o status do ASLR com o seguinte comando:
Para desabilitar ASLR, você define o valor de /proc/sys/kernel/randomize_va_space
para 0. Desabilitar ASLR geralmente não é recomendado fora de cenários de teste ou depuração. Aqui está como você pode desabilitá-lo:
Você também pode desativar ASLR para uma execução com:
Para habilitar ASLR, você pode escrever um valor de 2 no arquivo /proc/sys/kernel/randomize_va_space
. Isso geralmente requer privilégios de root. Habilitar a randomização completa pode ser feito com o seguinte comando:
As alterações feitas com os comandos echo
são temporárias e serão redefinidas após a reinicialização. Para tornar a alteração persistente, você precisa editar o arquivo /etc/sysctl.conf
e adicionar ou modificar a seguinte linha:
Após editar /etc/sysctl.conf
, aplique as alterações com:
Isso garantirá que suas configurações de ASLR permaneçam entre reinicializações.
PaX divide o espaço de endereçamento do processo em 3 grupos:
Código e dados (inicializados e não inicializados): .text
, .data
e .bss
—> 16 bits de entropia na variável delta_exec
. Esta variável é inicializada aleatoriamente com cada processo e adicionada aos endereços iniciais.
Memória alocada por mmap()
e bibliotecas compartilhadas —> 16 bits, chamada delta_mmap
.
A pilha —> 24 bits, referida como delta_stack
. No entanto, ela efetivamente usa 11 bits (do 10º ao 20º byte, inclusive), alinhados a 16 bytes —> Isso resulta em 524.288 endereços de pilha reais possíveis.
Os dados anteriores são para sistemas de 32 bits e a entropia final reduzida torna possível contornar o ASLR tentando a execução repetidamente até que a exploração seja concluída com sucesso.
Se você tiver um estouro grande o suficiente para hospedar um grande NOP sled antes do shellcode, você poderia simplesmente forçar endereços na pilha até que o fluxo salte sobre alguma parte do NOP sled.
Outra opção para isso, caso o estouro não seja tão grande e a exploração possa ser executada localmente, é possível adicionar o NOP sled e o shellcode em uma variável de ambiente.
Se a exploração for local, você pode tentar forçar o endereço base da libc (útil para sistemas de 32 bits):
Se você estiver atacando um servidor remoto, pode tentar forçar a descoberta do endereço da função usleep
da libc
, passando como argumento 10 (por exemplo). Se em algum momento o servidor demora 10s a mais para responder, você encontrou o endereço dessa função.
Em sistemas de 64 bits, a entropia é muito maior e isso não deveria ser possível.
É possível ocupar uma grande parte da pilha com variáveis de ambiente e então tentar abusar do binário centenas/milhares de vezes localmente para explorá-lo. O código a seguir mostra como é possível apenas selecionar um endereço na pilha e a cada algumas centenas de execuções esse endereço conterá a instrução NOP:
/proc/[pid]/stat
)O arquivo /proc/[pid]/stat
de um processo é sempre legível por todos e contém informações interessantes como:
startcode & endcode: Endereços acima e abaixo com o TEXT do binário
startstack: O endereço do início da stack
start_data & end_data: Endereços acima e abaixo onde está o BSS
kstkesp & kstkeip: Endereços atuais de ESP e EIP
arg_start & arg_end: Endereços acima e abaixo onde estão os argumentos do cli.
env_start &env_end: Endereços acima e abaixo onde estão as variáveis de ambiente.
Portanto, se o atacante estiver no mesmo computador que o binário sendo explorado e este binário não espera o overflow de argumentos brutos, mas de uma entrada diferente que pode ser criada após a leitura deste arquivo. É possível para um atacante obter alguns endereços deste arquivo e construir offsets a partir deles para a exploração.
Para mais informações sobre este arquivo, consulte https://man7.org/linux/man-pages/man5/proc.5.html procurando por /proc/pid/stat
O desafio é fornecer um leak
Se você receber um leak (desafios fáceis de CTF), você pode calcular offsets a partir dele (supondo, por exemplo, que você conhece a versão exata da libc que está sendo usada no sistema que você está explorando). Este exemplo de exploração é extraído do exemplo daqui (ver essa página para mais detalhes):
ret2plt
Abusando de um buffer overflow, seria possível explorar um ret2plt para exfiltrar um endereço de uma função da libc. Verifique:
Ret2pltFormat Strings Arbitrary Read
Assim como no ret2plt, se você tiver uma leitura arbitrária através de uma vulnerabilidade de format strings, é possível exfiltrar o endereço de uma função da libc do GOT. O seguinte exemplo é daqui:
Você pode encontrar mais informações sobre leitura arbitrária de Strings de Formato em:
Format StringsTente contornar o ASLR abusando de endereços dentro da pilha:
Ret2ret & Reo2popO mecanismo vsyscall
serve para melhorar o desempenho permitindo que certas chamadas de sistema sejam executadas no espaço do usuário, embora sejam fundamentalmente parte do kernel. A vantagem crítica dos vsyscalls reside em seus endereços fixos, que não estão sujeitos ao ASLR (Randomização de Layout de Espaço de Endereçamento). Essa natureza fixa significa que os atacantes não precisam de uma vulnerabilidade de vazamento de informações para determinar seus endereços e usá-los em um exploit.
No entanto, nenhum gadget super interessante será encontrado aqui (embora, por exemplo, seja possível obter um equivalente a ret;
)
(O seguinte exemplo e código é deste writeup)
Por exemplo, um atacante pode usar o endereço 0xffffffffff600800
dentro de um exploit. Enquanto tentar pular diretamente para uma instrução ret
pode levar à instabilidade ou falhas após a execução de alguns gadgets, pular para o início de um syscall
fornecido pela seção vsyscall pode se mostrar bem-sucedido. Ao colocar cuidadosamente um gadget ROP que leva a execução para este endereço vsyscall, um atacante pode conseguir a execução de código sem precisar contornar o ASLR para esta parte do exploit.
Note que pode ser possível burlar o ASLR abusando do vdso se o kernel for compilado com CONFIG_COMPAT_VDSO, pois o endereço do vdso não será randomizado. Para mais informações, consulte:
Ret2vDSOAprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)