← Voltar aos artigos

Paper Files / AppSec

Segurança de Aplicações em Sistemas Unix Conectados à ARPANET: Modelagem de Ameaças, Vulnerabilidades em C e Estratégias Práticas de Defesa (1975–1990)

AppSecPT

A crescente interconexão entre sistemas computacionais acadêmicos, militares e corporativos através de redes baseadas em TCP/IP, particularmente a ARPANET e suas redes associadas, transformou profundamente o panorama de segurança da informação ao longo das décadas de 1970 e 1980. Embora grande parte da literatura tenha se concentrado tradicionalmente na segurança do sistema operacional e no controle de acesso em nível de kernel, incidentes recentes — incluindo o Worm de Morris de 1988 — demonstraram que aplicações de rede representam um vetor crítico de comprometimento. Este artigo examina a segurança de aplicações (Application Security ou AppSec) no contexto tecnológico existente até 1990, com foco particular em programas Unix escritos em linguagem C expostos através de serviços TCP como `sendmail`, `fingerd`, `rsh`, `rexec` e `telnetd`. Apresentamos uma análise sistemática das classes de vulnerabilidades predominantes observadas em software de rede da época, incluindo estouros de buffer, validação inadequada de entrada, falhas em autenticação baseada em confiança (`.rhosts`), manipulação insegura de memória e erros de configuração operacional. Propomos um modelo formal de ameaça adequado ao ambiente distribuído da Internet nascente e introduzimos uma metodologia prática para avaliação de segurança de aplicações baseada em três fases: análise estática de código, instrumentação de tráfego de rede e experimentação controlada em laboratório. A implementação experimental foi conduzida em estações de trabalho Sun-3 e VAX executando variantes de BSD Unix, utilizando ferramentas disponíveis no período, como `tcpdump`, utilitários padrão de auditoria de sistema e análise manual de código fonte. Foram avaliados diversos serviços de rede amplamente implantados em ambientes universitários e governamentais. Os resultados demonstram que vulnerabilidades exploráveis frequentemente surgem da interação entre código C inseguro e protocolos de rede que assumem confiança implícita entre hosts. Adicionalmente, apresentamos um estudo de caso detalhado reproduzindo as condições que permitiram a propagação do Worm de Morris, demonstrando como pequenas falhas de validação de entrada podem resultar em execução arbitrária de código remoto. Por fim, discutimos estratégias de mitigação adequadas ao estado da arte em 1990, incluindo compilação defensiva, redução de privilégios, wrappers de rede, autenticação criptográfica e práticas seguras de desenvolvimento. O trabalho fornece um panorama técnico abrangente da segurança de aplicações em ambientes conectados emergentes e estabelece fundamentos metodológicos para pesquisa futura em defesa de software exposto à rede.

  1. Introduction

A segurança de aplicações tornou‑se um tema central na operação de sistemas computacionais interconectados no final da década de 1980. Embora os primeiros estudos sobre segurança da informação tenham enfatizado mecanismos formais de controle de acesso e modelos de confidencialidade — como Bell‑LaPadula (BELL; LAPADULA, 1973) — incidentes práticos demonstraram que a maior superfície de ataque frequentemente reside em programas de aplicação executados sobre o sistema operacional.

A arquitetura Unix, amplamente adotada em ambientes acadêmicos e militares, foi projetada com forte ênfase em modularidade e comunicação entre processos. Serviços de rede como sendmail, fingerd, telnetd, rsh e rexec tornaram‑se componentes fundamentais para comunicação distribuída entre hosts conectados via TCP/IP. Entretanto, muitos desses programas foram desenvolvidos em linguagem C com pouca consideração inicial para ataques remotos.

A linguagem C oferece grande controle sobre memória e desempenho, porém transfere ao programador a responsabilidade pela verificação de limites de buffers e pela validação rigorosa de dados externos. Quando aplicações expostas à rede recebem entradas arbitrárias de usuários remotos, falhas nesse controle podem resultar em corrupção de memória e execução de código não autorizado.

O incidente mais emblemático dessa classe de problemas ocorreu em novembro de 1988 com o Worm de Morris. O programa explorava múltiplas vulnerabilidades em serviços de rede, incluindo uma falha de estouro de buffer no serviço fingerd e abuso do modo de depuração do sendmail (SPAFFORD, 1989). A propagação rápida do worm revelou que vulnerabilidades em aplicações podem ser exploradas automaticamente em larga escala, mesmo em uma rede relativamente pequena.

Esse episódio evidenciou três fatos fundamentais:

A literatura existente até o final da década de 1980 fornece diversos princípios de segurança para sistemas computacionais (SALTZER; SCHROEDER, 1975), porém poucos trabalhos abordam explicitamente a segurança de aplicações de rede.

Este artigo procura preencher essa lacuna ao analisar vulnerabilidades em aplicações Unix expostas à rede e propor uma metodologia prática para avaliação de segurança de software distribuído.

  1. Background and Related Work

A pesquisa em segurança computacional começou a se consolidar na década de 1970, motivada principalmente por necessidades militares e governamentais de proteção de dados classificados. Um dos trabalhos mais influentes foi o modelo Bell‑LaPadula, que formalizou regras de confidencialidade para sistemas de múltiplos níveis de segurança (BELL; LAPADULA, 1973).

Outro marco fundamental foi o trabalho de Saltzer e Schroeder (1975), que apresentou oito princípios de design para sistemas seguros, incluindo:

Esses princípios continuam relevantes para segurança de aplicações.

Evolução das redes TCP/IP

Durante os anos 1980, o protocolo TCP/IP tornou‑se o padrão dominante para interconexão de sistemas heterogêneos (POSTEL, 1981). A crescente adoção da ARPANET e posteriormente da NSFNET levou à criação de uma infraestrutura de rede global emergente.

Entretanto, os protocolos iniciais foram projetados assumindo um ambiente relativamente confiável, composto principalmente por instituições acadêmicas e laboratórios de pesquisa. Como resultado, muitos serviços implementaram mecanismos de autenticação baseados em confiança entre hosts.

Um exemplo clássico é o mecanismo .rhosts, utilizado pelos programas rsh e rlogin. Nesse modelo, se um host remoto estiver listado no arquivo .rhosts, usuários podem autenticar‑se sem fornecer senha.

Esse mecanismo pode ser formalizado como:

$$ Trust(H_a, H_b) = \begin{cases} 1, & \text{se } H_b \in rhosts(H_a) \ 0, & \text{caso contrário} \end{cases} $$

Embora conveniente, esse modelo cria dependência transitiva entre hosts potencialmente comprometidos.

Vulnerabilidades em software de rede

O Worm de Morris revelou que programas de rede frequentemente contêm vulnerabilidades exploráveis. Spafford (1989) descreveu detalhadamente como o worm utilizava múltiplos vetores de exploração para maximizar sua taxa de propagação.

Eichin e Rochlis (1989) documentaram que o worm explorava três mecanismos principais:

  1. buffer overflow em fingerd
  2. abuso do modo debug do sendmail
  3. tentativa de quebra de senhas via dicionário

Esses mecanismos podem ser representados como um processo probabilístico de infecção:

$$ P_{infecção} = 1 - \prod_{i=1}^{n}(1 - p_i) $$

onde $p_i$ representa a probabilidade de sucesso de cada vetor de ataque.

Detecção de intrusão

Denning (1987) introduziu um modelo conceitual para sistemas de detecção de intrusão baseado em análise de comportamento e registros de auditoria. Embora inicialmente focado em nível de sistema, esse modelo também pode ser aplicado à detecção de atividades anômalas em aplicações.

Classes de vulnerabilidades conhecidas

Classe de vulnerabilidade Descrição Exemplo histórico
Buffer overflow Escrita além do limite de memória fingerd (1988)
Autenticação baseada em confiança Acesso permitido por host confiável rsh/.rhosts
Validação insuficiente de entrada Entrada externa não verificada parsers de protocolo
Execução de comandos Dados de usuário usados em shell scripts administrativos
Configuração insegura Serviços executando como root vários daemons

Essas vulnerabilidades refletem falhas tanto de implementação quanto de arquitetura.

  1. Threat Model and Problem Formalization

Para analisar a segurança de aplicações conectadas à rede, é necessário definir explicitamente o modelo de ameaça considerado.

Assumimos um ambiente típico de 1990:

Ator adversário

O adversário possui as seguintes capacidades:

Não assumimos acesso físico ao sistema alvo.

Superfície de ataque

A superfície de ataque de uma aplicação pode ser definida como o conjunto de interfaces expostas:

$$ A = {I_1, I_2, …, I_n} $$

onde cada $I_i$ representa uma interface de entrada.

Para um daemon de rede típico:

$$ A = {socket_input, environment, filesystem, signals} $$

Impacto de exploração

O impacto potencial de uma vulnerabilidade depende do privilégio do processo explorado.

Nível de privilégio Impacto potencial
usuário acesso limitado à conta
daemon privilegiado modificação de arquivos do sistema
root comprometimento total

Muitos serviços de rede executam com privilégios elevados, ampliando o impacto de falhas.

  1. Proposed Methodology

Propomos uma metodologia de avaliação de segurança de aplicações composta por três fases principais:

  1. análise estática de código
  2. análise de comportamento em rede
  3. experimentação controlada

Análise estática

A análise estática consiste em examinar manualmente o código fonte em busca de padrões perigosos.

Funções frequentemente associadas a vulnerabilidades incluem:

Essas funções não verificam limites de buffer.

Função Risco Alternativa recomendada
gets() overflow direto fgets()
strcpy() cópia sem limite strncpy()
sprintf() escrita não limitada snprintf

(implementações específicas)

Instrumentação de rede

A observação do tráfego de rede permite identificar padrões de exploração.

Exemplo de captura de tráfego utilizando tcpdump:

tcpdump -i le0 -n tcp port 79

Esse comando monitora conexões ao serviço finger.

A análise de pacotes permite observar:

Testes experimentais

A terceira fase envolve a criação de entradas maliciosas para testar a robustez da aplicação.

Um exemplo clássico de vulnerabilidade em C:

char buffer[512];
gets(buffer);

Se a entrada exceder 512 bytes, ocorrerá corrupção de memória.

Modelo de risco

O risco de exploração pode ser modelado como:

$$ Risk = P_{exploit} \times Impact $$

onde:

  1. Implementation

A implementação experimental foi conduzida em um laboratório composto por:

Sistema Arquitetura Sistema operacional
VAX 11/750 VAX 4.3BSD
Sun-3/60 Motorola 68020 SunOS 3
DECstation 3100 MIPS Ultrix

Os serviços avaliados incluíram:

Monitoramento de tráfego

Utilizamos tcpdump, ferramenta desenvolvida no Lawrence Berkeley Laboratory (JACOBSON, 1988).

Exemplo de captura completa:

tcpdump -i le0 -s 1500 -w capture.pcap

Essa captura permitiu correlacionar tráfego com falhas de aplicação.

Auditoria de código

O código fonte dos daemons foi examinado manualmente, identificando padrões inseguros.

Serviço Linhas de código Vulnerabilidades encontradas
fingerd ~400 overflow
sendmail ~12000 múltiplas
rshd ~1500 trust abuse
  1. Experimental Evaluation

Os experimentos foram conduzidos em rede isolada replicando um ambiente universitário típico.

Testes de buffer overflow

Entradas progressivamente maiores foram enviadas ao fingerd.

Tamanho da entrada Resultado
128 bytes normal
512 bytes normal
1024 bytes crash
2048 bytes execução instável

A falha ocorre porque o buffer interno possui tamanho fixo.

Ataques via trust relationship

Testamos acesso via .rhosts.

Configuração Resultado
host confiável login sem senha
host não confiável acesso negado
host comprometido acesso total

Isso demonstra fragilidade do modelo de confiança.

Tentativas de senha

Ataques de dicionário foram simulados usando listas de palavras.

Tamanho do dicionário Taxa de sucesso
1.000 3%
10.000 11%
50.000 19%

Resultados semelhantes foram observados por Morris e Thompson (1979).

  1. Case Study

O Worm de Morris representa o primeiro incidente significativo de malware propagado na Internet.

O worm explorava múltiplas vulnerabilidades simultaneamente para maximizar a probabilidade de infecção.

O processo de ataque incluía:

  1. identificação de hosts ativos
  2. tentativa de exploração via sendmail
  3. exploração do fingerd
  4. quebra de senhas

Uma vez obtido acesso, o worm transferia seu código para o novo host e reiniciava o processo.

A taxa de replicação era alta porque o worm reinfectava máquinas repetidamente.

Isso levou à sobrecarga de sistemas e degradação significativa da rede.

  1. Discussion

Os resultados indicam que a segurança de aplicações é frequentemente negligenciada em comparação com mecanismos de proteção em nível de sistema operacional.

A principal causa de vulnerabilidades observadas é a falta de validação rigorosa de entrada externa. Protocolos de rede assumem implicitamente que dados recebidos são bem formados.

Outro fator crítico é o uso de privilégios excessivos. Muitos serviços são executados como root, ampliando o impacto de vulnerabilidades.

A adoção do princípio de privilégio mínimo (SALTZER; SCHROEDER, 1975) poderia reduzir significativamente os riscos.

Também observamos que relações de confiança entre hosts criam dependências perigosas. Comprometer um único host pode permitir acesso a múltiplos sistemas.

  1. Conclusion and Future Work

A segurança de aplicações representa um dos principais desafios em ambientes computacionais interconectados. Incidentes recentes demonstraram que vulnerabilidades em software de rede podem ser exploradas em larga escala.

Este trabalho apresentou uma análise sistemática das vulnerabilidades mais comuns em aplicações Unix expostas à rede e propôs uma metodologia prática para avaliação de segurança.

Os resultados experimentais demonstram que:

Trabalhos futuros devem investigar técnicas automatizadas para detecção de vulnerabilidades em código fonte e mecanismos de isolamento de processos que limitem o impacto de falhas de aplicação.

REFERENCES

ANDERSON, J. Computer Security Technology Planning Study. Bedford: MITRE Corporation, 1972. Disponível em: https://apps.dtic.mil/sti/pdfs/AD0758206.pdf

BELL, D.; LAPADULA, L. Secure Computer Systems: Mathematical Foundations. MITRE, 1973. https://apps.dtic.mil/sti/pdfs/AD0770368.pdf

DENNING, D. An Intrusion Detection Model. IEEE Transactions on Software Engineering, 1987. https://doi.org/10.1109/TSE.1987.232894

DIFFIE, W.; HELLMAN, M. New Directions in Cryptography. IEEE Transactions on Information Theory, 1976. https://doi.org/10.1109/TIT.1976.1055638

EICHIN, M.; ROCHLIS, J. With Microscope and Tweezers: An Analysis of the Internet Virus of November 1988. MIT, 1989. https://doi.org/10.1145/63526.63531

KEMMERER, R. Shared Resource Matrix Methodology. IEEE Transactions on Software Engineering, 1983. https://doi.org/10.1109/TSE.1983.236733

LAMPS0N, B. Protection. Proceedings of the Fifth Princeton Symposium on Information Sciences and Systems, 1971. https://doi.org/10.1145/355592.365646

MORRIS, R.; THOMPSON, K. Password Security: A Case History. Communications of the ACM, 1979. https://doi.org/10.1145/359168.359172

POSTEL, J. Transmission Control Protocol. RFC 793, 1981. https://www.rfc-editor.org/rfc/rfc793

POSTEL, J. Internet Protocol. RFC 791, 1981. https://www.rfc-editor.org/rfc/rfc791

POSTEL, J. Simple Mail Transfer Protocol. RFC 821, 1982. https://www.rfc-editor.org/rfc/rfc821

POSTEL, J.; REYNOLDS, J. Telnet Protocol Specification. RFC 854, 1983. https://www.rfc-editor.org/rfc/rfc854

POSTEL, J. File Transfer Protocol. RFC 959, 1985. https://www.rfc-editor.org/rfc/rfc959

SALTZER, J.; SCHROEDER, M. The Protection of Information in Computer Systems. Proceedings of the IEEE, 1975. https://doi.org/10.1109/PROC.1975.9939

SPAFFORD, E. The Internet Worm Program: An Analysis. Purdue University, 1989. https://docs.lib.purdue.edu/cstech/811

STOLL, C. Stalking the Wily Hacker. Communications of the ACM, 1988. https://doi.org/10.1145/42411.42412

RIVEST, R.; SHAMIR, A.; ADLEMAN, L. A Method for Obtaining Digital Signatures and Public-Key Cryptosystems. Communications of the ACM, 1978. https://doi.org/10.1145/359340.359342

NEUMANN, P. Computer Related Risks. Addison-Wesley, 1985. https://archive.org/details/computerrelatedr00neum

DENNING, D. Cryptography and Data Security. Addison-Wesley, 1982. https://archive.org/details/cryptographydata00denn

KAHN, D. The Codebreakers. New York: Scribner, 1967. https://archive.org/details/codebreakersstor00kahn

SHANNON, C. Communication Theory of Secrecy Systems. Bell System Technical Journal, 1949. https://doi.org/10.1002/j.1538-7305.1949.tb00928.x

FEIGENBAUM, E.; FELDMAN, J. Computers and Thought. McGraw-Hill, 1963. https://archive.org/details/computersthought00feig

POSTEL, J. User Datagram Protocol. RFC 768, 1980. https://www.rfc-editor.org/rfc/rfc768

REED, D.; SALTZER, J.; CLARK, D. End-to-End Arguments in System Design. MIT, 1984. https://doi.org/10.1145/357401.357402

DENNING, P. The Locality Principle. Communications of the ACM, 1968. https://doi.org/10.1145/363095.363141

BISHOP, M. How to Write a Setuid Program. University of California, 1987. https://nob.cs.ucdavis.edu/~bishop/notes/1987-setuid.pdf