Sysadmin
Conexões TCP
Entendendo e evitando ataques ao protocolo TCP
É bastante simples derrubar uma conexão TCP bombardeando-a com pacotes TCP/RST. O risco aumenta nos serviços que
precisam de conexões de longa duração, como as VPNs, as transferências de zona DNS ou o Border Gateway Protocol (BGP).
Descreveremos como um ataque TCP pode ser perpetrado, bem como técnicas simples para proteger sua rede deles.
por Christoph Wegener e Wilhelm Dolle
D
esde 1985 os especialistas vão a
público execrar o protocolo Transmission Control Protocol (protocolo
de controle de transmissão), o conhecido
TCP. Derrubar serviços, corromper ou mesmo seqüestrar conexões TCP já existentes
é brincadeira de criança. As informações
necessárias para isso podem ser obtidas
com o mais simples dos sniffers : os endereços IP de origem e destino e um número
seqüencial TCP válido. Se o agressor puder
farejar a conexão em qualquer ponto do
trajeto, a batalha já estará perdida antes
de começar. É fato que para isso o invasor
precisa necessariamente controlar uma máquina que esteja no caminho entre o cliente
e o servidor – se não tiver, as coisas ficam
bem complicadas para ele. Entretanto, as
pessoas superestimam o esforço necessário
para “invadir” uma conexão. Truques como
a previsibilidade da janela TCP tornam as
coisas ainda mais fáceis.
Um dos problemas mais difíceis de resolver, para o agressor, é determinar (ou antes,
“chutar”) a seqüencia correta de números.
Só informando o número seqüencial exato
esperado pela máquina destino é que conseguiremos convencê-la de que os datagramas
66
outubro 2005
IP que estamos injetando na conexão realmente pertencem à conexão. Se o agressor
possuir os valores corretos, não há nada
que o impeça de injetar dados numa conexão já estabelecida. Com isso ele pode, por
exemplo, ganhar acesso não autorizado a
informações ou simplesmente derrubar a
conexão – basta enviar um único pacote
TCP com a flag de Reset (RST) ativada.
Em muitos casos, uma conexão interrompida é apenas irritante, mas não
desastrosa. Um exemplo: se você estiver
navegando na web, quando a conexão
cair basta atualizar a página. Mas em
outras situações, os problemas são bem
maiores: repetidas interrupções numa
conexão BGP (Border Gateway Protocol
ou protocolo de roteamento de fronteira)
entre dois roteadores no núcleo da Internet podem ser deveras caras.
Um ataque de negação de serviço (também chamado DoS – Denial of Service)
pode ser potencialmente prejudicial também para pequenas empresas. Imagine,
por exemplo, que crackers impiedosos
repetidamente derrubem uma loja virtual
por longos períodos. Os prejuízos resultantes seriam consideráveis [1].
edição 13
www.linuxmagazine.com.br
Começando pelo começo
Precisamos entender o funcionamento básico do protocolo TCP para compreender
o que é a tal vulnerabilidade e como pode
ser explorada. O protocolo TCP teve suas
especificações defi nidas no documento
Request for Comments (RFC) de número
793 [2] , publicado em 1981. O nome Request for Comments é intraduzível – ou,
antes, impossível de ser grafado numa forma sucinta como no inglês – mas pode ser
entendido como um documento primário,
que defi ne as especificações de alguma
coisa e pede que a comunidade científica
emita comentários a respeito. O peculiar
desse processo é que o documento, depois
de terminado, não muda de nome nem
se torna algo “defi nitivo”: continua a se
chamar Request for Comments.
De qualquer forma, o documento RFC
793 defi ne as especificações do protocolo
TCP. Conforme descrito, cada datagrama
TCP começa com um cabeçalho (figura
1), que contém as portas de origem e
destino da conexão – ambas são valores
de 16 bits, portanto variam, em decimal,
entre 0 e 65.535. Mais adiante, no mesmo cabeçalho, temos alguns parâmetros
credits of the images
Esquadrão
anti-seqüestro
Conexões TCP
Sysadmin
Histórico de Vulnerabilidades
importantes: o número seqüencial, que
MP3 de 4 MB tivesse que ser
identifica o pacote de forma única na
baixado em um único pacotão
1981: O Transmission Control Protocol (TCP) é especificado
conexão, e o número de reconhecimento, com esse tamanho. Além de um
num documento Request for Comment, a RFC793 [2].
que serve para informar à outra máquina
único pacote monopolizar a rede
1985: Bob Morris aponta vulnerabilidades no TCP [15].
que o pacote que ela enviou anterior- por muito tempo, o hardware
1994: Mesmo já ocorrendo há anos, a manipulação maldosa
mente foi recebido sem erros. Ambos os
para tratar esse pacote não seria
das vulnerabilidades do protocolo TCP só ganha as manchetes
quando Kevin Mitnick usa uma técnica chamada Christmas
números são de 32 bits. Temos, ainda, nem simples nem confiável. Para
Day (Dia de Natal) para invadir o especialista em segurança
algumas flags de controle da conexão
resolver o problema, o protocolo
Tsutumo Shimomura [19].
(SYN, ACK, PSH, URG, RST e FIN – fala- TCP baseia-se na fragmentação
1995: Paul Watson publica um documento que discorre sobre
remos delas mais adiante) e o tamanho
dos pacotes: os dados são divias vulnerabilidades do TCP ligadas à Usenet. Esse documento
da janela de recepção. Esse último é o
didos em pequenos segmentos
recebe atenção geral. Várias pesquisas são iniciadas, espeponto crítico em que se baseia o ataque
e cada um deles é transmitido
cialmente no que concerne aos geradores de numeração
seqüencial
TCP.
que discutiremos.
num pacote TCP.
1995: Laurent Joncheray apresenta seu artigo científico
Uma conexão estabelecida é unicaÉ fácil perceber o perigo
que isso acarreta. Qualquer "Simple Active Attack against TCP" (um ataque simples contra o
mente identificada por uma quádrupla
TCP) na conferência Usenix [15].
que consiste das duplas endereço IP/porta
um que possa determinar os
2001: O Cert descreve uma vulnerabilidade comum em vários
de origem e endereço IP/porta de destino. detalhes da quádrupla e inferir
geradores de números seqüenciais TCP/IP e menciona o proNuma conexão podem passar inúmeros
um número seqüencial válido
blema do tamanho da janela TCP. [16].
pacotes em ambos os sentidos (do clien- tem tudo o que é preciso para
2003: Paul Watson mostra que os ataques são bastante fáceis
te para o servidor e do servidor para o “entrar de penetra” em uma
de levar a cabo mesmo com simples conexões DSL.
conexão. Não importa a pocliente). Cada pacote possui um número
2004: O IETF (Internet Engineering Task Force ou força-tarefa
que o identifica e diferencia dos demais: o
sição em que o invasor esteja
de engenharia da Internet) publica uma versão inicial do
número seqüencial. Pense nele como um
na rede: basta criar um pacote
documento "Improving TCP's Robustness to Blind In-Window
Attacks"
(aprimorando a robustez do TCP contra ataques
“crachá” com um número escrito pelo nó
adulterado (“spoofado” – neolo“cegos”
a
seu tamanho de janela) [10].
de rede que o enviou. Todo pacote indivi- gismo derivado do inglês spoodual tem o seu “crachá” com um número
fed –, no jargão dos canalhas)
e enviá-lo ao destino.
exclusivo. O nó da rede que recebe os
certo. Entretanto, essa dificuldade fica própacotes sabe, por esse número, em qual
xima de zero caso os sistemas operacionais
ordem reorganizá-los (já que, graças ao
dos nós de origem e destino não iniciem a
“desorganizado” IP, eles podem chegar
A princípio, um número seqüencial pode re- contagem de números seqüenciais – esse
fora de ordem) e percebe, também, se
ceber um valor entre zero e 232. Isso, em te- valor é chamado de Initial Sequence Number
algum deles está faltando.
oria, deveria criar uma dificuldade enorme
(ISN) – com um valor aleatório quando a
Tudo isso é necessário porque seria im- para um agressor inferir um número válido, conexão é estabelecida.
praticável transmitir os dados do usuário
criar um pacote TCP com esse número e
Explicando melhor: quando uma cotodos de uma vez. Imagine se um arquivo
injetar esse pacote na conexão no momento
nexão TCP é estabelecida (usando o
chamado 3-way handshake), ambos os
0
7 8
15 16
23 24
31
participantes da conexão estabelecem
Source Port
Destination Port
seu número seqüencial inicial (ISN) com
Sequence Number
um número aleatório. Esse número vale
Acknowledgement Number
para o primeiro pacote que um dos nós
manda para o outro. A partir daí, os núData Offset
Reserved
Window
meros
seqüenciais de ambos os lados são
Checksum
Urgent Pointer
incrementados, a cada pacote, com um
Options
número que representa a quantidade de
... Padding
bytes transmitida.
Figura 1: Todo datagrama TCP começa com esse cabeçalho. Os dados do usuário são inseridos depois.
Enquanto o número de porta do serEm conjunto com o endereço IP, os números de porta identificam de forma única a conexão. O número
vidor é, normalmente, um valor padrão,
seqüencial, por sua vez, identifica qual a posição desse pacote TCP no fluxo de dados.
que depende do serviço que “escuta” naFIN
RST
SYN
PSH
ACK
URG
Números aleatórios
outubro 2005
www.linuxmagazine.com.br
edição 13
67
Sysadmin
quela porta (por exemplo, um servidor
FTP normalmente está na porta 21), a
porta do cliente é um valor que pode assumir qualquer número, entre 0 e 65.535.
O fato de que as portas abaixo de 1024
são reservadas para acesso privilegiado
no Unix não é importante, no momento.
Acontece que, multiplicando o número de
valores possíveis do número seqüencial
(232) pelos números possíveis de porta
(216), obtemos um número assombroso
de tentativas que um agressor teria de
fazer para atacar remotamente uma conexão TCP sem “farejá-la”. Muitas pessoas
acham que, só por isso, a dificuldade do
agressor seria bastante alta. Eu poderia
dizer que muitos sistemas operacionais
não selecionam portas aleatoriamente, o
que deixaria as estatísticas mais amigáveis para o invasor – mas não levaremos
isso em consideração. Ainda…
O maior problema do TCP é o seu sistema de janela de conexão. Como já dissemos, os pacotes podem tomar caminhos
diversos na Internet para chegar a um
mesmo destino. Assim, um pacote que
saiu depois pode tomar um atalho e chegar antes de seu irmão mais velho, que
decidiu dar uma passeada pelos roteadores do Uzbequistão. A janela de conexão
permite que o nó que está recebendo os
pacotes possa colocar todos eles na ordem
correta e confirmar sua recepção para a
máquina emissora.
O glossário da RFC 793 explica o mecanismo de janelas da seguinte maneira:
“[O mecanismo de janelas] é uma lista
com os números seqüenciais que o sis-
Tabela 1: Tamanho inicial da janela
Sistema operacional
Linux Kernel 2.4
Linux Kernel 2.6
OpenBSD 3.6
Windows 2000 SP1 e SP2
Windows 2000 SP3 e SP4
Windows 2000 MS05-019
Windows XP Professional SP2
68
outubro 2005
Tamanho
5.840 Bytes
5.840 Bytes
16.384 Byte
17.520 Bytes
65.535 Bytes
17.520 Bytes
65.535 Bytes
Conexões TCP
tema local (o que recebe os pacotes TCP)
está esperando. Assim, a pilha TCP local
considera que segmentos que se sobreponham à faixa que vai de RCV.NXT até RCV.
NXT + RCV.WND-1 trazem informações
de controle ou dados do usuário que podem ser aceitos. O segmento que contém
números seqüenciais inteiramente fora
dessa faixa são considerados duplicatas
e descartados”.
Fechando a janela
Se o número seqüencial de um pacote
estiver dentro da janela de recepção, o
subsistema TCP do sistema operacional
(normalmente apelidado de “pilha TCP”)
irá aceitar e processar esse pacote. Isso
reduz consideravelmente o número de
tentativas que um agressor teria de fazer para se infiltrar na conexão. No caso
dos números seqüenciais, o número de
tentativas cai de astronômicos 232 para
232 /tamanho da janela.
Dependendo do sistema operacional, o
tamanho da janela pode variar. Por exemplo, o Windows XP Professional com o
SP2 aplicado possui um tamanho de janela de 65.535 bytes. Já o kernel do Linux
(tanto o 2.4 quanto o 2.6) possui uma
janela de 5.840 bytes. A tabela 1 mostra
alguns valores de sistemas operacionais
populares. O tamanho da janela também
varia de acordo com o aplicativo. O Telnet
de roteadores Cisco usa um tamanho de
janela de 4.192 bytes, mas o protocolo
BGP no mesmo roteador abre uma janela
de 16.384 bytes.
Não importa como encaremos a situação. Independente de nossas opiniões,
a janela de conexão vai reduzir drasticamente a quantidade de números
seqüenciais que um agressor precisa
experimentar. Se tomarmos um sistema
com o Windows XP, a quantidade de tentativas ficará abaixo de 65 mil. Em outras
palavras, um agressor precisaria gerar (e
injetar na conexão) míseros 65 mil pacotes com a flag RST ligada para derrubá-
edição 13
www.linuxmagazine.com.br
la. Esse é um número assustadoramente
baixo. Sistemas de detecção de invasões
(IDS – Intrusion Detection System) vão
obviamente fazer estardalhaço caso um
ataque desses ocorra. Entretanto, redes
cujo tráfego é pesado e que não possuam
essa ferramenta não vão nem notar esses
pacotes extras.
Altamente escalável
As coisas ficam ainda piores se os participantes da conexão puderem trabalhar
com o chamado redimensionamento de
janela (window scaling). Essa extensão do
TCP (RFC 1323, [3]) aumenta a dificuldade
do agressor para encontrar um número
seqüencial válido em um período curto de
tempo. O redimensionamento de janelas
foi projetado para conexões que precisem
de uma janela maior do que o tamanho
padrão – normalmente para situações de
alto tráfego ou latência. Para que todos
possam transmitir sem interrupções (e
sem esperar pelo reconhecimento), essa
técnica aumenta a janela de conexão em
até 14 bits, ou seja, multiplica tudo por
um fator de 16.384 (no Microsoft Windows). Resultado: a antiga restrição imposta
pela RFC 793 de que a janela não pode
ser maior que 65.535 bytes só vale caso
nenhum dos participantes da conexão use
o redimensionamento de janelas.
O agressor também precisa transpor
outro obstáculo: a quádrupla de endereço/porta de origem e destino. Os
endereços IP não são problema – os
agressores normalmente sabem em quem
estão atirando – e a porta do servidor
também não é lá muito difícil de inferir.
É, entretanto, ligeiramente mais difícil
determinar a porta de origem da conexão
(a do cliente), que pode ser um número
qualquer entre 0 e 65.535 – em teoria.
Na prática, o número é um milhar mais
baixo, já que as portas abaixo de 1024 e
acima de um determinado valor (definido
pelo sistema operacional) são reservadas
para tarefas especiais.
Conexões TCP
Figura 2a: O comando netstat -nt lista as conexões TCP. A distribuição dos números de porta
segue um esquema simples – o kernel simplesmente soma 1 ao número para cada nova conexão.
Um sistema Linux (com kernel 2.4 ou
2.6, indiferentemente) e com pelo menos
128MB de RAM usa portas de origem entre
32.768 e 61.000. Com menos de 128 MB, a
faixa se reduz mais ainda. O kernel usa as
portas acima de 61.000 para mascaramento
de IP. Esses valores podem ser conferidos
no arquivo /proc/sys/net/ipv4/ip_local_range. É possível alterá-los usando
o subsistema sysctl. Por exemplo, com o
comando: sysctl -w net.ipv4.ip_local_range="32768 61000".
“Chutar” pra quê?
Para deleite dos agressores, as 28.232
opções restantes não são distribuídas
aleatoriamente. Para falar a verdade, o
kernel as distribui baseado em um esquema bastante específico. Essa é uma
das mais chocantes revelações no documento divulgado por Paul Watson [4].
Os agressores não têm nenhum problema
para prever as portas de origem. Uma das
honrosas exceções é o OpenBSD, que realmente as escolhe de forma aleatória. O
Windows XP, por exemplo, começa com
a porta 1050 na primeira conexão e aumenta esse número para cada conexão
consecutiva. O Linux (testamos em um
Fedora Core 3 com kernel 2.6.9) não faz
menos feio: começa na porta 32.768 e,
também, incrementa o número para cada
conexão posterior.
A figura 2a mostra um sistema Linux
com kernel 2.6 (que distribuiu portas
entre 32.771 e 32.777). Compare-a com
a figura 2b, que mostra como o OpenBSD
3.6 distribuiu suas portas: completamente
aleatório! Os sistemas Cisco incrementam
o número de porta em 512 a cada nova
conexão – mas isso não torna o mecanismo mais seguro. Nem de longe.
Os agressores não precisam “chutar”
uma porta de origem caso já saibam o
número atual usado na máquina da vítima. Tudo o que um agressor precisa
fazer é começar com um valor inicial e
tentar no máximo 50 portas. Com perseverança, hackers fuçadores não terão
nenhum problema para mapear o sistema
operacional da vítima. Portanto, prever a
porta de origem não é, de forma alguma,
um obstáculo.
Técnicas de ataque
Muitos ataques em conexões TCP baseiamse nas vulnerabilidades discutidas até
aqui. Um dos mais simples requer apenas
a injeção de um único pacote TCP com
o bit RST ativado. De acordo com a RFC
793, essa flag diz ao outro participante
da conexão que esta deve ser derrubada
imediatamente, sem que haja interação
posterior. O nó que recebe esse pacote
avalia o número seqüencial e, possivel-
Sysadmin
mente, o número de reconhecimento
para decidir se deve honrar ou ignorar o
pedido de reset. Pela RFC, o sistema de
destino está proibido de enviar um RST
em resposta ao que recebeu.
O ponto importante aqui é o fato de
que o destino precisa necessariamente
decidir se aceita ou ignora o RST baseado na validade do número seqüencial. O
nó de destino só encerra a conexão se e
somente se o número seqüencial estiver
dentro da janela de conexão. Embora o
nó receptor possa levar em consideração
também o número de reconhecimento, ele
não é obrigado a fazê-lo. O especialista
em segurança Paul Watson (ver quadro
Histórico) investigou um grande número
de pilhas TCP e descobriu que a maioria
delas simplesmente ignora o número de
reconhecimento [4].
Um pacote RST recebido dentro da janela
permitida, com dados que combinem com
a conexão, sempre derrubará a conexão.
Conexões que precisam estar sempre estabelecidas – como as usadas pelo protocolo
BGP entre roteadores – são particularmente
vulneráveis a ataques RST. Primeiro porque, como a conexão é semi-permanente, o
agressor tem todo o tempo do mundo para
criar e injetar um pacote cuidadosamente esculpido. Em segundo lugar, os danos
que uma negação de serviço causa a essas
conexões são inomináveis. Cada vez que
a conexão é restabelecida, os roteadores
precisam reconfigurar suas tabelas de vizinhança, processo que pode demorar alguns
minutos em condições de trabalho reais. ➟
Figura 2b: O OpenBSD realmente toma alguma atitude para tornar a vida dos invasores mais difícil.
Entre outras coisas, os números de porta de origem que o kernel atribui a cada conexão são, realmente
aleatórios – os agressores terão que “chutar” o número, pois não há como prever nada.
outubro 2005
www.linuxmagazine.com.br
edição 13
69
Sysadmin
Morte síncrona
O que pouca gente sabe é que também é
possível derrubar uma conexão com um
pacote TCP/SYN. A RFC 793 especifica que
quando uma flag SYN for ativada no início
da conexão, o campo de número seqüencial deve conter um número que será usado como base para os posteriores. Se um
pacote SYN chega depois que a conexão
estiver iniciada, a RFC 793 considera isso
um erro na conexão. Como conseqüência,
o receptor é forçado a cancelar a conexão
transmitindo um datagrama TCP/RST.
O protocolo TCP foi projetado dessa maneira para evitar que a mesma conexão
seja iniciada duas vezes – quando o sis-
Glossário
Assinatura MD5: MD5 é uma técnica de criptografia que calcula uma seqüencia alfanumérica
única (chamada de hash, termo normalmente não
traduzido) que identifica um conjunto de dados
arbitrário. O hash é calculado tomando como base
o próprio conjunto de dados. Se usarmos uma senha para calcular o hash, o MD5 pode gerar uma
assinatura (hash assinado).
BGP: O Border Gateway Protocol (ou protocolo
de roteamento de fronteira) descreve como os
roteadores avisam seus vizinhos a respeito das
rotas de dados disponíveis. O grande trunfo do
protocolo BGP é o fato de que ele pode reunir
inúmeras opções de rota em uma única tabela
de roteamento.
Bits de controle: Flags presentes no cabeçalho
do datagrama TCP. São informações de um único
bit, que informam o estado de alguma coisa ou
controlam o comportamento da conexão. Há seis
desses controles:
P SYN (SYNncronization): Pedido de sincronização
no início da conexão;
P ACK (ACKnowledgement): Um pacote com o bit
ACK ligado indica que quem o enviou está confirmando o recebimento de todos os pacotes
cujo número seqüencial é menor do que o valor
presente no campo número de reconhecimento
do datagrama;
P FIN (FINish): Todos os dados foram enviados,
encerrar a conexão;
P RST (ReSeT): Cancelar a conexão imediatamente (“botão de pânico”);
P PSH (PuSH): Um pacote com o bit PSH ligado
ordena ao sistema operacional que o recebe
70
outubro 2005
Conexões TCP
tema operacional de um dos lados trava e
o sistema é reiniciado, por exemplo. Com
isso, um pacote SYN causa quase o mesmo
transtorno que um pacote RST: derruba a
conexão – desde que, obviamente, o número
seqüencial seja válido. Mas, ao contrário
do pacote RST, que impede qualquer ação
por parte do receptor (a não ser, é claro,
encerrar a conexão), um pacote SYN fora
de hora faz com que o receptor responda
com um pacote RST. Há um termo técnico
para esse comportamento: dizemos que o
receptor reflete o pacote. E isso abre uma
nova maneira de ter sucesso em ataques
de negação de serviço. O agressor pode se
aproveitar da conexão de um “laranja” para
que transmita qualquer dado pendente imediatamente, ou que repasse os dados em buffer
para o aplicativo apropriado;
P URG (URGent): Se esse bit estiver ativado, há
um outro campo no cabeçalho TCP chamado
Ponteiro de Urgência que indica para o sistema
operacional receptor qual porção dos dados
transportados no pacote é mais urgente e deve
ser processada primeiro.
ICMP: Acrônimo para o Internet Control Message
Protocol (protocolo de mensagens de controle
para redes interconectadas). Esse protocolo foi
definido na RFC 792 e é usado basicamente para
troca de informações e diagnose de redes – o
conhecido utilitário ping usa o protocolo ICMP.
Looking Glass: Em português, “espelho”. Esse
serviço permite que os usuários determinem
se um servidor está disponível e quão boa é a
conexão [6]. Para isso, perguntam aos roteadores
BGP envolvidos na conexão. Os utilitários ping e
traceroute podem ajudar a obter mais informações
sobre os sistemas intermediários. O nome do
serviço veio da obra de Lewis Carrol, “Through the
looking glass”, cujo título em português é “Através
do espelho e o que Alice encontrou por lá”.
Número de reconhecimento: Um dos
campos do cabeçalho de um datagrama TCP.
possui um comprimento de 32 bits. Imagine uma
conexão entre a máquina X e a máquina Y. Em um
dado momento, X mandou um pacote para Y. O
número de reconhecimento é o número seqüencial que X espera receber de Y quando for a vez de
Y responder a X. Em resumo: quem manda o pacote põe, no número de reconhecimento, o próximo
número seqüencial que espera receber.
edição 13
www.linuxmagazine.com.br
atacar terceiros. Esta técnica é especialmente eficiente em conexões ADSL que, como o
nome (Assymetric Digital Subscriber Line) já
diz, é assimétrica, ou seja, a vítima recebe
os dados a uma velocidade muito maior do
que pode transmitir as respostas.
Enquanto os ataques RST e SYN não
usam a área de dados (payload ou carga útil,
nome oriundo do transporte ferroviário) do
pacote, uma terceira técnica injeta dados
nos datagramas de uma conexão existente.
Esses dados podem ser puro lixo, servindo
unicamente para corromper a conexão, ou
podem ser manipulados cuidadosamente
para provocar uma condição de erro. A vítima talvez nem perceba a manipulação.
Número seqüencial: Campo do cabeçalho
TCP que especifica a posição do primeiro byte de
dados do datagrama em relação ao início da conexão. O receptor usa esse número para verificar
a ordem e a validade dos datagramas que recebe.
Isso protege contra ataques por injeção ou
reprodução de pacotes. Entretanto, essa proteção
é eficaz apenas contra erros e tentativas grosseiras de ataque. Se os pacotes recebidos forem
especialmente manipulados na origem, o número
seqüencial não protegerá nada.
Redimensionamento de janela: Uma
tentativa de otimizar o desempenho em conexões
com alto tráfego ou com latência excessivamente
longa. O redimensionamento de janela permite
que, ao aumentar absurdamente o tamanho da
janela de conexão, se possa processar pacotes
que cheguem muitíssimo atrasados e transmitir
muito mais dados sem precisar esperar por números de reconhecimento que desloquem a janela
mais para a frente.
Tamanho da janela: Um campo numérico do
datagrama TCP que informa ao receptor quantos
bytes o emissor do pacote aceitará como válidos,
quando for a vez dele receber datagramas. O
tamanho da janela é um número de 16 bits, variando, portanto, de zero a 65.535.
TCP: O Transmission Control Protocol (protocolo
de controle de transmissão), definido na RFC 793,
controla a transferência de dados entre o emissor
e o receptor. Ao contrário do protocolo UDP (User
Datagram Protocol, definido na in RFC 768), o
TCP é o que chamamos de orientado à conexão e
assegura que todos os dados cheguem sem erros
e na ordem correta.
Conexões TCP
Aplicações práticas
Para testar suas teorias sob condições
reais [4], Paul Watson desenvolveu a ferramenta reset_tcp.c, tornada pública
em maio de 2004 [12]. Em seus testes, Paul
observou que uma conexão DSL básica
era tudo de que precisava para determinar com bastante precisão os números
seqüenciais que poderiam levar ao encerramento da conexão. Foram precisos
apenas onze minutos, com uma janela de
65.535 bytes e usando apenas 50 portas.
Com uma janela de 16.384, o processo
levou 45 minutos.
O programa requer a Libnet Packet
Construction Library (biblioteca de
construção de pacotes de rede) [13] de
Mike D. Schiffman. Basta especificar o
endereço MAC de sua própria máquina
e o da máquina sob ataque – ou de seu
gateway para a Internet – antes de compilar o programa.
Quando executado, o programa pede
uns poucos parâmetros:
reset_tcp interface IP_de_origem U
sas, podemos facilmente determinar
quanto tempo levaremos – no máximo – para derrubar a conexão: o valor
máximo do número seqüencial, multiplicado pelo tamanho do pacote, dividido pela taxa de transferência. Em
números: 4.294.967.296/5.840*320
bits/128.000 bps, o que nos dá 1.840
segundos ou, aproximadamente, 30
minutos e 40 segundos.
Se considerarmos ainda que todos os
pacotes, indistintamente, têm 50% de
chance de terem sucesso na empreitada,
o agressor levará somente metade desse
tempo para derrubar a conexão – mais ou
menos 15 minutos e 20 segundos. Nossos
testes práticos confirmam nosso empirismo: o valor médio medido em uma série
de 20 testes foi de 932 segundos – ou 15
minutos e 32 segundos.
Mas isso foi para uma única porta, que
já conhecíamos. Se precisarmos testar as
50 portas de que falamos anteriormente
(em um computador com umas poucas
conexões estabelecidas) o tempo para
concluir esse ataque seria de interminá-
Sysadmin
veis 13 horas – um bocado de trabalho,
mesmo para uma conexão de longa duração como uma sessão de SSH.
Janelas elásticas
Muitos sistemas operacionais modificam o
tamanho da janela em uma conexão ativa
para se adequar ao volume do tráfego. Por
exemplo, o Linux aumenta o tamanho da
janela em uma conexão SSH para um valor
maior que 16.000. Detalhe: tudo o que essa
conexão está transmitindo é o resultado
do comando top – nada demais, portanto. Imagine o quanto a janela “esticaria”
com tráfego mais pesado. Se o agressor
souber que a vítima usa a conexão para
transferir grandes quantidades de dados,
pode se aproveitar do tamanho descomunal da janela para perpetrar suas maldades. Repetimos o mesmo teste – ou seja,
considerando que o agressor já conhece
a porta de origem – usando essa conexão
SSH na qual rodamos o comando top. O
tempo para a conexão cair foi de apenas
5 minutos e 45 segundos para essa janela
de 16.000 bytes.
➟
porta_de_origem IP_de_destino U
porta_de_destino tamanho_da_janela
A interface é a placa de rede pela
qual os pacotes RST sairão da máquina
agressora.
O primeiro teste prático foi fazer o programinha derrubar uma conexão SSH
entre dois computadores com Linux (figura 3). Ambas as máquinas usam uma
linha ADSL T-DSL 1000 da Deutsch Telekom para se conectar à Internet (velocidade de upload: 128kbit/s). Para este
teste simples, vamos considerar que o
agressor já conhece a porta de origem.
O tamanho do pacote RST é de 40 bytes
(somando o cabeçalho TCP com o do
seu “envelope”, o cabeçalho IP) – ou, se
preferir, 320 bits.
Vamos arbitrar que o tamanho da
janela é de 5.840 bytes em ambas as
direções. Baseados nessas premis-
Figura 3: Monitoramos um ataque de TCP/RST em uma conexão SSH com o Ethereal. O agressor transmite
um número bastante grande de datagramas TCP com números seqüenciais crescentes (topo da janela, perto
do fim da linha: Seq=…). O detalhamento de tráfego (ao centro) mostra claramente que a flag RST foi ativada.
outubro 2005
www.linuxmagazine.com.br
edição 13
71
Sysadmin
Conexões TCP
Fizemos outros experimentos basea- menor os valores, mais difícil fica sados no exemplo de Watson: uma conexão
botar o sistema. Se possível, desabilite
o redimensionamento da janela. Como
BGP. Colocamos um computador com
Linux (kernel 2.4, tamanho inicial da
resultado, poucos números seqüenciais
janela 5.840 bytes) falando por BGP com “cabem” na janela, forçando o agressor a
um roteador Cisco (tamanho inicial da
ser mais preciso, o que demanda mais
tempo, esforço e largura de banda.
janela 16.384 bytes). Como esperado, as
janelas em ambos os sentidos “esticaram”
Entretanto, há limites para esse tipo de
durante a troca de dados. No início da
sintonia fina. Se os valores selecionados foconexão, o BGP precisa transmitir quan- rem muito pequenos, o desempenho da rede
tidades razoavelmente grandes de dados. vai cair. O protocolo TCP fica mais “preso”
Em nosso experimento, a janela cresceu
porque a pilha de rede tem que esperar por
para 16.616 em apenas alguns minutos
mais ACKs antes de transmitir. Além disso,
e se estabilizou nesse patamar. O tempo
terá também que transmitir mais ACKs – o
teórico de ataque nessa situação seria
desperdício de banda com cabeçalhos TCP
de 4.294.967.296/16.616*320 bits/128.000
vai ser bem maior. Vejamos um exemplo
bps/2 = 5 minutos e 23 segundos.
extremo: se ajustarmos a janela para 10,
Na prática, cravamos uma média de 5
precisaremos mandar um pacote ACK de 40
minutos e 39 segundos – confirmando a
bytes (20 bytes para o cabeçalho IP, mais
20 para o TCP) para cada pacote TCP que
teoria. As conexões BGP ficam ativas por
carregue 10 bytes de dados úteis.
semanas ou mesmo meses. Leva mais de
um minuto para restabelecer uma conexão depois de uma queda e os roteadores
BGP não abrem muitas conexões de rede
Regras de filtragem dão uma proteção
depois de estabilizados. Isso faz deles
mais granular contra ataques RST em
alvos fáceis para agressores: muito tempo, roteadores limítrofes. Tais gateways
poucas portas para testar… Para malfeito- devem aceitar tráfego – seja saindo ou
res, deve realmente parecer irresistível.
entrando – caso o endereço IP de origem realmente exista na interface pela
qual está entrando. Isso reduz o risco
Como o nível de exposição é altíssimo
de IP spoofing e deve ser o procedimene o risco, para o agressor, é quase nulo, to padrão de configuração para todo e
a prevenção torna-se obrigatória. Apre- qualquer roteador.
sentamos algumas abordagens para diOs filtros de ingresso e egresso protegem
minuir os efeitos desse problemas todos. a rede interna contra ataques de impostuComo regra geral, evite dar “colher de
ra (spoofing). Muitos crackers “espertos”
chá” para os crackers, não divulgando
travestem seus pacotes com endereços da
informações desnecessárias sobre suas
rede interna, mesmo que estejam entrando
redes e conexões. Dispositivos dotados
nessa rede pela Internet. Se o roteador
do serviço Looking Glass, por exemplo, bloquear pacotes que não deveriam estar
entrando por aquela interface, vai matar
são acintosamente promíscuos (ver [6] e
dois coelhos com uma cajadada:
o quadro Glossário). Servidores de DNS
mal configurados também podem dar
P 1) Vai bloquear pacotes vindos da Interdores de cabeça.
net que alegam ter endereços de origem
Muitos sistemas operacionais facultam
pertencentes à rede interna;
a seus administradores ajustar o tama- P 2) Vai bloquear pacotes vindos da rede
nho da janela de conexão (veja o quadro
interna que alegam ser de máquinas
Alterando o tamanho da janela). Quanto
pertencentes à Internet.
Porteiros atentos
Proteção pró-ativa
72
outubro 2005
edição 13
www.linuxmagazine.com.br
Alterando o tamanho da janela
O tamanho da janela de conexão do protocolo
TCP não é fixo. Os administradores podem modificar os tamanhos padrão e máximo em quase
todos os sistemas operacionais.
Cisco IOS: no modo enable, digite:
ip tcp window-size tamanho da janela.
Linux (kernel 2.4 e 2.6) com Ipv4: Modifique os
valores de /proc/sys/net/ipv4/tcp_rmem
e /proc/sys/net/ipv4/wmem ou informe esses valores nas variáveis tcp_rmem e
tcp_wmem do arquivo /etc/sysctl.conf.
Depois, rode o comando sysclt -p. Consulte
[18] para um tutorial detalhado.
Sun Solaris: Em sistemas Solaris o comando
ndd dá conta do recado: ndd -set
/dev/tcp tcp_xmit_hiwat tamanho_
da_janela e ndd -set /dev/tcp
tcp_recv_hiwat tamanho_da_janela.
Windows 2000 e XP: Modifique os valores das
variáveis GlobalMaxTcpWindowSize
(REG_DWORD) e TcpWindowSize (REG_
DWORD) na chave HKEY_LOCAL_MACHINE\
SYSTEM\CurrentControlSet\
Services\Tcpip\Parameters do regis-
tro. Consulte [18] para um tutorial detalhado.
Com esse último “coelho”, esse roteador
estará dando uma inestimável contribuição
à comunidade da Internet ao bloquear malfeitores que possivelmente estejam dentro
de sua própria rede privada. Administradores cônscios de suas responsabilidades de
segurança irão mais longe, criando regras
que permitam tráfego BGP somente entre
roteadores conhecidos. Isso torna ataques
contra as conexões BGP quase impossíveis.
Se levarmos em conta o perigo representado pela vulnerabilidade descrita neste
artigo, é uma ajuda e tanto!
Outra forma de proteção foi introduzida
já em 1998: a RFC 2385 descreve assinaturas baseadas em MD5 para conexões
TCP [7]. Por essa técnica, criam-se hashes
MD5 que combinam os campos críticos
do cabeçalho TCP com uma senha. Com
isso, o receptor pode detectar pacotes impostores. Obviamente, as senhas precisam
necessariamente ser robustas para que
sejam difíceis de quebrar com o bgpcrack
Conexões TCP
TCP-Stack
Data
TCP connection exists
Sequence numbers are synced
RST Packet
Sequence number not an exact
match but in receive window
Connection stays up
ACK Packet
RST Packet
Connection terminated
Sequence number exact match
Figura 4: A pilha de rede baseada em [10]
requer que o número seqüencial do datagrama
TCP/RST seja idêntico ao que o receptor espera.
[8] em um ataque de dicionário. Há uma
descrição dessa vulnerabilidade do BGP,
bem como as possíveis soluções, em [9].
Resposta cuidadosa
Em abril de 2004, o IETF (Internet Engineering Task Force) publicou um documento
preliminar [10] sugerindo mudanças no
comportamento de resposta do protocolo
TCP, para que a pilha de rede só reagisse imediatamente a um pacote RST se
o número seqüencial fosse exatamente
o que o receptor espera. Se o número
seqüencial do pacote RST simplesmente
caísse dentro da janela de conexão mas
não fosse o número exato, a pilha de rede
do receptor responderia com um pacote
ACK e descartaria sumariamente o datagrama que acabara de receber. Assim,
quando recebesse esse ACK de resposta,a
máquina que mandou o primeiro RST
mandaria um segundo RST (figura 4). A
idéia por trás disso é que um impostor
não veria o pacote ACK e, portanto, novas tentativas seriam tão nulas quanto a
primeira. Se o primeiro RST, por outro
lado, tiver sido enviado pelo participante
legítimo da conexão, ao receber o ACK
mencionado imediatamente responderá
com um segundo RST que possuirá o número seqüencial correto – e a conexão é,
portanto, legitimamente encerrada.
Entretanto, esse novo comportamento
introduz uma nova vulnerabilidade: nas
chamadas “guerras de ACK”, um agres-
sor poderia inundar a vítima com pacotes
RST. Se a vítima responder a cada RST, a
conexão vai ser rapidamente tomada por
pacotes de controle e não vai sobrar espaço
para os dados reais. Isso poderia afogar em
uma conexão ADSL comum num piscar
de olhos. Para evitar o problema, sugerese que cada nó da rede tenha permissão
para responder a, no máximo, 10 pacotes
TCP/RST a cada 5 segundos.
O documento recomenda que se verifique a validade de pacotes SYN enviando
um ACK em resposta. Esse comportamento
é compatível com o original, determinado pela RFC 793. Trocando em miúdos: o
documento proposto em [10] procura combater as vulnerabilidades do TCP usando
as definições e recursos do próprio TCP. O
perigo de um ataque DoS por inundação de
pacotes ainda é real, entretanto – mesmo
com todas essas medidas.
O Linux possui ainda uma técnica para
se esquivar desses ataques: um patch da
GR Security [11] assegura que os kernels
2.4 e 2.6 atribuam portas aleatórias a cada
nova conexão. Esse recurso foi “chupado”
do OpenBSD, assim como a maioria dos
outros implementados no patch. Nossos
experimentos confirmam que o patch realmente funciona: depois de aplicado, todos
as tentativas de derrubar uma conexão
usando os testes descritos fracassaram.
Prevenir é melhor
que remediar
Os ataques baseados nos pacotes TCP/RST
e TCP/SYN são perigosíssimos e não devem ser subestimados. Inúmeros exploits já
foram desenvolvidos para se valer dessas
vulnerabilidades; uma simples conexão
ADSL é só o que um agressor precisa para
detonar conexões semipermanentes. Ao se
referir a esse tipo de ataque, Theo de Raadt,
o líder do projeto OpenBSD, disse em certa
feita: “muitos dizem que esse é um problema imaginário, mas tenho certeza de que,
num futuro não muito distante, veremos
algum worm se aproveitando dele”.
■
Sysadmin
Informações
[1] Computer Security Institute: www.gocsi.com
[2] RFC 793, "Transmission Control
Protocol": rfc.net/rfc793.html
[3] RFC 1323, "TCP Extensions for High
Performance": rfc.net/rfc1323.html
[4] Open Source Vulnerability Database, Paul
(Tony) Watson, "Slipping in the Window: TCP
Reset Attacks":
www.osvdb.org/reference/
SlippingInTheWindow_v1.0.ppt
[5] Open Source Vulnerability Database,
Paul (Tony) Watson, "TCP Reset
Spoofing": www.osvdb.org/4030
[6] Nós BGP dotados do recurso Looking
Glass: www.bgp4.net/lg
[7] RFC 2385, "Protection of BGP
Sessions via the TCP MD5 Signature
Option": rfc.net/rfc2385.html
[8] Quebrador de senhas no protocolo BGP:
www.cisco.com/security_services/
ciag/tools/bgpcrack-2.1.tar.gz
[9] Sean Convery e Matthew Franz, "BGP Vulnerability
Testing: Separating Fact from FUD v1.1":
www.blackhat.com/presentations/bhusa-03/bh-us-03-convery-franz-v3.pdf
[10] Documento preliminar, "Improving TCP's
Robustness to Blind In-Window Attacks":
ietfreport.isoc.org/idref/draftietf-tcpm-tcpsecure
[11] GR Security: www.grsecurity.net
[12] TCP Connection Reset Remote Exploit:
www.frsirt.com/exploits/04232004.
tcp-exploit.php
[13] Libnet: www.packetfactory.net/projects/libnet
[14] Robert T. Morris, "A Weakness in the 4.2 BSD
Unix TCP/IP Software:
pdos.csail.mit.edu/~rtm/papers/117.pdf
[15] Laurent Joncheray, "Simple Active Attack
Against TCP": www.usenix.org/
publications/library/proceedings/
security95/full_papers/joncheray.ps
[16] Cert Advisory CA-2001-09, "Statistical Weaknesses
in TCP/IP Initial Sequence Numbers":
www.cert.org/advisories/CA-2001-09.html
[17] Dave MacDonald e Warren Barkley, "Microsoft
Windows 2000 TCP/IP Implementation Details":
www.microsoft.com/technet/itsolutions/
network/deploy/depovg/tcpip2k.mspx
[18] Oskar Andreasson, "Ipsysctl tutorial
-- Chapter 3, IPv4 variable reference":
ipsysctl-tutorial.frozentux.net/
chunkyhtml/tcpvariables.html
[19] Cert Advisory CA-1995-01, "IP Spoofing Attacks
and Hijacked Terminal Connections":
www.cert.org/advisories/CA-1995-01.html
outubro 2005
www.linuxmagazine.com.br
edição 13
73
Download

Esquadrão anti-seqüestro