Slashdot Mirror


Obfuscated Vote Counting Contest

Daniel Horn writes "In a flash of inspiration coming from the Obfuscated C code contest and the current E-voting scandals, I wondered if there shouldn't be a similar code obfuscation contest based on obfuscating voting results, that is, C code that appears correct but does the wrong thing when counting votes. Submit your obfuscated vote-counting code now, and the two winners will be selected on November 2 and will receive a free Vega Strike CD. Obviously incorrect code, however, is not welcome."

49 of 223 comments (clear)

  1. I WIN! by AmigaAvenger · · Score: 5, Funny

    Quick, someone post some of the Diebold voting machine code, you certainly will have a winner in there!

    1. Re:I WIN! by qube99 · · Score: 2, Funny

      10 print "KERRY WINS!" 20 goto 10

    2. Re:I WIN! by anonymous+cowherd+(m · · Score: 4, Funny

      Did anyone notice the irony in the fact that the email address for submissions is dyebold@gmail.com? LOL.

      --
      http://neokosmos.blogsome.com
    3. Re:I WIN! by Phillup · · Score: 4, Funny
      You gotta do it right (like... FAR right ;-))
      switch (c) {
      case YADA_YADA:
      yada_yada += 1;
      case NADER:
      nader += 1;
      case KERRY:
      kerry += 1;
      case BUSH:
      bush += 1;
      }
      That will more likely pass the "first glance" test... and give the big guys the numbers they "deserve".

      And, I'm sure Bush would believe he really does have that much more "support" from "his" citizens than Kerry.
      --

      --Phillip

      Can you say BIRTH TAX
    4. Re:I WIN! by Fjornir · · Score: 2, Informative

      You're missing something more important than a default case.

      --
      I want a new world. I think this one is broken.
    5. Re:I WIN! by 00420 · · Score: 4, Informative

      It has nothing to do with default case. It has to do with the lack of breaks.

      Read it again. A vote for kerry means both kerry and bush get a vote. A vote for nader means nader kerry and bush get a vote.

    6. Re:I WIN! by Tony-A · · Score: 2, Informative

      It's not the DEFAULT, it's the fall-through.
      This is one case where the lack of goto's is harmful.

      The body is
      yada_yada += 1;
      nader += 1;
      kerry += 1;
      bush += 1;

      The cases just determing where the stream is joined.
      Anytime nader gets a vote, kerry and bush also get a vote.
      Anytime kerry gets a vote, bush gets a vote.

      None of the above will fail to register, with or without a DEFAULT.

    7. Re:I WIN! by crywolf · · Score: 2, Funny

      And in election news, a record 117% of the nation's registered voters went out and voted.

      --
      CAUTION: Product may be hot after heating
    8. Re:I WIN! by ryanmfw · · Score: 2, Informative

      I think you misunderstood the point. It's *meant* to do the wrong thing.

      --
      Hurricane Ivan: A 17th century prison collapsed. All of the inmates escaped.
    9. Re:I WIN! by smittyoneeach · · Score: 2, Funny

      In other words failure to use a break; statement in a C switch construct has a qualitatively similar effect to the act of writing a rather longish sentence while omitting punctuation of any sort upon a human reader.

      --
      Get thee glass eyes, and, like a scurvy politician, seem to see things thou dost not.--King Lear
    10. Re:I WIN! by JUSTONEMORELATTE · · Score: 4, Funny

      You're missing something more important than a default case.
      Aww c'mon, give the guy a break already!

      --
      free gmail invites -- only one left!

  2. Damn by antifoidulus · · Score: 4, Funny

    I was going to submit the Diebold code till I read:Obviously incorrect code, however, is not welcome.

  3. Hiding... by Anonymous Coward · · Score: 5, Interesting

    If I were doing this, I would hide the date analysis and vote rigging in another part of the program. For example, the code used to handle the screen and menus, or the network stack.
    Then, you could obfuscate a call to jump the program pointer to that part of memory directly, run a tiny bit of code that appears to deal with graphics, but does something else when called with the correct offset.
    The devious would be scattered about, rather than in one single vote counting function.

    1. Re:Hiding... by Starji · · Score: 2, Interesting

      I wish I had more experience with code obfuscation, then I might actually submit something. Probably the poor man's way of doing this might be to copy their vote.c and then have some sort of on-the-fly vote redirector to favor one candidate. Compile it to assembly then copy the relavant portion back to the origional source code and do an inline assembly replacing the origional c code. if the assembly is especially long, it's likely nobody will be able to decode it anyway since almost nobody knows assembly anymore. Add a little more fun with some #defines at the top and you have something that's fairly obfuscated (to an untrained eye) and does what you want with the host language remaining the same. Don't know what the rules are on inline assembly though....

    2. Re:Hiding... by globalar · · Score: 3, Interesting

      In that same vein, I would use code which has somewhat unpredicatable and incremental behavior. It is much harder to detect code which alters data seemingly at random, and sometimes not at all.

      Changing a small amount of data with minimal condition at pseudorandom intervals is practically an intentional bug. Of course, if I can expect a certain threshold of data, I might be able to add a statistical leaning into the program that favors a particular outcome. Of course, this is the point of the contest. The point is, blind trust is no trust at all.

    3. Re:Hiding... by Lehk228 · · Score: 2, Interesting

      I just changed the memory location to output Kerrys vote count from, since the code increments array['K'] i just output array['k'], now kerry gets 0 votes and "other" gets all of his votes instead. I chose Kerry to target with the code because 'k' and 'K' are much more similar than 'b' and 'B' or 'N' and 'n'.

      --
      Snowden and Manning are heroes.
    4. Re:Hiding... by Anonymous Coward · · Score: 3, Interesting

      I would hide my code in the parts used for assisting disabled people. My code would be triggered once every so often when a voter takes lots of time to enter a choice or when the voter uses the visually impaired asistance functions vendors have been bragging about. This way you have a high chance of cheating on an older or visually impaired voter, which means a much better chance of going unnoticed even with a voter verified paper trail...

      Another good idea for cheating on the disabled, you can hide lots of stuff in an audio decompression codec with the added bonus of people not getting suspicious about highly optimized self modifing code there.

      If you were very devious you could even submit your code into an opensource audio project like ogg and then base your voting software on that. Not only would code auditors be looking mostly at what code changes from the public version to the voting machine version, if they found something it would be hard to say anything about who planted it. Instand plausible denyability, another reason to be suspecious about using third party software like windows CE and the access database stuff. Ofcourse if you really want denyability you just accidentally add an exploitable security vulnarability. If it gets cought you hit yourself on the forehead asking how you could have been so stupid, if it isn`t found you go around voting stations on election day and flip some votes around.

      Of course nobody would be stupid enough for their cheat code to be triggerd in the first hundred votes. Remember that story about voting machines being "tested" by entering one vote?

      One other thing, with everybody talking about software, the obious way to avoid detection is to put your tricks in hardware. Remember the X-box, it has a plain x86 pc design, cpu, northbridge southbridge and bios ROM chip. The guy that first published about cracking its copy protection surprissed quite a few people with the revalation that the X-box doesn`t actually boot from the bios chip but from a bit of rom hidden inside the southbridge chip.

  4. Summary of this year's election by Dancin_Santa · · Score: 5, Insightful

    enum Outcome
    {
    AMERICAWINS,
    AMERICALOSES
    }

    int main()
    {
    bool voted = didYouVote();

    Outcome o;

    switch (voted)
    {
    case true:
    o = AMERICAWINS;
    case false:
    o = AMERICALOSES;
    }
    return o;
    }

    1. Re:Summary of this year's election by fossa · · Score: 2, Insightful

      AVP: No matter who wins, we lose.

    2. Re:Summary of this year's election by tomhudson · · Score: 4, Funny
      More efficient code, to avoid all the suspense. It is guaranteed to return the correct outcome every time!
      #define AMERICALOSES 0x00

      int main() {
      return AMERICALOSES;
      }
    3. Re:Summary of this year's election by Anonymous Coward · · Score: 3, Insightful

      I don't know if you're trying to encourage voting or proposing code for the contest but by leaving out the "break;" in your switch statment I think you've certainly predicted the outcome of this year's elections.

  5. Patent pending by GrAfFiT · · Score: 5, Funny

    "C code that appears correct but does the wrong thing when counting votes"
    Beware of Diebold suing you for infringing one of their patents !

  6. Similar to Dr. Rubin's challenge by bjtuna · · Score: 4, Informative

    This seems to be similar to Dr. Avi Rubin's challenge to the community, which basically states that a team of security specialists and programmers should be given access to the development environment of one of the major DRE machines, by the vendor. The team should then attempt to rig the machine in favor of one candidate, and then submit the machine for approval by the elections board's testing agency. The testing agency doesn't know it's being tested, and doesn't know the machine is rigged. Could they catch the rigged machine as they currently claim? It's the same basic principle as having undercover agents attempt to sneak weapons through airport security.

    The paper can be found at:
    http://avirubin.com/vote/ita.challenge.pdf

    1. Re:Similar to Dr. Rubin's challenge by AsOldAsFortran · · Score: 2, Informative

      Dr. Rubin has already done this in a class. In CS 600.643: Advanced Topics in Computer Security he has student research methods for malicious code hiding and then as groups, try to hid code to rig the vote in a program. Once done, the groups switch programs and try to find the malicious sections. Groups were given one clean, one dirty and one version picked at random.
      Results? Very few sections of malicious code were found, even in this highly controlled environment. The graduate students proved very adept at obsfucation.
      I hope Dr. Rubin reports on this in the literature because the results sound fascinating from a keynote address he gave last Friday (Oct. 15 at CCSCE 04). Sounds like a great class assignment.

  7. Why? Already there! by DigitalRaptor · · Score: 4, Informative

    Why create code that distorts the voting results, Diebold has already done it.

    My favorite story was a county in Pennsylvania (if I remember correctly, it's in this months Readers Digest) where the electronic voting machine correctly counted all 144,000 votes. Except there were only 19,000 registered voters in the entire county.

    We're screwed in this election. It is going to make the 2000 Florida crap look like a cakewalk.

    --
    Lose Weight and Feel Great with Isagenix
  8. ok. by photon317 · · Score: 4, Funny

    /* Global vote tallies */
    int KerryVotes=0;
    int BushVotes=0;

    void ParseVote(const char* v) {
    if(!strcmp(v,"Kerry")) {
    KerryVotes++;
    } else if(strcmp(v,"Bush")) {
    BushVotes++;
    }
    }

    --
    11*43+456^2
    1. Re:ok. by Peyna · · Score: 2, Funny

      Just hope that more than 65535 people don't vote for the same candidate.

      --
      What?
    2. Re:ok. by Anonymous Coward · · Score: 3, Funny

      Now, what are the chances that the code is being run on a 17-bit platform?

  9. my submission by SamBeckett · · Score: 4, Funny
    /* Current population proportion polls show: */
    #define BUSH 0.512
    #define KERRY 0.481
    #define UNDECIDED (1.0 - BUSH - KERRY)

    #define NBC 0
    #define ABC 1
    #define CBS 2
    #define FOX 3

    int main() {

    int bush = 0;
    int kerry = 0;
    int nader = 0;
    int i;
    int vote;
    int broadcast_network = rand() % 4;

    for ( i = 0; i < 260000000; ++i) {
    vote = rand() % 10000;

    if ( vote < 10000.0*BUSH ) ++bush;
    else if ( vote < 10000.0*(BUSH+KERRY) ) ++kerry;
    else {
    if ( broadcast_network == NBC || broadcast_network == ABC ||
    broadcast_network == CBS )
    ++kerry;
    else if ( broadcast_network == FOX )
    ++bush;
    else
    ++nader;
    }
    }

    printf("Bush :%9d\nKerry:%9d\nNader:%9d\n", bush, kerry, nader);
    return 0;
    }
    1. Re:my submission by Peyna · · Score: 2, Insightful

      I fail to trust any poll, because most of them only call during the day, when a certain group of people are home, and another group are likely to not be home. They also do not include a large number of younger voters, who are less likely to respond to a survey, and are more likely to have a cell phone and not a landline phone (which means they won't be called.)

      The pollsters "are hoping" that young people continue their streak of not voting much, so their numbers remain accurate.

      It's all B.S.

      --
      What?
  10. Re:last election by Anonymous Coward · · Score: 5, Funny

    Surely you know that C and C++ don't give a damn if there are new lines and carriage returns in the whitespace or not.

    Only newbie programmers use new lines and carriage returns.

    Real programmers don't use new lines and carriage returns as it detracts from being able to glance at the whole program at once and immediately understand it's intent, purpose, and spot any bugs in a holistic fashion.

  11. Re:Powered by Windows? by psetzer · · Score: 4, Interesting

    Well, you must have misread. They use Windows CE. I shit you not.

    --
    "Anyone who attempts to generate random numbers by deterministic means is living in a state of sin." -- John von Neumann
  12. Re:last election by ezzzD55J · · Score: 3, Insightful

    forgetting strcmp() returns 0 when strings match are we?

  13. Re:last election by reddish · · Score: 2, Funny

    In addition to the mistakes others noticed: what's an elsif?

  14. Re:Nader not Nater by OneDeeTenTee · · Score: 3, Funny

    Nater is a Basketball player, Nader is a presidnetial candidate.

    And they both have the same chances of becoming president.

    --
    Stop the world; I need to get off.
  15. Course at Rice by offby1 · · Score: 3, Informative

    Dan Wallach is teaching a course at Rice that, I think, includes this sort of challenge.

    1. Re:Course at Rice by gr8_phk · · Score: 2, Funny

      Yes, teaching people how to make code look correct while doing something wrong is a valuable skill for everyday honest folks. I'd like to take the class and then write banking software....

    2. Re:Course at Rice by berteag00 · · Score: 2, Informative

      Okay. I know that was an off-hand comment, so I'll forgive you. But next, time perhaps you should check the syllabus before you go about criticizing what was truly an excellent course. One of the best CS class I took at Rice, actually (just behind Keith Cooper's compiler construction class.)

      You'll note that the very first substantial lecture is on ethics.

  16. Re:And while you're hacking away... by Tackhead · · Score: 2, Funny
    > ...please don't spend any time thinking about how you could do anything that might lead to a DECENT candidate for presidency being available next around.
    >
    > In fact, just forget to vote alltogether, not like your vote counts, right? ;)

    I dunno, I'd think that being able to hack the best-hidden trapdoor into the voting system would make your vote count for quite a bit!

    STALLMAN-BALMER 2008!

  17. What the fsck is wrong with this? by Visaris · · Score: 3, Interesting
    #include <stdio.h>
    #include <unistd.h>

    /* Just to clean things up a bit */
    #define REGISTERED_VOTERS 230597013
    #define kerry 1
    #define bush 2
    #define nader 3
    #define Count(y) f##or##y

    /* Where the votes come from */
    extern int get_vote();

    int main(int argc, char **argv)
    {
    int for_b=0, for_k=0, for_n=0, vote;

    /* Count the votes! */
    while(vote=get_vote()) {
    switch(vote) {
    case bush:
    for_b++;
    break;
    case nader:
    for_n++;
    break;
    case kerry:
    for_k++;
    break;
    }
    }

    /* Print results */
    printf("Bush: %d\nKerry: %d\nNader: %d\n",
    Count(_b),Count(k)(),Count(_n));
    return 0;
    }
    --

    I am a viral sig. Please help me spread.
  18. C code? by Pan+T.+Hose · · Score: 2, Funny

    C code that appears correct but does the wrong thing when counting votes.

    Does it have to be a C code? In my opinion C is not nearly obfuscatable enough. What about BF or Unlambda? Or, better yet, Lingua Romana Perligata? Now when I'm thinking about it, I think PASM might be perfect for such a task, if only-- I know! Acme DWIM or Bleach compiled directly into PASM! With JIT!! Dear God, that would be so cool!!! But wait, they want C code, right... Wait a minute, Perl is written in C! So is Parrot! And they can be embedded in a C program! Sweet Heavens! What an idea!!!1 Gotta go.

    --
    Sincerely,
    Pan Tarhei Hosé, PhD.
    "Homo sum et cogito ergo odi profanum vulgus et libido."
  19. This is pretty much accurate: by Anonymous Coward · · Score: 5, Insightful

    if(voter.ethnicity != WHITE)
    return 0;
    if(GetVote(&voter))
    {
    switch(voter.vote)
    {
    case BUSH:
    case KERRY:
    ++BusinessAsUsual;
    break;
    default:
    AlertFBI();
    }
    }

  20. Re:What size processor will this code run on? by Tackhead · · Score: 2, Funny
    > int candidate_1_count;
    > if (vote==candidate_1)
    > candidate_1_count++;
    >
    > On an 32-bit machine, this will count up to 2 billion votes before the counter rolls over and goes negative. On a 16-bit machine, 32,000 votes. On an 8-bit machine, 127 votes.
    So, if I'm a Democrat, I'll make sure to put 16-bit versions of this machine in precincts such as East Buttfuck, Texas, which has a popuation of around 25000.

    Likewise, if I'm a Republican, I'll put a 16-bit version of this machine in inner city areas with populations ranging from 18000 to 50000.

    And if I'm really smart, I'll change the sizeof() an int to 15 or 17 depending on the number of votes I want to count, and the number I want to overflow. Spinning it to computer-illiterate civic officials would be as simple as having my salesguy say either "Because you have more people to count up, you get the 17-bit version. It's one better than the 16-bit version, but we can offer it to you at the same price", or "We'll let you save $500 per unit by going to the 15-bit version, which is suitable for smaller districts such as yours."

  21. Almost as scary as Florida by toby · · Score: 2, Informative
    And a bit trickier than rigging evoting: the Byzantine setup that tilts Venezuelan elections. That should give Vote-Robbing Hood and her cronies some ideas.

    It would be interesting if contestants could defeat the statistical methods used to uncover fraud mentioned elsewhere on that blog.

    --
    you had me at #!
  22. Ken Thompson's compiler hack by FleaPlus · · Score: 5, Insightful

    The best way to do this would be a variant of Ken Thompson's cc hack, published in ACM back in 1984. Basically the voting code would be pristine, but the compiler itself would be modified to add in "features" at compile time. The compiler also had hooks to add in the trojans while compiling pristine compiler code.

    Both compiler and voting application code would appear pristine, with the the actual hack existing only in the compiled code.

  23. Indeed by Pan+T.+Hose · · Score: 4, Interesting

    try to make a point and the only thing people notice is the syntax errors... only on slashdot

    Indeed. Everywhere else normal people would just get the point presented in the form of a C program, but not the nerds on Slashdot! But seriously, I was sure that all of the errors in your code was just meant to be examples of real errors that might change the election outcome:

    • gorevotes = 1; instead of gorevotes += 1; to make gorevotes always less than or equal to one, and using +=1 instead of ++ only to make the =1 mistake less visible
    • comparing canidate to "Nater" instead of "Nader" to make real Nader's votes not counted
    • the second bushvotes += 1; instead of nadervotes += 1; to count Nader's votes as votes for Bush
    • using bushvotes += 10; instead of bushvotes += 1; to multiply votes for Bush by ten
    • using if(strcmp(canidate,"Bush")) instead of if(!strcmp(canidate,"Bush")) supposedly forgetting that strcmp returns 0 false value on a match and true otherwise, to invert the vote counts and count votes not for any given candidate as votes for him
    • using canidate instead of candidate variable, which might have a different value
    • while not an error per se, not using curly brackets in conditionals might introduce unexpected subtleties in the control flow in more complex code with deceptive indentation

    All in all, not counting the Perlish elsif there are no syntax errors, while every single logic error might be used on purpose in a vote-counting code to change the election outcome while being hard to spot in a large and complicated spaghetti code. Did I really miss something?

    Actually, I was very surprised reading all of the posts fixing the bugs in your code. "Weren't such bugs the whole point of a contest writing 'C code that appears correct but does the wrong thing when counting votes' after all," I thought to myself? [emphasis added]

    But now I am even more surprised! Were those really unintentional errors? Because when I first read your comment I though: "What a brilliant example with so many subtle errors in every single statement!" Have I really overestimated the brilliance of your code? I do really hope that I have not, because it was surely one of the best examples posted so far, the foolish down-moderation notwithstanding.

    Was I completely wrong? Doubtful. Was I fooled? I don't think so. Am I stupid? Highly unlikely. So what's wrong?

    --
    Sincerely,
    Pan Tarhei Hosé, PhD.
    "Homo sum et cogito ergo odi profanum vulgus et libido."
  24. Re:You Think You're Funny by pjt33 · · Score: 3, Insightful
    Or more accurately, half of America is sitting right in the middle, and the other two quarters are on the fringes.
    Right in the middle of America, maybe. From the perspective of those of us on the other side of the Atlantic, your middle is a good way to the right.
  25. registration fraud by attonitus · · Score: 2, Informative
    Sadly that's a little too close to what actually may have happened in the fantastically free and fair elections that the west has managed to organise in Afghanistan

    Which made me wonder whether when, during the third debate, President's Bush boasted that, "the first person to vote in that election was a 19 year old girl", he might also have been correct to say that she was the second person, and the third person ...

  26. Leaked Diebold Code by NuclearDog · · Score: 2, Funny
    int KerryVotes = 0; /* ID = 0 */
    int BushVotes = 0; /* ID = 1 */

    function votefor(int id)
    {
    switch (votefor)
    {
    case 0: /* Vote for Kerry */
    KerryVotes++;
    case 1: /* Vote for Bush */
    BushVotes++;
    }
    }
    --
    This statement is forty-five characters long.