2. Introdução
Os perigos da análise dinâmica de programa
Confinamento de programas com máquinas virtuais baseadas em hardware
Confinamento de programas com máquinas virtuais baseadas em software
Os perigos do confinamento com máquinas virtuais baseadas em softwares
Confinamento de programas com prisões de chroot()
Análise dinâmica com monitores de chamada de sistema
Confinamento de programa com censores de chamada de sistema
Confinamento de programa com spoofing de chamada de sistema
Os perigos do confinamento com chamadas de sistema
Análise dinâmica com monitor de chamada de biblioteca
Confinamento de programa com chamadas de biblioteca
Os perigos do confinamento com chamadas de biblioteca
Análise dinâmica no nível de instrução de máquina
Análise estática e engenharia reversa
Pequenos programas podem ter muitos problemas Contramedidas da análise de malwere
Conclusão
Sumário
3. Introdução
Estudando o comportamento de um programa;
Análise estática: a vantagem é a inteireza, ela pode revelar partes de um
programa que normalmente não são executadas;
Análise dinâmica: A vantagem é a velocidade, porém não é possível uma
análise mais aprofundada;
Análise post-modem: A única ferramenta possível após um “incidente”. A
estudo é feito após a execução.
4. Os perigos da análise dinâmica de
programa
Executar o programa e ver o que acontece oferece riscos: apagar informações ou
enviar e-mails.
“Caixa de areia” é o termo que nomeia o ambiente controlado para executar o
software, o mais simples é o “cordeiro artificial”.
Cordeiro artificial: uma máquina real, mas descartável é utilizada no processo.
Existem meios mais eficientes que não só executam, mas também possibilitam a
visualização mais detalhada.
5. Confinamento de programas com máquinas
virtuais baseadas em hardware
Maneiras de dividir um sistema de computador em múltiplos compartimentos:
podem ser implementadas no hardware ou software;
Dividir uma máquina no nível de hardware exige sistemas muito sofisticados, com
multiprocessadores, e isso pode sair caro;
6. Confinamento de programas com máquinas
virtuais baseadas em software
Máquinas baseadas em software apresentam uma maneira mais flexível, um ou mais
sistemas operacionais de convidado executam sobre uma interface de hardware virtual,
enquanto um programa monitor de máquina virtual faz a mediação do acesso com o
hardware real.
Pode ocorrer overhead de software no monitor da máquina virtual, mas oferece
recursos que não estão disponíveis em hardware real ou sistemas operacionais de
convidado.
É possível por exemplo implementar suporte e alterações no sistema de arquivos que
não podem ser desfeitas, redirecionando as operações de gravação em disco a um
arquivo de log fora da máquina virtual. Além disso, alguns sistemas permitem que o
investigador reproduza um incidente e retroceda, pause ou avance a máquina virtual
para um ponto qualquer no tempo.
7. Os perigos do confinamento com máquinas
virtuais baseadas em software
A máquina virtual não pode permitir que um software não confiável escape, e
manter ele confinado exige a implementação correta dos recursos de proteção do
hardware processador e do monitor da máquina virtual. Se ele reconhecer seu
ambiente virtual, ele pode explorar bugs na implementação do monitor virtual e
escapar do confinamento.
Detalhes como data/hora podem revelar instruções de máquina com tempo
diferentes.
É difícil, mas é possível combinar um nível alto de segurança com um bom
desempenho.
Para tanto, deve-se utilizar uma máquina de host dedicado que não contenha
informações sigilosas.
8. Confinamento de programas com prisões
chroot()
Existem soluções que fornecem separação no nível de processo.
Um recurso é o sistema de chroot() do UNIX. Ele restringe o acesso ao sistema de
arquivos, modificando o deretório raiz de um processo. Ele limita a exposição de
um sistema, e é frequentemente utilizado para dificultar o comprometimento de
servidores FTP e WWW.
Com o passar do tempo, as ideias foram expandindo, para abranger o escopo de
outras chamadas de sistema. Esses recursos podem ser chamados de prisões.
Prisões alteram não apenas a ideia que um processo faz do seu diretório-raiz no
sistema de arquivos, mas também o que são seus processos vizinhos, qual é o
endereço IP do sistema e assim por diante.
A vantagem das prisões em relação às máquinas virtuais é o custo: elas não têm o
overhead de software de um monitor de máquina virtual nem os custos de um
hardware especializado.
9. Análise dinâmica com monitores de
chamada de sistema
Com chamadas de sistema, examinamos as informações que vão do processo até os
limites do kernel: nomes de chamadas de função, argumentos e valores de resultado.
Entre as chamadas de sistema, ignoramos o que acontece dentro de um processo.
Efetivamente, o processo inteiro é chamado como uma caixa preta. Essa abordagem
faz sentido em ambientes operacionais onde cada acesso de arquivo, cada acesso de
rede e até algo tão simples como obter a hora do dia requer a assistência de uma
chamada de sistema pelo kernel do sistema operacional.
Informações sobre chamadas de sistema são particularmente apropriadas para filtrar
o nome da chamada de função, valores de argumento ou valores de resultado. Isso
ajuda a diminuir a pesquisa antes de descer até o nível da instrução de máquina para
melhores detalhes.
10. Resumidamente, aplicativos típicos de monitoramento de chamadas funcionam da seguinte
forma:
1) O processo monitorado invoca uma chamada de sistema.
2) O kernel de sistema operacional passa o controle ao processo de monitoramento para que este
possa inspecionar o processo monitorado. Isso inclui a memória do processo, registradores do
processador, o número de chamadas de sistema que identifica a operação solicitada e os argumentos
das chamadas de sistema.
3) O kernel do sistema operacional executa a chamada de sistema.
4) Ao término da chamada de sistema, o processo de monitoramento pode inspecionar o processo
monitorado novamente, incluindo a memória, os registradores do processador e os resultados da
chamada de sistema.
5) O kernel passa o controle de volta para o processo monitorado.
Análise dinâmica com monitores de
chamada de sistema
11. Em geral, programas de monitoramento de chamadas de sistema produzem uma
linha de saída por chamada, com o nome da chamada de sistema, seus
argumentos e seu valor de resultado.
Entretanto, há uma desvantagem importante quanto ao rastreamento de uma
chamada de sistema: só pode haver um processo de rastreamento por processo
rastreado. Portanto, é possível que um invasor determinado torne um processo
não-rastreável se conectando ao processo antes que uma outra pessoa tenha a
chance de fazer o mesmo. A mera existência de um processo não-rastreável pode,
naturalmente, levantar suspeitas extremas.
Análise dinâmica com monitores de
chamada de sistema
12. Confinamento de programa com censores
de chamada de sistema
Além do monitoramento passivo, é possível implantar ganchos de monitoramento
de chamadas de sistema para restringir as ações de um processo monitorado. As
ferramentas de censura de chamadas de sistema podem ajudar a executar software
desconhecido por meio de seus passos sem permitir que ele cause danos no seu
ambiente. Essas restrições são impostas quer por um processo no nível do usuário
que censura chamadas de sistema indesejáveis, quer pelo código no nível do kernel
que faz o mesmo.
O sistema Janus é um exemplo de censor de chamada de sistema no nível do
usuário. O propósito do Janus é limitar os danos que aplicativos falhos podem
causar quando executados por usuários normais. Tal sistema intercepta as chamadas
de sistema com um processo monitorado e examina seus valores de argumento. Ele
utiliza diretivas estáticas que devem ser definidas antecipadamente.
13. Confinamento de programa com censores
de chamada de sistema
Já o Systrace é um censor de chamada de sistema baseada em Kernel. Tal censor
intercepta as chamadas de sistema feitas por um processo monitorado e comunica-
se com um processo no nível do usuário que toma as decisões de diretiva.
Os censores de chamada de sistema que executam dentro do kernel têm uma
vantagem importante em relação a implementações no nível do usuário: eles têm
acesso ao estado completo do processo monitorado e, portanto, podem ser mais
precisos. Entretanto, podem apresentar limitações.
14. Confinamento de programa com spoofing
(falsificação) de chamada de sistema
Embora executar um programa sob o controle de um censor de chamada de
sistema impeça danos, isso também evita saber sobre esse dano. A alternativa é
permitir que o dano aconteça, mas sem efeitos permanentes. Uma abordagem é
utilizar uma máquina virtual baseada em software com suporte de sistema de
arquivos que não pode ser refeito.
Há dois momentos em que um processo de monitoramento pode facilmente
acessar a memória e os registradores de processador de um processo monitorado:
na entrada da chamada de sistema e no retorno da chamada de sistema.
O processo monitorado faz chamadas de sistema, mas essas chamadas na verdade
não acontecem. Tal processo permanece isolado do mundo, fornecendo apenas
uma ilusão.
15. Os perigos do confinamento com
chamadas de sistema
Como visto anteriormente, a interceptação de chamadas de sistema é atraente por
que abrange todas as interações entre um processo e seu ambiente, e porque ela
manipula as informações e um nível útil de agregação.
16. Os perigos do confinamento com
chamadas de sistema
Porém, há armadilhas nesse processo:
Quando a censura de chamada de sistema é implementada por um processo no
nível do usuário, esse processo tem de monitorar o diretório atual do processo
monitorado, abrir arquivos, abrir soquetes de rede e assim por diante. Essas
informações são mantidas pelo Kernel e tentar monitorar sua evolução em um
processo no nível do usuário introduz oportunidades para erros, condições de
ocorrência e outros problemas.
Censores de chamadas de sistema têm problemas de múltiplas threads, em que
múltiplas threads de execução compartilham o mesmo espaço de endereçamento.
Quando uma thread faz uma chamada de sistema, somente essa thread é
bloqueada. Isso torna os censores de chamadas de sistema vulneráveis a condições
de concorrência, sejam eles executados como um processo no nível do usuário ou
como um modulo do Kernel.
17. Análise dinâmica com monitores de
chamada de biblioteca
Enquanto um monitoramento de chamada de sistema trata um programa como uma
caixa preta e só examina as entradas e saídas, o monitoramento de chamadas de
biblioteca fornece melhor visão sobre a estrutura interna de um programa.
Exemplos de programas de monitoramento de chamadas de biblioteca são ltrace
(Linux e alguns descendentes 4.4BSD) e sotruss (Solaris). Esses programas em geral
podem mostrar tanto chamadas de sistema como chamadas de bibliotecas, embora
só mostrem chamadas de biblioteca por padrão.
18. Confinamento de programa com
chamadas de biblioteca
O spoofing de chamada de biblioteca é uma técnica que intercepta chamadas de
algum programa como bibliotecas de sistema. É um aplicativo simples, as
chamadas de rotina da biblioteca de sistema são monitoradas e talvez alguns
argumentos ou resultados modificados. Em um aplicativo mais extremo, as
bibliotecas de sistema nunca são invocadas.
O método da caixa de areia no nível da biblioteca funciona no Solaris, FreeBSD,
Linux e em outros sistemas com uma arquitetura semelhante de software.
19. Os perigos do confinamento com
chamadas de biblioteca
Embora a interceptação de chamada de sistema e de chamada de biblioteca pareçam
técnicas muito semelhantes, há diferenças fundamentais no que diz respeito a
segurança.
Chamadas de sistema têm de cruzar uma barreira baseada em hardware (a interface
entre o processo e o Kernel) e não podem ser detectadas, nem pode um processo
mentir sobre o nome de chamada de sistema.
Os monitores de chamada de biblioteca, por outro lado, dependem inteiramente das
informações existentes dentro do espaço de endereçamento do processo monitorado.
Se um programa não seguir as regras e se o programa de monitoramento não for
projetado para controlar código hostil, esse código pode driblar os mecanismos de
monitoramento de chamada de biblioteca de uma maneira relativamente fácil.
20. Análise dinâmica no nível de instrução de
máquina
A execução controlada das instruções de máquina individuais com depuradores de
software ou emuladores de máquina fornecem controle total sobre o conteúdo das
posições de memória, registradores de processador e podem alterar o fluxo do
programa de forma arbitraria, pulando as chamadas de função e alterando o
desvio tomado depois de uma decisão. No entanto, o uso dessa ferramenta
demanda tempo.
21. Análise estática e engenharia reversa
A desassemblagem de programa é um recurso padrão de todo programa
depurador importante. Entretanto, ferramentas que descompilam programas de
volta a uma linguagem de nível mais alto como C só existem em ambientes
limitados.
Preocupações quanto a furto de propriedade intelectual talvez tenham muito a ver
com essa disponibilidade limitada de descompiladores. Recuperar o código-fonte
em C por meio da engenharia reversa não é tão difícil assim. O compilador C típico
produz código de máquina preenchendo modelos padrão de instruções. O código
resultante contém uma grande quantidade de instruções redundantes que são
eliminadas pelo otimizador de compilador (que é desativado por padrão no UNIX).
22. Pequenos programas podem ter muitos
problemas
Com exceção de chamada de função de comparação de string strcmp ( ),
nenhuma chamada de função é testada quanto a retorno de erros. Se uma
operação falhar, o programa simplesmente prossegue.
23. Contramedidas da análise de malware
Anteriormente, foi mencionado que alguns malwares não seguem as regras a fim de
complicar a análise do programa. Muitas dessas técnicas têm por objetivo proteger a
propriedade intelectual do próprio software ou proteger os dados tratados por esse
software.
Um arquivo de programa não irá descompilar em código-fonte de alto nível se esse
programa não tiver sido gerado por um compilador de linguagem de alto nível, ou se a
saída de compilador tiver sido executada por ofuscador de código.
Um arquivo executável criptografado só pode ser examinado por aqueles que conhecem
a chave de decriptação.
A análise torna-se mais complexa pelo código automodificável, código que salta para os
dados (incluindo código de estouro de buffer), código que na verdade são dados para um
interceptador privado e outros truques que confundem o limite entre o código e os
dados.
24. Conclusão
Cada técnica discutida nesse estudo tem seu campo de aplicabilidade. A
desassemblagem e descompilação demonstra que a análise estática só é praticável
com programas muito pequenos.
Com programas maiores, uma combinação de análise estática e dinâmica é mais
promissora: a análise dinâmica mostra onde a execução entra e a análise estática
mostra por que o programa entra aí. Porém, a análise dinâmica não é recomendada
se salvaguardas: hosts dedicados, hosts virtuais ou, no mínimo, prisões, para
confinar um software suspeito a um local em que ele possa entrar e os danos
permanentes que ele possa causar.