Slashdot Mirror


The 2006 Underhanded C Contest Begins

Xcott Craver writes "The second annual Underhanded C Code Contest is live as of April 4th, and runs until July 4th. The object is to write malicious C code that looks perfectly readable and innocent under informal inspection of the source."

40 of 232 comments (clear)

  1. I Win by ExE122 · · Score: 5, Funny

    In this contest you must 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.

    system("c:\Program Files\Internet Explorer\iexplore.exe");

    Where's my prize?

    --
    "Man Bites Dog
    Then Bites Self"
    --
    Capitalism: When it uses the carrot, it's called democracy. When it uses the stick, it's called fascism.
    1. Re:I Win by Anonymous Coward · · Score: 2, Funny

      system("c:\Program Files\Internet Explorer\iexplore.exe");

      Where's my prize?


      I don't think you read the task description very good, it said:
        "it should do something subtly evil"

    2. Re:I Win by Kjella · · Score: 2, Informative

      Well, if you ran it on this machine you'd get a "File not found". In a related note, everyone who hardcodes paths like "C:\Program Files" "C:\Windows" , "My Documents" should suffer. Likewise those who completely ignore regional settings (no, my decimal point and thousands separator are not the same as yours). Variations include those who can't handle non-ASCII letters or sorting (heard of æøå?).

      --
      Live today, because you never know what tomorrow brings
    3. Re:I Win by ToxikFetus · · Score: 2
      system("c:\Program Files\Internet Explorer\iexplore.exe");

      I'm not sure what the \P, \I, and \i escape characters do, but I think you were looking for this:

      system("c:\\Program Files\\Internet Explorer\\iexplore.exe");

    4. Re:I Win by darkmeridian · · Score: 3, Funny
      In this contest you must write code that is as readable, clear, innocent and straightforward as possible ...


      Read the conditions of the contest clearly. You obviously lose.
      --
      A NYC lawyer blogs. http://www.chuangblog.com/
  2. Can someone explain this to me? by sgant · · Score: 3, Interesting

    Why is this a good thing? I'm not a programmer, so I don't really understand why writing code that appears to be innocent, yet is really evil, help the community?

    I understand about making source code available helps in a secure system, but what if that code has evil code...made to look innocent upon inspection....written into it?

    I know that showing how to crack into a system, or how to write a virus actually helps in the long run as it exposes weaknesses that can and should be patched and closed. But what does having people practice hiding malicious code do for us?

    Just wondering. I find this stuff fascinating....though not fascinating enough to actually learn how to do it!

    --

    "Leo Fender was in a 'state of grace' when he designed the Stratocaster." -- Paul Reed Smith
    1. Re:Can someone explain this to me? by chrismcdirty · · Score: 5, Insightful

      1. It teaches you not to take all code at face value, and actually read into it.
      2. It's fun.

      --
      It's like sex, except I'm having it!
    2. Re:Can someone explain this to me? by bluelip · · Score: 3, Funny

      It provides a method to enumerate the techniques used by those with less than pure intentions.

      IOW, it helps folks learn to spot these 'bugs' more readily.

      --

      Yep, I never spell check.
      More incorrect spellings can be found he
    3. Re:Can someone explain this to me? by Xcott+Craver · · Score: 5, Insightful
      Well, ask yourself how the Obfuscated C Code contest "helps the community." To some extent, it's just a contest, and not meant to bring about world peace.

      On the other hand, I think it does teach us a thing or two about what to look for when reviewing code. I know I've learned a lot about sneaky coding practices since it started. I learned C in the 1980s and thought I was pretty knowledgeable by now, but I actually didn't know about ASCII trigraphs until last year. X

    4. Re:Can someone explain this to me? by tmjr3353 · · Score: 5, Insightful

      I understand about making source code available helps in a secure system, but what if that code has evil code...made to look innocent upon inspection....written into it?

      I think you've highlighted the point right there. By getting the community to find ways to write code of this fashion, you're simultaneously getting them to learn to read code better (or at least that would be my hope). If I know how to write code in a fashion that looks innocent but brings with it not-so-innocent consequences, then hopefully I know how to tell when someone else is doing the same thing.

    5. Re:Can someone explain this to me? by l2718 · · Score: 5, Insightful

      This problem arises whenever you need to use software for an application that must be secure. One famous case of tampering was by the CIA; control software for a Soviet oil pipeline purchased in the West was modified to fail upon a remote command causing a massive explosion.

      One hypothetical scenario: Diebold decide to act on their CEO's promise to deliver the election to the Republican party by making a small modification to their voting machines. If they can use the techniques this contest is looking for they would write the code so that it would escape even scrutiny by an outside agency (say, the government).

      In general, the idea of the contest is to showcase ways of breaking security and therefore perhaps ways to overcome them.

    6. Re:Can someone explain this to me? by Anonymous+Brave+Guy · · Score: 3, Insightful
      I understand about making source code available helps in a secure system, but what if that code has evil code...made to look innocent upon inspection....written into it?

      The "many eyes" theory can only work in practice if there are indeed many eyes reviewing the source code and those eyes can see any problems. That doesn't just mean accidental bugs, or portability/future-proofing concerns, or a poor choice of data structures and algorithms leading to a performance hit. It also means spotting the devious and subtle attacks.

      Just imagine what would happen if a major OSS project like Apache or Linux accepted a "useful" patch that contained a backdoor that wasn't identified, and this then got distributed worldwide. A significant number of people believe, erroneously, that using OSS inherently makes them safer because of the many eyes theory. These people will happily download and build the updated code, or install prebuilt binaries with correct checksums, completely oblivious to the fact that they just stuck a major security hole in their system.

      Thus it's important for those who review submissions to software development projects - OSS, commercial or otherwise - to be very aware of these possibilities, and likewise for anyone else who contributes to them so they can spot a problem if they come across it.

      --
      If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
    7. Re:Can someone explain this to me? by adyus · · Score: 5, Funny

      Um, I think your signature should be number three:
      1. It teaches you not to take all code at face value, and actually read into it.
      2. It's fun.
      3. It's like sex, except I'm having it!

      :)
    8. Re:Can someone explain this to me? by Guignol · · Score: 5, Funny

      Yes, for instance we could say it is malicious if it wouldn't halt

    9. Re:Can someone explain this to me? by bitt3n · · Score: 3, Funny

      It's like a wet t-shirt contest, allowing you to show off your rack in a controlled environment. Except in this case it's the metaphorical rack nerds develop from years of programming prowess, and not the actual rack they develop from scarfing down doritos and Mountain Dew during the same interval.

    10. Re:Can someone explain this to me? by hughk · · Score: 2, Insightful
      Actually that pipeline case is probably disinformation.

      The Trans-Sib pipeline control system was developed by a UK company. It used MC6800s and was written in assembler. The stuff was so unstable anyway due to the hand coded networking that deliberate interference would hve been picked up during the shake down (the code was continually being rewritten and EPROMs reblown).

      --
      See my journal, I write things there
    11. Re:Can someone explain this to me? by kimvette · · Score: 4, Funny

      Perhaps this "contest" is sponsored behind the scenes by Sony, in their search for more stealtht rootkit implementation methodologies in their next Anti-Fair-Use software release. They're counting on some smartass or two submitting really clever malicious code, I just know they are!

      This has been the crackpot conspiracy theory of the day.

      (Why yes, I'm bored! Why do you ask?)

      --
      The Christian Right is Neither (Christian nor right). See: Matthew 23, Matthew 25, Ezekiel 16:48-50
  3. I know... by scolby · · Score: 5, Funny

    ...I'll design a media player that appears to be playing a CD when it's actually installing a root kit that creates an easy way back door for malware.

    And then I'll get sued by Sony for copyright infringement.

  4. Weird and has very little to do with C by Ihlosi · · Score: 3, Interesting

    I really liked last years task but this years, um ...

    It depends way too much on things like the compiler being used, the optimization level, the actual hardware (how do they compare program run-time if the two OSes in question run on very different CPUs ?), and so on, than on actual C.

  5. Any code by Anonymous Coward · · Score: 2, Insightful

    Any code that includes a patented idea could win this contest.

    Looks innocent, is malicious.

  6. Re:I'll submit the source code for... by Lumpy · · Score: 2, Funny

    Windows!

    Oh darn, it's not written in C.


    Hey Windows XP and Vista are great examples of how powerful and fast VB.NET is!

    You cant write as robust of a Operating system in Python or Ruby!

    --
    Do not look at laser with remaining good eye.
  7. Potential for malice? by MT628496 · · Score: 2, Interesting

    Isn't it likely that encouraging people to design programs in this way would lead to companies using these techniques in their own software? Say someone has a contract with Microsoft, the linux version, while being fully functional, could be made to be slower. Then someone would go and demonstrate how poor linux performanace is yadda yadda

    1. Re:Potential for malice? by plover · · Score: 2, Informative
      That's probably part of the point of the contest -- to point out that malicious code such as they're suggesting already exists in the world.

      Saying that this "helps the bad guys" (not that you did) misses the point. We know there are bad guys out there. This becomes an awareness campaign.

      There are several documented cases of stuff like this happening. Both ATI and nVidia (the graphics card companies) added code to their drivers to cheat -- take "shortcuts" when certain benchmark programs were running -- so the reported frame-rate looked great, while the resulting graphics quality silently fell. Detroit Diesel and six other companies were fined millions of dollars for tuning their engine management code to recognize the operating conditions that were specified in the emissions test -- some combination of RPM, time and load -- and adjusted the timing for minimal emissions and fuel consumption under only those conditions. The rest of the time they optimized for maximum power. It was discovered only when they failed to certify their engines in Europe, where the test conditions were different.

      Closer to open source, just a year or two ago an unknown person checked in a subtle change to the kernel source that would have granted root access in the case of a certain error condition. It was caught during a review.

      These are real-world hacks. Denial doesn't solve the problem. Only awareness can help smoke them out.

      --
      John
  8. Re:Fun idea, but... by Penguinoflight · · Score: 2, Interesting

    Yeah, but why pay when you can just get the HACKER to go to jail and be charged as a terrorist?

    --
    "And we have seen and do testify that the Father sent the Son to be the Savior of the World"
    1 John 4:14
  9. Lucid Programming? by frantzdb · · Score: 2, Interesting

    I see a lot of utility in a contest like this. As much fun as an obfuscated programming contest is, in a day and age when our critical infrastructure, including voting machines, are running on software, it is important that we be aware of just how difficult it to assure that code does what it should.

    A related contest I would like to see is a lucid programming contest. Given some small but insidiously tricky task, write a program in the language of your choice which solves the problem correctly and which is easy for someone else to understand. It would be interesting to discover which languages excel at this task and what sorts of patterns emerge when emphasis is placed on clarity.

  10. My entry! by radiumhahn · · Score: 4, Funny
    #include <stdio.h>

    main() {

    /* Rob a bank! */
    /* Steal Stuff! */
    printf("hello, world\n");
    /* Use Drugs! */
    /* Kill, Kill, Kill! */
    }

  11. My entry -- the world's last C bug by PeeAitchPee · · Score: 4, Funny

    An oldie but goodie . . .

    while (1)
    {
    status = GetRadarInfo();
    if (status = 1)
    LaunchMissiles();
    }
    1. Re:My entry -- the world's last C bug by CoughDropAddict · · Score: 3, Funny
      or:
      while(1)
      {
        status = GetRadarInfo();
        if(status == 1);
          LaunchMissles();
      }
    2. Re:My entry -- the world's last C bug by joe_bruin · · Score: 4, Insightful

      so if(status = 1) in his code is always true. In your code, not neccesarily. Hence, his is a bug. And funny.

      Look again. This time, look for any extra semi-colons that shouldn't be there. The responder's joke was an improvement on the original, and would not have been flagged by an optional compiler warning (at least in the case of gcc).

      if(status == 1);

  12. Re:I love this by Fizzl · · Score: 4, Interesting

    Heh, I've been ranting for years how I love C and C++ and how Java and pretty much all other higher level languages suck. I think they are ment just for crybabies who can't handle pointers and get confused while tying their shoelaces.
    I actually just thought that I'll whip something up for the contest. You know, first I'll just make the basic program and try to figure out how to sneak something in. It took me 10 minutes to realize that I have no fucking clue what I'm doing.

    "How do I read from stdin?"
    "How do I allocate without too much overhead for it?"
    "Wait, I really shouldn't be doing this in the main function. Perhaps I'll make a separate function. Now, hmm.. How do I define a function which takes a reference to an array of char pointers, and what else do I need to know to reallocate the array"
    "Oh right. It also needs to be separated by spaces too, not just newlines"
    "I wish there was a nice library function 'char *readfile(stream)' in ANSI C"
    "Shit. Real programming is hard!"

    I hereby turn in my coding gloves, and don the pink fluffy Java gloves I have actually worn for some time against my will.

  13. Re:Any C code is potentially malicious by BlueScreenOfTOM · · Score: 2, Insightful

    C# has pointers (unsafe blocks anyone?), and generally the OS protects against stupid pointer use in C by throwing the famous Segmentation Fault if you try to mess with something outside your memory boundaries. It gets dangerous when you start making system calls. Try allocating 100kb of Kernel memory in a while(1) loop. That'll fuck up the system real fast.

  14. Is this the sort of thing they're looking for? by Ashtead · · Score: 2, Interesting

    #include <stdio.h>

    main()
    {
      char stuf[80];

      while(1)
      {
        fputs("Enter something: ", stdout);
        fflush(stdout);
        gets(stuf);
        fputs("You have entered ", stdout);
        printf(stuf);
      }
    }

    silly (and looks innocent enough) but closer inspection will reveal nastyness...

    --
    SIGBUS @ NO-07.308
    1. Re:Is this the sort of thing they're looking for? by Otto · · Score: 3, Informative

      im not very good at programming. but apart from using fgets which gcc says is dangerous...what is the nastiness in question here?

      printf(stuf) is dangerous because "stuf" is being used as the format specifier to printf.

      Now, normally you use printf like this: printf("%s", stuf), which says to print the string contained in stuf to stdout. But with the printf(stuf) line, you can carefuly craft what is in stuf to make it execute arbitrary code. The key to doing this lies in the %n specifier.

      If you were to do printf("Ha!%n",&some_int), then not only would the word "Ha!" be printed to the screen, but the contents of some_int would get set to 3, since that's how many characters were printed and that's what %n is telling it to do.

      Now, say I pass in "%X" as stuf. My output will be a number. What number is that? Why, it's the return address of printf, because %X is really telling it to print the contents of the next address on the stack, and that address happens to be a return address (since we didn't pass in real arguments to printf). If I therefore carefully craft my string, I can not only overwrite that return addres using %n, but I can overwrite it with a pointer to a location which will be executed when printf returns by varying the length of my string. And I can easily vary the length of my string by doing some things like %.1234x in there, which will happily stick 1234 characters in my string easily and add 1234 to n.

      Once I know the return address, I can work out where my string buffer is actually being stored, and then I can include my exploit code in that string itself, and execute it right from there.

      Short version is that passing format specifier strings to printf as anything other than literals is dangerous unless you know exactly what the format specifier string really is.

      --
      - Give a man a fire and he's warm for a day, but set him on fire and he's warm for the rest of his life.
  15. Re:Any C code is potentially malicious by jchoyt · · Score: 3, Informative

    Er, Java has pointers. They are called references and you HAVE to use them every time you pass an object around - that includes any arrays, including arrays of primitives. It's just that in Java you don't have a choice on how to pass parameters to methods.

    --
    Sometimes the truth is arrived at by adding all the little lies together and deducting them from all that is known.
  16. So who wants to talk strategy? by patio11 · · Score: 3, Interesting
    Here's what I'm thinking: take a data structure which is well-understood, easy to implement, and boring as mud. Like, say, a hash-table with collisions resolved by linking. Everybody saw that back in sophomore CS right? And everybody knows with even a cursory inspection that a hash table offers constant-time performance on lookups and o(maximum size of table) time on reading out, right? Except when it doesn't. Malicious choice of data for feeding into a hash table can severely degrade performance, and we wouldn't want that, so we're going to be extraordinarily conscientious engineers and salt our hash function so that a malicious user can't cause our program to have worst-case performance.

    I think, with creative use of bad programming, you could corrupt either the salt or the calculation of the hash function in such a way as to guarantee that for a target OS the hash-table performance would degrade into worst-case. So if you took your borked hash table, and used it to implement an associative array, the fairly trivial read in stdin, increment fields in associative array, sort array in order code could be made to perform at average time complexity in non-targetted OSes and worst-case time complexity in your target OS. Assuming you pick an O(n log n) sort algorithm, if you manage to "accidentally" make each of those n's actually polynomial complexity (heck, n^2 even) the computer should essentially blow up on non-trivial data sets. Its late in the evening and I haven't thought through this very much, but one way would be to use utsname's sysname thing as part of your "random data" to make the salt. That sounds a little obvious though. Maybe there's some obscure function somewhere for getting dates or times or something that I can exploit format of the returned data to reveal the difference between OSes, as that would be a lot harder to detect ("oh, seeding a hash function with a date and some magic numbers, nothing wrong with that").

    Anybody got any ideas or corrections to share? Its been a while since I've taken data structures, and I've got essentially no ideas for obscure functions revealing system differences to exploit (C isn't my bag).

  17. Dangerous and suspicious looking by whitenaga · · Score: 4, Insightful

    Your code is dangerous, but it has to be exploited by a knowledgable user. I think what they're looking for in the Underhanded C Contest is code that exploits itself. But for the purpose of being pendantic, i'll bite... =)

    • You're using gets(), which is notorious for buffer overrun problems.
    • You mix fputs() and printf(), right next to each other. And you use printf() just like fputs(), and that looks suspicious.
    • printf(stuf); is practically asking for exploitation. If stuf contained the proper combination of "(filler) %junk %junk %n", printf()'s return address would be overwritten.
    --
    Lindsey
    @>-->-----
  18. Re:Any C code is potentially malicious by nuzak · · Score: 2, Insightful

    There's no requirement at all in the JVM that references are implemented as pointers.

    Pointers POINT to arbitrary memory locations. References do not. You cannot recast a reference to an arbitrary type, you can't put arbitrary data at a reference location, you cannot reseat a reference with a new instance, you cannot do pointer arithmetic with references.

    It happens that pointers can be like as references, among many other things. This does not make references into pointers.

    --
    Done with slashdot, done with nerds, getting a life.
  19. Re:Compiler says by Richy_T · · Score: 2, Funny

    #include "texan.h"

  20. Re:I love this by GWBasic · · Score: 2, Insightful
    I'm a real programmer who knows how to handle pointers in C. That's the language I cut my teeth on. The truth is that today high-level languages have significant advantages over C. (C is still great for squeezing ever last clock cycle out of a program.)

    Example 1: In my senior year of college, I took an AI class. The professor allowed us to do homework in C, LISP, or Java. My parter and I avoided LISP because we didn't see any benefit in learning it. We chose Java instead of C because we needed many features that are built into the language; using C would have doubled the time we spent coding and debugging. In the end, we recieved As on our assignments because they worked; the kids who were crazy enough to use C didn't get very far.

    Example 2: I currently work in C# and use a CPU-intense module written in C++. C# allows me to write code faster, but keeping the CPU-intense parts in C++ allows the project to still perform as fast as we need it to.

    To stay on-topic, such a contest would be more interesting if they chose a higher-level language. In C#, it's very easy to hide CPU-intensive operations in a single line of code. This is because one can have a property that goes and does something like a 10-second database query.

  21. Re:I love this by DavidHOzAu · · Score: 2, Informative
    "How do I read from stdin?"
    "How do I allocate without too much overhead for it?"
    "Wait, I really shouldn't be doing this in the main function. Perhaps I'll make a separate function."

    Easy.
    char* getaline(FILE* fp) {
      char buf[80];
      char* out;
      int len = 0;
      if (feof(fp)) { return NULL; }
      out = (char*)malloc(80);
      if (!out) { return NULL; }
      *out = 0;
      while (fscanf(fp, "%79[^\n]", buf) == 1) {
        strcat(out, buf);
        len += strlen(buf);
        if ((out = (char*)realloc(out, len+80)) == NULL) { return NULL; }
      }
      fscanf(fp, "%*c");
      return out;
    }

      "Now, hmm.. How do I define a function which takes a reference to an array of char pointers, and what else do I need to know to reallocate the array"
    "Oh right. It also needs to be separated by spaces too, not just newlines"
    "I wish there was a nice library function 'char *readfile(stream)' in ANSI C"

    Almost, but you're approaching it the wrong way. You get your reader function to do all the allocating.
    char** readfile(FILE* stream) {
      char** text;
      char* tmp;
      int line = 0;
      text = (char**)malloc(sizeof(char*));
      while(1) {
        if ((text[lines] = getaline(stream)) == NULL) {
          if (!lines) { free(text); return(NULL); }
          return text;
        }
        line++;
        if ((text = realloc(text, (line+1)*sizeof(char*)) == NULL) { return NULL; }
      }
    }


    Have fun!