Perl
殺死已完成的套接字(使用 libpcap - tcpdump/tcpkill)
我正在嘗試創建一個小型服務來監視和終止具有FIN標誌的套接字。我可以用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 (在
$$ $$括號)。使用帶有Net::Pcap的 perl 腳本,我可以確定過濾器工作正常。我不知道我做錯了什麼,或者它是否是舊版本的 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 標誌的用途。您是否嘗試過為該標誌使用不同的值?