Looking over my ftp-server logfiles, I find a lot of brute force attacks, where the same IP-address tries 100s of username/password combinations.

Is there something I can do to make life harder on these brute force attackers? Something like an IP is locked out for x time if it has y failed login-attempts?

Server is Microsoft Windows Server 2008.

3 Answers 3


See this post from the IIS newsgroup for some code to resolve the issue

Also below is Chrissy Lemaire's script

' This script created by Chrissy LeMaire ([email protected])
' Website: http://netnerds.net/
' 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)

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)
    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
            strLogFile = lastFile
            Set file = Nothing
          Set objFolder = Nothing

          'Use the IIS log file parser provided by MSFT
          objLog.OpenLogFile strLogFile, 1, "MSFTPSVC", 1, 0 
            ' 0 = NotApplicable, 1 = ForReading  
            While NOT objLog.AtEndOfLog
              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 " & serverIP, 1, True
                    Set WshShell = Nothing
                    objDictionary.Add ClientIP, "" '255 is just there for padding.
                  End If 
              End If
          objLog.CloseLogFiles 1
        End If

      '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), ""
            End If 

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

    Set objFTPIPSec = Nothing
    Set objDictionary = Nothing
    Set objLog = Nothing
    Set objFSO = Nothing
    Set objFTPSVC = Nothing
  End If
  End Sub
  • 2
    That's almost an upvote because I very nearly wrote a script to do that (and DID write a script to do that with OpenSSH) a couple of years ago. The problems with this script are (a) I don't trust my IIS metabase to the potentially thousands of different IPs that a distributed scanning attack will hit the box with, (b) it appears at first glance that it would create performance problems on really busy FTP servers, and (c) it only handles "Administrator". It's not the fault of the script's author, IMO, because Microsoft provides such poor failure reporting from MSFTPSVC to the event log. Commented Jul 18, 2009 at 9:18
  • well, I up-voted, even though I agree, in part, with Evan's comments. I guess it depends on your situation like, how busy is the box, running the script as Administrator can be mitigated by changing the administrator's account name (we use things like $administrator).
    – Kilo
    Commented Jul 18, 2009 at 14:22
  • It's not perfect for sure, I'm not worried about the metabase. Its not as big a peformance hit as you might think unless you are in the middle of a ddos attack, then you will wish you had a real IDS. Even if you have done the basics like change he admin account you'd probably still be happy banning anyone trying it.
    – Jim B
    Commented Jul 18, 2009 at 14:33

Simply block access to the FTP server to that IP or subnet. Odds are that IP won't ever need legit access to your FTP server.

You can do this in IIS or via your firewall/ACL.

  • 2
    Any publicly available ftp-server will eventually get hammered from all kinds of different ip's, so blocking the ip after will not have much effect.
    – Kjensen
    Commented Jul 18, 2009 at 1:11
  • You can blog the subnets which the IPs are coming from. Unless it's a distributed attack they will always be coming from the same IPs. You can also block the IPs from certain countries which are known for less strict policies (China, Iran, Russia) that you probably don't need to allow access to and block them.
    – mrdenny
    Commented Jul 18, 2009 at 1:37
  • That one attacker will always come from the same IP but just about any server that listens on port 21 will be connected to by automated scanners and brute-force attackers. Commented Jul 18, 2009 at 3:13

You could change the FTP port.

  1. Using Internet Service Manager, set the FTP properties to the desired port.
  2. Apply the changes and stop the service.
  3. Open the file Services (located in the \System32\Drivers\Etc directory.
  4. Find the line ftp 21/tcp, and change it to reflect the new port.
  5. Save the file, then run the file Services.exe located in the \System32 directory.
  6. Restart the FTP service in Internet Service Manager. (from this thread).

...alternatively, you could install CopSSH, point it to a high port and use SFTP.

If you really need FTP on port 21, check out FileZilla. It has a built-in anti-hammering feature.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .