Arch package guidelines (Português)/Security (Português)
Esta página descreve as diretrizes de empacotamento de segurança para pacotes do Arch Linux. Para projetos C/C++, o compilador e o vinculador podem aplicar opções de proteção de segurança. O Arch Linux aplica PIE, fonte Fortify, protetor de pilha, nx e relro por padrão.
Uso
As proteções hardening podem ser revisadas executando checksec.
$ checksec --file=/usr/bin/cat
RELRO
O RELRO é uma técnica genérica de mitigação para proteger as seções de dados de um processo/binário ELF. Quando um programa é carregado, várias seções da memória ELF precisam ser gravadas pelo vinculador, mas pode ser ativado como somente leitura antes de passar o controle para o programa. Isso evita que os invasores substituam algumas seções da ELF. Existem dois modos RELRO diferentes:
- Partial RELRO (
-Wl,-z,relro
): algumas seções são marcadas como somente leitura após o carregamento do programa, exceto que o GOT (.got.plt
) ainda pode ser gravado.
- Full RELRO (
-Wl,-z,now
) durante o carregamento do programa, todos os símbolos dinâmicos são resolvidos, permitindo que o GOT completo seja marcado como somente leitura.
Se um aplicativo relatar relro parcial, investigue se a cadeia de ferramentas de compilação passa nossos LDFLAGS ou permite substituir LDFLAGS. Para os pacotes Go, investigue se o método de compilação usa build.go
como uma substituição pura do Makefile golang, que não permite a passagem de LDFLAGS.
Haskell
Para Haskell, não está claro como alcançar o Full RELRO no momento.
Go
Veja Diretrizes de pacotes Go#Sinalizadores e opções de compilação.
Stack Canary
Um stack canary é adicionado pelo compilador entre o buffer e os dados de controle na pilha. Se esse valor conhecido estiver corrompido, ocorreu um estouro de buffer e o programa em execução é segmentado para impedir uma possível execução arbitrária do código.
O pacote gcc ativou a proteção de pilha por padrão com o --enable-default-ssp opção de compilação.
NX
C/C++
A proteção do espaço executável marca as regiões da memória como não executáveis, de modo que uma tentativa de executar o código da máquina nessas regiões causará uma exceção. Ele utiliza recursos de hardware como o bit NX (bit sem execução) ou, em alguns casos, emulação de software desses recursos.
PIE
C/C++
O pacote gcc o tem habilitado por padrão para C/C++ com --enable-default-pie.
Golang
Passe os seguintes sinalizadores para go build
export GOFLAGS='-buildmode=pie' export CGO_CPPFLAGS="-D_FORTIFY_SOURCE=3" export CGO_LDFLAGS="-Wl,-z,relro,-z,now"
Haskell
Passe o seguinte sinalizador para runhaskell Setup.hs configure
:
--ghc-option='-pie'
RPATH/RUNPATH
RUNPATH/RPATH fornece outros caminhos de pesquisa para o objeto em que está listado (pode ser usado para objetos executáveis e compartilhados).
$ objdump -x /usr/bin/perl | grep -E 'RPATH|RUNPATH'
Se o valor RPATH contiver um caminho dentro do controle de um invasor, ele poderá executar o código instalando uma biblioteca maliciosa nesse diretório. Por exemplo, CVE-2006-1566 e CVE-2005-4280. Veja Debian:RpathIssue.
A entrada RPATH é configurada pelo vinculador, passando, por exemplo, a seguinte string para LDFLAGS -Wl, -rpath -Wl,/usr/local/lib
. Para fazer uma entrada de RUNPATH, anexe --enable-new-dtags
aos sinalizadores do vinculador.
FORTIFY
A fonte Fortify é uma macro que adiciona proteção contra estouro de buffer (buffer overflow) em várias funções que executam operações na memória e nas strings. Ele verifica se um invasor tenta copiar mais bytes para estourar um buffer e interrompe a execução do programa. Essa proteção é ativada com o CPPFLAGS
padrão:
makepkg.conf
CPPFLAGS="-D_FORTIFY_SOURCE=3"
Veja makepkg (Português)#Configuração
Serviços systemd
Se um arquivo de serviço do systemd for enviado com o pacote devido à falta de fornecimento do upstream, aplique os seguintes recursos de proteção de serviço do systemd. O systemd fornece uma maneira de analisar os recursos de segurança habilitados para um serviço.
$ systemd-analyze security reflector.service
Acesso de arquivos
Um serviço pode ser protegido restringindo o acesso ao sistema de arquivos.
Configure um novo espaço de nomes do sistema fiel para o processo executado e que monta os diretórios /tmp
e /var/tmp
privados dentro dele que não são compartilhados pelos processos
PrivateTmp=true
O ProtectSystem
possui três variedades diferentes de diretórios de montagem como somente leitura para o processo executado. A opção full
monta /usr
, /boot
e /etc
como somente leitura. O ProtectHome
torna /home
, /root
e /run/user
\ inacessíveis ao processo executado.
ProtectSystem=strict ProtectHome=true
Configure um novo espaço de nomes /dev
para o processo executado e adiciona apenas pseudodispositivos API como /dev/null
, /dev/zero
ou /dev/random
, mas não para dispositivos físicos ou memória do sistema, portas do sistema e outros. Isso é útil para impedir que o processo de execução seja gravado diretamente em dispositivos físicos, o systemd também adiciona um filtro de chamadas do sistema para chamadas dentro do conjunto @raw-io
.
PrivateDevices=true
Essas opções impendem o processo executado de alterar as variáveis do kernel acessíveis por meio de /proc/sys
, /sys
etc. ProtectControlGroups
torna a hierarquia de /sys/fs/cgroup
somente leitura.
ProtectKernelTunables=true ProtectControlGroups=true
Tornar inacessíveis os caminhos de arquivos pode ser feito da seguinte forma:
InaccessiblePaths=/etc
Informações mais detalhadas podem ser encontradas em systemd.exec(5).
Usuário
Certifique-se que o processo executado e seus filhos nunca possam obter novos privilégios por meio do execve(2).
NoNewPrivileges=true
Memória
Proíba tentativas de criar mapeamentos de memória que sejam graváveis e executáveis, alterar os mapeamentos para executáveis ou criar memória compartilhada executável. Isso protege um processo contra a permissão de um invasor na memória, que também é executada. Observe que ativar isso não é compatível com todos os aplicativos que dependem de JIT.
MemoryDenyWriteExecute=true
Chamadas de sistema
Bloqueia a chamada de sistema personality(2) para que o domínio de execução do kernel não possa ser alterado.
LockPersonality=true
As chamadas de sistema também podem ser restritas em um serviço, o systemd pode exibir chamadas de sistema para filtrar:
$ systemd-analyze syscall-filter
Grupos predefinidos estão disponíveis, por exemplo, para usar o ponto de partida recomendado para chamadas de sistema na lista de permissões para serviços do sistema:
SystemCallFilter=@system-service
Chamadas de sistema podem ser restrita por sua arquitetura tal como evitar que binários 32 bits executem em máquinas 64 bit (binários não nativos):
SystemCallArchitectures=native
Rede
Se o processo em execução não exigir acesso à rede, este acesso pode ser totalmente desativado, configurando um novo espaço de nomes de rede para o processo e configurando apenas uma interface de loopback.
PrivateNetwork=true
Se a rede for necessária, o tipo de família de endereços usado pode ser restrito para a chamada de sistema socket(2), permitindo, por exemplo, apenas soquetes UNIX.
RestrictAddressFamilies=AF_UNIX
Quando é necessária apenas a rede para o localhost ou intervalos de IP específicos, um processo pode ser restringido, permitindo apenas o acesso da rede ao localhost.
IPAddressAllow=localhost IPAddressDeny=any
Mais informações sobre filtragem de rede pode ser encontrada em systemd.resource-control(5).
Várias
Configura um novo espaço de nomes UTS para o processo de execução e não permite alterar o nome de host ou o nome de domínio.
ProtectHostname=true