detecting Solaris tojans with argus

Peter Van Epp vanepp at sfu.ca
Thu Jan 6 17:14:02 EST 2000


	Here is a slightly better perl script for finding echo response packets.
The major change is a new summary table that counts hits from a source IP to
an entire class C net and a threshold variable ($SCAN_LIMIT, default 5). After
SCAN_LIMIT packets are seen from a source to a net further packets from that 
source to the net are suppressed in the next table (further down there is still
a complete table) and the count is displayed in the first table (again below
the summaries there is a complete copy of the table if needed). You can
search for "###" to find the start of a table, and for "---" to get to the end
of the summary tables and start of the full tables (so you can delete them 
easily if you don't want them). The change is because of gag scans. The
original gets unwieldy under a multi subnet gag scan (I haven't seen one yet
so it hadn't bitten me, but undoubtably will :-) ) with the summarization and
threshold you should still be able to see attacks on individual machines even
while a scan or scans is going on.

Peter Van Epp / Operations and Technical Support 

--- cut here ---
#!/usr/local/bin/perl

# when SCAN_LIMIT is exceeded for a source ip dest net pair the detail recording
# of the source and destination ip pairs stops (for table size limits) but 
# further hits are counted in the source ip to dest net count (the first
# table). Change the limit to suit your taste (or tolorance).

$SCAN_LIMIT = 5;

open(STDIN,$ARGV[0]) || die "Can't open $ARGV[0]: $!\n"
	if $ARGV[0];
$line = 0;
$start_time = "";
$end_time = "";
while (<STDIN>) {
	$line ++;
	if (($line % 10000) == 0) {
		print STDERR "Processing $line\n";
	}
	chop;
	$src_bytes = " ";
	$dest_bytes = " ";
	$source_net ="";
	$dest_net ="";
	$src_port = " ";
	$dst_port = " ";
	($date, $flag, $rest) = unpack("A18 A5 A200",$_);
	if ($start_time eq "") {
		$start_time = $date;
	}
	($type, $rest) = split(' ',$rest,2);
	if ($type eq "man") {
		$mid_flag = ' ';
	 	($source_ip, $dest_ip, $src_pkt, $dest_pkt, $src_bytes, 
		 $dest_bytes, $end_flag) = split(' ',$rest,7); 
	} elsif ($type eq "icmp") {
	 	($source_ip, $mid_flag, $dest_ip, $src_pkt, $dest_pkt, 
		 $end_flag) = split(' ',$rest,6); 
		if ($end_flag =~ /port/) {
			($t, $p, $dst_port, $rest) = split(' ',$end_flag);
		}
		($a,$b,$c,$d)= split(/\./,$source_ip);
		($e,$f,$g,$h)= split(/\./,$dest_ip);
	} else {
	 	($source_ip, $mid_flag, $dest_ip, $src_pkt, $dest_pkt, 
		 $src_bytes, $dest_bytes, $end_flag) = split(' ',$rest,8); 
		($a,$b,$c,$d,$src_port)= split(/\./,$source_ip);
		($e,$f,$g,$h,$dst_port)= split(/\./,$dest_ip);
	}
	$source_ip = "$a.$b.$c.$d";
	$source_net = "$a.$b.$c";
	$dest_ip = "$e.$f.$g.$h";
	$dest_net = "$e.$f.$g";
	if ($type eq "icmp") {
		if ($end_flag eq "ECO" || $end_flag eq "ECR") {
			$all_data{"$dest_ip"} .= "$date $source_ip $mid_flag $dest_ip $end_flag\n";
		}
		if ($end_flag eq "ECR") {

# Sometimes argus gets source and dest reversed, so correct everything to one
# format ...

			if ($mid_flag eq "<-") {
				$tmp = $source_ip;
				$source_ip = $dest_ip;
				$dest_ip = $tmp;
				$tmp = $source_net;
				$source_net = $dest_net;
				$dest_net = $tmp;
				$mid_flag = "->";
			}
			$ecr_dest_net_data{"$source_ip $dest_net"} += 1;
			if ($ecr_dest_net_data{"$source_ip $dest_net"} < $SCAN_LIMIT) {
				$ecr_src_data_limited{"$source_ip"} .= "$date $source_ip $mid_flag $dest_ip $end_flag\n";
				$ecr_dest_data_limited{"$dest_ip"} .= "$date $source_ip $mid_flag $dest_ip $end_flag\n";
			}
			$ecr_src_data{"$source_ip"} .= "$date $source_ip $mid_flag $dest_ip $end_flag\n";
			$ecr_dest_data{"$dest_ip"} .= "$date $source_ip $mid_flag $dest_ip $end_flag\n";
		}
	}
}
$end_time = $date;
print "Search for '###' to find next table header, search for '---' for full data\n\n*** Data from $start_time til $end_time\n\n";
print "### Unsolicited echo response by source IP and destination net count summary\n\t(counts greater than SCAN_LIMIT)\n\n";
foreach $source (sort (keys %ecr_dest_net_data)) {
	if ($ecr_dest_net_data{$source} >= $SCAN_LIMIT) {
		($src, $dst) = split(' ',$source);
		write;
	}
}

print "\n### Only echo response data sorted by destination machine less than SCAN_LIMIT\n\n";
foreach $source (sort (keys %ecr_dest_data_limited)) {
	print "$ecr_dest_data_limited{$source}\n";
}
print "\n### Only echo response data sorted by source machine less than SCAN_LIMIT\n\n";
foreach $source (sort (keys %ecr_src_data_limited)) {
	print "$ecr_src_data_limited{$source}\n";
}
print "---\n### Unsolicited echo response by source IP and destination net count summary\n\n";
foreach $source (sort (keys %ecr_dest_net_data)) {
	($src, $dst) = split(' ',$source);
	write;
}
print "\n### Only echo response data sorted by destination machine\n\n";
foreach $source (sort (keys %ecr_dest_data)) {
	print "$ecr_dest_data{$source}\n";
}
print "\n### Only echo response data sorted by source machine\n\n";
foreach $source (sort (keys %ecr_src_data)) {
	print "$ecr_src_data{$source}\n";
}
print "\n### All echo data\n\n";
foreach $source (sort (keys %all_data)) {
	print "$all_data{$source}\n";
}

format STDOUT =
@<<<<<<<<<<<<<<< @<<<<<<<<<<< @>>>>>>>>>>>>>>>>>
$src, $dst, $ecr_dest_net_data{$source}



More information about the argus mailing list