spacer.png, 0 kB
spacer.png, 0 kB
Home arrow All Articles arrow Hacking Articles arrow How to Detect Network Scans

Subscribe to our news and articles by RSS or by email
Read All of Our Hot News Items Here
How to Detect Network Scans Print E-mail
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.

  1. 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.
  2. 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:

 
< Prev   Next >
spacer.png, 0 kB
spacer.png, 0 kB
spacer.png, 0 kB