Become a fan of Slashdot on Facebook

 



Forgot your password?
typodupeerror
×
Programming The Almighty Buck

The 2015 Underhanded C Contest Has Begun 52

Xcott Craver writes: The 8th Underhanded C Contest is now underway. The goal of the Underhanded C Contest is to write C code that is as readable, clear, innocent and straightforward as possible, but which performs some malicious function that is not obvious from looking at the source code. This year's challenge is based on a real problem in joint development for nuclear treaty verification, and the prize is $1000.
This discussion has been archived. No new comments can be posted.

The 2015 Underhanded C Contest Has Begun

Comments Filter:
  • by Anonymous Coward on Sunday August 16, 2015 @10:34AM (#50326457)
    So, pretty much any C program will be competitive here.
  • by Anonymous Coward on Sunday August 16, 2015 @10:57AM (#50326515)

    Clearly this contest must be in someway related to Systemd but I find no mention in TFA

    • by Anonymous Coward
      The relationship is pretty straightforward actually. Systemd was the winner of this prize 2 years ago.
  • Isn't all C++ underhanded?

    My C++ programmer buddies swear that the language was designed by a team of masochists who had a poor sense of humor and anger management issues.

    • by Anonymous Coward on Sunday August 16, 2015 @12:42PM (#50326977)

      Isn't all C++ underhanded?

      This contest concerns underhanded C, not C++. There would be little point in an underhanded C++ contest.

      C is a trivially simple language, with a very small syntax and a very narrow set of semantics. As a result, you have to work pretty hard to make ordinary C contain hidden functionality --- usually this requires abusing the C preprocessor, because the C grammar itself doesn't provide much room for hiding things.

      C++ is at the other end of the complexity scale, being the language with the largest syntax and the most extremely complex semantics of any programming language on the planet. It took that crown from Ada many decades ago, and it hasn't stopped growing since.

      Because of C++'s huge size in every respect, C++ programmers tend to develop their own preferred subsets of the language, and they stick with that subset throughout their lives. There's nothing wrong with that (indeed, it's probably the only way of working with C++), but it has the consequence that one person's clear C++ is another person's incomprehensible C++.

      That makes writing underhanded C++ a rather pointless exercise.

      • by epine ( 68316 ) on Sunday August 16, 2015 @04:54PM (#50327923)

        C is a trivially simple language

        You're crazy.

        Back in the eighties when I was primarily a C programmer, I spent years mastering the art of writing portable C code. Our main application was required to compile under both the Microsoft and the Watcom compiler, and under the Watcom compiler we targeted both MSDOS and QNX. This was a royal PITA at times. The worst case I recall is that Microsoft had a bug in their type deduction logic for expressions that mixed signed and unsigned values. In actual fact, the Microsoft code generator used the correct rules, but the Microsoft diagnostic routine in the parser did not, causing it to issue "type conversion" warnings opposite to its own internal behaviour. Just imagine how that gave us a bad case of group-consciousness head spin until we tracked down the underlying cause.

        It's terribly hard in C to defend yourself against certain kinds of accidental errors, which is one of my original reasons for moving to C++. My well-developed C programming subset (oh yes, I had a subset) was even more robust in C++. For example, in modern C++ there's much less justification for writing complex expressions using #define. Modern C++ programmers largely restrict the use of the C++ preprocessor for implementing a Turing-complete language at compile time.

        Is the C99 preprocessor Turing complete? [stackoverflow.com]

        Actually, I lied. That harmless looking C preprocessor from the dusty depths of time is but a C-hair short of being Turing complete at compile time. The smallest fiddle in the specification of token pasting might get you there.

        Concerning underhandedness, the Karen Pease PIU winner would not survive having __isleap() recoded from a macro to a C++ inline function. Many of the other examples abuse the #define mechanism for encoding object lengths, rather than having the objects maintain their own lengths, such as any STL container does.

        What you can foist in the unwary if you're off-scale malicious in C++ is off-scale high (it is, after all, a superset of C itself).

        On the other end of the scale, if you use C++ abstractions to do good rather than evil, the never-ending refinement of the C++ language takes you to a better place, not a worse place.

        Elements of Modern C++ Style [herbsutter.com]

        I'm not overly enamoured of Great Man theory [wikipedia.org], and likewise I'm not greatly enamoured of sanitary-conception language design, in which all the sins of the past are taken behind the woodshed and put straight en masse.

        Co-existence with our dirty origins is a simple fact of human biology. It isn't true that every complexity of human evolution is automatically a turn for the worse (as you seem to imply about accrued complexity in programming language design).

        The truth of the matter is that C++ used wisely can be a clean and empowering programming language, for those of us able and willing to pay the price of admission.

        Whether it's reasonable to pay that price given the many other choices available now is another question. In my case, I had already paid half the price in my first professional decade as a C programmer, after stripping away the illusion that C is simple language.

        I'm pretty much agnostic at this point about whether an ambitious young programmer should bother learning C++ or not, unless it happens that C++ is the only vehicle that will take you where you want to go (high abstraction level co-existing with raw hardware performance).

        Too many people sit there in a state of contempt fundamentally saying "if C++ is the only viable solution, then I want a simpler problem to solve!"

        Well, go to it. Fill your boots. But don't sit there and sneer at the brave souls who make the opposite choice.

      • by peetm ( 781139 )

        ...but it has the consequence that one person's clear C++ is another person's incomprehensible C++

        That makes writing underhanded C++ a rather pointless exercise.

        No it doesn't - it's good for job security because no one else knows what your code does.

    • I'd argue that C++ has to be considered in two different cases, one for library writers and one for library users. Moreover, let's talk about modern C++ (C++14) rather than legacy C++, with all the cruft compatibility with C and older C++ version gives us.

      C++ is an incredibly complicated but unbelievably powerful language for writing libraries. It allows high-level abstraction that compiles down to code every bit as efficient as the much more dangerous equivalent C code. A lot of the really complicated p

  • by mykepredko ( 40154 ) on Sunday August 16, 2015 @10:59AM (#50326523) Homepage

    I'm trying to remember where I first saw this function (I think it's a pretty common example for security coding seminars):

    int passwordCompare(char* enteredPassword, char* validPassword) {
    int i;

            for (i = 0; (len(enteredPassword) > i) && (enteredPassword[i] == validPassword[i]; ++i) {
            }

            if (len(enteredPassword) == i) {
                    return -1; /* true */
            }
            else {
                    return 0; /* false */
            }
    }

    but, I would imagine that it would qualify as an example for the contest. I don't think it was originally designed to be malicious, but more of a coding error.

    I would expect most of the entries in the contest would be of this variety, something that a (new) coder has put in that works for basic test cases, but has a serious flaw...

    • by alvinrod ( 889928 ) on Sunday August 16, 2015 @11:18AM (#50326573)
      Go look at some of the winners from previous years. Some of the solutions are on such a diabolical level that they might take days or weeks to fully track down and understand and are so convoluted that no one could possibly think it was intentional.

      Last year's winner [underhanded-c.org] is a rather good example.
      • Serious question here. I was wondering whether C lends itself to obfuscation of undesired/malicious behavior or whether it is just the preferred language of people able to dream up such deviousness. Would someone with enough python-fu be able to pull this off or would the deception/error be easier to detect by the average coder? i.e. would an underhanded python contest be feasible or would the deception to readily apparent (or at least more apparent)?

        • Would someone with enough python-fu be able to pull this off or would the deception/error be easier to detect by the average coder?

          Isn't the main reason Python code is so slow that it's nigh impossible to prove anything about it, even to a computer?

        • I'd guess the reason C is used is because it's still the programming language of choice for operating systems and security libraries. Nearly every commonly-used OS is written in C, and as such, it's the most relevant language to demonstrate such techniques in.

          It also happens to be a somewhat low-level language that allows for all sorts of crazy tricks and techniques, especially once you add in the preprocessor. So, win-win, as far as this contest is concerned.

    • by dotancohen ( 1015143 ) on Sunday August 16, 2015 @12:15PM (#50326851) Homepage

      I'm trying to remember where I first saw this function (I think it's a pretty common example for security coding seminars):

      int passwordCompare(char* enteredPassword, char* validPassword) {

      Hey, that's the routine that checks the password on my luggage!

    • by fredan ( 54788 )
      int passwordCompare(char* enteredPassword, size_t enteredPassword_len, char* validPassword,  size_t* validPassword_len) {

      if (enteredPassword_len != validPassword_len) {
      return 0;
      }

      if (timeingsafe_memcmp(enteredPassword, validPassword, validPassword_len) == 0) {
      return -1;
      }
      return 0;
      }
    • So, i is always equal to the length of the entered password?
    • It took me a minute or two to realize you aren't checking the length of both strings. The real red flag for me was that it doesn't use the standard library's comparison function.

    • for (i = 0; (len(enteredPassword) > i) && (enteredPassword[i] == validPassword[i]; ++i) {

      Did you miss a ) out of there somewhere?

      How are we supposed to spot the bug in your bug-riddled code? ;)

  • that fits this bill. Code that I swore up and down covered all corner cases for input but with enough fuzzing could be coaxed into crashing.

  • Let us all set back and appreciate the scariest bit of C code ever written:

    main( ) {
    printf("hello, world");
    }
    • Let us all set back and appreciate the scariest bit of C code ever written: main( ) { printf("hello, world"); }

      It's scary because you used the same formatting they use in K&R. The same formatting that people have used for dozens of years as if they need to save white space because they're publishing a book! It drives me nuts when people put the { on the end of the line. They only did that in books to save space!

  • Only US$1,000.00? That's useless. For those who study the history of code (in any klanguage, but especially C [or microcode]), this could be a meaningful challenge. But only if we're talking six figures. At least the really smart people I've been blessed to associate with are worth it.

Avoid strange women and temporary variables.

Working...