Thursday 8 October 2009

Stop ILoveIM been accessed by IP addresses

Working as an IT Technician in a school always throws up issues and challenges, and one of the biggest i have found of late is students getting arround Web Filters using IP addresses. As a result, i have developed a small DLL that hooks into Internet Explorer and checks the URL before allowing the page to display. If the page is found to be a IP address it simply forwards the address to google.



Below is a step by step guide in developing the DLL.



This tutorial assumes you have a basic knowledge in C#.NET.


You also need to ensure you have a version of Visual Studio 2008, Visual C# Express will do just fine and is available from the Microsoft Website.


Once installed, open VCSE and select create new project



In the new window that has opened, select Class Library and give the app a name, in this case, we will use IPFilter. The DLL created will also be called IPFilter.dll.


In this new project, start by deleting the class1.cs file that was created by the file.


Now create a new folder, and name it 'BHO'. Remember everything is case sensitive..


In BHO folder, create new class called IObjectWithSite.cs.


Open IObjectWithSite.cs and change to the following. Save this file, and close it, we no longer require to edit this file.



IObjectWithSite.cs



using System;
using System.Runtime.InteropServices;

namespace IPFilter.BHO
{
[ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")]
public interface IObjectWithSite
{
[PreserveSig]
int SetSite([MarshalAs(UnmanagedType.IUnknown)] object site);
[PreserveSig]
int GetSite(ref Guid guid, out IntPtr ppvSite);
}

}


In this next section, we will develop the actual work horse behind our DLL.


To start with, we need to reference a couple of DLLs that are not loaded as standard. To do this, right click on the references folder and select 'Add references'. Under the COM tab, locate 'Microsoft HTML Objects' and click ok. Do the same for 'Microsoft Internet Controls'. You should now see these under the References folder using the names SHDocVw and MSHTML


Now in the BHO folder, create a new class called BHO.cs


Open this file and add the following.



BHO.cs

using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using SHDocVw;
using System.Text.RegularExpressions;

namespace IPfilter.BHO
{
[ComVisible(true), Guid("ACBDABCD-1234-5678-9012-ABCDABCDABCD"), ClassInterface(ClassInterfaceType.None)]
public class BHO : IObjectWithSite
{
private SHDocVw.WebBrowser webBrowser;

public void OnDocumentComplete(object pDisp, ref object URL)
{

}

public void OnBeforeNavigate2(object pDisp, ref object URL, ref object Flags, ref object TargetFrameName, ref object PostData, ref object Headers, ref bool Cancel)
{
string AddressUsed = URL.ToString().ToLower();

if (AddressUsed.StartsWith("http://"))
{
AddressUsed = AddressUsed.Remove(0, 7);
}
else if (AddressUsed.StartsWith("https://"))
{
AddressUsed = AddressUsed.Remove(0, 8);
}

AddressUsed = AddressUsed.Split(new char[] { '/' })[0];

string pattern = @"(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})";
string text = AddressUsed;
if (Regex.IsMatch(text, pattern))
{
int Auth = SiteAuthorised(AddressUsed);

if (Auth == 0)
{
System.Windows.Forms.MessageBox.Show("You have used an IP address (" + AddressUsed.ToString() + ")to gain access to a website. This is not authorised by the IT Staff");
this.webBrowser.Navigate("http://www.google.com", ref Flags, ref TargetFrameName, ref PostData, ref Headers);
}
else
{
}
}
}
public int SiteAuthorised(string IPAddress)
{
//You can add your own code here to determine if the user is authorised
//to view the site or not. It must return a number. This number will be
//used to determine the error and outcome from above
return 0;
}

public int SetSite(object site)
{
if (site != null)
{
webBrowser = (SHDocVw.WebBrowser)site;
webBrowser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
webBrowser.BeforeNavigate2 += new DWebBrowserEvents2_BeforeNavigate2EventHandler(this.OnBeforeNavigate2);
}
else
{
webBrowser.DocumentComplete -= new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
webBrowser.BeforeNavigate2 -= new DWebBrowserEvents2_BeforeNavigate2EventHandler(this.OnBeforeNavigate2);
webBrowser = null;
}

return 0;
}

public int GetSite(ref Guid guid, out IntPtr ppvSite)
{
IntPtr punk = Marshal.GetIUnknownForObject(webBrowser);
int hr = Marshal.QueryInterface(punk, ref guid, out ppvSite);

Marshal.Release(punk);

return hr;
}

public static string BHOKEYNAME = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects";

[ComRegisterFunction]
public static void RegisterBHO(Type type)
{
RegistryKey rk = Registry.LocalMachine.OpenSubKey(BHOKEYNAME, true);

if (rk == null)
rk = Registry.LocalMachine.CreateSubKey(BHOKEYNAME);

string guid = type.GUID.ToString("B");
RegistryKey ok = rk.OpenSubKey(guid);

if (ok == null)
ok = rk.CreateSubKey(guid);

ok.SetValue("Alright", 1);
rk.Close();
ok.Close();
}

[ComUnregisterFunction]
public static void UnregisterBHO(Type type)
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BHOKEYNAME, true);
string guid = type.GUID.ToString("B");

if (registryKey != null)
registryKey.DeleteSubKey(guid, false);
}
}
}


Now you are ready to build the DLL and test it


Go to File > Save and save it to a suitable location.


Right click the solution (first child item of treeview) and select build.


At the bottom of the screen, there should be a 'Build Successful', if not, check the errors.


Once built, you will need to register the DLL to work with IE. find the DLL, it will be in the bin/release or bin/debug folder of the location you selected to save to.


copy the contents to C:\Program Files\Internet Explorer\IPfilter\


once you have found it, you will need to run the following command at command prompt



"C:\windows\Microsoft.NET\Framework\v2.0.50727\regasm.exe" /codebase "c:\Program Files\Internet Explorer\IPFilter\IPfilter.dll"

In order to add a new version to here, you will need to uninstall first by running the following line



C:\windows\Microsoft.NET\Framework\v2.0.50727\regasm.exe /unregister "c:\Program Files\Internet Explorer\IPFilter\IPfilter.dll"