|
By: David Brumley [
This e-mail address is being protected from spam bots, you need JavaScript enabled to view it
] Definition: Network Scan A simple network scans is the result of a single source host contacting multiple hosts on one port, or a single host on multiple ports. What does a network scan look like? Example 1: One host probing many hosts
Fri 08/18 00:12:28 tcp 127.0.0.1.1328 <| 171.64.99.6.21 RST Fri 08/18 00:12:28 tcp 127.0.0.1.1327 <| 171.64.99.5.21 RST Fri 08/18 00:12:56 tcp 127.0.0.1.1336 <| 171.64.99.13.21 RST Fri 08/18 00:12:44 tcp 127.0.0.1.1334 |> 171.64.99.11.21 RST Fri 08/18 00:12:30 s tcp 127.0.0.1.1330 -> 171.64.99.7.21 REQ Fri 08/18 00:12:31 s tcp 127.0.0.1.1331 -> 171.64.99.8.21 REQ Fri 08/18 00:14:35 tcp 127.0.0.1.1356 <| 171.64.99.23.21 RST Fri 08/18 00:12:42 s tcp 127.0.0.1.1333 -> 171.64.99.10.21 REQ Fri 08/18 00:12:46 s tcp 127.0.0.1.1335 -> 171.64.99.12.21 REQ Fri 08/18 00:12:56 s tcp 127.0.0.1.1337 -> 171.64.99.14.21 REQ Fri 08/18 00:13:15 s tcp 127.0.0.1.1345 |> 171.64.99.20.21 RST Fri 08/18 00:12:58 tcp 127.0.0.1.1338 -> 171.64.99.15.21 FIN Fri 08/18 00:12:59 s tcp 127.0.0.1.1339 -> 171.64.99.16.21 REQ Fri 08/18 00:13:11 s tcp 127.0.0.1.1341 -> 171.64.99.17.21 REQ Fri 08/18 00:13:12 s tcp 127.0.0.1.1342 -> 171.64.99.18.21 REQ Fri 08/18 00:13:14 s tcp 127.0.0.1.1344 -> 171.64.99.19.21 REQ Fri 08/18 00:14:32 s tcp 127.0.0.1.1354 -> 171.64.99.21.21 CLO Fri 08/18 00:15:49 tcp 127.0.0.1.1364 |> 171.64.99.25.21 RST Fri 08/18 00:15:51 tcp 127.0.0.1.1365 |> 171.64.99.26.21 RST Fri 08/18 00:15:53 tcp 127.0.0.1.1366 |> 171.64.99.27.21 RST Fri 08/18 00:14:33 s tcp 127.0.0.1.1355 -> 171.64.99.22.21 REQ Fri 08/18 00:16:00 tcp 127.0.0.1.1367 |> 171.64.99.29.21 RST Fri 08/18 00:16:01 tcp 127.0.0.1.1368 |> 171.64.99.30.21 RST Fri 08/18 00:14:37 s tcp 127.0.0.1.1357 -> 171.64.99.24.21 REQ Fri 08/18 00:16:04 tcp 127.0.0.1.1370 |> 171.64.99.32.21 RST Fri 08/18 00:16:40 tcp 127.0.0.1.1381 <| 171.64.99.41.21 RST Fri 08/18 00:16:43 tcp 127.0.0.1.1383 <| 171.64.99.43.21 RST Fri 08/18 00:16:14 tcp 127.0.0.1.1373 |> 171.64.99.33.21 RST Fri 08/18 00:16:52 tcp 127.0.0.1.1385 <| 171.64.99.45.21 RST Fri 08/18 00:16:18 tcp 127.0.0.1.1376 |> 171.64.99.35.21 RST Fri 08/18 00:16:26 tcp 127.0.0.1.1377 |> 171.64.99.37.21 RST
Example 2: One host scanning a single host
Fri 08/18 11:50:15 tcp 127.0.0.1.56005 <| 207.5.1.122.343 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56006 <| 207.5.1.122.344 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56007 <| 207.5.1.122.345 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56008 <| 207.5.1.122.346 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56025 <| 207.5.1.122.363 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56026 <| 207.5.1.122.364 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56027 <| 207.5.1.122.365 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56028 <| 207.5.1.122.366 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56029 <| 207.5.1.122.367 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56030 <| 207.5.1.122.368 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56031 <| 207.5.1.122.369 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56032 <| 207.5.1.122.370 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56033 <| 207.5.1.122.371 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56034 <| 207.5.1.122.372 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56035 <| 207.5.1.122.373 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56036 <| 207.5.1.122.374 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56037 <| 207.5.1.122.375 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56038 <| 207.5.1.122.376 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56039 <| 207.5.1.122.377 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56040 <| 207.5.1.122.378 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56041 <| 207.5.1.122.379 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56042 <| 207.5.1.122.380 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56043 <| 207.5.1.122.381 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56044 <| 207.5.1.122.382 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56045 <| 207.5.1.122.383 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56046 <| 207.5.1.122.384 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56047 <| 207.5.1.122.385 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56048 <| 207.5.1.122.386 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56049 <| 207.5.1.122.387 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56050 <| 207.5.1.122.388 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56051 <| 207.5.1.122.389 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56052 <| 207.5.1.122.390 RST Fri 08/18 11:50:15 tcp 127.0.0.1.56053 <| 207.5.1.122.391 RST
How can I detect either scan? Upon careful inspection of the above, notice that the string of: "IP.PORT" Changes each time. In perl, the syntax would be: $DST = $dsti_p . $dst_port We can use this to build a hash table with the form:
$DST = $dst_ip . $dst_port
$src -> #1 $DST -> #2 $DST -> #3 $DST ....
To detect either type of scan, simply count the number of hashes a given source IP generates. If that number is over X, where X is what you consider a scan, simply display the results. Do you have example code? Of course! #!/usr/bin/perl
# The command to open the file of records my $commnad="/usr/bin/foo";
# How often to cleans the hash table. The more often you clean, # the less likely you are to pick up slow scans, but the less # memory you will use. my $CLEAN_MARK=500000;
# THe minimum number of hashs need to keep a record past the # hash table cleaning. This is basically how sparse each hash # can be before cleaning. my $MIN=5;
# table to store ip hashes my %table;
# record format my @rec;
# number of bad hosts seen my $num_bad_hosts = 0;
# Total number of ip's seen my $total_ip = 0;
# Format is my example that of netflow callrecords. e.g.: # 1 2 3 4 5 6 # src ip|dst ip|src port|dst port| protocol|tos # # 7 8 9 10 11 12 # packets|bytes|flows|starttime|lasttime|totalactivetime
my $SRC = 0; my $DST = 1; my $SPORT = 2; my $DPORT = 3; my $PROTO = 4; my $TOS = 5; my $PACKETS = 6; my $BYTES = 7; my $FLOWS = 8; my $START = 9; my $STOP = 10; my $TTIME = 11;
# Open stream. open(SW, $command) || die "Couldn't open input stream\n";
# Throw away header in netflow records. $header = ;
# This is where we clean out our hash table. Any source that doesn't # Have at least $MIN hashes will be deleted to save space.
sub clean_hashes() { # printf "Cleaning tables...\n"; my $c = 0; foreach my $ip (keys %table) { $num_keys = scalar(keys %{$table{$ip}} ); if($num_keys < $MIN){ delete $table{$ip}; $c++; } } }
# This is the magic part. We read in the records, format, and hash while(){ chomp; my @record = split (/\|/, $_); $total_record++; # Argh clean_hashes if($total_record % $CLEAN_MARK == 0);
my $src = @record[$SRC]; my $dst = "@record[$DST].@record[$DPORT]";
if(! exists $table{$src}){ $table{$src}->{$dst} = 1; } if( ! exists $table{$src}->{$dst} ) { $table{$src}->{$dst} = 1; } else { $table{$src}->{$dst}++; } } clean_hashes;
# Print out the scanning IP addresses! foreach my $ip (keys %table){ $num_keys = scalar(keys %{$table{$ip}} ); if($num_keys > $THRESHOLD){ $num_bad_hosts++; foreach my $dst (keys %{$table{$ip}} ){ printf "\t$dst\n"; } }
printf "Total number of hosts scanning our network: $num_bad_hosts\n";
How do I report scans? There are two main ways of finding contact information for contacting hosts that originate scans. - If the domain resolves, you can use "whois" to find out contact information for the domain. If the domain resolves but whois gives no useful information, email "abuse@domain" and "postmaster@domain". The abuse address is defined for well managed sites. The postmaster address is needed for sites that accept email.
- You can use the IP address registry, known as ARIN in the US, to find contact information for the IP address.
Note that the two methods are distinct. The owner of the IP address quite often is not the owner of the domain name. This is because ISP's often own the IP address and "rent out" space for domain names. Is there a useful tool for finding out this information? Yes, there is "whois" under most unix variants. I recommend using the BSD whois available many places including: ftp://www.theorygroup.com/pub/net-tools/whois-4.4.5.tar.gz Credits Thanks to Russell Fulton and Russell Street for giving me sample perl code from which the above example is derrived. Last modified: Mon Aug 21 13:08:45 PDT 2000
Related Items:
|