' addbanip.vbs - Lock IP addresses with more than a number of invalid ' login attemps. ' ' Legal notice! ' Script provided by Michael Kunzendorf in the GlobalSCAPE user forum. ' This script provided as a courtesy, BUT USE IT AT YOUR OWN RISK. ' You can use this script free of charge, private or commercial. ' No warranty, expressed or implied, is made by GlobalSCAPE as to the ' accuracy of this script or its fitness for a particular use. ' The act of distribution does not constitute any such warranty, ' and no responsibility is assumed by GlobalSCAPE in the use of this script. ' Option Explicit '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Constants for server details ' Change these for your environment '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Const cServer = "localhost" Const cServerSite = "MySite" ' Change as reqired Const cPort = "1000" ' Default port: 1000 for Secure FTP, 1100 for EFT or whatever you have configured Const cUserName = "admin" Const cPassword = "ThisIsNotARealPassword" ' Change as reqired Const cLogFile = "c:\temp\InvalidIP.txt" Const cWorkFile = "c:\temp\InvalidIP.wrk" Const MaxInvalidLogins = 10 Const cIgnoreIP = "192.168.20.1" ' to prevent you from lockout yourself Const sTo = "admin@mycompany.com" ' Your email address or comment out if not needed Const sSubject = "Server Info: IP address locked!" '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Constants for opening files '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Const OpenFileForReading = 1 Const OpenFileForWriting = 2 Const OpenFileForAppending = 8 ' Usefull global variables Dim SFTPServer dim IpCol dim LockedIpCol dim objSites ' Sites collection on the server dim objSite ' Current processed site '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' The main program - delegating nearly all actions to sub routines '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Create global objects for the server and the address collection Set SFTPServer = WScript.CreateObject("SFTPCOMInterface.CIServer") set IpCol = CreateObject("Scripting.Dictionary") set LockedIpCol = CreateObject("Scripting.Dictionary") ' Process the log file ProcessLogFile ' If the log file is empty, the collection IpCol is empty, too. So nothing is to do. ' Otherwise process all entries in IPpCol and lock IPs if neccesary if IpCol.Count = 0 then print "No IPs found" else print IpCol.Count & " different IPs found!" SFTPServer.Connect cServer, cPort, cUserName, cPassword GetServerSite (cServerSite) ' First get a collection of already locked IP addresses GetLockedIPs LockAllIPs ' At least, print out the complete list of locked IP addresses. ShowIPs SFTPServer.Close end if ' Clean up set objSite = nothing set objSites = nothing Set SFTPServer = nothing set IpCol = nothing set LockedIpCol = nothing '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' All subroutines and functions '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Point to the correct server site ' Abort the script when not found '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' sub GetServerSite (sServerSite) dim i set objSites = SFTPServer.Sites for i = 0 to objSites.Count - 1 set objSite = objSites.item(i) if objSite.Name = sServerSite then exit for end if next if objSite.Name <> sServerSite then Err.Raise 65535, "", "Site " & sServerSite & " not on this server!" end if wscript.echo "Server site " & objSite.Name end sub '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Lock all IP addresses in directory object IpCol with more than ' MaxInvalidLogins login tries '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Sub LockAllIPs dim sIP dim nCount dim arrIPs dim i dim sMessage arrIPs = IpCol.Keys for i = lbound (arrIPs) to ubound (arrIPs) sIP = arrIPs (i) nCount = IpCol.Item (sIP) 'Print "Processing IP address " & sIP & " with count " & nCount if Clng (nCount) >= MaxInvalidLogins then if sIP = cIgnoreIP then sMessage = "Warning: Internal gateway IP address " & sIP & " has " & nCount & " invalid logins!" Print vbTab & sMessage SendMail sTo, sSubject, sMessage else if AlreadyLocked (sIp) then sMessage = "Warning: Already locked IP address " & sIP & " has " & nCount & " invalid logins." Print vbTab & sMessage SendMail sTo, sSubject, sMessage else sMessage = "Lock IP address " & sIP & " after " & nCount & " invalid logins." Print vbTab & sMessage AddIPs (sIP) SendMail sTo, sSubject, sMessage end if end if end if next end sub '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Read the log file and collect for each IP address the number of ' invalid login attempts. IP addresses and login counts are stored ' in the directory object 'IpCol' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Sub ProcessLogFile dim FSO dim sLine dim fd dim sIP dim sName dim nCount Set FSO = CreateObject("Scripting.FileSystemObject") ' Check if logfile exists and exit if not if not (FSO.FileExists (cLogFile)) then Print "Log file " & cLogFile & " does not exist" & vbCRLF set FSO = nothing exit sub end if Print "Log file " & cLogFile & " exists, process it now." & vbCRLF ' Move the current log file to a work file FSO.MoveFile cLogFile, cWorkFile ' Loop through the work file and count invalid logins for each IP address set fd = FSO.OpenTextFile (cWorkFile, OpenFileForReading) do while not (fd.AtEndOfStream) sLine = fd.ReadLine() sLine = FormatLine (sLine) sIp = GetIpOfLine (sLine) sName = GetNameOfLine (sLine) Print sIp & vbTab & sName with IpCol if .Exists (sIP) then nCount = .Item (sIp) nCount = nCount + 1 .Item (sIp) = nCount else .Add sIP, "1" end if end with loop fd.close FSO.DeleteFile cWorkFile ' FSO.MoveFile cWorkFile, cLogFile set fd = nothing set FSO = nothing end sub '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Extract the IP address from the current line ' Parameters: ' sLine: Current log file line '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' function GetIpOfLine (sLine) dim a dim s a = Split (sLine, vbTab) if ubound (a) = 5 then GetIpOfLine = a(2) else GetIpOfLine = "" end if end function '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Extract the login name from the current line ' Parameters: ' sLine: Current log file line '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' function GetNameOfLine (sLine) dim a dim s a = Split (sLine, vbTab) if ubound (a) = 5 then GetNameOfLine = a(1) else GetNameOfLine = "" end if end function '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Format the current line for easier handling ' Parameters: ' sLine: Current log file line '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' function FormatLine (sLine) dim s dim sQuote dim sSep sQuote = chr(34) sSep = sQuote & " " & sQuote s = Replace (sLine, sSep, vbTab) FormatLine = Replace (s, sQuote, "") end function '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Check if IP address is already locked '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' function AlreadyLocked (sIp) AlreadyLocked = LockedIpCol.Exists (sIp) end function '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Print the current locked IP addresses onto the screen '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Sub ShowIPs() dim arIPs dim s Print "Server : " & cServer Print "Site : " & cServerSite Print "Site IPAccessAllowedDefault : " & objSite.IPAccessAllowedDefault Print "IPs denied :" arIPs = objSite.GetDeniedMasks() For Each s In arIPs Print vbTab & "IP : " & s Next set arIPs = nothing Print "" end sub '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Get the current locked IPs and add them into directory ' object LockedIpCol '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Sub GetLockedIPs() dim arIPs dim s arIPs = objSite.GetDeniedMasks() For Each s In arIPs LockedIpCol.Add s, "0" Next set arIPs = nothing end sub '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Add an IP address to the denied addresses ' Parameters: ' sIP: IP address to be locked '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' sub AddIPs (sIP) ' Add an IP denied Print "Add " & sIP & " to denied IPs" & vbCRLF objSite.AddIPAccessRule sIP, false call SFTPServer.ApplyChanges() end sub '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Send a notification mail using the command line tool "blat" ' Parameters: ' sTo: The mail recipient ' sSubject: The mail subject ' sBody: The message body. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' sub SendMail (sTo, sSubject, sBody) Dim WshShell Dim oExec Dim sCmd ' Build the blat command line. The subject should be surrounded by quotes . sCmd = "blat.exe - -t " & sTo sCmd = sCmd & " -s " & chr(34) & sSubject & chr(34) Set WshShell = CreateObject("WScript.Shell") Set oExec = WshShell.Exec(sCmd) ' The message body is passed through stdin with oExec.StdIn .WriteLine sBody .WriteLine chr(26) end with ' Wait until blat has finished Do While oExec.Status <> 1 WScript.Sleep 100 Loop set oExec = nothing set WshShell = nothing end sub '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Print a line onto the screen. ' This is only a wrapper for WScript.Echo ' Parameters: ' sLine: Text to be printed '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Sub Print(sLine) WScript.Echo sLine End Sub