I just spent a few minutes writing a console application in .NET that artificially generates traffic on any given website. I will come back with details next week after testing the results.
Stay tuned…
UPDATE:
Have your site even been audited for traffic? In the days of big online advertising businesses, more traffic can mean more $$$ so web traffic auditing becomes important for validating your site popularity in terms of visitors, conversion rates, etc.
I always wondered how that information is filtered and validated to make sure the audit results are legitimate. This is particularly important on sites that monetize referrals to sponsored links or advertising delivering and unlike e-commerce portals, don’t have a shopping cart as a safe source of conversion data. With this in mind I decided to spend a few minutes writing a script that generates artificial traffic to any given site.
My main goal is to kick start an open discussion and if I’m lucky enough, get illustrated by an expert in the field on how traffic coming from a script similar to the one described here can be filtered out from different analytics data sources.
Since I just wanted to have a working example without spending much time on it, I took a quick & dirty approach. I created a C# console application that takes advantage of the fantastic Tor network to “anonymize” the web requests. Using this blog post as a target I ran the script on a modest VirtualBox instance in my home computer. The results? well as per Google Analytics, this post rapidly surpassed in number of visits the most popular post in this blog by a wide margin. This is too obvious and too small to have any impact on a minimally popular site but I believe you get the idea.
While coding I took many shortcuts to keep the code simple (again this is intended to be nothing but a quick experiment) but if someone is willing to spend more time, it should not be too difficult to run multiple threads and multiple Tor instances to generate a decent amount of traffic, simulate user interaction through browser automation instead of just creating browser instances (using selenium or a similar tool?), add http_referer’s to the game, dynamically restrict Tor’s exit nodes to generate traffic from limited geographical areas, etc.
The console application below simply randomly opens the target url using one of the installed browsers at a (again) random interval. The application ran on a VM instance configured to use Privoxy as a proxy to Tor (with the G Analytics tracking code whitelisted). I wanted to make sure most calls are seen coming from different locations, so the script restarts the Tor process before opening each browser, forcing Tor reconnect to the network and pick up a (typically) new exit node and a different IP. It also deletes the browser cookies file after closing it to keep the tracking code history clean so all visits are considered unique.
As a result a new web request coming from a random user agent is generated from a different source IP each time at random intervals. Which is exactly what I wanted to test..
IMPORTANT: Most of us love the Tor project, if bots start to continuously add load to the network circuits it will rapidly become unusable. I limited the script traffic to about one request a minute for this very reason. Please do not abuse it so we can all use it…
Beside blacklisting known Tor exit nodes IPs pulled from the server logs, I can’t think on any way to separate legitime traffic from the one generated by an improved version of the script below.
Any tech guru out there willing to educate this fool? Please?
Finally, here is the code (please excuse the formatting):
private const string TargetUrl = "http://YourTargetUrl.com";
private const string TorAppLocation = @"C:\YourPathToTheTorApp\tor.exe";
private static readonly string[] InstalledBrowsers = new[]{"IExplore","Chrome","Firefox","Safari"};
static private Process _prc;
static private int _reqCounter = 0;
static void Main(string[] args)
{
StopTor(); //Initial Stop in case Tor is running when the script was started
while (true){
StartTor(); //Start the Tor process (Gets new IP)
OpenBrowser(InstalledBrowsers[new Random().Next(0, InstalledBrowsers.GetUpperBound(0)+1)]); //Use a random browser from the list of installed.
StopTor(); // Stops Tor
}
}
static void OpenBrowser(string browserName)
{
try {
//create the request..
var processInfo = new ProcessStartInfo(browserName + ".exe") {WindowStyle = ProcessWindowStyle.Hidden, Arguments = TargetUrl};
Process.Start(processInfo);
Console.WriteLine("Currently Using: " + browserName + ", Total Visits: " + _reqCounter);
// Wait for a random interval in between 40 and 60 secs. This limits the requests frequency to aprox. 1 per minute. I don't want add too much unnecessary traffic to the Tor network or the web server.
Thread.Sleep(new Random().Next(40000, 60000)); //This can be easily changed to make the traffic it more natural.
Process[] brProcesses = Process.GetProcessesByName(browserName);
foreach (var br in brProcesses) br.Kill(); //Killing all processes is a very bad idea but works for this quick test.
Thread.Sleep(2000);
deleteCookies(browserName); //Delete browser cookies so each request is considered unique.
_reqCounter++;
}
catch(Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
}
static void deleteCookies (string BrowserName)
{
try {
switch (BrowserName) //A switch statement for this?? I guess I'm tired already..
{
case "IExplore":
Directory.Delete(@"YourPathToCookiesFile\Cookies",true);
break;
case "Chrome":
File.Delete(@"YourPathToCookiesFile\Cookies");
break;
case "Firefox":
File.Delete(@"YourPathToCookiesFile\Cookies");
break;
case "Safari":
File.Delete(@"YourPathToCookiesFile\Cookies");
break;
}
}
catch (Exception ex)
{} //Ignore Errors..
}
static void StartTor()
{
Console.WriteLine("Starting Tor Process...");
try{
//create and start the Tor Win process
_prc = new Process {StartInfo = new ProcessStartInfo(TorAppLocation, "ControlPort 9051 CircuitBuildTimeout 10")};
_prc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
_prc.Start();
Thread.Sleep(10000); //Wait for Tor to be ready, this should be improved but is good enough for now.
}catch(Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
}
static void StopTor()
{
Console.WriteLine("Stopping Tor Process...");
try
{
_prc.Kill();
}
catch (Exception ex)
{} // Empty catch statement to suppress errors when the Tor process isn't running
Thread.Sleep(5000);
}