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.
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). …
COMMENTS
-
-
-
Thursday 4th February 2016 11:32 GMT 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.
-
Thursday 4th February 2016 15:10 GMT 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.
-
Thursday 4th February 2016 16:36 GMT Ken Hagan
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).
-
-
-
-
-
Thursday 4th February 2016 09:30 GMT Michael H.F. Wilkinson
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).
-
Thursday 4th February 2016 10:57 GMT 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.
-
-
Thursday 4th February 2016 09:42 GMT 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!
-
Thursday 4th February 2016 10:00 GMT 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.
-
Thursday 4th February 2016 11:09 GMT 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.
-
Thursday 4th February 2016 11:26 GMT 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.
-
Thursday 4th February 2016 14:23 GMT 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...
-
-
Thursday 4th February 2016 21:29 GMT 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.
-
-
Thursday 4th February 2016 10:35 GMT Dan 55
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.
-
Thursday 4th February 2016 10:37 GMT 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.
-
Thursday 4th February 2016 11:32 GMT Detective Emil
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.)
-
-
-
Thursday 4th February 2016 17:11 GMT 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.
-
-
Thursday 4th February 2016 15:34 GMT 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?
-
Friday 5th February 2016 00:03 GMT JeffyPoooh
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.
-
Friday 5th February 2016 14:11 GMT 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.
-
Friday 5th February 2016 22:44 GMT JeffyPoooh
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.