Espécie de Sniffer em Java

É possível obter uma referência à um socket criado por outro processo aberto? Este processo poderia ser qualquer um que estivesse rodando no sistemas operacional.

Por exemplo:

Eu estou com o MSN aberto e conectado. Para tal conexão o cliente MSN usa sockets para se comunicar com o servidor do MSN.

Eu gostaria então que a minha aplicação em java obtivesse uma referência à este socket que faz a comunicação do MSN acontecer.

Desta forma eu poderia obter objetos DataInputStream e DataOutputStream deste socket, podendo através da minha aplicação em java mandar mensagens para o servidor do MSN e saber as mensagens que este servidor está mandando para o cliente do MSN. Claro que para esta operação o cliente do MSN estaria aberto e conectado.

Será que é possível obter referência a estes sockets externos?

Isto funcionaria semelhante a um sniffer.

Agradeço desde já qualquer ajuda.

De maneira “pura”, sem JNI, não.

Existe um tipo de socket, chamado de RAW socket, que permite que você manipule totalmente a pilha TCP inteira.
Ele seria necessário para você mascarar a mensagem, de modo a parecer que ela sai de outro IP ou porta.

O Java não tem suporte a RAW sockets.

Além disso, para conseguir fazer o que um sniffer faz, você terá que entrar em modo promíscuo, coisa que o Java também não faz.

Entretanto, tem gente que já se deu ao trabalho de escrever JNI para parte dessas coisas:
http://netresearch.ics.uci.edu/kfujii/Jpcap/doc/

O Winpcap é a mesma API por trás do Wireshark.

[quote=ViniGodoy]De maneira “pura”, sem JNI, não.

Existe um tipo de socket, chamado de RAW socket, que permite que você manipule totalmente a pilha TCP inteira.
Ele seria necessário para você mascarar a mensagem, de modo a parecer que ela sai de outro IP ou porta.

O Java não tem suporte a RAW sockets.

Além disso, para conseguir fazer o que um sniffer faz, você terá que entrar em modo promíscuo, coisa que o Java também não faz.

Entretanto, tem gente que já se deu ao trabalho de escrever JNI para parte dessas coisas:
http://netresearch.ics.uci.edu/kfujii/Jpcap/doc/

O Winpcap é a mesma API por trás do Wireshark.[/quote]

Com o RAW socket eu poderia até mesmo manipular e alterar os dados capturados antes deles chegarem ao destino?

Por exemplo, o MSN envia o seguinte “pacote” para o seu servidor: “MSG@oi.”. Antes que este pacote chegasse ao servidor, ele seria capturado pelo “sniffer” e modificado para “MSG@tudo bem?.”, por exemplo. Então o servidor do MSN receberia “MSG@tudo bem?.”.

Qual linguagem tem suporte a RAW sockets?

Com o Winpcap eu posso ler e escrever em sockets externos?

Brigado ae Vini. =)

O nome do que você quer fazer é “man in the middle”.
Para capturar mensagens dos outros, só usando o socket em modo promíscuo.

Para coisas sinistras assim, como interceptar mensagens de outras aplicações, a melhor linguagem é geralmente o C++.
E prepare-se para estudar muita API do sistema operacional. Não é uma tarefa fácil.
E nem adianta me perguntar como fazer pq, apesar de saber que teoricamente é possível, nunca perdi meu tempo tentando.

Agora, eu começaria tentando procurar alguma documentação do protocolo do messenger em si.

[quote=ViniGodoy]O nome do que você quer fazer é “man in the middle”.
Para capturar mensagens dos outros, só usando o socket em modo promíscuo.

Para coisas sinistras assim, como interceptar mensagens de outras aplicações, a melhor linguagem é geralmente o C++.
E prepare-se para estudar muita API do sistema operacional. Não é uma tarefa fácil.
E nem adianta me perguntar como fazer pq, apesar de saber que teoricamente é possível, nunca perdi meu tempo tentando.

Agora, eu começaria tentando procurar alguma documentação do protocolo do messenger em si.[/quote]

Como assim em modo promíscuo? Esqueci de perguntar no outro post.

E quanto a JNI que vc mencionou: Winpcap, com ela seria possível ler/escrever em sockets externos? (Nada de alterar o conteúdo do pacote antes deste chegar ao destinatário, apenas ler e escrever nos sockets)

Grato!

[quote=gabrielost][quote=ViniGodoy]O nome do que você quer fazer é “man in the middle”.
Para capturar mensagens dos outros, só usando o socket em modo promíscuo.

Para coisas sinistras assim, como interceptar mensagens de outras aplicações, a melhor linguagem é geralmente o C++.
E prepare-se para estudar muita API do sistema operacional. Não é uma tarefa fácil.
E nem adianta me perguntar como fazer pq, apesar de saber que teoricamente é possível, nunca perdi meu tempo tentando.

Agora, eu começaria tentando procurar alguma documentação do protocolo do messenger em si.[/quote]

Como assim em modo promíscuo? Esqueci de perguntar no outro post.

E quanto a JNI que vc mencionou: Winpcap, com ela seria possível ler/escrever em sockets externos? (Nada de alterar o conteúdo do pacote antes deste chegar ao destinatário, apenas ler e escrever nos sockets)

Grato![/quote]
com a pcap você consegue fazer isso. É a biblioteca do wireshark.

[quote=juliocbq][quote=gabrielost][quote=ViniGodoy]O nome do que você quer fazer é “man in the middle”.
Para capturar mensagens dos outros, só usando o socket em modo promíscuo.

Para coisas sinistras assim, como interceptar mensagens de outras aplicações, a melhor linguagem é geralmente o C++.
E prepare-se para estudar muita API do sistema operacional. Não é uma tarefa fácil.
E nem adianta me perguntar como fazer pq, apesar de saber que teoricamente é possível, nunca perdi meu tempo tentando.

Agora, eu começaria tentando procurar alguma documentação do protocolo do messenger em si.[/quote]

Como assim em modo promíscuo? Esqueci de perguntar no outro post.

E quanto a JNI que vc mencionou: Winpcap, com ela seria possível ler/escrever em sockets externos? (Nada de alterar o conteúdo do pacote antes deste chegar ao destinatário, apenas ler e escrever nos sockets)

Grato![/quote]
com a pcap você consegue fazer isso. É a biblioteca do wireshark.[/quote]

Inclusive “selecionar” um socket externo (aberto por outro processo) e ler/escrever NESTE socket?

Grato!

[quote=gabrielost][quote=juliocbq][quote=gabrielost][quote=ViniGodoy]O nome do que você quer fazer é “man in the middle”.
Para capturar mensagens dos outros, só usando o socket em modo promíscuo.

Para coisas sinistras assim, como interceptar mensagens de outras aplicações, a melhor linguagem é geralmente o C++.
E prepare-se para estudar muita API do sistema operacional. Não é uma tarefa fácil.
E nem adianta me perguntar como fazer pq, apesar de saber que teoricamente é possível, nunca perdi meu tempo tentando.

Agora, eu começaria tentando procurar alguma documentação do protocolo do messenger em si.[/quote]

Como assim em modo promíscuo? Esqueci de perguntar no outro post.

E quanto a JNI que vc mencionou: Winpcap, com ela seria possível ler/escrever em sockets externos? (Nada de alterar o conteúdo do pacote antes deste chegar ao destinatário, apenas ler e escrever nos sockets)

Grato![/quote]
com a pcap você consegue fazer isso. É a biblioteca do wireshark.[/quote]

Inclusive “selecionar” um socket externo (aberto por outro processo) e ler/escrever NESTE socket?

Grato![/quote]

isso só se você provocar um estouro de pilha e rezar pro seu programa acertar a área de memória do outro. Alguns hackers usam isso.

juliocbq, post vazio?

olha direito lá.

juliocbq, na verdade eu acho que não seria necessário ter acesso ao socket do outro aplicativo (msn por exemplo).

Usando a API citada por vcs eu poderia ler todos os pacotes que estão entrando no adaptador e através da porta destes pacotes saber para qual processo eles estão sendo enviados.

Agora o problema seria fazer o socket externo enviar dados para o seu destinatário através da minha aplicação java.

Suponha que o processo cliente do MSN esteja conectado com o processo servidor do MSN. O processo servidor tem endereço IP: 200.30.45.67 e está realizando a comunicação com o processo cliente através da porta 8764. Em minha aplicação java teria como eu “montar” um pacote TCP e enviar para 200.30.45.67:8764 independente de eu ter um socket TCP conectado a este servidor? Talvez eu fazendo isso o servidor entenderia esse pacote como sendo do cliente MSN e não da minha aplicação java.

Com os RAW sockets sim. Você terá que escrever não só a mensagem, mas o pacote TCP inteiro. E isso te permite escrever exatamente o mesmo ip e porta do msn original.

Por outro lado, o servidor irá devolver mensagens para o messenger original. Você pode até lê-las através do modo promíscuo da placa, mas não pode intercepta-las e impedir que vão para a aplicação original. Nesse caso, seria necessário usar chamadas a API do Windows.

O modo promíscuo é o que faz a placa ler tudo o que vem pela rede, não só o que está endereçado a ela. Ativando esse modo, você pode ver toda comunicação que chegar pela ponta do cabo ethernet, inclusive a de outras máquinas da sua rede local.

eu conheço um pouco da teoria, mais também nunca coloquei em prática…

vou dar um exemplo de uma rede:

Host A: MAC f2:f2:f2:f2 IP 192.168.0.25 <-> Servidor B: MAC t4:t4:t4:t4 IP 192.168.0.1 <-> internet <-> MSN Server

Atacante-TROLL: MAC x9:x9:x9:x9 ip 192.168.0.40

com maior facilidade, você deveria Envenenar a tabela ARP do HOST e do Servidor.

Enviando um RAW Socket - ARP Reponse criado em C/C++… com a seguinte informação: HOST A -> altere na sua tabela ARP: ip: 192.168.0.40 MAC t4:t4:t4:t4

Enviando um RAW Socket - ARP Reponse criado em C/C++… com a seguinte informação, Servidor B -> altere na sua tabela ARP: ip: 192.168.0.40 MAC f2:f2:f2:f2

ta envenenado…

agora você vai começar a receber os pacotes Enviados Recebidos de um host para o outro…

você poderá fazer alterações/drop/visualizar os pacotes enviados…e redireciona-los para os destinatarios

2º Forma:

  • forçar o Switch a trabalhar em modo HUB…você envia varias responses falsas de MAC para o switch, quando ele começar a travar, ver que ta tudo falso, ele vai começar a fazer broadcast dos pacotes…assim como o hub

dai pra frente você irá receber todos os pacotes que o switch envia, apenas deverá configurar sua placa de rede para o modo promiscuo

http://www.n3trino.com/papers/arp-poisoning

Só uma perguntinha babaca.
Será que o MSN criptografa os pacotes ou não?
Nunca rodei isso (não tenho conta no MSN) e nunca fiquei examinando os pacotes com o Wireshark (ou com o Microsoft Network Monitor).
Se ele não criptografar os pacotes, pode-se fazer, via injeção de DLLs, uma forma de você injetar uma DLL que interceptasse as chamadas à biblioteca de sockets do Windows.
Mas pelo que imagino, ele deve usar uma criptografia, mas bem fraquinha, para que o pessoal do Departamento de Defesa, FBI e outras agências governamentais americanas possam fuçar na sua comunicação.

[quote=entanglement]Só uma perguntinha babaca.
Será que o MSN criptografa os pacotes ou não?
Nunca rodei isso (não tenho conta no MSN) e nunca fiquei examinando os pacotes com o Wireshark (ou com o Microsoft Network Monitor).
Se ele não criptografar os pacotes, pode-se fazer, via injeção de DLLs, uma forma de você injetar uma DLL que interceptasse as chamadas à biblioteca de sockets do Windows.
Mas pelo que imagino, ele deve usar uma criptografia, mas bem fraquinha, para que o pessoal do Departamento de Defesa, FBI e outras agências governamentais americanas possam fuçar na sua comunicação.[/quote]

Eles não usam criptografia. Por isso tem como usar o squid e o sarg para filtrarem conversas de msn numa empresa. Já o googletalk e seus outros serviços usam ssl, dessa maneira sendo bem mais seguro.

amigo faça como falei, e então faça os testes e veja rodando

baixe e instale o Winpcap,
baixe e instale o Jpcap,

baixe o código que te passei, compila executa e veja o que acontece…

ai vai mudando o código conforme precisa,

no código do site ele passa para as maquinas um MAC falso, passe o mac da sua maquina e prepare um cara para enterpretar os pacotes que forem do mesmo protocolo que o msn,

quando vier os pacotes você imprime na tela e veja como ele é…

[quote=ViniGodoy]Com os RAW sockets sim. Você terá que escrever não só a mensagem, mas o pacote TCP inteiro. E isso te permite escrever exatamente o mesmo ip e porta do msn original.

Por outro lado, o servidor irá devolver mensagens para o messenger original. Você pode até lê-las através do modo promíscuo da placa, mas não pode intercepta-las e impedir que vão para a aplicação original. Nesse caso, seria necessário usar chamadas a API do Windows.

O modo promíscuo é o que faz a placa ler tudo o que vem pela rede, não só o que está endereçado a ela. Ativando esse modo, você pode ver toda comunicação que chegar pela ponta do cabo ethernet, inclusive a de outras máquinas da sua rede local.[/quote]

Olhando a documentação do JPCAP pude perceber que com esta API é possível você montar e enviar um pacote TCP e UDP inteiros.

http://netresearch.ics.uci.edu/kfujii/Jpcap/doc/javadoc/index.html

Agora quanto a algumas informações necessárias para preencher um pacote TCP, como o número de sequência do pacote, eu necessitaria conhecer os pacotes que foram enviados anteriormente para colocar um número de sequência correto? Tenho esta mesma dúvida para outras informações que identificam um pacote. Ou eu poderia simplesmente inventar valores lógicos para estes campos sem nem mesmo ter conhecimento do que foi enviado anteriormente?

Realmente, acho que para interceptar os pacotes e alterá-los antes que estes cheguem a seus destinos, apenas conhecendo bastante a API do sistema operacional.

Grato! ^^

Consegui usar a API PCAP, porém estou com dificuldades para montar um pacote que seja aceito e transmitido para o processo(aplicativo) destino.

Eu peguei este código do site da PCAP e modifiquei para a minha situação:

[code]import java.net.InetAddress;

import jpcap.*;
import jpcap.packet.EthernetPacket;
import jpcap.packet.IPPacket;
import jpcap.packet.TCPPacket;

class SendTCP
{
public static void main(String[] args) throws java.io.IOException{
NetworkInterface[] devices = JpcapCaptor.getDeviceList();
if(args.length<1){
System.out.println(“Usage: java SentTCP <device index (e.g., 0, 1…)>”);
for(int i=0;i<devices.length;i++)
System.out.println(i+":"+devices[i].name+"("+devices[i].description+")");
//System.exit(0);
}
int index=Integer.parseInt(“0”);
JpcapSender sender=JpcapSender.openDevice(devices[index]);

	TCPPacket p=new TCPPacket(57235,1057,5000,78,false,false,false,false,false,false,false,false,64400,10);
p.setIPv4Parameter(0,false,false,false,0,false,true,false,0,24300,118,IPPacket.IPPROTO_TCP,
		InetAddress.getByName("192.168.1.118"),InetAddress.getByName("192.168.1.118"));
p.data=("<Gabriel.> oi.").getBytes();
	
	EthernetPacket ether=new EthernetPacket();
	ether.frametype=EthernetPacket.ETHERTYPE_IP;
	ether.src_mac=new byte[]{(byte)0,(byte)36,(byte)140,(byte)137,(byte)152,(byte)24};
	ether.dst_mac=new byte[]{(byte)116,(byte)234,(byte)58,(byte)233,(byte)236,(byte)227};
	p.datalink=ether;

	for(int i=0;i<10;i++)
		sender.sendPacket(p);
}

}[/code]

Mas os dados não chegam ao processo destino.

Utilizando o wireshark para analisar o tráfego durante a execução do código anterior, vejam o que acontece:

Creio eu que o problema esteja com este Reserved, que eu não sei do que se trata.

Até+!