nerds:~ #

2Jul/06145

IIS: Instantly Ban IPs Attempting to Login to MS-FTP as Administrator

UPDATE 12/18/06: The startup script has been modified slightly (cscript.exe was changed to wscript.exe). Now, console users will no longer encounter a blank black box upon login.
UPDATE 11/21/06: Now that banning at the IP level has been added to the script, offending users are completely banned before they can even attempt a second login on Windows 2003 machines. Windows 2000 machines still have a slight delay.
UPDATE 1/18/07: I updated the code so that it does not throw out an "unknown" error on line 48 for Win2k users. Thanks to the commenters for figuring that out. Also, check the comments for some really great script modification and ideas posted by blog visitors. Thanks to everyone who has posted!

Recently while reviewing my Windows Events, I noticed over 2800 failed login attempts to my Microsoft FTP server. Apparently, a bot was trying to brute force the Administrator password. Thankfully, I soon determined that there were only two IPs I needed to ban. The FTP server needs to be accessed by my employer's clients so I couldn't just change the port (as I did when I found 30,000+ SSH login attempts to my Linux box). Thus, I decided to instantly ban any IPs attempting to login as Administrator. I did this using a VBScript file (saved as: C:\Scripts\Startup\banftpips.vbs) that is set to execute upon boot-up. This can be done like so.

'****************************************************************************
' This script created by Chrissy LeMaire (clemaire@gmail.com)
' Website: http://netnerds.net/
'
' NO WARRANTIES, etc.
'
' This script instantly bans IP addresses trying to login to FTP
' using the NT account "Administrator"
'
' Run this script on the FTP server. It sits in the back and waits for an
' event viewer "push" that lets it know someone failed FTP authentication.
'
' This script has only been tested on Windows Server 2003. It assumes, as it
' should, that there are no legitimate Administrator account FTP logins.
'
' "What it does"
' 1. Sets an Async Event Sink to notify the script when someone fails MS-FTP auth
' 2. When alerted, the script parses the last day's FTP logs for all FTP sites (this
'    is because the Event Viewer doesn't tell you which FTP site, if you have more than
'    one, is the one getting hit)
' 3. Compiles the list of IPs to be banned and then bans them using IIS /and/
'    IP level banning (thanks Spencer @ netortech.com for the idea)
'*****************************************************************************

' Push Event Viewer Alert
    Set objWMIService = GetObject("winmgmts:{(security)}!root/cimv2")
    Set eventSink = wscript.CreateObject("WbemScripting.SWbemSink", "EVSINK_")
    strWQL = "Select * from __InstanceCreationEvent where TargetInstance isa  'Win32_NTLogEvent' and TargetInstance.SourceName = 'MSFTPSVC' and TargetInstance.EventCode = 100"
    objWMIService.ExecNotificationQueryAsync eventSink,strWQL

' Keep it going forever
While (True)
    Wscript.Sleep(1000)
Wend

Sub EVSINK_OnObjectReady(objObject, objAsyncContext)
If InStr(LCase(objObject.TargetInstance.Message),"administrator") > 0 Then
Set objFTPSVC = GetObject("IIS://localhost/MSFTPSVC")
Set WshShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objLog = CreateObject("MSWC.IISLog")
Set objDictionary = CreateObject("Scripting.Dictionary")
Set objFTPIPSec = objFTPSVC.IPSecurity

'Get IP address of server so we can use it later to give the offending IP a bad route
Set IPConfigSet = GetObject("winmgmts:\\.\root\cimv2").ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled=TRUE")
for each IPConfig in IPConfigSet
  if Not IsNull(IPConfig.DefaultIPGateway) then serverIP =  IPConfig.IPAddress(0)
Next
Set IPConfigSet = Nothing

'Iterate through each FTP site. See #2 up above.
For Each objSITE in objFTPSVC
If lcase(objSITE.class) = "iisftpserver" Then
ftpLogFilePath =  WshShell.ExpandEnvironmentStrings(objSITE.LogFileDirectory) & "\msftpsvc" & objSITE.Name

Set objFolder = objFSO.GetFolder(ftpLogFilePath)
Set objFiles = objFolder.Files
For Each fileName In objFiles
lastFile = fileName
Next
strLogFile = lastFile
Set file = Nothing
Set objFolder = Nothing

'Use the IIS log file parser provided by MSFT
objLog.OpenLogFile strLogFile, 1, "MSFTPSVC", 1, 0
'(FileName,IOMode,ServiceName,ServiceInstance,OutputLogFileFormat)
' 0 = NotApplicable, 1 = ForReading
While NOT objLog.AtEndOfLog
objLog.ReadLogRecord
If LCase(objLog.URIStem) = "administrator" Then
ClientIP = objLog.ClientIP
If objDictionary.Exists(ClientIP) = False Then
   'Kill the route to the machine then add it to the array of banned IPs.
   Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "ROUTE ADD " & clientIP & " MASK 255.255.255.255 " & serverIP, 1, True
Set WshShell = Nothing
objDictionary.Add ClientIP, "255.255.255.255" '255 is just there for padding.
End If
End If
Wend
objLog.CloseLogFiles 1
End If
Next

'Append the newly banned IPs to the currently banned IPs
If objDictionary.Count > 0 And objFTPIPSec.GrantByDefault = True Then
bannedIPArray = objFTPIPSec.IPDeny
For i = 0 to ubound(bannedIPArray)
clientIP = Left(bannedIPArray(i),InStr(bannedIPArray(i),",")-1)
If objDictionary.Exists(ClientIP) = False Then
objDictionary.Add bannedIPArray(i), "255.255.255.255"
End If
Next

objFTPIPSec.IPDeny = objDictionary.Keys
objFTPSVC.IPSecurity = objFTPIPSec
objFTPSVC.SetInfo
End If

Set objFTPIPSec = Nothing
Set objDictionary = Nothing
Set objLog = Nothing
Set objFSO = Nothing
Set objFTPSVC = Nothing
End If
End Sub

Once the IP has been added to the ban list, the user will no longer be able to connect to the machine via TCP/IP as it has been given a bad route. If the server reboots, it will lose the route but the IP will still be banned in IIS. The offending user will then see the following message:

Connected to ftpserver
530 Connection refused, unknown IP address.
421 Service not available, closing control connection.
Connection closed by remote host.

Note that this bans the IPs on a global FTP level. You will find the banned IPs listed under Windows 2003 @ IIS -> FTP -> Properties and under Windows 2000 @ IIS -> Hostname -> Properties -> FTP Service -> Edit -> Directory Security. This means you will not find it on the properties of the Default FTP Site. This pro-actively bans the IPs from hitting other FTP sites in an IIS setup with multiple FTP sites. In addition, with the new ban at the IP level, the machine can't even contact your server until your Windows server has been rebooted and the manual routes have thus been reset.

Posted by: Chrissy   Filed under: IIS, Security, VBScript Leave a comment
Comments (145) Trackbacks (2)
  1. I just installed this and it’s not banning (2003 sp2). I’m getting the Object required: ‘WshShell’ error. I saw that someone suggested creating a MSFTPSVC1 directory to fix the error, but I already have that directory. Are there any permissions I might be missing?

    Tim’s solution looked interesting, but I didn’t quite understand what his final file looked like – Tim, if you’re there – can you post?

    Thanks,
    Michelle

  2. Chrissy,

    The script is great but I have run into a problem where not all of my FTP sites follow the msftpsvc naming. I could create a script for each FTP site that is in a sub directory of logfiles but that would be to hard on the system. Will there be an update that will loop through the logfiles directory pulling logs for each subdirectory? Hope this question makes sense.

    Thanks,
    Chewy

  3. Thanks tons for writing this, and thanks tons for answering my emails so helpfully!

    I created a psexec installer package for this that runs with a batch file. Basically that means you can deploy this to lots of remote computers on your network easily with one swoop. Check it out here on my blog: http://blog.integrii.net/?p=18

    Tons of thanks to Chrissy!

  4. I’ve posted my current solution on our website (I can’t seem to get this site to accept my code without cutting it short).

    See it at http://www.vizimetrics.com (Ban FTP Logins).

    Tim

  5. Sorry – I’m trying to understand this code and … why, exactly, does the code to add the client’s ip to the routing table (as the destination) with the server’s ip as the gateway result in the client being unable to connect to the server via TCP?
    I thought you could use the routing table to block access TO a destination, not FROM a client. And, is the serverIP supposed to be an unused address in the local network, or my actual server IP (which wouldn’t seem to work).
    Thanks a million, and thanks for posting this code in the first place.

  6. Strange this is one of the few websites I could find on the internet that addresses this problem at all and Ive done all kinds of searches.

    Thanks to the ideas on this site, I got the idea to block the ips on our cisco firewall.

    if anyone is interested in persueing this method, I downloaded sock.dll from
    http://tech.dimac.net/FreeDownloads/dlstart.asp?ProductID=2

    and another file, winsck.ocx from here
    http://www.gurgensvbstuff.com/index.php?ID=27

    so I could vbscript a telnet session.

    Instead of creating an event alert, I used a scheduled tasked to check the last log every couple of minutes. The alert does stop the hacker faster though.

    I used a 2nd script to clear the blocked ips once a day since our hackers seem to use a different ip everyday. The nice thing about blocking at the firewall is it completely stlops the IP from doing anything, including FTP. Cisco firewalls have a shun command that does this, and I would think most other firewalls have a similar command.

    The full script is below.

    Const NotApplicable = 0
    Const ForReading = 1
    Const ForWriting = 2
    Const ForAppending = 8
    Const AllOpenFiles = 32

    strScriptLogFile = “\\server01\schedule\shunIPs\shunips.log”
    strIPS = “\\server01\schedule\shunIPs\bannedips.txt”
    strFtpLogFilePath = “\\server01\c$\windows\system32\LogFiles\MSFTPSVC392258225″

    ‘Get the last log file
    Set objFSO = CreateObject(“Scripting.FileSystemObject”)
    Set objFolder = objFSO.GetFolder(strFtpLogFilePath)
    Set objFiles = objFolder.Files
    For Each fileName In objFiles
    lastFile = fileName
    Next

    strLogFile = lastFile
    ’strLogFile = “\\server01\schedule\shunips\test.log”
    ‘wscript.echo strLogFile

    Set objFiles = Nothing
    Set objFolder = Nothing

    ‘read in a list of IPs that are already banned so we dont keep banning the same IPs
    set bannedips = objfso.OpenTextFile(strIPs, ForReading, True)

    Set objDictionary = CreateObject(“Scripting.Dictionary”)
    Do While not bannedips.atendofstream
    strIP = bannedips.readline
    if NOT(strIP = “clear”) AND NOT(strIP=”") then
    objDictionary.add strIP, “bannedIP”
    end if
    Loop

    bannedips.close

    ‘re-open the bannedips list so we can possibly add to it.
    set bannedips = objfso.OpenTextFile(strIPs, ForAppending, True)

    ‘open the log file and see if anyone is hacking us, test to see if someone is logging in as administrator, test, or root.
    set scriptLog = objfso.OpenTextFile(strScriptLogFile, ForAppending, True)

    Set objLog = CreateObject(“MSWC.IISLog”)
    ‘Use the IIS log file parser provided by MSFT
    objLog.OpenLogFile strLogFile, ForReading, “MSFTPSVC”, 1, NotApplicable
    ‘(FileName,IOMode,ServiceName,ServiceInstance,OutputLogFileFormat)
    ‘ 0 = NotApplicable, 1 = ForReading

    While NOT objLog.AtEndOfLog
    objLog.ReadLogRecord
    If InStr(LCase(objLog.URIStem),”admin”) > 0 or InStr(LCase(objLog.URIStem),”root”) > 0 or InStr(LCase(objLog.URIStem),”test”) > 0 Then
    ClientIP = objLog.ClientIP
    If objDictionary.Exists(ClientIP) = False and objDictionary.Count ”
    objw3sock.SendLine “enable”
    objw3sock.WaitFor “Password:”
    objw3sock.SendLine “SwitchM3″
    objw3sock.WaitFor “ZERO#”
    objw3sock.SendLine “shun ” & IP
    objw3sock.WaitFor “ZERO#”
    objw3sock.SendLine “exit”
    objw3sock.Close
    set objW3Sock = NOTHING
    wscript.sleep 1000
    end sub

  7. looks like i might have exceeded the line limit, heres how the script is suppose to end

    While NOT objLog.AtEndOfLog
    objLog.ReadLogRecord
    If InStr(LCase(objLog.URIStem),”admin”) > 0 or InStr(LCase(objLog.URIStem),”root”) > 0 or InStr(LCase(objLog.URIStem),”test”) > 0 Then
    ClientIP = objLog.ClientIP
    If objDictionary.Exists(ClientIP) = False and objDictionary.Count ”
    objw3sock.SendLine “enable”
    objw3sock.WaitFor “Password:”
    objw3sock.SendLine “SwitchM3″
    objw3sock.WaitFor “ZERO#”
    objw3sock.SendLine “shun ” & IP
    objw3sock.WaitFor “ZERO#”
    objw3sock.SendLine “exit”
    objw3sock.Close
    set objW3Sock = NOTHING
    wscript.sleep 1000
    end sub

  8. Thanks, Chrissy, for a brilliant script – and to frijoles for the instructions on running it as a service. You guys rock!

    I’ve been playing with a version that defends agains brute-force attacks direct on the server, too (not just via FTP) and thought some of you may be interested.

    The reason I started doing this is that – by the time I found this page – I’d already solved the FTP problem by installing the free (and secure) zFTP Server from http://www.zftpserver.com. This has a feature which can block IPs of reapeat bad logins, so the problem went away.

    However, I was still left with the problem of people trying to hack in directly via RDC; the logs (emailed out via EventSentry) show that my server had been the target of sporadic bursts of rapid-fire password guesses, for example 60 attempts in 4 seconds and, on another occasion, 800 attempts in 18 minutes.

    To try to deter this kind of rapid-fire brute force attack, the script I’ve developed — based heavily on Chrissie’s — detects the IP address from the Windows Event Log and then blocks the offending IP for a user-definable period (defaulting to 10 seconds), after which the block is released.

    The advantage of this is that brute-force attempts would be discouraged, but people sitting being a firewall or public proxy wouldn’t be locked out of a website simply because an offending machine was using the same gateway, they’d just get a delay in seeing the web page (or perhaps have to try again in a little while).

    Thanks again to Chrissie for getting the ball rolling and being (I think) the first (only?) person on the net to tackle this problem!

    Best wishes,

    David

    [script]
    ‘****************************************************************************
    ‘ BanIP.vbs version 0.02

    ‘ Greatly reduces brute-force password cracking attempts

    ‘ Created by David Landy (david@milldata.co.uk)
    ‘ 2 Aug 2007

    ‘ Adapted from the script by Chrissy LeMaire (clemaire@gmail.com)
    http://blog.netnerds.net/2006/07/ban-administrator-ftp-login-attemps
    ‘ IP level banning (thanks Spencer @ netortech.com for the idea)

    ‘ To run this as a service see http://blogs.mscorlib.com/Home/tabid/111/EntryID/42/Default.aspx
    ‘ Thanks, frijoles!

    ‘ NO WARRANTIES, etc.

    ‘ This script instantly bans IP addresses trying to login to windows
    ‘ using the NT account “Administrator”

    ‘ This script has only been tested on Windows Server 2003.

    ‘ “What it does”
    ‘ 1. Sets an Async Event Sink to notify the script when a login fails because of bad username/password,
    ‘ locked-out account, or disabled account
    ‘ 2. When alerted, parses the log entry to get the ip address of the machine attempting to login
    ‘ 3. The offending ip address is banned (blocked) for a user-specified period
    ‘ 3. After the user-specified period has elapsed, unbans the offending ip

    ‘ Event Logs are posted on startup, ban, and unban events

    ‘*****************************************************************************

    option explicit

    const app = “BanIP” ‘App Title
    const unBanDelay = 10 ‘The number of seconds to wait before unbanning an IP. Specifying a negative value will prevent automatic unbanning

    const ForReading = 1, ForWriting = 2, ForAppending = 8
    const elSuccess = 0, elError = 1, elWarning = 2, elInformation = 4, elAuditSuccess = 8, elAuditFailure = 16

    dim objWMIService
    dim eventSink
    dim strSQL

    dim serverIP
    dim IPConfigSet
    dim IPConfig

    dim run
    dim ips

    dim wshell
    Set wshell = WScript.CreateObject(“WScript.Shell”)

    ‘Log startup
    EventLog elSuccess, app & ” Starting”

    ‘Push Event Viewer Alert
    Set objWMIService = GetObject(“winmgmts:{(security)}!root/cimv2″)
    Set eventSink = wscript.CreateObject(“WbemScripting.SWbemSink”, “EVSINK_”)
    strSQL = “Select * from __InstanceCreationEvent ”
    strSQL = strSQL & “where TargetInstance isa ‘Win32_NTLogEvent’ and ”
    strSQL = strSQL & “TargetInstance.SourceName = ‘Security’ and (”
    strSQL = strSQL & “TargetInstance.EventCode = 529 Or ”
    strSQL = strSQL & “TargetInstance.EventCode = 531 Or ”
    strSQL = strSQL & “TargetInstance.EventCode = 539)”
    objWMIService.ExecNotificationQueryAsync eventSink, strSQL

    ‘Get IP address of server so we can use it later to give the offending IP a bad route
    Set IPConfigSet = GetObject(“winmgmts:\\.\root\cimv2″).ExecQuery(“SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled=TRUE”)
    for each IPConfig in IPConfigSet
    if Not IsNull(IPConfig.DefaultIPGateway) then serverIP = IPConfig.IPAddress(0)
    Next
    Set IPConfigSet = Nothing

    ‘Initialise banned IP array
    ips = array()

    ‘Keep it going forever
    do While true
    UnBanIPs
    WScript.Sleep(1000)
    loop

    Sub EVSINK_OnObjectReady(objObject, objAsyncContext)
    dim msg
    dim msgout
    dim tag
    dim clientIP
    dim userName
    dim eventID
    dim eventType

    msg = objObject.TargetInstance.Message
    msgout = “”

    tag = “Source Network Address:”
    clientIP = GetField(msg, tag)
    msgout = msgout & “clientIP =’” & clientIP & “‘” & vbCrLf

    tag = “User Name:”
    userName = GetField(msg, tag)
    msgout = msgout & “userName =’” & userName & “‘” & vbCrLf

    tag = “Event ID:”
    eventID = objObject.TargetInstance.EventCode
    msgout = msgout & “eventID =’” & eventID & “‘” & vbCrLf

    tag = “Type:”
    eventType = objObject.TargetInstance.Type
    msgout = msgout & “Type =’” & eventType & “‘” & vbCrLf

    ‘msgbox msgout, vbOKOnly, app

    select case eventID
    case 529, 531, 539 ‘unknown username or pwd, disabled account, or locked-out account
    ‘Could test here for LCase(userName) = “administrator” but this script
    ‘locks out all failed logins for a short period, just to be safe

    ‘Log the event
    EventLog elWarning, “Banning ” & clientIP & ” – User Name: ” & userName & “, Event: ” & eventID

    ‘Ban the IP
    Shell “ROUTE ADD ” & clientIP & ” ” & serverIP ‘No need to specify MASK as 255.255.255.255 is the default

    ‘Add the IP to the array so it can be unbanned later
    aadd ips, array(clientIP, Now())

    End select
    End Sub

    Sub UnBanIPs()
    if unBanDelay = unBanDelay then
    ‘Log the event
    EventLog elWarning, “Unbanning ” & ips(i)(0)

    ‘Restore the route and delete it from the array of banned IPs
    Shell “ROUTE DELETE ” & ips(i)(0)
    adel ips, i
    else
    i = i + 1
    end if
    loop
    End Sub

    Function GetField(s, tag)
    Dim i
    Dim j
    i = InStr(s, tag)
    If i > 0 Then
    i = i + Len(tag)
    j = InStr(i, s, vbCrLf)
    GetField = MyTrim(Mid(s, i, j – i))
    else
    GetField = “Not Found”
    end if
    End Function

    Function MyTrim(s)
    dim t
    t = Trim(s)
    if t > “” then
    do while left(t, 1) = chr(9)
    t = mid(t, 2)
    loop
    end if
    MyTrim = t
    End Function

    Function aadd(a, s)
    redim preserve a(ubound(a)+1)
    a(ubound(a)) = s
    End Function

    Function adel(a, i)
    dim j
    for j = i to ubound(a) – 1
    a(j) = a(j + 1)
    next
    redim preserve a(ubound(a) – 1)
    End Function

    Function afind(a, s)
    dim i
    for i = 0 to ubound(a)
    if not isarray(a(i)) then
    if a(i) = s then
    afind = i
    exit function
    end if
    end if
    next
    afind = -1
    End Function

    Function afind2(a, s, j)
    dim i
    for i = 0 to ubound(a)
    if isarray(a(i)) then
    if a(i)(j) = s then
    afind2 = i
    exit function
    end if
    end if
    next
    afind2 = -1
    End Function

    Function Shell(s)
    shell = wshell.Run(s, 0, false) ‘command, windowstate, waitforreturn
    End Function

    Function EventLog(t, s)
    wshell.LogEvent t, app & “: ” & s
    End Function
    [/script]

  9. Hi, I tried running the script at the top of the page, on Win2003 SE tried invalid admin login via FTP and it blocked me on second attempt – ok – however my IP is completly blocked from the server I cant access websites or RDC – is this correct or should it jsut block FTP – or is there something that I need to change to just block FTP?

  10. Chrissy.. you are a GOD!!!!!

    Installed the script a last week and today it did its job!

    Running Win2k Server and it caught and stopped a Brute Force attack in 10 seconds(8 attempts).

    Thank you for the script!

  11. if we have edited the file to block more than just “Administrator” ala Phi’s modification on October 15th, 2006 at 11:45 pm

    If InStr(LCase(objLog.URIStem),”admin”) > 0 or InStr(LCase(objLog.URIStem),”guest”) > 0 or InStr(LCase(objLog.URIStem),”root”) > 0 or InStr(LCase(objLog.URIStem),”test”) > 0 or InStr(LCase(objLog.URIStem),”user”) > 0 Then

    shouldn’t we also add those same bogus usernames to the section

    ‘Use the IIS log file parser provided by MSFT

    If LCase(objLog.URIStem) = “administrator” Then
    ClientIP = objLog.ClientIP

    ????????????

    like this?

    If LCase(objLog.URIStem) = “admin” or If LCase(objLog.URIStem) = “guest” or If LCase(objLog.URIStem) = “root” or If LCase(objLog.URIStem) = “test” or If LCase(objLog.URIStem) = “user” Then
    ClientIP = objLog.ClientIP

  12. Great script! You are my hero of the day :-)

  13. Hello!
    Thank you for this script, and also thank you David L. for your version as well. I took the two and made a new version. Some things i noticed in them:

    Chrissy’s – Your’s parses through the entire log file at every event. The “route add client mask fakeIP” just reroutes back to the server, which does nothing (or at least thats what happened for me).

    David’s – I liked your setup, but you only banned using the routing table, and not within IIS too.

    I didn’t really write down the problems as I was going, so I am probably forgetting to mention something. =\

    I had to learn vbs as I went, so it took me a little longer than it should have. I am used to C/C++/Java/PHP/etc..

    Here is a link to the code, which I will update, should there be any problems found:
    http://cheshire6.livejournal.com/565.html

    I also added some features. I hope you like it, and thanks again!

    (The first post did not copy the code correctly, so just visit the link provided to view it.)

  14. Thanks Martin! The other script wasn’t working for me on my 2003 server. I’ll give yours a try. I get hit every day from several locations so I should know pretty quickly if it works smoothly and will report back.

  15. Hi,
    thanks for the inspiration!
    Though I tried to use your skript, it does not work the way I like (ban IPs regardless of username).
    So I simply wrote my own.

    It takes use of LogParser and has to be scheduled as task.
    You can find it here:
    http://ascheiwe.blogspot.com/2007/09/brute-force-attacken-auf-microsoft-ftp.html

  16. Well, those scripts will make sure that no matter how many times they try, the brute force robot will never get in, but your server will still respond to every request for hours on end using precious resources and bandwidth. I’ve written a small application in .NET that will stop your server from responding completely. You’ll see a few entries in your logs, but once the app sees the attack those entries will cease from that IP. It works for me, but I would need to add some additional configuration options if I were to distribute it. So, that being said, would anyone here pay 3-5 bucks for something that would solve this problem once and for all? Also let me know if you’d prefer a windows service over a desktop application though I’ll probably write both and give you guys a choice.

    Please reply in this thread or contact me.

    Thanks.

  17. How could I not post anything? :P

    Complete life saver! The script installed as a service works wonderfully and is as close to damn it instant. Very impressed and some great vbs code.

    I see you got hacked and didn’t restore all the posts to your blog. So this one is blank but you can still get the original script from this address:
    http://blog.integrii.net/?p=18

    The zip file contains the original vbs from this site. Really struggled to find a copy of it – so thought I’d share. Really teasing to see the happy comments but not know what they are talking about!

    In response to someone asking about the logging type – yes you need to change it to Microsoft IIS Log File Format to get it to work. I was puzzled for a while but changing that and it all sprung into life.

    Again thanks Chrissy – great work.

  18. I would suggest logging to an sql db and add triggers on the table, looking for insert action. Checking the servicestatus field should get u there.
    Thanks Chrissy 4 a great site and reading!

  19. Those wanting Crissy to run for President of the US say I!

  20. Thanks for this code, found it very usefull.

    For a server running win2k, I found that setting the gateway to the server IP address did not block routing. I had to set it to an unused IP address on the local subnet of the server. Also, on the command line, the metric keyword and value are required, so I added it to the script.

    With Win2k, I am showing the ip address as denied in the Directory Security properties, however, if I clear the bad route, the ip address is still allowed to connect. I guess this is the lag issue that was mentioned regarding win2k. Regardless, the IP route ban accomplishes the necessary goal.

    I believe there is an error in the posted code at the top. For some reason winmgmts:\.\root\cimv2 was causing an error on my box. Adding a second slash seemed to resolve it winmgmts:\\.\root\cimv2 (as per the way it is in David’s script)

    thanks again, very useful

  21. Just a followup. I was incorrect in assuming setting the gateway to the server IP address did not block routing. I was testing from a computer on the local subnet.

  22. Wow, excellent script!

    It seems that this blog/site is still the authority when it comes to searching for blocking failed attempts via FTP. Great Job Chrissy.

    One snag i’ve encountered and would appreciate any guidance.

    It seems that the following code is causing problems for my W2K server box it’s running on: -

    ———
    Set IPConfigSet = GetObject(“winmgmts:\.\root\cimv2″).ExecQuery(“SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled=TRUE”)
    for each IPConfig in IPConfigSet
    if Not IsNull(IPConfig.DefaultIPGateway) then serverIP = IPConfig.IPAddress(0)
    ———

    I understand its purpose but the “Set IPConfigSet = GetObject…..” throws up an “Error: Unspecified Error” and “.ExecQuery” entry returns “Error: Not a Collection”.

    Is it too much to process or am i missing something else here?

    Thanks!

    Pop

  23. Wow, excellent script!

    It seems that this blog/site is still the authority when it comes to searching for blocking failed attempts via FTP. Great Job Chrissy.

    One snag i’ve encountered and would appreciate any guidance.

    It seems that the following code is causing problems for my W2K server box it’s running on: -

    ———
    Set IPConfigSet = GetObject(“winmgmts:\.\root\cimv2″).ExecQuery(“SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled=TRUE”)
    for each IPConfig in IPConfigSet
    if Not IsNull(IPConfig.DefaultIPGateway) then serverIP = IPConfig.IPAddress(0)
    ———

    I understand its purpose but the “Set IPConfigSet = GetObject…..” throws up an “Error: Unspecified Error” and “.ExecQuery” entry returns “Error: Not a Collection”.

    Is it too much to process or am i missing something else here?

    Thanks!

    Pop

  24. Sorry for the double post. Havefun’s problem seemed to be the same error we were experiencing and once i added the extra slash it fixed the scripting error.

    Cheers,

    Pop

  25. When someone try to brute force it I get this error :

    Line : 46
    Char : 5
    Error : Error not specified

    Code : 80004005

    Can you help me out? I’m running it on win2k server

  26. Hey poplou, I think the slash may have fallen off when I migrated the posts. I’ve updated the code, thanks for writing!

    Also to everyone else with questions..sorry, I no longer have time to test but be sure to check out the comments, a lot of smart people have great ideas!

  27. Chrissy,

    Where can I get the latest code for this FTP screener? We too have an FTP site that gets hammered every night and i want to implement an IP ban solution but I didn’t see a clear “Download latest” anywhere on the site here.

    Thanks to all for this great utility. I can’t wait to implement it.

  28. I have this script installed and set to run through the HKLM key as it should be. I’ve added a task scheduler to run the script with my credentials (I have admin access to the machine) at startup but it won’t start until I log in and as soon as I log off, wscript.exe stops running. I am running pslist remotely to the server to confirm that it starts when I am logged in and then stops when I log out. Is there something I am missing? Server 2003 Standard latest and greatest Windows Updates are all installed.

  29. I installed the script on one of our servers which runs multiple sites.
    I had to change line 78 from ‘Set WshShell = Nothing’ to ‘Set WshShell = CreateObject(“WScript.Shell”)’
    This is to prevent it from bailing out with a “Object requiered
    ‘WshShell” on line 55 while looping through the EVSINK sub. Unaltered the
    script will bail out on the 2nd loop.

    Thanks for the script!
    It works as expected after my modification.

  30. Chrissy, Gang, this is all too cool and appreciated. I got it all installed, running and updated for some more names. I seem to get a lot of hits trying to login as ‘test’.

    Let me note that after all of that it seems that this issue has caught the attention of the gang in Redmond. I found that they have developed an IIS add-on to address the same issues.

    http://www.insight-onsite.us/IO/Programs/FTP%20Security.aspx

    Oh well, I needed to brush up on my scripting anyway!

    Keep up the good fight, what you have done is bring attention to an issue the big guys should have taken care of two years ago.

    You are definitely ahead of the curve! :)

  31. Oh, I gave the gang from Redmond too much credit, the fix is from Kansas! :)

  32. c:\users\ziyaul\app data\local\temp\.tt166c.temp.vbs
    line: 4
    char: 1
    error: access denied
    code: 80041003
    source: swbemobjectex

    how to correct it? thank u.

  33. how to correct it?

    c:\users\ziyaul\app data\local\temp\.tt166c.temp.vbs
    line: 4
    char: 1
    error: access denied
    code: 80041003
    source: swbemobjectex

    thank u.

  34. Hello,
    Has anyone successfully deployed this script on Server 2008?

    Thanks

    Rob

  35. Just another extremely grateful person – thanks very much for this Chrissie (and everyone else who took the time to add their suggestions)

  36. I too have the same issue with the script seemingly taking a long time to kick in and am on Windows 2003.

    I’ve just had an automated dictionary attempt on the administrator account. I can see in the event log that there were 71,088 attempts in about 18 minutes. The attack may well have been going on for longer but the event log reached it’s maximum log size so these will have been lost.

    It works fine when I test it by attempting to login from an FTP client though. I wonder if it is the sheer number of attempts that overwhelms it?

  37. Thanks for the code Chrissy :-)

    Over a period of time on 2003 server occasionally the script failed to work, the error being related to WshShell

    To solve it I changed your code from

    ‘Iterate through each FTP site. See #2 up above.
    For Each objSITE in objFTPSVC
    If lcase(objSITE.class) = “iisftpserver” Then
    ftpLogFilePath = WshShell.ExpandEnvironmentStrings(objSITE.LogFileDirectory) & “\msftpsvc” & objSITE.Name

    to

    ‘Iterate through each FTP site. See #2 up above.
    For Each objSITE in objFTPSVC
    If lcase(objSITE.class) = “iisftpserver” Then
    ‘ Phil Nov 2008
    Set WshShell = Nothing
    Set WshShell = WScript.CreateObject(“WScript.Shell”)
    ftpLogFilePath = WshShell.ExpandEnvironmentStrings(objSITE.LogFileDirectory) & “\msftpsvc” & objSITE.Name
    Set WshShell = Nothing
    ‘ End Phil nov 2008

    and since then it has been purfect :-)

    Kindest

    Phil

  38. Nice script, but it has an issue: Everytime a login-request is send, the script takes resources. It even starts running if the IP is already blocked.
    This results to the issue, my CPU is at nearly 100% when someone tries to login as “Administrator”.

  39. Nice script.

    Does anyone know if there is a way to mod the code to allow certain IP addresses? A couple of our web apps end up getting blocked internally when users fail to enter the password correctly. They aren’t even using the admin username but I take it the connection string is calling on it somehow.

    Thanks,

    Patrick

  40. Very nice script.

    But one problem I have:
    Code: 8004106C
    Quelle: SWbemServicesEx
    Error: Quota violation

    can you help with this Prob…?

    Thanks,
    Andy

  41. Thanks for so much help!!!

    The Problem still exist…

  42. I start the service with user network and this stop the messges… hope that will help

  43. The script doesn’t seem to work with Windows Server 2008. Has anyone got it running on Windows 2008?

  44. Dear All
    The scripts looks great

    I am getting error on line 150, saying path not found

    Any idea, Please

    And I am using WK3 server

    149. ftpLogFilePath = wshell.ExpandEnvironmentStrings(objSITE.LogFileDirectory) & “\msftpsvc” & objSITE.Name
    150. Set objFolder = objFSO.GetFolder(ftpLogFilePath)
    151. Set objFiles = objFolder.Files

  45. Is there a way to list the address’ that have been placed in the BAN ..?? and then an UNBAN method..??


Leave a comment