Presentation on theme: "Countering Trusting Trust with Diverse Double-Compiling (by David A Wheeler) Dan Frohlich."— Presentation transcript:
Countering Trusting Trust with Diverse Double-Compiling (by David A Wheeler) Dan Frohlich
Trusting Trust “…compilers can be subverted to insert malicious Trojan horses into critical software, including themselves.” –Thompson “Reflection on Trusting Trust”
What does Trusting Trust do? The attack uses 2 triggers: 1 to subvert system access and 1 to propagate the attack when re-compiled
Features of Trusting Trust Attack. Trigger –A condition determined by an attacker in which a malicious event is to occur Payload –The code that performs the malicious event –The inserted code and the code that causes the insertions Non-Discovery –Binary files are non-transparent. Therefore the attack is difficult to identify.
The threat of Trusting Trust. An attacker who subverted a few of the most widely-used operating systems could effectively control, directly or indirectly almost every computer in existence. –This could be aggravated by a monoculture in computing platforms. Wheeler claims that many persons in the community believe that the risk of these kinds of attacks are increasing.
Detecting the Trusting Trust Attack is problematic. Security evaluations examine source code under the assumption that it accurately represents the product being examined. But, an attacker who can control the compiler binary can render source code evaluations worthless. For source code security evaluations to be strongly credible, there needs to be a way to justify that the source code being examined accurately represents the files being executed.
Diverse Double-Compiling (defined.) In DDC, if the final result is bit-for-bit identical to the original compiler binary, then the compiler source code accurately represents the binary. –c(sA, A) == c(sA, c(sA, T )) c(s,X) is the result of compiling s with X. sA is the untrusted compiler source A is the untrusted compiler T is the trusted compiler
c(sA, A) == c(sA, c(sA, T ))
Inadequate solutions to Trusting Trust defense Manually compare binary to source Compare binary to source by an automated process Use second compiler –test semantic equivalence of the two binaries. Only receive source –compile everything yourself Interpreted languages –Simply changes the target of attack.
Why not compare the binary to the source? Manual comparison is impractical due to resource requirements. Automated comparison is difficult due to optimizing compilers. –Doesn’t DDC suffer from the very same issues?
Use a trusted compiler. Use second compiler and compare binaries. –Testing the semantic equivalence of the two binaries is very difficult. Only receive source / compile yourself –fails when receivers compiler is already malicious. But this only fails if receiver compiler T has a trigger on A. –Doesn’t DDC have the same issue if T has a trigger on A?
These approaches require the defender to insert themselves into the compiler creation process (to recompile it themselves before using it. This is often impractical. –But with DDC I have to compile it twice then debug it, then compare the binaries for equivalence. How is this an improvement? The problems with the other solutions to Trusting Trust
It can be completely automated. –After debugging each compiler involved. Doesn’t require proofs –Doesn’t guarantee the attack will be found either. Reveals defects in the compilers involved. –A beneficial side effect, but not why I’m doing this. Can be expanded to cover all software running on a system. Why use DDC to detect Trusting trust?
Is there any value to discovering this attack as opposed to blindly destroying it with the trusted compiler alternative? Questions?