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 SubOnce 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.



July 6th, 2006 - 14:01
Really useful !!!
Thanks
Vittorio
July 6th, 2006 - 17:07
Hey Vittorio,
Make sure you don’t put this script into the GPO startup. Since it’s a monitoring script that doesn’t end until you kill the process, the machine hangs at “Running startup scripts…” Not too sure what the default time-out is for GPO scripts but it was too long for me. I’m going to update the blog to let others know.
July 11th, 2006 - 18:31
Thanks for this.
Your code helped me write my own script which I now use to curb dictionary attacks.
July 23rd, 2006 - 15:49
Hey Chrissy,
This snippet rocks. Thank you again for sharing.
I would like to ask you about an ASP solution that is similar in concept…adding an IP to a specific site where the IIsIPSecuritySetting DenyByDefault is used instead of GrantByDefault. I have a IIS Web Site that is configured to use an Admin account in which NTLM auth is disabled, and an ASP login form where the user/pass is validated against a SQL record (MySQL5) — no NTLM involved period. If the user is validated, I would like the ASP script to add the IP addy dynamicaly to a couple of other web sites hosted on the same server. My WSH/WMI skills are pretty weak to say the least and was hoping maybe if you have time one day you could maybe point me in the right direction….oh hell, who am I kidding…I need code girl, plain and simple, lol. I am not beyond begging, so let me know if there is anything that maybe I could do for you. The only part I have no clue on is the WSH/WMI interaction with IIS to accomplish this specific task.
Shouts from the Mississippi Delta!
July 24th, 2006 - 16:19
Looks like an excellent script–thank you for posting it!
I’d like to get this running on my Windows 2000 server. I’m not familiar with Group Policy objects or startup scripts (other than reading the Windows 2000 help, which isn’t too helpful). Can you suggest how to install the script on a Windows 2000 server so that the script runs asynchronously and doesn’t hang the system on reboot?
Thanks again,
Jeri
July 27th, 2006 - 14:21
You are a lifesaver. After logging upwards of 10K attempts at administrator logins from ~12 different IP’s we needed something to combat the inherent stupidity of being locked out of logging into the server as administrator because some other clown(s) was banging away illictly at that server!
Two questions, one dumb & the other hopefully not so:
>how do I tell that it’s actually working?
>how can I add this BANIPFTP functionality to a couple other usual suspects (“admin”, “guest”)? Duplicate the section of code starting with ‘Sub EVSINK_OnObjectReady(objObject…’ and sub the desired name? Of couse it’s not a big deal because these logins don’t exist and/or are securely disabled, but would still like to ban the uninvited.
Many thanks,
Steve
July 27th, 2006 - 14:39
p.s. I asked the dumb “how do I know…” question because after a dry spell of no attempts there was a recent dictionary attempt by someone and the first few hundred logins attempted was with “administrator” (then ‘admin’, ‘guest’, etc.) – I was suprised that this attempt was able to continue after first trying with ‘administrator’
July 27th, 2006 - 18:16
Hey Jeri,
You can add it to the startup registry. http://blog.netnerds.net/code/startup.txt lists how to do it though I don’t know if Win2k supports “reg add” if not, just add it using regedit.
July 27th, 2006 - 18:18
Hey Rick,
That’s completely doable. I’ll think about it and get back to you.
Chrissy
July 27th, 2006 - 18:41
Hey Steven,
first, to add other users, just add to the following line
If InStr(LCase(objObject.TargetInstance.Message),”administrator”) > 0 Then
So in your case, that line would say
If InStr(LCase(objObject.TargetInstance.Message),”admin”) > 0 or InStr(LCase(objObject.TargetInstance.Message),”guest”) > 0 Then
Also, make a similar change on the objLog.URIStem line…
Since the “instr” doesn’t look for exact matches, “admin” would work for both admin and administrator.
To see if its running, go to Task Manager and order by name. Look for Wscript.exe ..if you see that running, it may be this script.
To see if it’s working, go to IIS -> FTP -> Properties -> Directory Security.
For the record, on ONE of my machines.. there was a delay in IIS enforcing the policy. It took about 4 hours and then hasn’t had a problem since. Weird!
EDIT: I took a snapshot of the wrong location. It should be 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.
August 6th, 2006 - 18:32
Hey Chrissy, I am experiencing an anomaly I have been unable to solve with the startup method of your script on a server I manage remotely…it works fine on my VMWare instance that I initialy tested the script on, but I logon to it local.
I used the “reg add” method you posted, double-checked the paths and NTFS perms, but on the remote server the script does not appear to be running until I login via RDP, and then terminates when I logoff of the remote server…at least it appears to be so…I mean, I tried to login to FTP as Administrator and it never banned my IP addy and I waited for a day as I see in your comment above that sometimes it might take a while for it to appear under Directory Security.
The remote server is not part of a domain (workgroup only), and is running 2003SE+all current patches.
Penny for your thoughts?
Thanks,
Rick
August 8th, 2006 - 11:32
Ok Chrissy, I can be a little scatter brained sometimes…I was lloking at the Default FTP Site properties instead of the FTP Sites Master Properties…there I found the Denied IP addys I have been testing with.
Thanks again for this wonderful script!
Best Regards,
Rick
August 14th, 2006 - 02:28
Hello Chrissy,
I had tried the script, but I had encounter some problem after run the seript. So I don’t have any idea what is the error.
It show :
Script: c:\baniisadm.vbs
Line: 28
Char: 5
Error: Access denied
Code: 80041003
Source: SWbemServices
Thanks in advance,
MK
August 14th, 2006 - 02:30
Sorry, I had missing some information, I had test it in the Server2000 /wSP4 and under a Domain (Server2003 Std)
August 21st, 2006 - 06:22
Hello.
I copied the sctript to notepad as saved as vbs then ran it on server 2003 sp1 and i get a error.
(96,1) Microsoft VBScript compilaiton error: Exspected ‘End’
Any Ideas?
August 21st, 2006 - 06:43
Added…At the end of the script I needed to add ‘End Sub’ on a new last line, line 96. All works GREAT now and initialized as soon as I ran it with a CMD window. As you guessed, this script can manually be run with a command promt minimized (suggested for testing to minimize the restart times). Now the big test will be if these idiot attackers have thier bots set to realize their IP’s are blocked and the attacks stops there.
August 23rd, 2006 - 09:23
Chrisy: I got hit hard the other day and none of the offending addresses were banned.
I made some additions to the words to check similar to what you showed Stevan above, but nothing was checked.
Here’s what I changed;
If InStr(LCase(objObject.TargetInstance.Message),”admin”) > 0 or InStr(LCase(objObject.TargetInstance.Message),”user”) > 0 or InStr(LCase(objObject.TargetInstance.Message),”tomy”) > 0 or InStr(LCase(objObject.TargetInstance.Message),”guest”) > 0 or InStr(LCase(objObject.TargetInstance.Message),”Www”) > 0 Then
Does that look ok?
August 23rd, 2006 - 09:27
Is there anyway to have a whitelist of acceptable userames and everything else gets banned?
August 28th, 2006 - 13:06
Something else I was thinking about that could (I think) use part of this code; add those same IPs to the www service ban list, and, perhaps even more importantly, the SMTP Virtual Server Connection Control Deny list(s).
Or just add it to the Global Settings Message Delivery Connection Filtering Deny list…
Whatcha think?
September 21st, 2006 - 06:25
Cool script – thanks. It’s added an internal ip to the ban list after logging in from the lan (to test) but I can still connect to the ftp server and get a login prompt which I wasn’t sure should happen.
I’m going to try a bit more debugging to see whats going on.
September 22nd, 2006 - 07:56
I am getting the same access enied error, any thoughts on why?
September 24th, 2006 - 07:40
Hi Chrissy.
This script is just what I need – thx! Having a problem with it, tho. It seems to be runing (I see the script process), but it doesn’t ban my test IP- even after waiting the “four hours” you observed.
Few questions: what format does the log file need to be in? Mine is set for daily using W3C Extended. Also, does it matter if I have added a few ‘deny’ IP’s manualy?
I’m running Windows Small Business Server2003 Standard.
Thank for any help…
September 26th, 2006 - 22:30
Hello Chrissy,
Thanks for sharing with us your very nice script.
I’m just wondering if the script is to handle multiple login accounts, e.g. admin and guest, shouldn’t this line be changed too?
If LCase(objLog.URIStem) = “administrator” Then
Btw, if the script can be modified to block IP only if that particular IP has entered the wrong password for, say 6 times withing 10 minutes, that will be awesome.
Cheers,
Phi
September 27th, 2006 - 14:47
Whoa, lots of responses! Sorry I haven’t been on the ball, guys.. I’ve been slammed at work and schoool.
Right off the top of my head..not sure what the access denied error is about. As for the lag in enforcing the IP ban, someone said rebooting IIS fixed their prob. That’s not a solution, of course..but it may mean I’m missing one finalizing line from my code. I’ll check around it when I can. That was the mysterious “four hours” i spoke of..I probably restarted the service at some point.
And Phi, you are totally right. I’ll update my comment to reflect that. Thanks!
October 4th, 2006 - 08:15
Very nice script Chrissy, thank you for posting this. Just installed on win2k3 SE SP I with much sucess. Kudos is also due to those who listed the multi username catch mods.
Quick question… is there an easy way to supress the cscript.exe window from loading? Everytime I RDS into the server a blank cscript window pops up.
Thanks Again,
John Andrews
October 6th, 2006 - 10:06
If LCase(objLog.URIStem) = “administrator” Then
Can someone please post the modified version of this line to include multiple login names? I made a few attempts and can’t seem to NOT screw it up.
October 7th, 2006 - 16:40
Access denied error (80041003): I got this error on a Windows XP machine. The problem was that the Win32_NTLogEvent class needed the wbemPrivilegeSecurity (SeSecurityPrivilege) privilege to be enabled. Change the moniker string:
Set objWMIService = GetObject(“winmgmts:{(security)}!root/cimv2″)
Unfortunately, Chrissy’s script doesn’t work on Windows XP. It contains IIS 5.1, which doesn’t support denying IP addresses (as far, as I know).
October 11th, 2006 - 09:56
G … That worked perfectly.
Now I get the same behaviour as others have reported which is that the newly banned ips do not take effect immidiately. I verified that they are on the list and when I restart the FTP service they take affect .
I just added a script to restart the FTP service every night which seems to work.
October 13th, 2006 - 06:35
Well this would be great but my FTP runs on a Win 2K Server. Im not sure this works on 2K.
I cant seem to see the process running, and IPs dont seem to be being banned even after the restart of the service.
Shame.
Jim
October 15th, 2006 - 23:45
Mike, here’s my modified version to include multiple login names:
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
Does anyone know how to use a script to auto restart the FTP service when there is no active connection?
October 19th, 2006 - 05:06
objDictionary.Add ClientIP, “255.255.255.255″ ’255 is just there for padding.
This line dosnt add the IP to the blocked list… anyone have any idea what can cause this? I am running this on an w2k3 EE SP1 Server with lots of s/w installed.
The variable ClientIP contains the correct IP.
Thanks,
Tomas Krug
Stockholm, Sweden
October 26th, 2006 - 14:48
They Thomas,
You are right, that line doesnt add the IP to the blocked list. It just adds it to the dictionary when then adds the IP to the blocked list.
objFTPIPSec.IPDeny = objDictionary.Keys is the line that actually does the work.
October 26th, 2006 - 14:49
Phi,
I swear I’ll find the way to add those IPs for good w/o restarting.. I just havent had a chance to look. Worst case, I’ll ask the Scripting Guys.
October 27th, 2006 - 03:36
I love the ftp anti-hack script…but let’s take this to the next level. The script currently doesn’t stop them from hammering and generating huge logs, or from trying to hack anything else on the server. How would you modify the script to ban them from even connecting to the server in the first place? I am guessing that the script would need to be changed to add the offending IP address to the denied list in the Routing & Remote Access?
Thanks for the great script.
October 28th, 2006 - 17:58
Great script! Running it as a service using srvany.exe utility so I don’t have to leave the server logged in. The IP’s aren’t banned unless I restart my FTP server so I put this at the end of the script.
strComputer = “.”
Set objWMIService = GetObject _
(“winmgmts:{authenticationLevel=pktPrivacy}\\” _
& strComputer & “\root\microsoftiisv2″)
Set colItems = objWMIService.ExecQuery _
(“Select * From IIsFtpServer Where Name LIKE ” & _
“‘%MSFTPSVC/%’”)
For Each objItem in colItems
objItem.Stop
objItem.Start
Next
October 30th, 2006 - 21:37
Thanks Chrissy. I admire your persistence and will be looking forward to your solution.
Meanwhile, have fun!
November 16th, 2006 - 06:17
Clayten, where exactly in th script did you add your “restarting” code?
November 16th, 2006 - 12:39
Hey everyone! I used this idea plus a lot of modification to create a windows service which does this and a little more. Let me know what you think!
http://www.insight-onsite.us/ftpsecurity
November 17th, 2006 - 13:34
sam,
Add it between the:
End If
Set objFTPIPSec = Nothing
Set objDictionary = Nothing
in Chrissy’s code.
November 18th, 2006 - 14:36
Wouldn’t your stop and start code eject any users that were currently connected to the FTP service?
November 19th, 2006 - 10:11
Thx Clayten. That works, but there seems to be a delay in the time it takes the service to restart, sometimes 1-2 minutes. Of course in that time, the newly-detected IP is not banned, and dozens more attempts are allowed.
Any idea what may cause the delay??
November 19th, 2006 - 13:52
Anyone get this working with windows 2000?
Andie
November 21st, 2006 - 13:39
sam,
I happens to me as well. Attackers normally get about a dozen or two tries before they are locked out.
If I had to take a guess, that 1 or 2 minutes is the time it takes for the Event to get logged to trigger the script (if you do a lot auditing it has to wait in line), processing your entire log file for the day (which could be big), then restarting the ftp servers.
If Chrissy can find out how to ban IPs instantly that will solve the delay.
November 21st, 2006 - 13:59
Ahhh! You know.. Clayten .. I think I may have just figured out a solution.
First, you got me thinking.. IIS Log files take a little bit to write from memory to disk…perhaps that is where the delay comes in? But I wonder if the MSWC.IISLog object can read “unwritten” data.
If it does, what I can do is combine Spencer Rupert’s script with mine to temporarily create a bad route to the offending IP address which will stay in effect (I’m guessing until the next reboot) at least until the FTP server catches up.
I tried newsgroups for a way to solve that delay but received 0 responses. Perhaps I should get around to writing to David Wang. Till then, I’ll rewrite the script and add that in then email you guys with the new script.
November 21st, 2006 - 15:55
Hey Guys,
Okay, the script has been retooled and it now stops attackers before they can even login a second time.
The modifications I made was to figure out the server’s IP address (so that Spencer’s fakeGateway variable wouldnt have to be manually set) then use that to add a route to the IP routing table that instantly kills off the attacker’s packets. While Spencer’s script writes all the IPs to a batch file for permanent banning, I decided to just take my chances and do a “temporary” ban. How temporary? Depends on how often you reboot. So if you go for a year without rebooting, then the bad route will last for a year.
So for the record MSWC.IISLog reads data that is still unwritten to disk. This script now works so quickly, that again, I couldn’t even get a second login attempt in when testing.
When implementing the new script at work, I also randomly ran into the access denied error that another commenter encountered. Thankfully “G” solved that by suggesting that the the WMI object string change slightly. That worked wonderfully and I’ve modified the original script to reflect the change.
I didn’t add the IIS restarter script that Clayten so graciously posted because I didn’t want to chance kicking off legit users. Hopefully the IP level ban will take care of that time delay.
Now to figure out the slickest way to get this going each time the computer boots up. The run key works but my coworkers who login to the console always see a black box. Not cool.
November 22nd, 2006 - 16:42
Chrissy,
I figured you’d find a better way and render my restart part moot.
Thanks again for the script! Note: Running the script as a service eliminates the black box.
November 27th, 2006 - 07:31
Chrissy,
Thanks so much for posting this script. We have been getting pounded by login attempts and this has really helped.
Your excellent solution is greatly appreciated.
Thanks again, Mike
December 5th, 2006 - 10:46
I am a total nube to this so excuse my nube issue but I get Microsoft VBScript runtime error: Object required: ‘WshShell’
when running the script. The machine is running server 2003 SE. Can anyone shed some light here
December 7th, 2006 - 07:24
This looks like a kickin script to get running… been looking for a solution like this … does anyone have the source for the new script crissy was talking about I would like to take a look.. also has anyone tried to script in some variables so that you could possibly set a attempt limit instead off banning them if they get it wrong the first time … typos can really suck in that case and sometimes half asleep at the keyboard it does happen
December 8th, 2006 - 06:55
OK ignore my question. It works, I was broken. Chrissy YOU ARE MY PERSONAL HERO!!!!!
I cannot express in words how unbelievably awesome this script is. YOU ROCK!
December 14th, 2006 - 12:13
Takes a lot to impress me.. I’m impressed..
December 19th, 2006 - 10:11
Thanks for this script! I was getting hit everyday with so many unauthorized login attempts that it was avg. 4 attempts every SECOND!!! Not anymore!! Saweeeeeeeeeeeeeeeeet!
December 28th, 2006 - 12:16
One problem I had with this script is that if you don’t have a folder called “MSFTPSVC1″ in “%WinDir%\System32\LogFiles” you will receive the Object required: ‘WshShell’ error that Gaelan received just above. If you create a dummy folder with that name the script will run without error.
If I had to guess, I would say this is because the script assumes that the log file location hasn’t changed for the Default FTP site. If it has, it errors out before even getting to the second FTP site. (But I’m no scripting expert.)
If anyone is wondering; If you are testing this script and it does lock your IP address out, you can simply run “route delete ” in a command prompt and you will be allowed again for further testing.
December 28th, 2006 - 12:19
To add to my previous post, you have to type “route delete xxx.xxx.xxx.xxx”
Also, if your running a Windows 2000 server and the command-line tool “reg” isn’t available, you can copy and past the following into a text file, rename it to a .reg extension, and run the file:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run]
“banftpip”=”C:\\WINDOWS\\system32\\wscript.exe C:\\WINNT\\SYSVOL\\sysvol\\biomedix.local\\scripts\\banftpips.vbs”
December 28th, 2006 - 12:21
Sorry, I forgot to tell you to rename the path in the last part of that .reg file.
January 2nd, 2007 - 18:37
Thanks Jim.
Clayten, I’m getting a delay on my Windows 2000 machine.. I was all confused thinking the delay was at the IIS end. It is indeed on the Event service end. I don’t really think there’s a way to get around that other than “tailing” the log file forever and that seems to be way more overhead. Perhaps Vista and Longhorn will have some better solutions!
January 3rd, 2007 - 21:00
I installed the above script on 21/12/06 so I assume this is the latest evolution. (script “retooled” 21/11/06)….unless the above is not the “retooled” version of the script.
If it is….
I have it working fine in winK2 and between 21/12/06 and 02/01/07 it banned some 15 IP’s. The problem remains, however, that the attacks can last up 20+ minutes and all of the “premier attack period” is still reflected in the log …some times as many as 2 per second. The attacker may only get one shot but the “shot” is still lasting quite awhile.
If the above isn’t the “retooled” version of the script and the new version really stops the attacker from a second log on (not just a second attack) where can a copy be obtained? mucho thanx
January 4th, 2007 - 22:12
Hey Rogue, I tested it on Windows 2003 and the ban is instant but that doesn’t seem to be the case on the Windows 2000 machine I tested on. Not sure at this point how to speed things up.
January 9th, 2007 - 09:19
hi
i just tried this script and when i attempt a logon with adminstrator from another computer. my server pops out an error about the vbs script
Line: 57
Char: 11
Error: Path not found
Code: 800A004C
Source: Microsoft VBScript runtime error
im pretty nub on scripting any help would be great
thx
January 9th, 2007 - 11:00
Hey Nitz,
You changed the default path for the FTP logs.. line 57 is this
ftpLogFilePath = WshShell.ExpandEnvironmentStrings(objSITE.LogFileDirectory) & “\msftpsvc” & objSITE.Name
just change that to whatever the path of your FTP logs are.. ie
ftpLogFilePath = “D:\Logfiles\FTPSite”
January 9th, 2007 - 16:20
Btw. this script WILL ban IPs on XP. As it turns out, IP banning works in XP programatically — just not in the GUI. Awes!
January 10th, 2007 - 20:34
thank you so much Chrissy that worked =)
January 15th, 2007 - 10:14
Chrissy, first of all great work on this very handy script. thank you. I am wondering if you can figure out why normal ‘user’ users logging in over terminal services get this error pop up:
C:/scripts/startup/banftips.vbs
line 27
char 5
Access denied
source swbemservicesex
& how to correct it? Thank you!
January 19th, 2007 - 12:56
Has anyone tested the script with a FTP site that logs to a SQL DB? We currently log the site to a DB for better reporting. It gets huge from the attacks but that is how the powers that be want to log. This is the perfect script to help me but will it still work with a DB?
February 3rd, 2007 - 02:37
Thanks for this great script Chrissy! It works like a charm. I’ve got it running on WinXP-SP2 IIS 5.1…flawlessly. It blocks IPs as if the door is slammed! I’ve been looking for a tool like this for ages. Thanks again!
February 12th, 2007 - 19:09
Why not just rename the default administrative account “Administrator” to another name??
February 12th, 2007 - 19:21
Louay, for a number of reasons. No administrator account should have a password easy enough for any of this bots to crack. Thus, I’m not concerned about a cracked password. I’m concerned about intense resource usage by thousands of attempted logins per minute as well as the Event Viewer getting so filled up.
February 13th, 2007 - 16:15
Thanks for the code!
I am having some problems with it though. I adapted it to ban any IP that used any unknown username (I have a security group that has valid usernames). It works for the first ban, then doesn’t catch events from the even log anymore until I restart it the script.
I have been running the script as a scheduled task to run at system startup, but the behavior is exhibited if I run it directly from the shell or from the task scheduler.
Has anyone seen this behavior?
February 14th, 2007 - 14:16
I guess my post above this one is a bit off. Eventually, the event’s get processed but there is quite a large delay in when they get processed.
Has anyone seen this?
February 14th, 2007 - 22:21
Awesome, thank you so much, this works perfectly right out of the … uhh… “box”. It stopped 2 attackers within 5 seconds of being launched.
February 21st, 2007 - 21:14
Nice script!
I too am having the speed issue… Im running on Windows 2000. It eventually does catch the offending IP address, but not before the attacker has been allowed hundreds or thousands of administrator login attempts. Has anyone resolved the speed issue on W2K?
February 26th, 2007 - 05:21
I forgot to mention, I am running Windows 2003 Standard SP1.
Still have the delay. Sometimes it’s as short as 5 seconds, sometimes it’s 5 minutes. It has something to do with the timing of that event being generated that triggers the meat of the script.
I wonder how we can control that?
March 5th, 2007 - 20:52
Thanks a TON for this. I’ve been routinely going through our logs and manually banning IP addresses as they show up. As someone mentioned above, I’ve combined this script with srvany.exe. Just make sure you use CScript.exe to execute it, otherwise you’ll get an error when you try to start the service.
Thanks again, this works great. I actually saw one of the bots get banned as I was messing around with it.
March 5th, 2007 - 21:20
(This is the Bob Marley guy above
)
I posted an article on your script on my own blog, mainly how to turn it in to a service (I send them here to get the script and read about it):
http://blogs.mscorlib.com/Home/tabid/111/EntryID/42/Default.aspx
This is a step-by-step instruction guide on how to make it run as a service. Thanks again!
March 11th, 2007 - 19:30
First , thanks Chrissy for the usefull script.
we work with plesk and we have multiple ftp sites also log directories.like ;
I’ve a questiom
..\7438\logs\MSFTPSVC7438\
..\7435\logs\MSFTPSVC7435\
How can i set or is it possible to set multiple log directories ?
thanks again…
March 14th, 2007 - 13:29
The event is fired from NON-root FTP site. The result is that it gets the directory for the logs from the wrong site Id.
March 14th, 2007 - 19:54
Uh oh…
I got this successfully working on my IIS 5.0 Windows 2000 Professional Box (Sp4). It blocks IPs wonderfully, but I can’t seem to remove them. Unfortunately, even after a reboot I cannot remove entries from the denied list. I’ve manually tried removing it from the routing table at the command prompt with:
route delete
It has removed it from the table, but even then it still appears under directory security tab as denied. Unfortunately, in 2000 Professional the Directory Security table is all grayed out, so I cannot click on the entry and select remove! I’m stock with an IP I don’t want to block.
Like an idiot, I tested this out with my home box and now can’t get into my FTP site.
Any suggestions?
March 15th, 2007 - 21:27
no you can use
route -f
this is the incorrect method to do this.
http://www.codeproject.com/csharp/iiswmi.asp
it is the correct method. I am sorry but i would rather have it added to IIS where it is easy to manage, rather than using routing. It would have been nice to use IPSec instead for this peice of code. but i created it to go to the MSFTPSVC node in the metabase it works well.
March 15th, 2007 - 22:08
afterburn, thanks for the pointer about it firing from a non-root site. When I get a chance, I’ll adjust the script to handle situations with multiple FTP sites or sites with non-standard ftp logging directories.
As for the routing, if you don’t want it, you can remove it. The script bans at the IIS level in addition to the routing level. Route banning was added to this script because people were experiencing delays with pure IIS banning. And while IPSec would be nice, it’s also a pain to work with. If you’ve got easy code, please feel free to post.
As for Mr. Furious, anyone with win2k workstation or xp pro that experience similar problems can do one of two things
1. Backup the metabase before trying the script, and replace it if necessary (which is what he ended up doing)
2. Use scripting to add/remove ips as can be seen here.
March 16th, 2007 - 12:52
Const c_strDomainControllerName = “DomainServer”
Const c_strServerName = “WebServer”
Dim objDsIpSec
Set objDsIpSec = CreateObject(“ExIpSec.ExIpSecurity”)
objDsIpSec.BindToSmtpVsi c_strServerName , “1″, c_strDomainControllerName
objDsIpSec.GetIpSecurityList
objDsIpSec.GrantByDefault=false
redim Preserve objDsIpSec.IpGrant(UBound(objDsIpSec.IpGrant)+1)
listGrant(UBound(objDsIpSec.IpGrant)) = “1.2.3.4″
objDsIpSec.WriteList
objDsIpSec.ReleaseBinding
set objDsIpSec = Nothing
March 16th, 2007 - 15:56
Hey afterburn,
Thanks for posting the code. I thought you were referring to IPSec at the network level. This looks like IP Security at the IIS level, specifically SMTP. I’m not sure how it relates to banning at the FTP level.. In my script, I used objFTPSVC.IPSecurity to accomplish that.
March 21st, 2007 - 14:56
Thanks for the script however i have some questions
1-is the new script the one that is published at the top of this blog. if not where is it?
2- i have tried to unban an IP with the script the you listed but it is not working.
3-While there is a banned IP , and has been removed form the security directory of the default site, this ip still can not connect and your script does not list this ip before or after the manual removal.
4- What about the specific times of logging instead of the second time.
The script is running on w2k sp4 with IIS 5.0.
Thanks for the great script again…you are doing an awesome job
March 21st, 2007 - 15:09
Hey Rewesh:
1. Yes
2. Not sure why.. but I’ve only tested this on win2k3.
3. It bans the IP both at the IIS level and the network level. To remove from the network level, run cmd then type route DELETE ip.add.res.s
4. Not sure what you mean by that
As for running it in win2k, I don’t think the script works as well under win2k.. the events are slower to register.
April 2nd, 2007 - 17:11
Can someone explain what makes the route added in the code a “Bad Route”?
April 3rd, 2007 - 23:07
Hi Chrissy (and all)….
I’ve installed your script as a service (as detailed above). The network level IP block works GREAT. Instantaneous.
It’s been HOURS now since my tests, and still no sign of any IPs in the FTP blocked IP listing. I’ve looked at the Global level and the Default website level and… nada.
Can you give me a clue what I might do to troubleshoot this?
PS…. you’re hot! Your script is hot! If I can get this working right, you’re my HERO forever!!! And you’re my hero right now just for the part that IS working!!!!!
April 5th, 2007 - 10:08
Chrissy, thank you for the awesome script!
Frijoles, thank you for showing how to add as a service.
I’d never tried vbs before yesterday, very cool stuff.
Thought I might share the script I whipped up for unbanning. It’ll show you the banned IPs and let you unban single IPs, as I haven’t figured out how to make it ‘purge’ the list… yet.
banftpview.vbs
—————–
strComputer = “localhost”
‘Set Objects
Set objFTPSVC = GetObject(“IIS://” & strComputer & “/MSFTPSVC”)
Set WshShell = CreateObject(“WScript.Shell”)
Set objIPRestrict = objFTPSVC.IPSecurity
arrDeny = objFTPSVC.Get(“IPSecurity”).IPDeny
For i = 0 to Ubound(arrDeny)
strBannedIPs = strBannedIPs & arrDeny(i) & vbCrlf
Next
If len(strBannedIPs) > 0 Then
strUnbanIP = InputBox(“IP, Subnet: ” & vbCrLF & strBannedIPs ,”Banned FTP IP List”,”Enter IP To Unban”)
arrIPAddresses = objIPRestrict.IPDeny
For i = 0 to ubound(arrIPAddresses)
strClientIP = Left(arrIPAddresses(i),InStr(arrIPAddresses(i),”,”)-1)
If strClientIP strUnbanIP Then
If Len(strStillBanned) = 0 Then
strStillBanned = strClientIP
Else
strStillBanned = strStillBanned & “,” & strClientIP
End If
End If
Next
WshShell.Run “ROUTE DELETE ” & strUnbanIP
arrStillBannedIPs = split(strStillBanned,”,”)
objIPRestrict.IPDeny = arrStillBannedIPs
objFTPSVC.IPSecurity = objIPRestrict
objFTPSVC.SetInfo
Else
msgbox “No IPs have been banned.”,,”Banned FTP IP List”
End if
‘Kill Objects
Set objIPRestrict = Nothing
Set WshShell = Nothing
Set objFTPSVC = Nothing
April 5th, 2007 - 10:28
Hey Crimson,
You’re totally welcome! I remember the first time I made a .vbs file and ran it, I was freakin pumped. I knew ASP but never understood how to run VBScript on a workstation as opposed to an IIS Server.
Thanks a ton for pasting your code too. Very useful!
http://blog.netnerds.net/2007/01/vbscript-windows-xpiis-51-does-support-denying-access-by-ip-addresses/
That has a purge script that may help you.
April 5th, 2007 - 11:20
Tim,
You’re hot too!
I really don’t know why it works instantly sometimes, within X minutes other times, then X hours other times. Thats one of the reasons I added the ban at the network level.
Yeah… I’ll update the blog if I ever find out
April 5th, 2007 - 12:12
Tim,
I have a feeling that you’re looking in the wrong spot for the bans.
Don’t look at the Default FTP Site-Properties-Directory Security, instead look in the FTP Sites “Folder”-Properties-Directory Security for your banned IPs.
My .vbs script (above) will unban single test IPs from FTP Directory Security and the Route List, giving instant access again.
April 6th, 2007 - 08:43
Crimson… Nope: I don’t think I’m looking in the wrong spot. I’ve checked the top level FTP Sites FOLDER properties-Directory Security tab too. No banned IPs ever show up.
Chrissy: It’s been DAYS, and no IPs have shown up. I can only assume there is something wrong with my install. I’ve done ftp tests numerous times from several different machines. I DO get banned instantaneously. But I never get ANY IPs in the banned IP list.
Any ideas what else it might be?
April 6th, 2007 - 08:51
Ok….. Let’s see.
1. Make sure there’s no on error resume next in there so that if an error comes up, you’ll be notified
2. Run this script and see if anything shows up
strComputer = “localhost”
‘Set Objects
Set objWebSite = GetObject(“IIS://” & strComputer & “/MSFTPSVC”)
Set objIPRestrict = objWebSite.IPSecurity
arrDeny = objWebSite.Get(“IPSecurity”).IPDeny
For i = 0 to Ubound(arrDeny)
strBannedIPs = strBannedIPs & arrDeny(i) & vbCrlf
Next
If len(strBannedIPs) > 0 Then
msgbox “IP, Subnet: ” & vbCrLF & strBannedIPs
Else
msgbox “No IPs have been banned.”
End if
‘Kill Objects
Set objIPRestrict = Nothing
Set objWebSite = Nothing
3. If that doesn’t work.. I have no idea
April 6th, 2007 - 19:59
Thanks Chrissy…
Your script showed NO banned IPs. But there WERE banned IPs for the network because I couldn’t connect from two test machines at all until rebooting.
Interestingly… I started taking apart your original script and found that if I remove the network ban code, then the FTP banned IPs show up just fine. But, if I add in the network ban code, the FTP banned IPs do NOT show up. So, there must be something going wrong right there… at least for my machine.
Anyway… The FTP banned IP list works instantly for me, so I’ve removed the network ban. This gives me the ability to “manage” the list better than for the network bans.
Finally… I’ve added a couple of lines to auto-delete ftp logs older than X days.
So.. for now, for what I need, it’s all working like a charm. I’m eternally in your debt. Feel free to call on me anytime for anything.
Warm regards…
Tim
April 6th, 2007 - 20:05
Hey Tim,
That’s really interesting. Can you do me a favor and add the network banning back /after/ the IIS ban? Let me know if that works?
Hopefully this will all be easier with IIS 7…
April 7th, 2007 - 18:56
Hi again Chrissy…
Putting the network ban AFTER the FTP ban works for me.
But I did something else at the same time, so I’m not certain which change did the trick….
I noticed that in the first few lines of the EVSINK sub, you create all the objects, one of which is the line…
Set WshShell = WScript.CreateObject(“WScript.Shell”)
You use this object to get the FTP log file path.
Later you recreate the same WshShell for the network IP ban.
Could the re-creation of the object perhaps be the problem. You don’t destroy the previous WshShell object anywhere in your code before this.
I removed the 2nd WshShell creation code, and also moved the Set WshShell line to the bottom of the code where you destroy all the other objects.
And now… it all seems to be working in harmony!
Tim
PS… can you possibly give me some guidance for how I would add this IP to existing IPSec settings?
I’ve added a list of banned IPs to the IPSec “Security Settings on Local Computer” under a folder I created called “FireWall”. I would MUCH rather add the Banned IPs to this list rather than do the network ban to the route table.
Any suggestions?
April 10th, 2007 - 07:33
Can someone explain what makes the route added in the code a “Bad Route”?
On my server, the script adds the banned IP, but doesn’t stop the network connection.
Any ideas?
April 11th, 2007 - 10:46
I added the following code to email me when an FTP attack occurs. Put it right after the ” WshShell.Run “ROUTE ADD ” & clientIP & ” MASK 255.255.255.255 ” & serverIP, 1, True” statement.
‘ —— SCRIPT CONFIGURATION ——
strFrom = “xxx@xxx.edu”
strTo = “xxx@xxx.edu;yyy@xxx.edu”
strSub = “FTP Attack on FILESERV”
strBody = “FTP attack on Fileserv by IP ” & clientIP
strSMTP = “10.9.9.9″
‘ —— END CONFIGURATION ———
set objEmail = CreateObject(“CDO.Message”)
objEmail.From = strFrom
objEmail.To = strTo
objEmail.Subject = strSub
objEmail.Textbody = strBody
objEmail.Configuration.Fields.Item(“http://schemas.microsoft.com/cdo/configuration/sendusing”) = 2
objEmail.Configuration.Fields.Item(“http://schemas.microsoft.com/cdo/configuration/smtpserver”) = strSMTP
objEmail.Configuration.Fields.Update
objEmail.Send
April 14th, 2007 - 05:36
I have been using the script for a few weeks now and can finally breathe a sigh of relief as I feel that I am back in control of my equipment.
Now when I receive an e-mail that I am under attack, I just smile….
I thank Chrissy and the other supporters here for that.
Since the script helped me so much, I feel like I should give something back.
I made a few changes to the script to suit my situation that I would like to share with the group.
I will call it 2 enhancements and 1 bug fix.
1. Added email report when attacker is blocked
2. Made routing changes persistent across reboots
3. Moved dictionary code out of subroutine so it would be persistent
First; I am running on Windows 2000 and I not only do I have the “cached” IIS log file delay that others have mentioned in this blog.
Apparently Windows 2003 flushes the IIS logs much quicker than W2k although I have not tested this myself.
The script is designed to initially stop attacks at the IP route level and permanently ban the offender by adding the IP to the IIS FTP “Denied” list.
I was not interested in banning at the IIS level.
My testing with Windows 2000 Server (I did not make the same tests with Windows 2003.) revealed that although the offender’s IP was added to the blocked list, the offender was still able to make login attempts against the FTP server. When the correct password was “finally” used, the server denied the user access, but with a different error message than the user received when they guessed with the wrong password.
For that reason, the IIS ban was of no value to me, but the bad IP route seemed like the solution for me.
Note: Although I kept the IIS ban code in place it never added any IPs to the list as others have also confirmed.
1. Added email report when attacker is blocked
I wanted to be notified when an attacker was blocked so I added some email code after the following line:
objDictionary.Add ClientIP, “255.255.255.255″ ’255 is just there for padding.
To my surprise, I started getting “tons” of duplicate emails when I expected to get only one per ban.
My friend helped me diagnose the fact that the dictionary gets initialized every time the subrouting got called.
I believe this is unintentional and is a bug. (forgive me if I am wrong)
See item 3 below for fix.
2. Made routing changes persistent across reboots
I waned to make the bad routes survive reboots so I modified the ROUTE ADD line to:
WshShell.Run “ROUTE -p ADD ” & clientIP & ” MASK 255.255.255.255 ” & serverIP & ” METRIC 10″, 1, True
I added the METRIC 10 so I could spot the changes to the routing table easier when I did a “route print”
The persistent routes are printed below the table as well, sorted in the order they were banned.
3. Moved dictionary code out of subroutine so it would be persistent
After adding the email code, I noticed that I received an email for every new Event 100 in the Event log even though it was the same IP in the FTP logs.
This means that the dictionary was unaware the current IP address was in fact the same as the previous 20 that
So if there were 30 new Event 100 entries from the same IP, I would get 30 emails (plus any previous offenses from the same day)
I moved the line:
Set objDictionary = CreateObject(“Scripting.Dictionary”)
From inside the subroutine to the “’ Push Event Viewer Alert” section of code at the top. Anywhere above the “While (True)” line should be fine.
Thanks so much for your help…
April 16th, 2007 - 06:50
Bob – Thanks for the heads-up on the email bug. Because the “bad route” step doesn’t seem to work for me, I was greeted by 30,000 emails this morning!
April 17th, 2007 - 12:02
Chrissy,
You are awesome!! Thank you so much for script. It worked like a charm.
April 18th, 2007 - 18:40
Stellar! Trying it out now.
May 6th, 2007 - 09:48
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
May 24th, 2007 - 10:21
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
May 28th, 2007 - 04:14
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!
May 28th, 2007 - 04:21
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
June 1st, 2007 - 05:13
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.
June 28th, 2007 - 00:55
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
June 28th, 2007 - 01:02
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
August 1st, 2007 - 10:58
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]
August 19th, 2007 - 19:32
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?
September 2nd, 2007 - 05:53
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!
September 13th, 2007 - 13:08
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
September 17th, 2007 - 16:15
Great script! You are my hero of the day
September 22nd, 2007 - 13:40
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.)
September 25th, 2007 - 11:05
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.
September 26th, 2007 - 21:41
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
October 26th, 2007 - 10:15
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.
December 21st, 2010 - 14:46
I would definitely pay 3-5 bucks for something that would solve this problem once and for all!
November 1st, 2007 - 04:11
How could I not post anything?
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.
November 9th, 2007 - 04:48
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!
November 13th, 2007 - 09:30
Those wanting Crissy to run for President of the US say I!
November 15th, 2007 - 15:02
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
November 19th, 2007 - 09:10
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.
January 14th, 2008 - 13:33
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
January 15th, 2008 - 13:05
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
January 15th, 2008 - 14:07
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
January 18th, 2008 - 08:51
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
January 18th, 2008 - 17:10
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!
February 26th, 2008 - 09:03
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.
February 28th, 2008 - 14:47
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.
July 24th, 2008 - 01:12
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.
August 8th, 2008 - 13:04
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!
August 8th, 2008 - 15:06
Oh, I gave the gang from Redmond too much credit, the fix is from Kansas!
August 26th, 2008 - 23:27
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.
August 26th, 2008 - 23:28
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.
September 15th, 2008 - 11:53
Hello,
Has anyone successfully deployed this script on Server 2008?
Thanks
Rob
September 30th, 2008 - 15:17
Just another extremely grateful person – thanks very much for this Chrissie (and everyone else who took the time to add their suggestions)
October 27th, 2008 - 17:56
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?
December 19th, 2008 - 11:36
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
March 4th, 2009 - 10:57
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”.
May 20th, 2009 - 08:08
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
November 13th, 2009 - 04:24
Very nice script.
But one problem I have:
Code: 8004106C
Quelle: SWbemServicesEx
Error: Quota violation
can you help with this Prob…?
Thanks,
Andy
December 18th, 2009 - 05:25
Thanks for so much help!!!
The Problem still exist…
December 18th, 2009 - 05:35
I start the service with user network and this stop the messges… hope that will help
January 4th, 2010 - 08:30
The script doesn’t seem to work with Windows Server 2008. Has anyone got it running on Windows 2008?
January 16th, 2010 - 04:19
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
January 20th, 2010 - 12:10
Is there a way to list the address’ that have been placed in the BAN ..?? and then an UNBAN method..??
March 24th, 2010 - 06:25
It seems the scripts worked for you.
On my windows 2003 server is not running, it gives me the error I am getting error on line 150, saying path not found.
any help please !!!
149. ftpLogFilePath = wshell.ExpandEnvironmentStrings(objSITE.LogFileDirectory) & “\msftpsvc” & objSITE.Name
150. Set objFolder = objFSO.GetFolder(ftpLogFilePath)
151. Set objFiles = objFolder.Files
March 20th, 2010 - 12:26
@Isprin: This script adds the ban directly into your IIS settings. Just go to IIS administrator to manage the IP bans.
May 17th, 2010 - 23:59
Thank you very much for this execellent script. It runs without modifications om my Windows Server 2003.
But, and this is essential, on Windows Server 2008, the NotificationQuery must be chnaged to contain TargetInstance.SourceName=’Microsoft-Windows-IIS-FTP’ instead of TargetInstance.SourceName=’MSFTPSVC’
July 9th, 2010 - 13:14
(Attempting to run it on Server 2008) – I changed TargetInstance.SourceName=’MSFTPSVC’ to TargetInstance.SourceName=’Microsoft-Windows-IIS-FTP’ and I receive an error on line 41 ActiveX Component can’t create object: ‘MSWC.IISLog
Any ideas?
October 17th, 2010 - 15:02
Some notes on how to make it work nicely on Win2K IIS5…
Copy the script into c:ScriptsStartup folder.
Then check FTP logging is enabled on both the master FTP properties and the FTP server. In logfiles system32logfiles there should be two folders Logfiles (usually empty) and MSFTPSVC1 containing FTP logs. Do not name the log directories in IIS properties, the server will automatically create them. Leave it as %windir%system32logfiles for both. This is important so the script can find the logfiles.
Then go to regedit and find the key for LM software microsoft current version run and make a new string value – call it banftpip and add the path to run wscript or cscript .exe and then the path to the vbs file scriptsstartupbanftpips.vbs.
This is an example : c:winntsystem32wscript.exe C:scriptsstartupbanftpips.vbs You may have to change winnt to windows on some servers. Also if the script is the old version change wscript to cscript or change the instances in the script to wscript from cscript. Then reboot the server and the script will execute on startup. To verify it is running use taskmanager and wscript or cscript should then show as a process.
Because the script only bans Administrator logins, check logfiles for the first username in an attempt and make a second script replacing Administrator (in two places) with the new user name and call this script banftpips1 and make a new registry key of the same name banftpips1 to also start that script. Common hacks use admin, abby, test, administrador and so on, make a script and registry entry for each one. Reboot and now each script will catch each new name and ban it – once the first attempt is stopped the hacker cannot then try additional names as his ip will not connect.
April 21st, 2011 - 11:24
Hi
Great script Crissy. The 'like so' link to setup instructions are broken – just wanted to let you know.
August 28th, 2011 - 01:05
Hi to Everyone.
I'm very sorry to go against all these nice comments but I personally think this script is *no good* for one simple reason: you must restart FTP service to make the BAN effective… (well, that's what happens on my two W2K3 boxes). Although the banned IP are listed in the "Directory Security" of IIS and are also propagated in all the sublevels… you are forced to restart FTP.
And that means that my log gets filled with millions (yes,millions) of Failed Login events…
Now, on a production machine with 100 users there's no way I can restart the service after every ban.
I could restart the service during the night… but this way the BAN simply doesn't work!!! And I get my LOG FULL OF Events 529 & Co.; I can get something like 1,2 million in a day.
My solution is another one: the BAN must happen on another level, adding it to and IPSEC policy via a BATCH program and not to IIS. The VBS scans the log and if an IP is found it can execute a BATCH which does something like this:
netsh ipsec static add filter filterlist=BlockIP srcaddr=me dstaddr=%1
Where %1 is the parameter the VBS passes to the BATCH.
What you need is an IPSEC policy active (yes, talking about standalone servers, no AD) where both the Policy has "BlockIP" name.
And that works in real time, no restarts and no delay… only the time for IIS to flush the log buffer.
Bye, and thanks for the script, it's good a part from the fact it's not suitable for me!
Bye,
Julian
August 29th, 2011 - 16:20
Julian,
That's somewhat what is happening at this line: WshShell.Run "ROUTE ADD " & clientIP & " MASK 255.255.255.255 " & serverIP, 1, True
That takes effect immediately (until reboot) and the FTP ban keeps it permanent.