back to article Winning Underhand C Contest code silently tricks nuke inspectors

The winner of an annual competition to write the best innocent-looking but actually malicious C code has been announced – and it involves hoodwinking nuclear weapons inspectors. Hypothetically, of course. On Wednesday, the Underhand C Contest named Linus Åkesson the champion of its 2015 fixture. His prize: $1,000 (£685). …

  1. Destroy All Monsters Silver badge
    Windows

    Nice coding, but I think "dismantling" means "show me the plutonium in the form of MOX fuel rods" or something like that, doesn't it? So this trikcery ain't gonna work.

    1. Anonymous Coward
      Anonymous Coward

      As I read it, the point is that you can make several fake fuel rods with the plutonium from one, so as to appear to have dismantled several times as many warheads as you really did.

      1. Gotno iShit Wantno iShit

        The scenario is irrelevant.

        The point is to get people thinking about devious code. Something that in other circumstances would be called a bug but here is deliberately coded to game the system and be subtle enough to not be seen in a code inspection.

        This is exactly what any number of TLAs must (and should, it's their job) be up to and it is good to see a different kind of spotlight on it. It's exactly the sort of thinking the Open Truecrypt Audit needs to engage.

        1. allthecoolshortnamesweretaken

          Re: The scenario is irrelevant.

          Yes and no. As it's a purely intellectual exercise, sure, what the hell. But if someone presents a "real life example" to me, it should qualify as one. Otherwise I'm just annoyed, and thus distracted from the actual topic of the exercise.

          In this case: a conventional warhead isn't supposed to contain fissionable material at all, so if the Geiger counter sings, shred it. (The warhead, not the Geiger counter.)

          Having got that off my chest: Very clever coding indeed.

          1. Ken Hagan Gold badge

            Re: The scenario is irrelevant.

            "In this case: a conventional warhead isn't supposed to contain fissionable material at all, so if the Geiger counter sings, shred it."

            Then you've missed the point about how the false positives let you keep back some of your real warheads, untested. The scenario didn't seem that contrived. In fact, the most implausible part was the bit where no-one thought to run static analysis tools over the source code (many of which would pick up conflicting definitions like this without any trouble).

            1. ZSn

              Re: The scenario is irrelevant.

              Considering the large number of real-life programs where static analysis tools obviously were *not* run, I think that you're being optimistic there.

    2. Anonymous Coward
      Anonymous Coward

      Totally suspicious news item...

      Public is being prepared for nasty things coming up in the near future.

      1. Anonymous Coward
        Anonymous Coward

        Re: Totally suspicious news item...

        Suppose all your nukes use supergrade plutonium. There will be nary detectable radiation outside, so you can pretend these are all conventional warheads in any case...

  2. Michael H.F. Wilkinson Silver badge

    Reminds me of a single coding error (or horror) that caused trouble when switching from 32 to 64 bit machines on code initially written by two students. The interpretation of "long" and "int" was the same on the 32 bit machines, but differed on 64 bit machines. Storing an array of longs in an int array gave, let's say, "interesting" results. Not underhand, of course, just stupid (and easily fixed once found).

    1. Anonymous Coward
      Anonymous Coward

      In the 1960s floating point arithmetic differed between different computer types - so the same program source could produce different results.

      A program's precision was affected by different numbers of bits - or the rounding - in iterative calculations.

      Partly it was the difference in the number of bits in a "word" - but also in the algorithm used to do the instructions. IIRC KDF9 had 48/96 bit single/double values - which made them very useful for some scientific calculations. The split between the number of bits assigned to the exponent and mantissa was a less obvious factor.

      Obviously the order in which the parts of a calculation were done could also affect the final result - and that is still true even with a standardised floating point instruction set.

    2. bpfh
      Mushroom

      The first Ariane 5 shot

      Mixed 16 and 32 (or was it 32 and 64) bit values, and the rocket had to be destroyed a couple of seconds off the pad after the navigation systems overflowed...

      Explosion...well because bang...

  3. Mike 125

    horses for courses

    It's a great entry, because the code itself is so benign. The problem would never be spotted through inspection. Tools would maybe spot the #include discrepancy, but it's doubtful. And anyway, build systems often hides differences such as which particular #include gets #included.

    It's also a great example of why, in the real world, anyone found using C for such a 'correct-critical', 'non-time/size critical' application should be instantly fired. In the real world, loose typing has its place. This isn't it!

    1. Tom 7

      Re: horses for courses

      Having seen type-safe languages with optimising overrides added cause rockets to explode a few hundred feed from the launch pad I'd say - once again - that blaming it on the language is completely wrong.

      Something of this seriousness require belts, braces and a seriously well hardened bolt through the navel.

      The software engineering wrapped around the code should ensure this shit cant happen. You dont blame the bricky who makes a wall of substandard bricks - its the dick-head that didnt make sure they were up to standard that needs a case of manslaughter against them.

      1. Anonymous Coward
        Anonymous Coward

        Re: horses for courses

        "[...] languages with optimising overrides [...]"

        Once had a 'C' program misbehaving after it was optimised.

        The optimiser had found several functions with apparently identical code - so reduced them all to one block of code. The problem was that the program was expecting the name of each function to be a self-identifying unique entry point. So every time it did a comparison between the functions' names (viz entry addresses) it always matched on the first one.

        The optimiser should have produced a single block of code for the body of the function - but with unique code for each entry point.

        1. Tom 7

          Re: horses for courses "[...] languages with optimising overrides [...]"

          Shit optimizers need checking too - simple unit tests should pick that up. Its the whole development environment that needs to work - including the Fuckwits Up Top who claim all the glory and none of the shit. The number of places I've worked where some FUT has got a bonus for implementing a time saving shortcut that has added years to the project and then got another bonus for removing the shortcut and everything has started progressing again.

        2. Anonymous Coward
          Anonymous Coward

          The optimiser should have produced a single block of code

          No it shouldn't - it's job is to optimise within the constraints permitted by the C Standard.

          The code writer should have been taught that any unspecified or undefined behaviour specified in the C Standard can result in code behaving in an unexpected way.

          Many of the "bugs" people report against compilers are related to them falling down these holes...

      2. Mike 125

        Re: horses for courses

        @Tim7

        >>type-safe languages with optimising overrides

        If that's a thing, it's a nonsense thing if 'optimising overrides' overrides type-safety. The program fails on exactly this attribute. In any case, in such an application, there's no need for extreme optimisation, (unless I'm missing something). It's a data analysis tool, in no particular hurry.

        >>blaming it on the language is completely wrong.

        Indeed. I'm glad we agree. C's a great language - mine of choice.

        >>Something of this seriousness require belts, braces and a seriously well >>hardened bolt through the navel.

        Absolutely. And more to the point, it's not system code. It is without constraints on runtime or code-size.

        >>the dick-head that didn’t make sure they were up to standard that needs a >>case of manslaughter against them.

        Other than for this competition, only a dick-head would write such a critical application in C. (OK, it may well be a dick-head manager insisting.)

        When there's a critical safety requirement and no platform or performance constraints, C is not appropriate. Hence the firing.

    2. Dan 55 Silver badge

      Re: horses for courses

      I've been tripped up by wrong type sizes too many times, I think I would have caught it. If someone's redefining standard types (or anything else in the standard include files) then there's probably something wrong somewhere else and they're hammering a nail with a hammer held by the wrong end.

    3. Anonymous Coward
      Anonymous Coward

      Re: horses for courses

      Any decent static analysis tool would spot this, especially if it's being used to apply a language subset such as MISRA C.

      This is one of the many traps that 'C' sets for programmers that are easy to fall into (on a big / multi-organisation project) but which are also very easy to detect when tools are used, even when a set of targeted guidelines is not being enforced.

    4. Detective Emil
      Headmaster

      Re: horses for courses

      C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off. Stroustrup (See link for his scholarly gloss.)

  4. jake Silver badge

    And then there is TheRealWorld[tm].

    EOF

    1. Alistair
      Windows

      Re: And then there is TheRealWorld[tm].

      @jake

      "End of line......"

      FTFY.

      <I'm dealing with a package called mCP today>

      1. jake Silver badge

        Re: And then there is TheRealWorld[tm].

        No. I typoed EOF, and I meant EOF.

        -1

  5. John Smith 19 Gold badge
    Unhappy

    Simple, yet subtle.

    Very neat

    And pretty worrying.

  6. Nifty Silver badge

    Next... a contest for the most innocent looking snippet of code/script/VB that can be posted on a forum as a 'solution' to someone's question, that in fact plants a virus.

    1. Anonymous Coward
      Anonymous Coward

      Back in the days of usenet someone would often post attachments which were just a .bat file to erase the DOS root directory.

      1. Anonymous Coward
        Anonymous Coward

        RE: Back in the days of usenet

        Back in the day Usenet didn't support attachments, and the average user wouldn't have been running DOS anyway.

        1. jake Silver badge

          Re: RE: Back in the days of usenet

          Actually, back in the day Usenet DID support attachments (of a sort). See "UUE", which was born on UUCP, a year or so before Usenet existed.

          Kids these days ... they think they invented everything.

          Hey, you! Get off my lawn!

    2. Frumious Bandersnatch

      "most innocent looking snippet of code that in fact plants a virus"

      Well, it's not a virus, but a fork bomb is generally very short. You could obfuscate it by writing the loop condition so that it looks like it's supposed to just run once if there's no error, but is actually designed to always loop infinitely (like the third example in the recent article here).

      It's hard to disguise all bits of a virus since you need to include file I/O and that's going to look suspicious in many bits of code. Still, there are some things you could try...

      1. companion viruses

      It seems that these are still possible. Make a hidden .COM file corresponding to an existing .EXE or whatever. The .COM is executed when both extensions are present. Alternatively, get the user to set %PATHEXT (tell them it's needed for your program to work due to filename conflicts)

      2. Unicode

      If the compiler accepts Unicode characters, use the fact that some characters look the same even though they're different code points. Put an innocuous version of a routine in an obvious place at the top of a file and hide the malicious version (that's actually called) somewhere more out of the way.

      3. Deliberately smash the stack

      If the program looks like it should legitimately be using XOR on strings (like in a random number generator, encryption routine or similar) then introduce a bug that overwrites the call stack and executes a bit of machine code that's already embedded in the code (in obfuscated form, requiring the xor to decrypt it).

      4. Other

      It's a lot easier to introduce deliberate bugs that can be exploited later (by specially-crafted input) than it is to hide a complex program inside another.

    3. Pirate Dave Silver badge
      Pirate

      " contest for the most innocent looking snippet of code/script/VB that can be posted on a forum as a 'solution' to someone's question, that in fact plants a virus."

      You mean something like...

      Get-WUInstall -KBArticle KB3012973 -AcceptAll

      ;)

    4. Adam 1

      Does a PDF with embedded fonts count?

  7. BurnT'offering

    the best innocent-looking but actually malicious C code

    No entries from Microsoft?

    1. allthecoolshortnamesweretaken

      Re: the best innocent-looking but actually malicious C code

      I don't think the rules allow to enter an entire OS in the competition.

  8. Primus Secundus Tertius

    Look at the real code

    I had to sort out various problems by looking at the output of the C preprocessor, to see the real code after the macros were deciphered.

    However, the raw output contained an excessive amount of spaces and blank lines, and had to be edited and pretty-printed.

    As others above have noted, code inspection must include some degree of machine verification. Like, does it actually compile, without warnings?

    1. Anonymous Coward
      Anonymous Coward

      Re: Look at the real code

      Yep, abuse / overuse / unnecessary use of the preprocessor can make it impossible to understand what's going on.

      I've seen a whole real-time OS and a set of tasks kicked off as the result of a single macro expansion within main :-(

  9. Phil Endecott

    Any entries from employees of VW ?

    1. raving angry loony

      VW?

      Pretty sure that code would be considered proprietary. And evidence.

      1. Gordon 11

        Re: VW?

        Pretty sure that code would be considered proprietary.

        Perhaps the winning entry was also "proprietary", in that someone else is currently using it?

        Not that they'd ever sue for copyright...

  10. Jay Zelos

    ....the Peoples Glorious Democratic Republic of Alice and the Glorious Democratic Peoples Republic of Bob...

    Really the test should have been set in Python rather than C.

  11. JeffyPoooh
    Pint

    The power of backspace

    If one can pack the source code with backspaces, typically by using an obscure placeholder character and then running a find&replace script to replace the placeholders with ^h, then one can completely separate the apparent source code (which is actually just trailing comment text), from the actual source code (cleverly hidden 'beneath' the backspaces).

    Here's a trivial example written in BASIC where 'ĥ' is used to represent the ^h backspaces that have been packed into the code by a trivial script.

    10 PRINT "YES!!"; REM ĥĥĥĥĥĥĥĥĥĥĥĥĥ"NO!!"

    LIST

    10 PRINT "NO!!"

    RUN

    YES!!

    With this trick, one can do almost anything. The source code can be whatever you want, because it's just commenting, while the actual code is hidden by the backspaces.

    I came up with this evil trick around 1980 or so. A nice example was making LIST appear to do RUN, and make RUN appear to do LIST. Mysterious math errors were fun. Almost no limit.

    (I know other languages, but I chose to use BASIC for this example. Forgive me.)

    This will probably work with any language that allows trailing comments on a line.

    1. Dale 3
      Coat

      Re: The power of backspace

      Upvote, simply because it's 2016 and you're posting BASIC code. Which is fun.

      1. JeffyPoooh
        Pint

        Re: The power of backspace

        I could do COBOL. Or FORTRAN (yes, the all-uppercase era).

        Problem is that the backspace trick doesn't work as well with punch cards.

    2. Wilseus

      Re: The power of backspace

      Agreed, tricks like that would work on a BBC Micro or Electron, except that I think it would have actually printed:

      10 PRINT "NO!!"": REM ĥĥĥĥĥĥĥĥĥĥĥĥĥ

      You could also insert a control code that disabled text output, then another that re-enabled it further on, completely hiding sections of your program.

      1. el_oscuro

        Re: The power of backspace

        There is a really gnarly Unicode in Windows, U+202E RIGHT TO LEFT OVERRIDE. Reverses everything after it like a Möbius strip. Even fucks with your cursor keys.

  12. JeffyPoooh
    Pint

    Re: The power of backspace

    The LIST command should display this:

    10 PRINT "YES!!"; REM , followed by (in this example) 13 backspaces.

    Resulting in this:

    10 PRINT , then resume with "NO!!"

    The end result is displayed like this:

    10 PRINT "NO!!"

    YMMV, but I'm not sure why it would if it meets our one fundamental assumption.

    Find&Replace 'Script' vice one-line in-line snippet:

    I'm now recalling that I might have had a BASIC code snippet, perhaps starting at (for example) line 1000, which did the searching through memory (in the right area) to find the placeholders and replace them with ^h (using PEEK and POKE). So the previously mention script was probably as simple as RUN 1000. And then delete the snippet, and SAVE the resultant magic code.

    Knowing myself, the snippet would have been just one line of code.

POST COMMENT House rules

Not a member of The Register? Create a new account here.

  • Enter your comment

  • Add an icon

Anonymous cowards cannot choose their icon