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."

11 of 223 comments (clear)

  1. 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.

  2. Smartmatic! by Anonymous Coward · · Score: 1, Interesting

    Is welcome the code inside Smartmatic Votting machines used in Venezuela?

  3. 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
  4. Re:ok. by Anonymous Coward · · Score: 1, Interesting

    #include <stdio.h>
    #include <unistd.h>
    #include <ctype.h>
    #include <setjmp.h>
    jmp_buf escape;
    /* NOTE: to save memory, the low byte of results is used as a buffer *\
    \* NOTE: notice the shifts (and adding 256 for each vote) to fix it. */
    vcc(int vote, int results[4]);
    int main(void)
    {
    int results[4];
    if (!setjmp(escape))
    do {
    vcc(read(0, results, 1), results);
    } while (1);
    results[0] >>= 8;
    results[1] >>= 8;
    results[2] >>= 8;
    results[3] >>= 8;
    printf("Bush: %d Kerry: %d Nader: %d Other: %d\n", results[0], results[1], results[2], results[3]);
    }

    vcc(int vote, int results[4])
    {
    if (vote == EOF)
    longjmp(escape, 1);
    if (!isspace(vote))
    switch (vote)
    {
    case 'K': results[1]+=256; break;
    case 'B': results[0]+=256; break;
    case 'N': results[2]+=256; break;
    default: results[3]+=256; break;
    }
    }

  5. Is it sad... by bizpile · · Score: 1, Interesting

    Is it sad that I just ran your code? It worked, by the way. See the results here.

  6. 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.
  7. 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."