Kill sockets acabados (usando libpcap - tcpdump / tcpkill)

3

Estou tentando criar um pequeno serviço que monitora e mata os sockets que possuem o sinalizador FIN . Eu posso obtê-los com tcpdump (eu também tentei tcp [13] & 1):

tcpdump "tcp[tcpflags] & tcp-fin != 0"

tcpkill é suposto usar a mesma interface do tcpdump , mas não está funcionando da mesma forma. Eu tentei um monte de comandos, mas deve ser apenas (-i eth0 opcional):

tcpkill -9 "tcp[tcpflags] & tcp-fin != 0"

O que diz (mas nada mais, resultados tcpkill saidos):

tcpkill: listening on eth0 [tcp[tcpflags] & tcp-fin != 0]

Olhando para a fonte, ela deve passar o filtro correto para pcap (entre os colchetes []). Usando um script perl com Net :: Pcap , posso determinar que o filtro funciona bem. Eu não sei o que estou fazendo errado, ou se é uma versão mais antiga do tcpkill / pcap isso é um problema. Qualquer ajuda com tcpkill ou ajuda usando Net :: Pcap para matar sockets seria apreciada. Obrigado!

#!/usr/bin/perl

use strict;
use warnings;

use Net::Pcap;

my $err = '';
my $dev = 'eth0';

my ($address, $netmask);
Net::Pcap::lookupnet($dev, \$address, \$netmask, \$err);

my $pcap = Net::Pcap::open_live($dev, 1500, 1, 0, \$err);

my $filter;
Net::Pcap::compile($pcap, \$filter, "tcp[tcpflags] & tcp-fin != 0", 0, $netmask);
Net::Pcap::setfilter($pcap, $filter);

while(1)
{
 Net::Pcap::loop($pcap, 1, \&process_packet, "packet found");
}

Net::Pcap::close($pcap);

sub process_packet
{
 my($user_data, $header, $packet) = @_;
 print "$user_data\n";
}

exit 0;
    
por Eric Muyser 12.07.2010 / 08:14

1 resposta

0

Olhando o código-fonte para tcpkill , ele usa a libnet para gerar um pacote RST para matar uma determinada conexão TCP. Não sei por que não está funcionando (embora verificar a versão do PCAP em que ela foi construída seja um ótimo local para começar). Você também pode usar o tcpdump para procurar os pacotes RST que ele deve enviar.

Em relação à implementação do equivalente em Perl, uma vez tive que fazer algo parecido. Abaixo está o código (não testado!) Que pode apontar você na direção certa.

use NetPacket::Ethernet;
use NetPacket::IP;
use NetPacket::TCP;
use Net::RawIP;

... (the rest of your script) ...

sub process_packet {
    my ($user_data,$header,$packet) = @_;

    my $ethernet_frame = NetPacket::Ethernet::strip($packet);
    my $ip_packet = NetPacket::IP->decode($ethernet_frame);
    my $tcp = NetPacket::TCP->decode($ip_packet->{data});

    my $reset_packet = new Net::RawIP;

    $reset_packet->set({
        ip => {
            saddr => $ip_packet->{dest_ip},
            daddr => $ip_packet->{src_ip}
        },
        tcp => {
            source => $tcp->{dest_port},
            dest => $tcp->{src_port}
        },
        rst => 1,
        seq => $ip->{acknum},
        data => 'access denied'
    });

    $reset_packet->send();
}

tcpkill é mais refinado em termos de tentar descobrir o número de seqüência correto, que é o que os sinalizadores -1..9 são para. Você tentou usar valores diferentes para esse sinalizador?

    
por 30.07.2010 / 02:11