How to Exploit an Online Poll

UPDATE April 20th 2009: Once again Jeff Atwood has read my mind and posted his own version of how to conduct an online poll. As usual he provides an interesting take on the subject, and it's definitely worth a read.

Not that many people talk about it but there's a dark side to freelancing. It's amazing how many people out there are looking for a hired gun to do something illicit to somebody else. I've been asked to do everything from installing cracked software to hacking websites and everything in between.

I'm sure the proper thing to do when approached for this type of work would be to politely decline, but freelancing can get a little boring, so I've always heard the client out in the hope of finding something interesting.

One such request that I'm guilty of was to exploit an online poll.

(Cymbal Crash!!!)

Basically, the client company was up for some award, where voting was done online, and I was tasked with making sure they won. I made sure they did, and in the process I learned a few thing about how NOT to create an online poll.

Anyway, to do any sort of an exploit the first thing you need to do is recon. You need to find out as much about the target as possible. In this case we're talking about a poll on a website so this usually entails visiting the site and absorbing everything.

You want to read the terms of service and any sort of rules for the poll to find out what's allowed and what isn't. Not so you can follow the rules but because knowing what the site allows will tell you what they're protecting against. For example, if the terms of service says something like "one entry per IP" you know they're tracking IP addresses of registrants.

It's also important to take a look at the actual HTML code of the form so you know how it's built. Nine times out of ten the poll's going to be a radio group. You also want to grab the form action URL as well as any hidden form values.

You're going to need to know the HTML of the target site like you wrote it.

There's also the need to cover your tracks. Most, if not all, online polls will record as much information about each transaction as they can. It's actually easier to record everything, like IP address, referer and the date than it is not to.

What I did, which may not be the best idea I admit, was to create a text file of proxies in order to mask the IP address of the server the script was on. I then set the script to choose a random proxie on every "submit" with a different, random, referrer after waiting a random amount of time between transaction with sending a random user agent.

All this in the hopes of throwing off a manual inspection of the database. A little extreme but if anyone actually looks at the data they shouldn't see too obvious of a pattern.

Below is an example script that should help highlight the above.

<?php//the amount of votes to cast in this batch$amount_of_votes_to_cast=10000;//the minimum amount of time, in seconds, to wait in between runs.$wait_time=60;//URL to visit (don't forget the "http://"!)$submit_url="http://CHANGE_ME";//name and value of the form field$submit_vars="1";$proxy_file='/path/to/proxy/file';$agent_file='/path/to/agent/file';$proxy_hosts=file($proxy_file);$agents=file($agent_file);include"snoopy/Snoopy.class.php";$snoopy=new Snoopy;for($i=0;$i<=$amount_of_votes_to_cast;$i++){$snoopy->agent=$agents;$snoopy->referer=$referrers;$snoopy->proxy_host=$proxy_hosts;$snoopy->rawheaders="no-cache";if($snoopy->submit($submit_url,$submit_vars)){while(list($key,$val)=each($snoopy->headers)){echo$key.": ".$val."<br>\n";}echohtmlspecialchars($snoopy->results);}else{echo"error fetching document: ".$snoopy->error."\n";sleep($wait_time);}sleep(rand(0,$wait_time);}?>

So, it's pretty easy to do something like this but it kind of begs the question: what do you do if you're building a poll? How should you protect yourself?

Unfortunately, it's all in the data. It's important to actually look at your data and verify the integrity.

Look for patterns.

Take solace in the knowledge that if a programmer did exploit your script it's a safe bet to say he's pretty lazy (we all, pretty much, are). If it looks like your poll was only taken primarily by Linux users on a Sunday during the hours of 10AM to 2AM on Monday with all submissions posted within a minute or less of each other, you might want to flag those votes.

Basically, there's a finite amount of proxy servers, user agents and referrers your average programmer will be able to compile. In my example, I only used 150 proxie servers with 20 user agents; even a basic look at the data would have revealed some anomalies. It was pretty half-assed on my part.

But the target in the above story didn't bother doing any diligence and I was rewarded with a nice paycheck and box full of clothes from the client for just a couple hours of work.