Winning Underhand C Contest code silently tricks nuke inspectors
Top evil source looks simple and innocent but is actually a warmonger's dream
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.
Entrants had to write a function that compared two sets of data and returned a 1 if the values matched within a given threshold, or 0 if they are too unlike. The data in question: one set is an array of readings from a device scanning warheads for fissile material, such as plutonium; the other set is an array of readings you'd expect from a real nuclear warhead. Here's the background:
Two countries, the Peoples Glorious Democratic Republic of Alice and the Glorious Democratic Peoples Republic of Bob, have agreed to a nuclear disarmament treaty. In practice, this is implemented by nuclear inspectors visiting each country and verifying the presence of fissile material such as Plutonium in a warhead, at which point the warhead can be destroyed.
Ideally, the inspectors would subject a warhead to a scan and observe a graph such as a radiogram or a gamma ray spectrum of the object under test, so that they can confirm the warhead contains what it is supposed to contain. But both the PGDRA and the GDPRB are dissatisfied with this approach because the results of these scans contain sensitive information about their nuclear programs and the design of their nuclear weapons. However, each country wants to ensure that the other country is dismantling real nuclear warheads, and not fakes.
To this end, the two countries agree to build a fissile material detector with an “information barrier” – essentially a computer program that will take the result of a scan, determine if it matches some reference pattern, and output only a “yes” or “no.”
So far, so good. You've got to write an algorithm that can turn an external scan of a warhead into a yes (1) or no (0) output: yes, this is a real nuke because it matches the signature of a nuclear warhead; or no, this is a normal warhead because it doesn't match the signature.
The underhand part: rig the algorithm so that it fires off false positives in certain circumstances, thus earmarking warheads for destruction even if they are not nukes. The code should return 1 when it should really return 0. It can't be an obviously bad detector, though; throwing lots of non-matching data at the function should return 0 as expected. The reference signature also cannot be changed.
What's the point? Well, imagine you're a country with 1,000 nuclear bombs and 100,000 normal warheads, and you've agreed to dismantle 950 of your nukes. You don't really want to do that, so you present, say, 50 nukes and 900 normal warheads for inspection. Thanks to the nobbled match algorithm, all are flagged up as containing sufficient fissile material and are destroyed. Everyone thinks you've disarmed 950 nuclear warheads, when really you've only rid yourself of 50.
Some entrants to the 2015 competition relied on the environment of the program: for example, if the computer's clock can be secretly wound back during the test of a weapon, it will trigger a false positive. This requires a little too much tampering for the judges' liking.
Åkesson's winning code works by exploiting the fact that on 64-bit x86 and 32-bit ARM systems, a float variable is four bytes in size and a double is eight bytes. In one source file, a header is included that overrides float_t as an eight-byte double, and in another source file, float_t is left as a four-byte float defined by the standard math.h header file.
This means the match function defined in one source file takes data as an array of eight-byte double-precision floating-point numbers, and passes them to a function defined in the other source file that expects an array of four-byte single-precision floating-point numbers due to the mischievous float_t typecasting.
The result is the data is interpreted all wrong. Really, only the first half of the input data is scanned, and each eight-byte floating-point number is read as two four-byte numbers.
Ultimately, it means a country can present a warhead with a very, very small amount of fissile material inside it along with another harmless compound that triggers the required false positive for a given reference signature.
The competition this time round had more than 40 entrants, and was sponsored by the Nuclear Threat Initiative. The contest was supposed to be "a real-world problem in nuclear verification," according to the organizers. "We hope that [this year's challenge] emphasizes the need for care and rigor, not to mention new research, in secure software development for such applications," the judges added. No kidding. ®