Anonimato & OPSEC
Vulnerabilidades do I2P: CVE-2023-36325 e anonimato
Análise técnica da CVE-2023-36325, isolamento de replay, correlação temporal e auditoria de uma instalação I2P, com testes locais e fontes primárias.
A segurança de uma rede de anonimato não termina na criptografia. Um serviço pode manter o conteúdo cifrado e ainda revelar pistas sobre o computador que o hospeda, por diferenças de processamento, metadados ou comportamento temporal. O histórico do I2P oferece exemplos concretos dessa fronteira: uma CVE em um mecanismo antirrepetição, pesquisas sobre correlação de disponibilidade e mudanças defensivas na implementação.
Esta análise examina a CVE-2023-36325, explica o que a correção protege e propõe testes locais para compreender a classe de falha. Também diferencia a implementação Java I2P do i2pd, escrito em C++. A presença de uma vulnerabilidade em um deles não demonstra automaticamente que o outro esteja afetado.
O que o I2P tenta esconder
É preciso separar o roteador participante de uma destination, a identidade criptográfica utilizada por uma aplicação. O funcionamento da rede depende de informações para contactar roteadores, enquanto a associação entre uma aplicação e seu roteador deve permanecer protegida. Conhecer o endereço de um participante não equivale a identificar o operador de determinado serviço.
Os túneis são unidirecionais. Comunicação nos dois sentidos utiliza caminhos de entrada e saída, com proteção em camadas. A netDB distribui RouterInfo, usado para alcançar roteadores, e LeaseSets, usados para alcançar destinations por seus túneis. Essa distinção está descrita na introdução oficial à arquitetura do I2P.
Uma revisão profissional deve representar esses elementos como domínios de confiança separados. A pergunta relevante não é apenas se um pacote pode ser decifrado. É também se uma observação feita na camada pública do roteador revela algo que deveria pertencer exclusivamente à aplicação anônima. Caches, tempos, contadores e mensagens de erro entram nessa avaliação.
CVE-2023-36325: confusão de contexto no filtro de replay
A CVE-2023-36325 afeta versões do Java I2P anteriores à 2.3.0. O problema envolvia a reutilização de estado do filtro de Bloom entre contextos de mensagens. Um identificador visto pelo caminho de um cliente podia influenciar o tratamento de uma mensagem recebida diretamente pelo roteador.
Esse comportamento fornecia uma pista para associar o cliente ao roteador. A correção, publicada em 25 de junho de 2023, separou o processamento conforme a origem: túnel de cliente, túnel exploratório e recepção direta. O projeto descreve limitações práticas, incluindo falsos positivos e reinicializações, e informa que a correlação normalmente exigia vários dias. A fonte técnica é o anúncio oficial da versão 2.3.0.
O caso ilustra um vazamento de estado. A aplicação não precisava entregar um endereço IP dentro do conteúdo para que o comportamento do software fornecesse informação adicional. Isso exige avaliar diferenças observáveis entre caminhos, mesmo quando cada caminho parece correto isoladamente.
| Elemento | Leitura técnica |
|---|---|
| Produto afetado | Java I2P anterior à correção 2.3.0 |
| Classe de falha | Confusão entre domínios de processamento |
| Consequência documentada | Pista de associação entre serviço e roteador |
| Conclusão que não decorre do caso | Quebra geral das cifras ou identificação instantânea de todos os usuários |
Por que uma proteção contra repetição pode vazar informação
Uma proteção antirreplay registra identificadores já processados e rejeita repetições. Em uma implementação simplificada, a decisão depende de duas variáveis: o identificador recebido e o histórico armazenado. Se duas sessões privadas dividem esse histórico indevidamente, uma delas passa a produzir respostas que dependem da atividade da outra.
O princípio de projeto é a separação de domínio. Uma chave lógica pode incorporar o contexto definido pelo host, além do identificador. Esse contexto deve ser derivado de uma origem autenticada ou de um caminho interno confiável. Permitir que a própria mensagem escolha livremente seu domínio de validação criaria outra fronteira fraca.
Também é necessário definir o ciclo de vida do estado: prazo de validade, limite de memória, descarte e concorrência. Um teste que cobre apenas a primeira inserção não descobre efeitos após reinício, colisões, saturação ou interleaving de tarefas. Em estruturas probabilísticas, uma rejeição isolada pode ter outra explicação; a análise precisa considerar a taxa de falso positivo e a incerteza.
Laboratório local: observar e corrigir uma colisão entre contextos
O exemplo abaixo é um modelo didático original em Python. Utiliza conjuntos exatos, sem filtro de Bloom, I2NP ou acesso à rede. Portanto, demonstra a propriedade de isolamento, mas não reproduz o exploit da CVE nem substitui testes da implementação real.
class FiltroCompartilhado:
def __init__(self):
self.vistos = set()
def aceitar(self, contexto, identificador):
if identificador in self.vistos:
return False
self.vistos.add(identificador)
return True
class FiltroSeparado:
def __init__(self):
self.vistos = {}
def aceitar(self, contexto, identificador):
if contexto not in {"cliente", "exploratorio", "direto"}:
raise ValueError("Contexto invalido")
estado = self.vistos.setdefault(contexto, set())
if identificador in estado:
return False
estado.add(identificador)
return True
compartilhado = FiltroCompartilhado()
assert compartilhado.aceitar("cliente", "lab-16")
assert not compartilhado.aceitar("direto", "lab-16")
separado = FiltroSeparado()
assert separado.aceitar("cliente", "lab-16")
assert separado.aceitar("direto", "lab-16")
assert separado.aceitar("exploratorio", "lab-16")
assert not separado.aceitar("cliente", "lab-16")
print("Isolamento entre contextos validado")
O resultado esperado é explícito. No primeiro modelo, uma operação no domínio cliente altera a resposta do domínio direto. No segundo, a repetição dentro do mesmo domínio continua rejeitada, enquanto o identificador pode existir em domínios distintos. Corrigir isolamento sem preservar a proteção contra repetição seria uma regressão funcional.
Para levar esse raciocínio a um projeto real, uma suíte de regressão deve incluir duas conexões simultâneas, expiração do estado, entradas inválidas e quotas. O teste precisa observar a propriedade prometida pela interface e usar mensagens sintéticas, sem coletar identidades de participantes da rede pública.
I2PERCEPTION: o comportamento de disponibilidade como canal lateral
O estudo Time will Tell, de Wang e colaboradores, publicado como preprint em dezembro de 2025, descreve I2PERCEPTION. A pesquisa relaciona padrões de entrada e saída de roteadores com períodos de disponibilidade de serviços. O experimento utilizou 15 floodfills e serviços controlados ao longo de aproximadamente oito meses. Os autores informam divulgação responsável e tratamento dos problemas reportados.
O resultado experimental não permite afirmar que todo serviço atual pode ser identificado com a mesma precisão. Versão, observação incompleta e comportamento de execução fazem diferença. A pesquisa é distinta da CVE de replay: usa uma relação temporal, enquanto a CVE explora estado compartilhado no processamento de identificadores.
Como análise de engenharia, há uma lição mais ampla: dois sistemas que mudam de estado juntos podem produzir uma pista de associação. Reiniciar aplicação e infraestrutura sempre no mesmo segundo, por exemplo, cria uma dependência operacional que merece revisão. Isso não prova uma identificação; define uma hipótese que precisa ser confrontada com alternativas e controles.
Uma correlação perfeita também pode ser ambígua
Este segundo modelo utiliza oito amostras binárias totalmente fictícias. A medida é apenas a fração de posições iguais, sem o algoritmo ou as medições da pesquisa. Duas máquinas diferentes apresentam a mesma sequência, mostrando por que similaridade não deve ser convertida automaticamente em identidade.
def similaridade(a, b):
if len(a) != len(b) or not a:
raise ValueError("Amostras incompativeis")
return sum(x == y for x, y in zip(a, b)) / len(a)
servico = [1, 1, 0, 0, 1, 1, 0, 1]
roteadores = {
"lab-a": [1, 1, 0, 0, 1, 1, 0, 1],
"lab-b": [1, 1, 0, 0, 1, 1, 0, 1],
"lab-c": [1, 0, 1, 0, 1, 0, 1, 0],
}
pontuacoes = {nome: similaridade(servico, dados)
for nome, dados in roteadores.items()}
melhor = max(pontuacoes.values())
candidatos = [nome for nome, valor in pontuacoes.items()
if valor == melhor]
assert candidatos == ["lab-a", "lab-b"]
print({"candidatos": candidatos, "conclusao": "ambigua"})
A produção de um relatório exige registrar janela, dados ausentes e explicações concorrentes. Uma indisponibilidade comum pode decorrer de manutenção, de uma falha do ponto de observação ou de congestionamento. Repetir o experimento com controles ajuda a testar a hipótese, mas aumentar a coleta indiscriminadamente não corrige um modelo mal definido.
Disponibilidade, Sybil e diferenças entre falha e ameaça
O modelo de ameaças oficial discute adversários que controlam múltiplos participantes e observam tráfego. Ameaças Sybil, correlação e negação de serviço pertencem a categorias diferentes. A documentação é histórica em alguns trechos e deve ser lida junto às notas atuais de versão, sem tratar suas descrições como um inventário atualizado de cada mitigação.
A versão 2.11.0, de fevereiro de 2026, registra uma primeira rodada de mitigação a ataques de spam, além da exigência de Java 17 e adoção do Jetty 12. Isso é evidência de trabalho defensivo sobre disponibilidade. Não demonstra uma nova CVE nem que uma cifra tenha sido quebrada.
Na classificação de um incidente, mantenha campos separados para conteúdo, identidade e continuidade. Uma fila saturada pode interromper um serviço sem revelar seu operador. Uma associação estatística pode prejudicar privacidade sem permitir modificar mensagens. Um defeito de interface pode comprometer o navegador local sem representar uma falha dos túneis.
Roteiro de auditoria para uma instalação própria
- Inventário: registrar implementação, versão efetiva, origem do pacote, Java, plugins e serviços expostos. Não comparar somente o nome comercial.
- Atualização: consultar o canal oficial utilizado e verificar a assinatura ou o mecanismo de autenticidade disponibilizado pelo projeto.
- Isolamento: limitar console e interfaces administrativas ao acesso necessário. Separar o usuário do serviço e os arquivos das aplicações.
- Aplicações: revisar conteúdo que denuncia identidade, chamadas externas, cookies, contas reutilizadas, logs e configurações do navegador.
- Continuidade: documentar reinícios, dependências e falhas observadas. Evitar interpretar ausência de resposta como prova de ataque.
- Regressão: executar modelos locais, confirmar propriedades e manter a validação de rede limitada a ambientes autorizados.
Na consulta editorial de 7 de outubro de 2026, o anúncio principal mais recente verificado era o 2.13.0, de julho. O repositório Debian oficial esclarece que o pacote 2.13.1 contém o I2P 2.13.0, com incremento por um problema de upload. Versão do pacote e versão do motor precisam ser registradas separadamente. Para instalar, consulte novamente o canal atual.
Perguntas frequentes sobre vulnerabilidades do I2P
A CVE-2023-36325 quebrou a criptografia do I2P?
A falha descrita envolve o processamento de estado e a associação de contextos. Não sustenta uma conclusão de quebra geral das cifras. A remediação deve considerar a implementação afetada e sua atualização.
Ter vários túneis garante anonimato em qualquer aplicação?
Uma aplicação pode revelar identidade pelo próprio conteúdo, por uma conta reutilizada ou por integrações externas. O teste deve incluir as fronteiras entre aplicação, navegador e infraestrutura, além dos mecanismos de transporte.
Posso usar os exemplos para testar a rede pública?
Os exemplos funcionam apenas com dados locais. Eles verificam propriedades de software e ambiguidade de correlação. Não contêm identificação de serviços, sondagem de participantes ou ferramenta de desanonimização.
Conclusão: testar as fronteiras que a cifra não cobre
A análise de anonimato precisa de um objeto de teste bem definido. Para cada observação, descreva quem consegue vê-la, qual estado ela depende e qual associação se pretende impedir. Isso transforma uma afirmação vaga de privacidade em propriedades verificáveis: isolamento de caches, independência entre sessões, controle das interfaces e tratamento explícito da incerteza.
O profissional ganha mais com uma evidência reproduzível e limitada do que com um rótulo genérico de rede insegura. Preserve as versões, os testes e as hipóteses descartadas. O histórico de correções serve para orientar a auditoria, enquanto a avaliação da instalação atual exige verificar seu software e seu modelo de uso.