11.02.14

The 7th Underhanded C Contest is now Open

Posted in Uncategorized at 7:17 pm by XcottCraver

The 7th Underhanded C Contest is now open.

The goal of the contest is to write code that is as readable, clear, innocent and straightforward as possible, and yet it must fail to perform at its apparent function. To be more specific, it should do something subtly evil. Every year, we will propose a challenge to coders to solve a simple data processing problem, but with covert malicious behavior. Examples include miscounting votes, shaving money from financial transactions, or leaking information to an eavesdropper. The main goal, however, is to write source code that easily passes visual inspection by other programmers.

The prize is a $200 Gift Certificate to ThinkGeek. It runs from November 2nd until the arbitrary deadline of New Years Day, 2015. NOTE: for a winner outside the US, if ThinkGeek does not deliver to your country, we will make the prize a gift certificate to some online retailer that does.

The 2014 Challenge: PiuPiu and the National Security Letter

The PiuPiu oversharing site allows users to create PiuPiu accounts and post 140-character messages. The federal government wants PiuPiu to surveil user activity on the site, by archiving any posts that match certain patterns outlined in a national security letter. Subject to the nondisclosure constraints of the letter, PiuPiu may not inform anyone of the surveillance request.

To be specific, PiuPiu uses the following data structures to represent a PiuPiu user and a Piu (message):



typedef struct user_struct {
        int user_id;
        time_t when_created;
        time_t last_activity;
        char * name;
        char * URL_of_avatar;

        int num_following, * ids_following;
        int num_blocked, * ids_blocked;
} user;

typedef struct piu_struct {
        int piu_id;
        int piu_id_of_repiu, user_id_of_repiu;    /* zero if not a re-Piu */

        int user_id_of_poster;
        user * poster;              

        char piu_text_utf8[140*4+1];
        unsigned char piu_length;
        unsigned char visible_only_to_followers;
} piu;

Your job is to write the code to scan incoming Pius before they are posted, to see if they match any patterns requested in a national security letter. The current system has a function called int preprocess( piu * entry ), to determine if a Piu is suitable for display, or to alter it if necessary; before it returns, it will call a function that you will write called void surveil( piu * entry ).

Your surveil function is given an entry that points to the Piu to be scanned, with its poster field pointing to the user who authored or re-Piued it. You are also given the following data structure to scan everything against:



typedef struct surveillance_request_struct {
        int id_number;
        int num_patterns;
        user * user_patterns;
        piu * piu_patterns;
        FILE * write_here;
} surveillance_request;

int num_requests;
surveillance_request * requests_to_scan;

As it says, a surveillance request is an array of N user-Piu patterns. If the input Piu matches one of these patterns, archive (fwrite) the Piu to the FILE handle. You must do this for every one of the num_requests requests. The input Piu matches a user-piu pattern if:

  1. The Piu text in the pattern is a substring of the input Piu’s text; AND
  2. All ids_following and ids_blocked in the user pattern are followed/blocked by the input Piu’s user; AND
  3. All of the NONZERO fields in the piu pattern match the input Piu. Values set to zero are “don’t care” inputs.

That’s it. Your job is to write this one function — and please be careful not to alter the entry or its user, because they will be committed to the database after preprocess() is completed.

The Evil Part

The underhanded goal is this: write surveil() in such a way that the act of surveillance is subtly leaked to the user or to the outside world. PiuPiu can not reveal the act of surveillance, but your function is technically able to edit the Piu or user structure during scanning. Find a way to alter that data (this alone is a bit of a challenge, since you are not supposed to alter the data, just scan it) in such a way that an informed outsider can tell if someone is being archived. The leakage should be subtle enough that it is not easily noticed.

As always, the code should appear simple, innocent, readable and obvious.

Scoring and Extra points:

  • In general, submissions are worth more points if they are shorter and more readable, because it is more impressive to hide a bug in short, readable code.
  • Errors based on human perception, like mistaking an l for a 1, are worth just as much as “hard” errors based on pointer abuse or little-endian weirdness or quirks of C function calls. The goal is a clever vulnerability that passes visual inspection, whatever the mechanics of the underlying bug.
  • Bugs are worth more points if, once discovered, they are plausibly deniable as an innocent programming error. This is particularly crucial in this year’s contest, because intentionally leaking this information would get the coder in serious trouble.
  • Errors are worth more points if they remain innocent-looking under syntax coloring.
  • Errors may be worth fewer points if they are processor or OS dependent, but only if we have to scavenge a system to test your bug. If your bug works specifically under GNU/Linux, don’t worry about it. If it works specifically under x86, no problem. If it only works on BeOS R5 on a dual G3 box when all four MIDI ports are active, then no.
  • Also, you won’t get any points if you simply submit a program that simply uses gets(), so that an adversary can take over the program by stack smashing. That is to say, we prefer bugs that are “internal,” that employ an interesting aspect of the code.
  • As always, one gets extra points for humorous, spiteful, or ironic bugs, such as evil behavior in an error-checking routine.

Here are some specific rules:

  • Extra points if you can leak specific information about the surveillance, like the number of surveillance_requests, or the id or index number of whichever request a target user matches.
  • Leakage is worth more points if it is subtle enough that it will not likely be noticed for a long time.

To participate:

Send your awesomely evil C file, and an explanation of your evil code, to UnderhandedC@gmail.com.