那个分析数据包的脚本

前些天在《简单分析数据包判断攻击》中说整理一下然后发脚本的,结果搞忘记了。这几天有人提醒,那么就把没整理的发出来吧。博客中发代码的插件不是很好,所以代码会有部分字符会转义,将就一下吧。

  1. #!/usr/bin/perl
  2.  
  3. use warnings;
  4. use strict;
  5. use Getopt::Std;
  6. use NetPacket::TCP;
  7. use Net::TcpDumpLog;
  8. use NetPacket::Ethernet qw(:strip ETH_TYPE_IP);
  9. use NetPacket::IP qw(:strip IP_PROTO_TCP);
  10.  
  11. my %opts = ();
  12. my %ips = ();
  13. my %connection = ();
  14.  
  15. getopts('i:p:f:', \%opts);
  16. if( !defined($opts{i}) || !defined($opts{p}) || !defined($opts{f}) )
  17. {
  18. print "\nuse tcpdump to capture incoming packets first.\n";
  19. print "tcpdump -w /tmp/test.pcap -n -nn -i eth0 tcp port 80 and dst host 192.168.1.1\n";
  20. print "Usage: ./packets.pl -i <server_ip> -p <server_port> -f <pcap_file>\n";
  21. print "Example: ./packets.pl -i 192.168.1.1 -p 80 -f /tmp/packets.pcap\n\n";
  22. exit 0;
  23. }
  24.  
  25. my $tcp_pkt_num = 0;
  26. my $syn_pkt_num = 0;
  27. my $ack_pkt_num = 0;
  28.  
  29. my $syn_host_num = 0;
  30. my $fake_ip_num = 0;
  31.  
  32. my $log = Net::TcpDumpLog->new();
  33. $log->read( $opts{f} );
  34.  
  35. my @indexes = $log->indexes();
  36.  
  37. my (undef,undef,undef,$start_time,undef) = $log->header(0);
  38. my (undef,undef,undef,$end_time,undef) = $log->header(scalar(@indexes) - 1);
  39. my $use_time = $end_time - $start_time;
  40.  
  41. foreach my $index (@indexes)
  42. {
  43. my $data = $log->data($index);
  44. my $eth_obj = NetPacket::Ethernet->decode($data);
  45.  
  46. # if not ip protocol
  47. if( $eth_obj->{'type'} != ETH_TYPE_IP )
  48. {
  49. next;
  50. }
  51.  
  52. my $ip_obj = NetPacket::IP->decode(eth_strip($data));
  53.  
  54. # if not the ip we care
  55. if( $ip_obj->{dest_ip} ne $opts{i} )
  56. {
  57. next;
  58. }
  59.  
  60. # if not tcp protocol
  61. if( $ip_obj->{'proto'} != IP_PROTO_TCP )
  62. {
  63. next;
  64. }
  65.  
  66. my $tcp_obj = NetPacket::TCP->decode( $ip_obj->{data} );
  67.  
  68. # if not the port we care
  69. if( $tcp_obj->{dest_port} != $opts{p} )
  70. {
  71. next;
  72. }
  73.  
  74. $tcp_pkt_num ++;
  75.  
  76. my $src_ip = $ip_obj->{'src_ip'};
  77. my $src_port = $tcp_obj->{'src_port'};
  78. if( !exists($ips{$src_ip}{syn}) )
  79. {
  80. $ips{$src_ip}{syn} = 0;
  81. }
  82.  
  83. if( !exists($ips{$src_ip}{ack}) )
  84. {
  85. $ips{$src_ip}{ack} = 0;
  86. }
  87.  
  88. # use srcip and src port to detect flow.
  89. # it's not exact, but it's ok.
  90. my $key = $src_ip.":".$src_port;
  91. if( !exists($connection{$src_ip}{'count'}) )
  92. {
  93. $connection{$src_ip}{'count'} = 0;
  94. }
  95.  
  96. if( !exists($connection{$src_ip}{$key}) )
  97. {
  98. $connection{$src_ip}{$key} = 1;
  99. $connection{$src_ip}{'count'} ++;
  100. }
  101.  
  102. if( $tcp_obj->{flags} == SYN )
  103. {
  104. $ips{$src_ip}{syn} ++;
  105. $syn_pkt_num ++;
  106. }
  107. elsif( $tcp_obj->{flags} == ACK )
  108. {
  109. $ips{$src_ip}{ack} ++;
  110. }
  111. }
  112.  
  113. print "\nSummary:\n Recv $tcp_pkt_num tcp packets to $opts{i}:$opts{p} in $use_time seconds";
  114. if( $use_time != 0 )
  115. {
  116. print ", PPS is ".$tcp_pkt_num/$use_time."\n";
  117. }
  118. else
  119. {
  120. print "\n";
  121. }
  122.  
  123. if( &DetectSYN() !=1 )
  124. {
  125. &ShowConn();
  126. }
  127.  
  128. sub DetectSYN
  129. {
  130. my %focus_ip;
  131. foreach my $ip( keys %ips )
  132. {
  133. if( $ips{$ip}{syn} != 0 )
  134. {
  135. $syn_host_num ++;
  136.  
  137. if( $ips{$ip}{ack} != 0 )
  138. {
  139. $ack_pkt_num += $ips{$ip}{ack};
  140. }
  141. else
  142. {
  143. $focus_ip{$ip} = $ips{$ip}{syn};
  144. $fake_ip_num ++;
  145. }
  146. }
  147. }
  148. print " $syn_pkt_num syn packets from $syn_host_num hosts, and $ack_pkt_num ack packets from these hosts.";
  149. if( $syn_pkt_num != 0 )
  150. {
  151. print "(ack/syn=".$ack_pkt_num*100/$syn_pkt_num."%)\n";
  152. }
  153. else
  154. {
  155. print "\n";
  156. }
  157. print " $fake_ip_num ip is fake";
  158.  
  159. my $percentage = 0;
  160. if( $syn_host_num != 0 )
  161. {
  162. $percentage = $fake_ip_num/$syn_host_num;
  163. my $tmp = $percentage * 100;
  164. print ", percentage of fake ip is $tmp%.\n\n";
  165. }
  166. else
  167. {
  168. print "\n";
  169. }
  170.  
  171. print "SYN Flood:\n";
  172.  
  173. if( $percentage >= 0.1 )
  174. {
  175. print " We're under SYN Flooding!\n\n";
  176. return 1;
  177. =pod
  178.   print "Details:\n";
  179.  
  180.   foreach my $ip (sort {$focus_ip{$b} <=> $focus_ip{$a}} keys %focus_ip)
  181.   {
  182.   print " $ip send $focus_ip{$ip} syn packets but no ack packets.\n";
  183.   }
  184. =cut
  185. }
  186. elsif( $percentage > 0.05 )
  187. {
  188. print " There're no SYN Flooding, or a little?\n\n";
  189. return 0;
  190. }
  191. elsif( $percentage == 0 )
  192. {
  193. print " nothing, check the ip and port.\n";
  194. return 0;
  195. }
  196. else
  197. {
  198. print " There're no SYN Flooding.\n\n";
  199. return 0;
  200. }
  201. }
  202.  
  203. sub ShowConn
  204. {
  205. my %focus_ip = ( );
  206.  
  207. foreach my $ip( keys %connection )
  208. {
  209. $focus_ip{$ip} = $connection{$ip}{count};
  210. }
  211.  
  212. my $i = 0;
  213. print "Connection:\n";
  214. if( scalar keys %focus_ip == 0 )
  215. {
  216. print " nothing, check the ip and port.\n";
  217. }
  218.  
  219. foreach my $ip (sort {$focus_ip{$b} <=> $focus_ip{$a}} keys %focus_ip)
  220. {
  221. if( $i == 10 )
  222. {
  223. last;
  224. }
  225.  
  226. print " $ip create $focus_ip{$ip} connections to $opts{i}:$opts{p} in $use_time seconds.\n";
  227. $i ++;
  228. }
  229. print "\n";
  230. }
  231.  

此条目发表在技术分类目录。将固定链接加入收藏夹。

那个分析数据包的脚本》有 4 条评论

  1. vessial说:

    哈哈perl大拿,不错不错,有点意思,不过要是熟悉python的话,我建议使用scapy,这个可以实时抓包检测,也就是有回调功能:)

  2. 云舒说:

    perl也可以的,但是服务器上有tcpdump,而不一定有指定的模块。所以反生攻击但是安全人员不在的时候,其他部门可以先tcpdump把包抓到分析服务器来,用这个脚本做一个初步的判断。

  3. zuhd说:

    问下云大,这个预测的算法是自己定义的吧,能描述下算法不,不懂perl

发表评论

电子邮件地址不会被公开。 必填项已用*标注