Sourcing e awk
são ideias ruins
Fornecer esses tipos de arquivos com um interpretador de shell script é uma idéia pobre, já que introduz outro lugar onde o malicioso pode ocultar o shell script para ser executado com permissões de superusuário, ou pode introduzir coisas como uma substituição para variáveis como PATH
, LANG
e LD_LIBRARY_PATH
.
% cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 9 (stretch with subversive \$PATH)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
echo 1>&2 'install -m 0644 /etc/shadow /home/malefactor/etc/ 2>/dev/null'
PATH="/home/malefactor/bin:${PATH}"
%
% ( source /etc/os-release ; command -v start-stop-daemon ; )
install -m 0644 /etc/shadow /home/malefactor/etc/ 2>/dev/null
/home/malefactor/bin/start-stop-daemon
%
O sourcing realmente viola uma das semânticas definidas para /etc/os-release
, que é que (para citar seu manual) "expansão de variável não é explicitamente suportada".
Da mesma forma, awk
, conforme fornecido na resposta do Archemar, não manipula corretamente as cotações; e qualquer valor pode ser citado. Observe como a resposta do Archemar não aborda o valor VERSION
na questão, para o qual o script awk
fornecido não fornece o valor correto, porque retém erroneamente a cotação e não manipula as seqüências de escape.
% awk -F= '$1=="VERSION" { print $2 ;}' /etc/os-release
"9 (stretch)"
% awk -F= '$1=="PRETTY_NAME" { print $2 ;}' /etc/os-release
"Debian GNU/Linux 9 (stretch with subversive \$PATH)"
%
/etc/os-release
tem realmente uma latitude bastante ampla nas cotações e também exige que as seqüências de escape sejam processadas corretamente. awk
não é realmente a ferramenta certa para o trabalho, aqui.
Existem outros problemas, mais sutis, como o vazamento de variáveis já definidas nos resultados, se a chave real desejada estiver faltando no arquivo.
% ( source /etc/os-release ; echo $LANG ; )
install -m 0644 /etc/shadow /home/malefactor/etc/ 2>/dev/null
en_GB.UTF-8
%
Há também o fato de que, se ID
ou PRETTY_NAME
estiverem ausentes, eles serão definidos como tendo valores padrão. E, além disso, há o substituto para o /usr/lib/os-release
.
Aprendendo com outras pessoas
Os arquivos que contêm atribuições de valor de chave-igual, com texto, escape e comentários em estilosh
, são uma coisa bastante comum. Algumas linguagens de programação possuem funções de biblioteca para lidar com elas diretamente. A lição de mudança de regras do OpenBSD no /etc/rc.conf
no OpenBSD 5.6 é que é o curso mais sábio para usar tais funções de biblioteca, se disponíveis, ou ferramentas dedicadas que não têm nem de perto as capacidades de um interpretador de shell completo para processar tais arquivos. / p>
De scripts de shell, eu, pelo menos, uso uma ferramenta chamada read-conf
para processar tais arquivos:
% read_os() {
if test -r /etc/os-release
then
clearenv setenv "$1" "$2" read-conf /etc/os-release "'command -v printenv'" "$1"
else
clearenv setenv "$1" "$2" read-conf /usr/lib/os-release "'command -v printenv'" "$1"
fi
}
% read_os ID linux
debian
% read_os VERSION
9 (stretch)
% read_os PRETTY_NAME Linux
Debian GNU/Linux 9 (stretch with subversive $PATH)
% read_os PATH
/home/malefactor/bin:${PATH}
% read_os LANG
%
Observe o uso cuidadoso de command -v
para evitar a procura de printenv
após o arquivo de configuração infectado ter definido maliciosamente um PATH
alterado. (Um dia desses, adicionarei uma cadeia printenv
que read-conf
pode incorporar em.)
Leitura adicional
- Theo de Raadt et al. (2014-11-01). OpenBSD 5.6 Changelog . OpenBSD.
- Jonathan de Boyne Pollard (2018). "
read-conf
". Manual . conjunto de ferramentas. Softwares.
- Jonathan de Boyne Pollard (2018). "
clearenv
". Manual . conjunto de ferramentas. Softwares.
- Jonathan de Boyne Pollard (2018). "
setenv
". Manual . conjunto de ferramentas. Softwares.
- Jonathan de Boyne Pollard (2018). "
printenv
". Manual . conjunto de ferramentas. Softwares.