![]() |
General Programming »
Cryptography & Security »
Security
Beginner
How to Programmatically add IP Addresses to IIS's Deny Access List using C# and WMIBy Scott BurgettAn article that shows the basic steps to programmatically adding an IP address to the IIS deny access list. |
C#.NET 1.1, Win2K, WinXP, Visual Studio, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
Over the course of a few days, I've been spending a lot of time trying to secure my personal web server. I have used the IISLockDown tool and installed the latest URLScan. Since that time, I've been looking through my IIS logs and have found entries where people have been attempting to get into my system, either intentionally or because they've fallen victim to a "worm" or virus. It's annoying to see so many entries in my logs of where attacks have occurred.
So, one day as I was browsing other sites similar to CodeProject, I came across a snippet of code someone wrote to automatically report abuse to the ISP that owns the IP address of where the attack originated from. So, after modifying the code quite a bit to fit my needs, I got it up and running. Of course, the next thing I wanted to do was to ban these reported IP addresses from my site, hence this article.
Before I go any further, let me state that there are a few downsides with the approach I'm taking here to add additional "security" to my personal web server:
With that said, it was still an interesting exercise.
In order to gain access to the IIS server for my project, you have to use Windows Management Instrumentation (WMI) and Active Directory Service Interfaces (ADSI). For a general overview of these two items, refer to the MSDN website.
Since I've never worked with WMI, the first thing I did was look for examples. I found a few, but what I found were in VBScript. I'm not sure why, other than administrators wanting to write a few quick scripts to get something done or maybe it has something to do with the fact that you have to use late binding. I've had to work with objects that were late bound in ATL, and it was not fun. VB/VBScript makes it quite easy to do (which may be why I saw so many examples in VB). Anyway, I've never really had to do anything with late binding in C#, so it took me a few minutes to get acquainted with it. For those of you not familiar with early vs late binding, check here for an explanation:
Parameter passing and method execution are lots of fun if you're not used to it if late binding is involved.
using System;
using System.IO;
using System.Collections;
using System.DirectoryServices;
using System.Reflection;
namespace soccerwrek
{
class IISWMI
{
[STAThread]
static void Main(string[] args)
{
try
{
// retrieve the directory entry for the root of the IIS server
System.DirectoryServices.DirectoryEntry IIS =
new System.DirectoryServices.DirectoryEntry(
"IIS://localhost/w3svc/1/root");
// retrieve the list of currently denied IPs
Console.WriteLine(
"Retrieving the list of currently denied IPs.");
// get the IPSecurity property
Type typ = IIS.Properties["IPSecurity"][0].GetType();
object IPSecurity = IIS.Properties["IPSecurity"][0];
// retrieve the IPDeny list from the IPSecurity object
Array origIPDenyList = (Array) typ.InvokeMember("IPDeny",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.GetProperty,
null, IPSecurity, null);
// display what was being denied
foreach(string s in origIPDenyList)
Console.WriteLine("Before: " + s);
// check GrantByDefault. This has to be set to true,
// or what we are doing will not work.
bool bGrantByDefault = (bool) typ.InvokeMember("GrantByDefault",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.GetProperty,
null, IPSecurity, null);
Console.WriteLine("GrantByDefault = " + bGrantByDefault);
if(!bGrantByDefault)
{
typ.InvokeMember("GrantByDefault",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.SetProperty,
null, IPSecurity, new object[] {true});
}
// update the list of denied IPs. This is a
// complete replace. If you want to maintain what
// was already being denied, you need to make sure
// those IPs are in here as well. This area
// will be where you will most likely modify to
// your needs as this is just an example.
Console.WriteLine("Updating the list of denied IPs.");
object[] newIPDenyList = new object[4];
newIPDenyList[0] = "192.168.1.1, 255.255.255.255";
newIPDenyList[1] = "192.168.1.2, 255.255.255.255";
newIPDenyList[2] = "192.168.1.3, 255.255.255.255";
newIPDenyList[3] = "192.168.1.4, 255.255.255.255";
Console.WriteLine("Calling SetProperty");
// add the updated list back to the IPSecurity object
typ.InvokeMember("IPDeny",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.SetProperty,
null, IPSecurity, new object[] {newIPDenyList});
IIS.Properties["IPSecurity"][0] = IPSecurity;
Console.WriteLine("Commiting the changes.");
// commit the changes
IIS.CommitChanges();
IIS.RefreshCache();
// check to see if the update took
Console.WriteLine("Checking to see if the update took.");
IPSecurity = IIS.Properties["IPSecurity"][0];
Array y = (Array) typ.InvokeMember("IPDeny",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.GetProperty,
null, IPSecurity, null);
foreach(string s in y)
Console.WriteLine("After: " + s);
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.ToString());
}
}
}
}
As you can see it's not terribly difficult or complicated. The hardest part of this exercise is just looking up what you need to know and putting it all together.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 31 Jul 2003 Editor: Nishant Sivakumar |
Copyright 2003 by Scott Burgett Everything else Copyright © CodeProject, 1999-2009 Web20 | Advertise on the Code Project |