Verificação de binários de comando antes da execução

13

Existem métodos para verificar o que você está realmente executando a partir de um script bash?

Digamos que seu script bash esteja chamando vários comandos (por exemplo: tar , mail , scp , mysqldump ) e você esteja disposto a garantir que tar seja o real, real tar , que é determinável pelo usuário root sendo o proprietário do diretório de arquivos e pai e o único com permissões de gravação e não com /tmp/surprise/tar com www-data ou apache2 sendo o proprietário.

Claro que sei sobre PATH e o ambiente, estou curioso para saber se isso pode ser verificado adicionalmente a partir de um script bash em execução e, em caso afirmativo, como exatamente

Exemplo: (pseudo-código)

tarfile=$(which tar)
isroot=$(ls -l "$tarfile") | grep "root root"
#and so on...
    
por Miloš Đakonović 12.01.2017 / 10:40

6 respostas

24

Em vez de validar os binários que você vai executar, você pode executar os binários corretos desde o início. Por exemplo. Se você quiser ter certeza de que não vai executar /tmp/surprise/tar , apenas execute /usr/bin/tar no seu script. Como alternativa, defina seu $PATH para um valor sane antes de executar qualquer coisa.

Se você não confiar em arquivos em /usr/bin/ e outros diretórios do sistema, não há como recuperar a confiança. No seu exemplo, você está verificando o proprietário com ls , mas como você sabe que pode confiar em ls ? O mesmo argumento se aplica a outras soluções, como md5sum e strace .

Onde é necessária alta confiança na integridade do sistema, soluções especializadas como IMA são usadas. Mas isso não é algo que você poderia usar a partir de um script: todo o sistema tem que ser configurado de uma maneira especial, com o conceito de arquivos imutáveis no lugar.

    
por 12.01.2017 / 13:47
6

Se um intruso tiver obtido acesso ao seu sistema e puder modificar seu $PATH (que não deve incluir /tmp sob nenhuma circunstância), então é muito tarde para começar a se preocupar com as posses dos executáveis.

Em vez disso, você deve ler sobre como lidar com uma intrusão .

Melhor se concentrar em evitar a intrusão por completo.

Se você tem um sistema onde esses tipos de coisas são importantes, pode ser uma boa ideia isolar as partes dele que precisam ser públicas das partes que precisam ser privadas, bem como realizar uma auditoria das modos de comunicação entre estes.

    
por 12.01.2017 / 11:18
4

É possível, até certo ponto, verificar o md5sum de um arquivo. Portanto, em sistemas que usam o gerenciamento de pacotes apt - no meu caso particular, Ubuntu 16.04 - existe o arquivo /var/lib/dpkg/info/tar.md5sums , que armazena as somas md5 de todos os arquivos que vieram de tar durante a instalação. Então você poderia escrever uma instrução if simples que verifica se a saída de md5sum /bin/tar corresponde ao que está nesse arquivo.

Isso, obviamente, pressupõe que o arquivo em si não tenha sido adulterado. Isso, é claro, só pode acontecer quando o atacante tiver acesso root / sudo, quando todas as apostas estão desativadas.

    
por 12.01.2017 / 10:58
3

Sim, existe um método: o incorporado em type . Ao contrário do comando which , que só procura em seu PATH, type dirá se o nome do comando é, na verdade, uma palavra-chave reservada, uma embutida, um alias, uma função ou um arquivo de disco.

$ type -t foobar || echo "Not found"
Not found

$ type -t echo
builtin

$ enable -n echo; type -t echo; type -p echo
file
/usr/bin/echo

$ echo() { printf "(echoing) %s\n" "$*"; }; type -t echo
function

$ alias echo="/bin/echo 'I say: ' "; type -t echo
alias

Além disso, type -a dará a você todos os candidatos ao seu comando (da primeira à última opção):

$ type -a echo
echo is aliased to '/bin/echo 'I say: ' '
echo is a function
echo () 
{ 
    printf "(echoing) %s\n" "$*"
}
echo is a shell builtin
echo is /usr/local/bin/echo
echo is /bin/echo

Finalmente, se você estiver preocupado apenas com os binários em seu disco, você pode usar type -Pa para obter todos os binários em seu PATH (a mesma ordem acima):

$ type -Pa tar
/home/me/bin/tar                <= oh oh, is this normal?
/bin/tar

Dito isto, type sozinho não lhe dirá exatamente qual comando será chamado no final. Por exemplo, se o seu tar for um alias que chame um binário (por exemplo, alias tar="/tmp/tar" ), então type dirá que este é um alias .

    
por 12.01.2017 / 11:12
3

Você pode verificar quais comandos estão sendo executados exatamente por um script usando strace . Por exemplo:

strace -f -e execve ./script.sh

Com o seguinte script:

#!/bin/bash
touch testfile.txt
echo "Hello" >> testfile.txt
cat testfile.txt
rm testfile.txt

strace informará o caminho exato para os comandos executados quando usados com o parâmetro -e execve :

execve("./script.sh", ["./script.sh"], [/* 69 vars */]) = 0 
Process 8524 attached
[pid  8524] execve("/usr/bin/touch", ["touch", "testfile.txt"], [/* 68 vars */]) = 0 
[pid  8524] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8524, si_status=0, si_utime=0, si_stime=0} --- 
Process 8525 attached [pid > 8525] execve("/bin/cat", ["cat", "testfile.txt"], [/* 68 vars */]) = 0
Hello [pid  8525] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8525, si_status=0, si_utime=0, si_stime=0} --- 
Process 8526 attached [pid > 8526] execve("/bin/rm", ["rm", "testfile.txt"], [/* 68 vars */]) = 0
[pid  8526] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8526, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 0 +++

Parâmetros (do strace man):

-f : rastrear processos filho conforme eles são criados pelos processos atualmente rastreados como resultado das chamadas do sistema fork (2), vfork (2) e clone (2). Note que -p PID -f irá anexar todos os threads do processo PID se ele for multi-threaded, não apenas thread com thread_id = PID.

-e trace=file : rastreia todas as chamadas de sistema que usam um nome de arquivo como argumento. Você pode pensar nisso como uma abreviação de -e trace=open,stat,chmod,unlink,... , que é útil para ver quais arquivos o processo está referenciando. Além disso, usando a abreviação garantir que você não se esqueça de incluir uma chamada como lstat na lista.

    
por 12.01.2017 / 11:09
0

O sistema operacional Linux é baseado em arquivos e muitos comandos executados no linux provavelmente resolverão algumas mudanças nos arquivos localizados em sua máquina. Por causa disso talvez seja a melhor solução para o seu problema. Você pode testar seus comandos para qualquer alteração no sistema de arquivos antes que ele seja executado.

Existeocomando'strace'quedescompilaoseucomandoempartes...

Se você realmente quer ir fundo, você quer fazer check-out de descompiladores para os scripts que serão executados. Em outras palavras, você deve verificar a interpretação assembler desse comando. Por bash há objdump -d . Os scripts de bin do Linux são criados principalmente com a linguagem de programação C , portanto use bom C decompiler.

    
por 14.01.2017 / 15:39