[HN Gopher] How to Build an Evil Compiler
___________________________________________________________________
How to Build an Evil Compiler
Author : kiyanwang
Score : 43 points
Date : 2022-04-17 16:36 UTC (1 days ago)
(HTM) web link (www.awelm.com)
(TXT) w3m dump (www.awelm.com)
| more_corn wrote:
| I'd be interested to hear if anyone has found an evil compiler in
| the wild.
| yccs27 wrote:
| Doesn't XcodeGhost (mentioned in the first paragraph) qualify
| as an evil compiler?
| josephcsible wrote:
| I don't think so. "Evil compiler" here doesn't just mean a
| compiler that's malicious; it specifically means a compiler
| that, if asked to compile a clean compiler, will instead
| compile another copy of itself. And I don't think XcodeGhost
| did that.
| awelm wrote:
| Here's one on Quora. This story actually inspired me to write
| this blog post:
|
| https://www.quora.com/What-is-a-coders-worst-nightmare/answe...
| PennRobotics wrote:
| https://news.ycombinator.com/item?id=31033294
| Tomte wrote:
| Three points, no comments.
|
| Why would you link that?
| kibwen wrote:
| _> Also DDC can't even be applied to newer languages like Rust
| with only one compiler._
|
| This is mistaken, as there exists a second Rust "compiler" known
| as mrustc (written in C++). I put "compiler" in quotes, as it
| doesn't implement all of Rust's static analysis, so it's more
| like an alternative code generator. That said, it still suffices
| to build the compiler itself (it was originally devised as a
| rustc bootstrapping tool), and it has been used in the past to
| successfully perform DDC.
| [deleted]
| jcranmer wrote:
| The Thompson attack sounds scary, but it's not a real practical
| concern.
|
| Look, as this article demonstrates, it's not hard to build a
| backdooring compiler. Even if you want to build it in a more
| robust way than checking filenames, it's really not difficult:
| it's (admittedly complex) pattern matching, and quite a lot of
| optimization in fact boils down to pattern matching. The problem
| is that the pattern matching you'd need to do to get the
| everything-is-backdoored scary effect is _brittle as fuck_.
|
| Compiler output tends to be effectively nondeterministic. I mean,
| the goal of the compiler is to produce completely deterministic
| input, but very subtle changes can have cascading consequences.
| (I say this as I am trying to fix a test for LLVM's opaque
| pointer changes). Even something so simple as figuring out how to
| make bit-equivalent reproducible builds with the reproducible
| builds initiative took a few years to really get going, since
| there are so many things that are effectively random that you
| wouldn't consider at first (e.g., iterate over all files in a
| directory).
| hackthesystem wrote:
| It's possible to make a compiler backdoor that is "updatable"
| and therefore a lot less brittle. And yes this does make the
| backdoor easier to detect since it's now communicating over the
| network. But such flexibility could really future-proof the
| backdoor and let it evolve over time as the target language
| changes.
| deckarep wrote:
| Is it just me...or does article seem a bit contrived? I was
| expecting to read this to learn about a really powerful hijacking
| technique when in reality it's just a program that manipulates
| your input program.
|
| This is something that could easily occur with scripting
| languages, backend systems, open source, closed source, etc.
|
| Basically any black-box system that takes in some input could
| pre-manipulate the input yielding an unknown/unexpected output.
| josephcsible wrote:
| The key point is that if your system has an evil compiler,
| building your own compiler from known-good source code will
| just give you another evil compiler, no matter how many times
| you do it. It creates a bootstrapping problem for the victim
| that doesn't have easy solutions.
| cpill wrote:
| > 2. Modify LoginWithBackdoor.cpp to also accept the password
| "backdoor" by doing a find-and-replace that modifies the if-
| condition checking the password
|
| Yeah, how is this going to generalise to _any_ program that gets
| compiled without introducing bugs in the executable? If you can
| write a backdoor that can accept _any_ program and compormise its
| integrity you can solve the haulting problem, can't you?
|
| So this only works if the bad compiler has access to the source
| code that its compiling before hand and a _hand crafted_ hack is
| made for it. With opensource projects like the Linux kernal i can
| see this is a problem but for everyone else, meh.
| hackthesystem wrote:
| Who said it has to "generalize"? No virus generalizes to hack
| every program. That doesn't mean viruses aren't dangerous.
|
| Also OSS makes up most of the modern stack, so access to source
| code is a given. And hand-crafting a backdoor when you have the
| source code is trivial because you can literally change
| anything you want with confidence.
| prettyStandard wrote:
| Not going to read the whole article because I should be doing
| work, but...
|
| The Ken Thompson hack is not undefeatable. You can detect it
| using a cross compilation technique comparing the binary output
| with a clean complier. I think you have to about 4 compilations
| to figure out if you're infected, but then you don't know which
| one is infected and which one isn't. You will need more data
| points to compare. Disassembling the binary would help as well if
| you know what you are looking for.
| henning wrote:
| How do you know the other compiler is "clean"? That just begs
| the question. Also, different compilers could produce
| different, equally valid instructions, such as debug vs.
| release builds.
|
| There are malware analysts who are good at finding
| sophisticated malware in binaries. They could probably locate
| suspicious code that could be obfuscated malicious code.
|
| Other than that, if you can't trust any of the compiler vendors
| (which makes things like checksums on an HTTPS website
| useless), you'll have to write your own. What about the
| firmware of the machine you're writing your clean code on?
| Taking this argument to its logical conclusion makes the idea
| of developing even simple software astronomically expensive.
| trinovantes wrote:
| This is why I think some things in life should not be
| digitized e.g. electronic voting.
|
| Nobody can realistically know if all of the components from
| hardware to software is clean. And the more technical you
| are, the more you realize how many attack surfaces there are.
| It's impossible to verify everything and you just have to
| blindly trust that it's all safe.
| willis936 wrote:
| I can see a high tech future where the only work left for
| humans is voting and auditing.
| prettyStandard wrote:
| Your not wrong, but that's why I mentioned reviewing the
| assembly. You cross compile to detect the issue, inspect to
| confirm the issue.
|
| This is my primary issue with closed source software, binary
| blobs, etc; trust.
| cortesoft wrote:
| What are you using to inspect the assembly? Something
| compiled!
| idkwhojamesis wrote:
| Finally found the link after remembering that I read about this
| somewhere:
|
| "David A. Wheeler's Page on Fully Countering Trusting Trust
| through Diverse Double-Compiling (DDC) - Countering Trojan
| Horse attacks on Compilers"
|
| https://dwheeler.com/trusting-trust/
___________________________________________________________________
(page generated 2022-04-18 23:01 UTC)