Recentemente eu aprendi que (pelo menos no Fedora e Red Hat Enterprise Linux), os programas executáveis que são compilados como PIE (Position Independent Executables) recebem proteção mais forte de randomização do espaço de endereço (ASLR).
Então: como testar se um executável específico foi compilado como um executável independente de posição, no Linux?
-pie -fpie
sinalizadores especiais do compilador para compilar um programa como uma TORTA. Esse link tinha outras informações interessantes - obrigado!Respostas:
Você pode usar o
perl
script contido nohardening-check
pacote, disponível no Fedora e Debian (ashardening-includes
). Leia esta página wiki da Debian para obter detalhes sobre quais sinalizadores de compilação são verificados. É específico do Debian, mas a teoria se aplica ao Red Hat também.Exemplo:
fonte
sudo apt-get install hardening-includes
e então ohardening-check
script perl executável está disponível no usualPATH
(/usr/bin/hardening-check
); apenas um nit: Sugerir para remover a./
partir da resposta ;-)devscripts
.Eu costumava
readelf --relocs
testar se a biblioteca estática ou dinâmica é PIC em x86-64 da seguinte maneira:Nós vemos aqui
R_X86_64_32
eR_X86_64_32S
. Isso significa que o código não é independente de posição. Quando reconstruo uma biblioteca com -fPIC, recebo:Esse método provavelmente pode funcionar para executáveis, mas eu não o usei dessa maneira.
fonte
-fPIE -no-pie
, ele sempre seria carregado no mesmo endereço, mesmo que pudesse ter sido vinculado como um executável PIE. Usefile a.out
e procure porELF executable
objetos compartilhados (não PIE) vs. ELF (PIE): endereços absolutos de 32 bits não são mais permitidos no Linux x86-64?Basta usar
file
no binário:Observe o tipo diferente impresso após as informações do LSB.
fonte
executable
eshared object
. Presumo que os objetos compartilhados precisam ser realocados, portanto, na minha opinião, foram compilados com o PIE.gcc -fPIE -pie
agora é o padrão em muitas distribuições.file
5.36 agora pode realmente reconhecer PIE-ness com base naDT_1_PIE
bandeira deDT_FLAGS_1
, e diz claramente empie executable
vez deshared object
.file
5.36 diz claramentefile
5.36 realmente imprime claramente se o executável é TORTA ou não. Por exemplo, um executável PIE mostra como:e um não-TORTA como:
O recurso foi introduzido na 5.33, mas fez apenas uma
chmod +x
verificação simples . Antes disso, apenas imprimiashared object
para TORTA.Na versão 5.34, ele deveria começar a verificar os
DF_1_PIE
metadados ELF mais especializados , mas devido a um erro na implementação, ele realmente quebrou as coisas e mostrou os executáveis do GCC PIE comoshared objects
.Eu interpretei o
file
código fonte, incluindo o bug, e exatamente quais bytes do formato ELF ele verifica com detalhes excruciantes em: https://stackoverflow.com/questions/34519521/why-does-gcc-create-a-shared-object de acordo com um binário executável de acordo com / 55704865 # 55704865Um resumo rápido do comportamento do arquivo 5.36 é:
Elf32_Ehdr.e_type == ET_EXEC
executable
Elf32_Ehdr.e_type == ET_DYN
DT_FLAGS_1
a entrada de seção dinâmica estiver presenteDF_1_PIE
estiver definido emDT_FLAGS_1
:pie executable
shared object
pie executable
shared object
O GDB executa o executável duas vezes e consulte ASLR
Uma coisa muito direta que você pode fazer é executar o executável duas vezes através do GDB e verificar se o endereço muda entre as execuções devido ao ASLR.
Expliquei como fazer isso em detalhes em: https://stackoverflow.com/questions/2463150/what-is-the-fpie-option-for-position-independent-executables-in-gcc-and-ld/51308031 # 51308031
Embora essa não seja necessariamente a solução mais prática e não seja possível se você não confia no executável, é divertido e faz a verificação final com a qual realmente nos preocupamos, ou seja, se o kernel / carregador dinâmico do Linux altera o local do executável ou não.
fonte
setarch -R
man7.org/linux/man-pages/man8/setarch.8.html "-R, --addr-no-randomize
Desativa a randomização do espaço de endereço virtual. LigaADDR_NO_RANDOMIZE
." man7.org/linux/man-pages/man2/personality.2.html "ADDR_NO_RANDOMIZE
(desde Linux 2.6.12) Com esse sinalizador definido, desative a randomização do layout do espaço de endereço."Existe o script bash checksec.sh no Github para verificar as propriedades de atenuação dos executáveis (incluindo RELRO, Stack Canary, NX bit, PIE, RPATH, RUNPATH, Fortify Source).
Execute
checksec
com-f
argumentos (entrada de arquivo):fonte