0

I'm looking for a way to block some webpages on a computer. If the user visits, let's say, http://www.google.com/, then an error window will appear (I don't mind if the error is inside the browser or on a separate form). Some antiviruses/web protection softwares do this: please note that I'm interested only in blocking a little and specific number of pages.

I've already searched on the web for this. I found lots of examples, mostly about hosts file. However, nothing on displaying an error page when the user goes into a "forbidden" page.

The code to edit the hosts file is this:

Dim s As String = My.Computer.FileSystem.ReadAllText("C:\Windows\system32\drivers\etc\hosts")
Dim finalFile As String = s & VbCrLf & "127.0.0.1    http://www.example.com/"
My.Computer.FileSystem.WriteAllText(finalFile, "z:\desktop\hosts")
My.Computer.FileSystem.DeleteFile("C:\Windows\system32\drivers\etc\hosts")
My.Computer.FileSystem.CopyFile("z:\desktop\hosts", "C:\Windows\system32\drivers\etc\hosts")

My application has administrator privileges to copy/delete system files.

I'm working with VB.NET WinForms, Visual Studio 2013.

Thanks,

FWhite

PWhite
  • 141
  • 1
  • 12
  • One thing you could try, that is very limited and pretty bad - but pretty much the only way to do it, is to read the title of the internet browser window (In chrome it says the title provided by the webpage) and take actions based on that. http://stackoverflow.com/questions/3131303/how-to-get-the-window-title-of-a-process-using-vb-net – Alex Nov 02 '14 at 19:54
  • 1
    I found something else which might be THE way to solve this - modifying the hosts file you are apparently able to redirect to a certain site. (http://www.trishtech.com/2013/03/redirect-or-block-web-sites-using-hosts-file/) This "site" could probably be local. If you are familiar with web development, then you could code the error page to be shown - if you want it to open a program you can make the webpage redirect to a link that opens the program using something called URI Protocol (http://stackoverflow.com/questions/389204/how-do-i-create-my-own-url-protocol-e-g-so). – Alex Nov 02 '14 at 20:07
  • Tell me if you need help implementing it. – Alex Nov 02 '14 at 20:08
  • Hi Alex! Thanks for your reply. I've looked to that websites. The first tells that I can redirect the browser to another local page. Would it work like that: `C:\myfile.html badsite.com`as HOSTS line model? Thanks again for the help – PWhite Nov 03 '14 at 16:41
  • It seems like I was a bit incorrect, you can redirect just like that - but just not to a file, it has to be a server. You could, however, open a server on the local machine (127.0.0.1) and write: 127.0.0.1 www.example.com in the hosts file. I will try to find other solutions. – Alex Nov 03 '14 at 17:23
  • Another way would be blocking the website in the hosts file (0.0.0.0 www.example.com) and then detecting through code when a browser is on that website (just trying to brainstorm here) - (Chrome C#: http://stackoverflow.com/questions/18897070/getting-the-current-tabs-url-from-google-chrome-using-c-sharp) (Internet Explorer VB.NET: http://stackoverflow.com/questions/11158341/get-current-url-in-ie-using-visual-basic) – Alex Nov 03 '14 at 17:38
  • Hi! I like the second way. I'll try now to produce some code from your suggestions! – PWhite Nov 03 '14 at 17:50
  • @Alex Unfortunately, all the solutions found on the web on getting the URL are not working or too slow. If the user is redirected by the HOSTS file, the program must be quick to detect the page. Should I consider to open a server on the local machine? How? – PWhite Nov 03 '14 at 18:18
  • You can through code initiate a web server running on the local machine, whenever the server gets a request (just like when you go to www.example.com) your program will get the notification and return some data (if you want) that will show as a webpage. I can, If you want to, write a complete anwser for you tomorrow as soon as I get home! (I will try to over simplify and explain all the steps) – Alex Nov 03 '14 at 20:05
  • Hi Alex, thank you so much! That would be great! – PWhite Nov 04 '14 at 11:28
  • Are you fine with having the program detect when the user is entering a blocked site and alerthing the user through the program, or do you want to write to the browser as well? (Like showing a custom webpage) EDIT: I'm going to go with the first one, alerting the program for your ease. – Alex Nov 04 '14 at 15:53
  • Thank you Alex, it's the same for me. Both solutions are suitable. Thanks again for the kind help. -FWhite – PWhite Nov 04 '14 at 16:06

1 Answers1

1

How to block webpages and raise an event when doing so.

You are well on your way to blocking a website and getting told whenever the user visits a blocked site. Firstly you block the website in your hosts file telling the user's computer to go to localhost (127.0.0.1) instead of the wanted website. When you go to http://example.com/ the domain's server sees that you're trying to connect and feed you the corresponding data ( usually a website ).

In this case we will run our own server and instead of feeding the user any data, we will just use the incoming connection as a triggerer to see that the user is trying to access a blocked website.

Step 1:

Block the website and redirect it to localhost (127.0.0.1) using the hosts file ( Windows )

C:\Windows\System32\drivers\etc

# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#   127.0.0.1       localhost
#   ::1             localhost

# This is our blocked site
127.0.0.1 example.com

This will make all the calls to http://example.com redirected to our local machine, port 80.

To intercept this traffic we setup a server running on the local machine, port 80.

Step 2:

Imports System.Net
Imports System.Net.Sockets
Imports System.Threading

Public Class Form1
    Private Sub StartBlocker()
        'Declare a BlockListener
        Dim blocker As BlockListener
        'Declare a thread to run the server on
        Dim thread As Thread
        'Set the blocker to be a new "Block Listener"
        blocker = New BlockListener
        'Set the current thread to be a new thread ( so that there is no noticable performance drop for the main window )
        'It runs the function blocker.listen ( further described below )
        thread = New Thread(New ThreadStart(AddressOf blocker.listen))
        'Start the thread to run the function
        thread.Start()
        'Add a handler to handle a function whenever a user is blocked ( connected )
        'The event's name is Blocked and the callback function is Restart
        AddHandler blocker.Blocked, AddressOf User_Blocked
    End Sub

    'The function that handles whenever a user is blocked ( connected )
    Private Sub User_Blocked()
        'This function is called whenever a user is blocked
        MessageBox.Show("Blocked")
        'NOTE
        'For some reasons, sometimes there are more than one connection meaning
        'that the Blocked event is raised more than once in turn resulting in this function being called multiple times
        'usually 2-3 when the user actually only connects once.
        'To deal with this you can simply wait one second before you listen for connections again
    End Sub
End Class

'The class to act as the blocker
Public Class BlockListener
    'The block to run the server on ( must be 80 to work with hosts file and browsers, 80 is default for webservers )
    Private port As Integer = 80
    'Declare a TcpListener called listener to act as the actual server
    Private listener As TcpListener
    'Declare a boolean for turning the server's blocking capabilities on or off
    Private BlockUsers As Boolean = True

    'Declare the event to be called whenever a user is blocked ( connected )
    Public Event Blocked As EventHandler

    'The main function of the BlockListener : listen | listen for incoming connections
    Public Sub listen()
        'Create a new listener to act as a server on the localhost with 80 as port
        listener = New TcpListener(IPAddress.Parse("127.0.0.1"), port)
        'Start the listener
        listener.Start()
        'For as long as BlockUsers is true / for as long as you should block users
        While (BlockUsers)
            'Create a connection to the user and wait for the user to connect
            Dim clientConnection As TcpClient = listener.AcceptTcpClient
            'Whenever the user connects, close the connection directly
            clientConnection.Close()
            'Raise the "Blocked" event with no event arguments, so that you can easily handle your blocking elsewhere
            RaiseEvent Blocked(Me, EventArgs.Empty)
        End While
        'When the BlockListener should no longer listen for incoming connections - stop the server ( for performance and compatibility )
        listener.Stop()
    End Sub
End Class

Whenever a user tries to access a blocked site, this program will get the request and raise an event. Tested on Windows 7 x64 running Visual Studio 2012.

Note. There are, however one problem with this, well at least a very small one. The problem with this is that by editing the hosts file, you can only redirect where the user gets redirected - not to which port ( making us run the server on port 80 ). The problem with this is, what if the user is already running a server on 127.0.0.1 port 80 already? This is something that you might want to take into account, although it probably won't happen - there might be a chance it will.

Alex
  • 606
  • 11
  • 23
  • Alex, this was simply GREAT! It works perfectly, thank you so much! I would like to ask you one last thing (only if it's possible :)): can I display on the warning MessageBox the address that has been blocked? For example, if I block google.com, the MessageBox will be "You can't go on google.com!". Anyway, thanks a lot for your extraordinary help! _FWhite_ – PWhite Nov 04 '14 at 17:35
  • In my testing with coming up with this code (based on a webserver) you can get the resource name (i.e. www.example.com/this_is_the_resource) but not the requested url. – Alex Nov 04 '14 at 19:18
  • Thanks a lot anyway, you really helped me! – PWhite Nov 04 '14 at 19:31