#!/usr/bin/perl # # J-Dog's Scan Detector 1.0B # # This script was written as a quick example as to how someone might detect # portscans. This script was developed in about 4 hours late one monday night # after a 36 hour workday, so please lighten up on my code, I know it isn't # pretty, but hey, it gets the job done. # I will be working on implementing automatic ident and fingering of the user # doing the portscanning and possible a whois on the domain name and a mailto # the tech and admin contacts for the domain from which the scan is coming from. # # If you have any questions/requests, please feel free to email them to me at # J-Dog@Resentment.org # # Note: as soon as I get all the features I want to in here, I will be porting this # to perl32 so that 95/98/NT users who do not have the benefit of such great utils # as tcplog and scanlogd will be able to detect portscans. # ########################################################################## # Declare that we are going to be using the Sockets Library use Socket; # Read in the port number we are to use (if specified) ($port) = @ARGV; # If no port specified, run on 54 (keep low to catch even small scans) $port = 54 unless $port; $tcpport = $port; # Tell the administrator what port we are listening on print "Watching for portscans on port $port...\n"; # setup the socket and bind it socket(S,AF_INET,SOCK_STREAM,$protocol) || die "socket : $!"; $sockaddr = 'S n a4 x8'; $this = pack($sockaddr, AF_INET, $port, "\0\0\0\0"); bind(S, $this) || die "bind : $!"; # Queue up to 10 connections until they can be processed listen(S,10) || die "listen: $!"; # Select S temporarily as the default output channel, turn on # autoflushing, then select standard output again. select(S); $| = 1; select(STDOUT); # Create connections as clients "arrive". $con maintains the connection # number of the last client for ($connection_number = 1; ; $connection_number++) { # grab that users info ($addr = accept(NS,S)) || die $!; # Temporarily set default output to the handle NS select(NS); $| = 1; select(STDOUT); # Fork this sukka if (($child = fork()) == 0) { # unpack the information returned by 'accept' to get some # (readable) information about the client and print it ($af,$port, $inetaddr) = unpack($sockaddr, $addr); @inetaddr = unpack('C4', $inetaddr); $hostname = gethostbyaddr ($inetaddr, 2); ($ip1,$ip2,$ip3,$ip4) = @inetaddr; $ipaddress = "$ip1.$ip2.$ip3.$ip4"; # Tell the user we have a portscan attempt print "\n--------------=[ PORTSCAN DETECTED ]=--------------\n"; print "Portscan attempt # $connection_number\n"; print "IP Address is $ipaddress\n"; print "Hostname is $hostname\n"; print "Connection to $ipaddress Closed.\n"; print "---------------------------------------------------\n"; print "\nContinuing to listen on port $tcpport ...\n"; # If you want to let them now they were detected, # just uncomment the line below. # print NS "Portscan detected from you at $ipaddress - $hostname$ # Close the socket connection close(NS); exit; } }