Become a fan of Slashdot on Facebook

 



Forgot your password?
typodupeerror
×

The 2006 Underhanded C Contest Begins 232

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."
This discussion has been archived. No new comments can be posted.

The 2006 Underhanded C Contest Begins

Comments Filter:
  • Re:I Win (Score:2, Informative)

    by Kjella ( 173770 ) on Wednesday April 05, 2006 @09:47AM (#15065814) Homepage
    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 æøå?).
  • by scmason ( 574559 ) on Wednesday April 05, 2006 @11:09AM (#15066629) Homepage
    Uhm, yeah, you missed the joke.
  • by plover ( 150551 ) * on Wednesday April 05, 2006 @11:10AM (#15066647) Homepage Journal
    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 [extremetech.com] -- 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 [highbeam.com] 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.

  • by jchoyt ( 729301 ) on Wednesday April 05, 2006 @12:16PM (#15067487) Homepage
    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.
  • by Otto ( 17870 ) on Wednesday April 05, 2006 @04:05PM (#15070045) Homepage Journal
    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.
  • Re:I love this (Score:2, Informative)

    by DavidHOzAu ( 925585 ) on Thursday April 06, 2006 @03:17AM (#15074033)
    "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!

Intel CPUs are not defective, they just act that way. -- Henry Spencer

Working...