Tor – How to install for specific country and reset identity with C#?

For requirements in my private tool, I need to change my IP according to demand and only use IPs of a specific country. I don’t have much money to buy a private VPN or a premium service to get HTTP/SOCKs proxy. Even that I can buy a service like that, the resources of IPs are still very limit. I think we can’t get more than 10 new IPs per day. That’s not enough for me. Besides I have no inspiration to expand the current source code to login to a service, get list of proxy and apply to my web browser. I need an integrated solution which requires once configuration, works forever and not too much time-consuming for implementing. Therefore I think of Tor (https://www.torproject.org/).

Tor is free software and an open network that helps you defend against a form of network surveillance that threatens personal freedom and privacy, confidential business activities and relationships, and state security known as traffic analysis

. Using Tor, I can completely hide me behind a proxy and thanks to his powerful flexible configuration, I can set from which exit nodes I will go out. In this small blog, I will guide you how to install Tor, set the exit nodes to specific country and requires new identity with C#.

1. Go to Tor homepage (https://www.torproject.org/), click on “Download Tor”, you will see a direct link to download “Tor Browser Bundle”. Don’t download it because it’s only for normal user who needs an anonymous identity when surfing over internet through an integrated browser. I need something more powerful because I would like to build a proxy and use this proxy for any web browser I like. Therefore, click on “View All Downloads” as image below

Tor View all downloads

2. Choose “Vidalia Bundle”, download and install it with all default settings.

Vidalia Bundle

3. After installation is finish, start Vidalia – a cross-platform graphical controller for the Tor software, built using the Qt framework, wait until authentication process is done. If not successful, then check your firewall if he allows Vidalia to access internet. If successful, you’ll have “Connected to the Tor network”

4. Now we have a local Sock proxy running on our computer, we would like to check if it works. Start Internet Explorer –> Internet Options –> Connections –> LAN settings –> Check on “Use a proxy server for your LAN…” and click on Advanced. At the Socks textbox, enter “127.0.0.1” for address and 9050 for port. Click OK to finish. Then go to any IP checking website to check if we are now anonymous.

Internet Explorer Tor Settings

5. This integrated solution is much better than we add proxy manually/programmatically to web browser. Because if we add proxy ourselves, we must first check if proxy work and if it is too slow to use, that requires a lot of programming and really time consuming when running in real time. Tor integrated solution is not that case because we don’t have to change proxy and the exit nodes will be examined by Tor for working node and as fast as possible. Moreover with Tor, every time when we start new instance of Internet Explorer, we’ll get new identity.

6. Now the proxy runs smoothly, but it will choose any exit nodes around the world for us. That’s again not what we want. We want, for example, only use exit nodes from Germany. Thanks to flexible configuration of Tor, we can exclude the exit nodes of other countries which we don’t believe or don’t want to go through. In Vidalia Control Panel, Settings –> Advanced –> Edit current torrc –> Insert Exclude Nodes to configuration file –> Click OK.

ExcludeNodes {be},{pl},{ca},{za},{vn},{uz},{ua},{tw},{tr},{th},{sk},{sg},{se},{sd},{sa},{ru},{ro},{pt},{ph},{pa},{nz},{np},{no},{my},{mx},{md},{lv},{lu},{kr},{jp},{it},{ir},{il},{ie},{id},{hr},{hk},{gr},{gi},{gb},{fi},{es},{ee},{dk},{cz},{cy},{cr},{co},{cn},{cl},{ci},{ch},{by},{br},{bg},{au},{at},{ar},{aq},{ao},{ae},{nl},{us},{fr},{lt}

7. Let’s start some instances of Internet Explorer; we’ll see that we are now always exited from Germany nodes. You can find in Internet another solution to exclude nodes, for example through name or fingerprint. It depends on your requirement how you would like to hide yourself then choose one appropriate method for you. So now is the last requirement. It’s ok to start new instance with new identity but what should I do if I want to get new identity within an instance. Let’s consider that you are programmer, you have already start an instance of web browser control. You want now to get new identity but you can’t not dispose the old one and initialize a new one because it’s really time-consuming and resources-consuming. We must find out how we can force Tor to change his identity. Vidalia has a built-in function for us to get new identity

New Identity
Of course it’s completely possible to call this function from our program. But again I don’t want to make it so complex. I would like somehow talk with Tor to order him reset identity, somehow through remotely sending message from Socket to Tor. Man calls this function as Telnet function and Tor allows us to “telnet” to his host for remotely controlling. But we need to configure Tor for allowing remote configuration.

8. Go to Settings –> Advanced –> Remove ticks from “Randomly Generate” and enter your password. You have to use this password to connect to control host.

Tor Control Host Password Settings

9. In your program, connect to control host and send message to reset identity

private bool RequestNewIdentityFromTor()
{
	IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9051);
	Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
	try
	{
		client.Connect(ip);
	}
	catch (SocketException e)
	{
		MessageBox.Show("Unable to connect to server of Tor.");
		return false;
	}

	client.Send(Encoding.ASCII.GetBytes("AUTHENTICATE \"YourPassword\"\n"));
	byte[] data = new byte[1024];
	int receivedDataLength = client.Receive(data);
	string stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);

	if (stringData.Contains("250"))
	{
		client.Send(Encoding.ASCII.GetBytes("SIGNAL NEWNYM\r\n"));
		data = new byte[1024];
		receivedDataLength = client.Receive(data);
		stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
		if (!stringData.Contains("250"))
		{
			MessageBox.Show("Unable to signal new user to server of Tor.");
			client.Shutdown(SocketShutdown.Both);
			client.Close();
			return false;
		}
	}
	else
	{
		MessageBox.Show("Unable to authenticate to server of Tor.");
		client.Shutdown(SocketShutdown.Both);
		client.Close();
		return false;
	}
	client.Shutdown(SocketShutdown.Both);
	client.Close();
	return true;
}

10. We now fulfill all requirements. But there are still some considerations about the security of Tor that we should discuss. Because we connect to end website through a lot of nodes and our messages will be much more vulnerable to be attacked or decrypted. If a hacker operates a node in network, he can follow the network traffic or do whatever only god knows to get our data, for example mail password, ftp password, bank password… So I recommend use Tor only for transmitting not sensible data, don’t use Tor for email checking or online banking. You know that nothing is free. If you’re interested in Tor security, there’re some helpful links:
https://www.torproject.org/about/overview.html.en
http://en.wikipedia.org/wiki/Tor_%28anonymity_network%29

9 thoughts on “Tor – How to install for specific country and reset identity with C#?”

  1. Good article, but I would do it more effectively via the tor interface, rather than vidalia, which is overkill when you write your own apps anyway.

    Download the trunk here via svn: https://svn.torproject.org/svn/torctl/trunk and let’s get started.
    Make a simple tor controller where you control tor from your app (new identity, etc.). It’s much better to do it via a http proxy rather than socks, due to anonimity, because dns streams over socks can expose you, due to their broadcasting. So you need a socks -> http proxy, something like privoxy.

    Plus, I would encapsulate:
    client.Shutdown(SocketShutdown.Both);
    client.Close();
    in a final block, because now it’s redundant.

    Using the tor interface, you got total control and it’s better secured, plus, your code is better for reusibility and doesn’t have conditional statements for “guessing”, like you did with the statuscodes, which can be obsolete anyway in the future by tor.

    Hope this helps 😉
    -Casper

  2. @Casio1987: Thank you for your comment. I’ll take a look and try to use your suggestion in my next projects with Tor.

  3. No problem 🙂
    Note that the trunk is pretty deprecated for the newest tor source regarding v1 protocol. You have to make a custom interface, which you already made a great start with.

    Also note that tor is automatically changing circuits every 10 minutes, which can be a huge problem when you are bound to a specific ip.
    To overcome this, you have to tell tor to increase the cycle with “setconf maxcircuitdirtiness=$timeInSec”, where $timeInSec is a max value of int, for the current circuit.

    Vidalia uses the following arguments:
    -f .DataTortorrc DataDirectory .DataTor ControlPort XXXX __OwningControllerProcess XXXXX HashedControlPassword XXXXX
    You can replace this easily with code to start a proc with arguments. Passowrd is a hex encoded string or just plain text double quoted.
    See https://www.torproject.org/docs/tor-manual.html.en for interesting ones.

    Note that some switches can only be set with the interface, which starts with “__”.

    If your app is bandwidth expensive, try to find an exit-node with at least the relayflags “EXIT” and “FAST” and try to use 2 hops at max. To get one hop, you have to modify the source and recompile it. Not recommended, because that exit-node will know who you are when you keep coming back for him.

    Enjoy and maybe we see eachother again, this time in the tor network 🙂

  4. Hey, I tried your routine for changing identity, but I just can’t get it to work. I’m calling a site that identifies my IP address in a loop, and calling your method every 10 requests, but my IP address never changes. I don’t get any errors, so I have no idea what the problem might be. I just downloaded Tor today using the method you suggested — any thoughts on why I can’t get your routine to work and force Tor to change my circuit/identity at will? Thanks.

  5. @RambleC: My solution works only if you reset the TOR by the C# code above. Without reseting TOR, you’ll never get new identity.

  6. Thanks for the response. What do you mean by “reset Tor”? I copied your method directly and used it, but no luck. Is there another step I need to take? I’m issuing HttpWebRequests via the Pilopo proxy in a loop, and on occasion I stop to run your routine, and I’m not having any luck. So my request is like this:

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Proxy = new WebProxy(“127.0.0.1:8118”); // Pilopo proxy set to use Tor

    I scrape a page I have setup to display IP, and I only run your routine every ten seconds, but my IP never changes. Is there something else I need to do?

    Thanks for your help.

  7. @RambleC: There is no more step to do. Try to get your IP through this code after you reseting TOR.

    private string GetIP()
    {
    	try
    	{
    		IProxyClient proxyClient = new Socks5ProxyClient("127.0.0.1", 9050, "", "");
    		TcpClient tcpClient = proxyClient.CreateConnection("checkip.dyndns.org", 80);
    		//TcpClient tcpClient = tcpClient = new TcpClient("checkip.dyndns.org", 80);
    		tcpClient.Client.Send(ASCIIEncoding.ASCII.GetBytes(String.Format("GET / HTTP/1.1rnHost: {0}rnrn", "checkip.dyndns.org")));
    
    		// retrieve the response from the remote web server
    		int size = 1024 * 2;
    		byte[] receiveBuffer = new byte[size];
    		int bytes = tcpClient.Client.Receive(receiveBuffer, size, SocketFlags.None);
    		string strIP = ASCIIEncoding.ASCII.GetString(receiveBuffer, 0, bytes);
    		strIP = (new Regex(@"bd{1,3}.d{1,3}.d{1,3}.d{1,3}b")).Match(strIP).Value;
    		tcpClient.Close();
    		return strIP;
    	}
    	catch (Exception ex)
    	{
    		Console.WriteLine(ex.Message);
    		return "";
    	}
    }
    

    I don’t use HttpWebRequest but I use WebBrowser component directly to get data.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.