Назад | Перейти на главную страницу

Убейте FINished сокеты (используя libpcap - tcpdump / tcpkill)

Я пытаюсь создать небольшую службу, которая отслеживает и убивает сокеты, у которых есть ПЛАВНИК флаг. Я могу получить их с tcpdump (Я также пробовал tcp [13] & 1):

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

tcpkill предполагается использовать тот же интерфейс, что и tcpdump, но это не работает. Я пробовал кучу команд, но это должно быть просто (-i eth0 необязательно):

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

Что говорит (но ничего другого, успешно tcpkill выводит данные):

tcpkill: прослушивание eth0 [tcp [tcpflags] & tcp-fin! = 0]

Если посмотреть на исходный код, он должен передать в pcap правильный фильтр (между скобками []). Использование Perl-скрипта с Net :: Pcap Я могу определить, что фильтр работает нормально. Я не знаю, что я делаю не так, или проблема в более старой версии tcpkill / pcap. Любая помощь с tcpkill или помощь с использованием perl Net :: Pcap убить сокеты будут оценены. Спасибо!

#!/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;

Глядя на исходный код для tcpkill, он использует libnet для генерации пакета (ов) RST, чтобы уничтожить данное TCP-соединение. Я не уверен, почему он не работает (хотя проверка версии PCAP, для которой он был создан, - отличное место для начала). Вы также можете использовать tcpdump для поиска пакетов RST, которые он должен отправлять.

Что касается реализации эквивалента в Perl, мне однажды пришлось сделать нечто подобное. Ниже приведен (непроверенный!) Код, который может указать вам правильное направление.

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 более усовершенствован с точки зрения попытки определить правильный порядковый номер, для чего нужны флаги -1..9. Вы пробовали использовать другие значения для этого флага?