[HN Gopher] The Linux backdoor attempt of 2003 (2013)
       ___________________________________________________________________
        
       The Linux backdoor attempt of 2003 (2013)
        
       Author : zhan_eg
       Score  : 148 points
       Date   : 2023-12-29 14:42 UTC (8 hours ago)
        
 (HTM) web link (freedom-to-tinker.com)
 (TXT) w3m dump (freedom-to-tinker.com)
        
       | zhan_eg wrote:
       | Previous discussions - [1] [2]
       | 
       | [1] https://news.ycombinator.com/item?id=24106213
       | 
       | [2] https://news.ycombinator.com/item?id=18173173
        
         | dang wrote:
         | Thanks! Macroexpanded:
         | 
         |  _The Linux Backdoor Attempt of 2003 (2013)_ -
         | https://news.ycombinator.com/item?id=24106213 - Aug 2020 (141
         | comments)
         | 
         |  _The Linux Backdoor Attempt of 2003_ -
         | https://news.ycombinator.com/item?id=18173173 - Oct 2018 (28
         | comments)
         | 
         |  _The Linux Backdoor Attempt of 2003_ -
         | https://news.ycombinator.com/item?id=6520678 - Oct 2013 (63
         | comments)
        
       | grugq wrote:
       | I have the full story on that incident. It is actually really
       | funny.
       | 
       | If the guy who did it wants to come forward, that is his
       | decision. [edit: I won't name names.]
       | 
       | He did provided me the full story. He told me with the
       | understanding that the story would go public, so I will dig it up
       | and post it.
       | 
       | I also interviewed the sysadmins who were running the box at the
       | time.
       | 
       | 1. it was not an NSA operation, it was done by a hacker.
       | 
       | 2. it was discovered by accident, not because of clever due
       | diligence.
       | 
       | Basically, there was a developer who had a flakey connection and
       | one time his commits didn't go through. To detect this in future
       | he had a script that would download the entire tree from the
       | server and compare it against his local copy to make sure that
       | his changes had been committed.
       | 
       | It was discovered because of the discrepancy between his local
       | working copy and the upstream copy. Which was checked not for
       | security reasons, but because sometimes the two were out of sync.
       | That's all. Just dumb luck.
       | 
       | The sysadmins are still quite bitter about it. I know how it
       | feels when your box is hacked and you really take it personally.
       | 
       | The code wasn't added by hacking the CVS, as far as I remember,
       | but rather through a hacked developer with commit rights.
       | 
       | that's the story as I was told
        
         | causal wrote:
         | Wait was the guy you know the hacker or someone who discovered
         | the hack by accident? If the latter, how do you know anything
         | about the hacker's identity or motive?
        
           | ngneer wrote:
           | That confused me, too. They appear to know the person who
           | accidentally discovered the issue, not the hacker.
        
             | jstanley wrote:
             | How do they know it wasn't the NSA then?
        
               | _notreallyme_ wrote:
               | The guy who did it was quite vocal about it in some
               | circles. It was a "for the lulz" kind of hack...
        
             | netsharc wrote:
             | Developer tries to tell a story...
             | 
             | Sounds like OP interviewed the person who uploaded the
             | code, whose system was previously inflitrated (it can still
             | be the NSA). So why say "If the guy who did it wants to
             | come forward, that is his decision. But he did provide me
             | the full story", it doesn't sound like OP interviewed the
             | "guy who did it"...
        
               | AnimalMuppet wrote:
               | I read that the other way. "If the guy who did it wants
               | to come forward, that is his decision. But he [still
               | talking about the guy who did it] did provide me the full
               | story."
               | 
               | That is, the perpetrator gave him the full story, but he
               | won't name names, because it's the perpetrator's choice
               | whether or not to reveal his identity.
        
               | netsharc wrote:
               | OK, makes sense.. so the interviewed hacker mentioned
               | that he got the code in by infiltrating the computer of
               | "some developer"...
        
               | grugq wrote:
               | he was more specific, but I (a) don't remember the name
               | off the top of my head, and (b) don't think it is
               | beneficial to put them on blast. It isn't their fault
               | they got hacked 20 years ago.
        
           | grugq wrote:
           | the hacker. I interviewed the sysadmins about it.
        
           | greggsy wrote:
           | It's the grugq.. he knows everything and everyone
        
         | ajross wrote:
         | To be clear: you're telling us the full story of the discovery,
         | not the full story of the exploit? You and your source don't
         | know who the attacker was, right?
        
           | grugq wrote:
           | What is there to say about the hack? Like everything back
           | then it was probably accomplished by exploiting trust
           | relationships. I can ask him, but it is not at interesting 20
           | years later.
        
             | spenczar5 wrote:
             | It is _very_ interesting to prove whether or not it was a
             | state actor! Surely you can see that that mystery is
             | interesting to many people.
        
             | _notreallyme_ wrote:
             | > Like everything back then it was probably accomplished by
             | exploiting trust relationships
             | 
             | That's wrong on many levels. Bold and stupid "hacks"
             | committed by teenagers using SE tend to get a lot of
             | traction, because it is both bold and stupid. This hasn't
             | changed. But "back then" there was much more than that...
        
             | ShamelessC wrote:
             | > What is there to say about the hack?
             | 
             | What is there to say about the [discovery]? Like everything
             | back then it was probably accomplished by [a simple source
             | code diff]...it is not at interesting 20 years later.
             | 
             | You get the idea. The story you know might be interesting
             | to you because you happen to know the person involved. And
             | it is sort of interesting? But not really as interesting as
             | the _full_ story would be. In particular because your
             | grammar in your original comment kind of implies you knew
             | the actual attacker.
             | 
             | This all seems fairly obvious to me? Is there anything
             | we're missing about the discovery? It's pretty mundane that
             | one of hundreds of devs working on that source code
             | happened to have a vanilla copy, especially in 2003 with a
             | less reliable and slower internet.
        
         | mathverse wrote:
         | Did not cliph / wojciech purczynski also try to backdoor the
         | kernel?
        
         | hulitu wrote:
         | > 1. it was not an NSA operation, it was done by a hacker.
         | 
         | Just like the NPR is not financed by the US government, but by
         | NGOs.
        
       | agilob wrote:
       | This is a single example of an unsuccessful attempt to backdoor
       | Linux. There were successful attempts too
       | https://www.bleepingcomputer.com/news/security/nsa-linked-bv...
        
         | grugq wrote:
         | Am I missing something? That seems to link to a Linux backdoor,
         | not a backdoor in Linux.
        
           | deelowe wrote:
           | Yeah. This doesn't appear to be the same sort of thing
           | (malicious code being integrated into the kernel itself).
           | This is just a backdoor that leverages an exploit.
        
       | ngneer wrote:
       | We used to use this as a cautionary tale in the CS department
       | security course at the Technion. First, to highlight trust
       | relationships in the "supply chain" (as the notion is now known
       | in contemporary usage). Second, to pose the question of whether
       | open source is inherently more trustworthy.
        
         | laweijfmvo wrote:
         | I guess you could argue that more [evil] people would try to
         | backdoor the linux kernel than there are [malicious] people
         | inside private companies, but the level of trust inside a
         | private company is probably much higher? Seems complex
        
           | ngneer wrote:
           | You hit the nail on the head. It is a complex question
           | without a straightforward answer.
        
       | ijustlovemath wrote:
       | Another bit of cleverness not mentioned in the article is that
       | assignment expressions always evaluate to the rvalue. So the
       | expression `current->uid = 0` has the effect of making sure that
       | entire conditional never actually runs (or at least, the return
       | never runs), which means the overall behavior of wait4 doesn't
       | change in an observable way. Very clever if you're trying to pass
       | all of the existing tests
        
         | AnimalMuppet wrote:
         | Ohh, that is clever - unless someone writes a test for these
         | two new lines, and finds that they never return -EINVAL.
        
           | TheJoeMan wrote:
           | Maybe the unit tests should test that the variables you
           | intend to "not touch" do not in fact change. So record UID
           | before and after the function. When I'm writing critical code
           | like this, one gets a tingly feeling when typing in that
           | variable name.
        
         | GuB-42 wrote:
         | But that should be something the compiler could catch. The
         | expression is always false and the condition would never be
         | executed. You usually get a warning for that. And if the
         | compiler doesn't, linters do.
         | 
         | This is a common mistake, and I believe most linters have rules
         | for that. And I don't think there is any situation where there
         | is a good reason for code like this to exist. Either the
         | expression is wrong, or it doesn't belong in a "if". You may
         | get stuff like that in legitimate code with macro expansion,
         | but again, it is not the case here, and from my experience, you
         | get a warning anyways.
        
           | _notreallyme_ wrote:
           | You didn't get a warning for that in 2003... or maybe with
           | the pedantic flag. And even if it were the case, it would
           | have been drowned by all the other unfixed warnings...
           | 
           | The only people using linters at that time was because it was
           | forced by regulation (like automotive, aeronautics, ...)
        
           | lelanthran wrote:
           | > But that should be something the compiler could catch.
           | 
           | Today, certainly. My compiler even catches errors in the
           | format strings to printf[1].
           | 
           | But back then? I doubt it, even with all the warnings turned
           | up.
           | 
           | [1] Removing yet another common source of bugs.
        
           | diath wrote:
           | The compiler does not, but tools like clang-tidy do,
           | (bugprone-assignment-in-if-condition in clang-tidy) but that
           | didn't exist back then.
        
       | aftbit wrote:
       | While I'm here, does anyone know of a good trustworthy RAT for
       | Windows machines that I can control from my Linux box? I have
       | some relatives for whom I provide technical support. I'd love to
       | just put an EXE on their desktop that would launch a VNC session
       | and connect back to me (since they have the typical NAT +
       | firewall of home users), but I don't want to install a virus on
       | their machines.
        
         | ngneer wrote:
         | Not sure what your decision procedure is for "a virus" versus
         | "trustworthy RAT", but there are plenty of open source options
         | out there, in case that helps, https://medevel.com/18-os-rat-
         | list/
        
         | popcalc wrote:
         | Anydesk?
        
         | olivierduval wrote:
         | AFAIK, solutions like TeamViewer or AnyDesk may be securely
         | connected from the outside and manage the NAT+firewall of home
         | user... no need to have a RAT (in the "virus/backdoor" meaning)
        
         | genpfault wrote:
         | Tor + ssh onion service?
        
         | avidiax wrote:
         | Put Tailscale on their machines and use a normal remote desktop
         | application (probably the built-in RDP). Or put a RaspberryPi
         | with Tailscale on their network.
         | 
         | Just make sure you set the key for those clients to not expire.
        
       | mmsc wrote:
       | Wasn't this done by Ac1dB1tch3z? See
       | http://phrack.org/issues/64/15.html for the CVS exploit from the
       | same time.
        
         | mathverse wrote:
         | Nice find. Maybe sd?
        
       | robblbobbl wrote:
       | I'm pretty sure there are tons on unreleased and unpublished
       | backdoor exploits for linux and windows likewise. The problem is
       | you can't fix them yourself if the signature keeps unknown to
       | anyone.
        
         | cwillu wrote:
         | "Backdoor" means something deliberately and specifically added
         | to enable the vulnerability. I.e., something can't really be
         | both a backdoor and an exploit.
        
           | hn_go_brrrrr wrote:
           | Really? I think of a backdoor as a deliberate vulnerability,
           | and the exploit as the attack (or attack code) that makes use
           | of any kind of vulnerability.
           | 
           | Let's say the NSA adds a backdoor. If someone else finds it,
           | isn't that an exploit?
        
       | IshKebab wrote:
       | I think the risk from this type of attack is probably near zero.
       | You can't hack into Github and add a commit to Linux.
       | 
       | Probably most of the deliberate backdoors that are present in
       | Linux have been inserted by well funded state sponsored
       | developers performing useful work. Easy to sneak a vulnerability
       | in that way. (There was a controversial incident a few years ago
       | when some researchers proved as much.)
        
         | LMYahooTFY wrote:
         | Link to the incident you're referring to?
        
           | richbell wrote:
           | If I had to guess it's this, but it seems like the
           | researcher's claims didnt stand up to scrutiny.
           | 
           | https://old.reddit.com/r/HobbyDrama/comments/nku6bt/kernel_d.
           | ..
        
       | charonn0 wrote:
       | > it said "= 0" rather than "== 0"
       | 
       | Why do so many programming languages have different
       | equals/assigns operators?
       | 
       | There are languages that combine them and apparently don't have
       | any problems. Is it something to do with being strongly vs.
       | weakly typed?
        
         | nurettin wrote:
         | It's just syntax. Pascal had := and =
        
         | klodolph wrote:
         | I don't think strong/weak typing is the culprit here.
         | 
         | I think partly that being explicit is nice. Assignment and
         | equality are two very different things, so it makes sense for
         | there to be different syntax. You can easily prevent the code
         | in the article from working--just disallow assignment inside of
         | expressions. This is probably a good idea, and a lot of newer
         | languages make that choice.
         | 
         | Even when you read papers about programming, you often see
         | different notation for assignment and equality. Assignment may
         | be <- or := or something, and equality will just be =, to match
         | the mathematical notation. I see a lot of <- in manuals for
         | processors & architectures. I would hate to see something like
         | this in my code base:                   a = x = y;
         | 
         | If that meant "set 'a' to true if 'x' is equal to 'y', and
         | false otherwise." I would, honestly, be a little pissed off.
         | 
         | I would only accept something like that if it meant
         | (a==x)&&(x==y).
        
           | JadeNB wrote:
           | > I would hate to see something like this in my code base:
           | 
           | > a = x = y;
           | 
           | > If that meant "set 'a' to true if 'x' is equal to 'y', and
           | false otherwise." I would, honestly, be a little pissed off.
           | 
           | Would you find it more acceptable as `a = (x = y)`? To me,
           | that is reasonably clear.
        
             | klodolph wrote:
             | > Would you find it more acceptable as `a = (x = y)`? To
             | me, that is reasonably clear.
             | 
             | No, I don't consider that acceptable. It is not enough that
             | it is clear to some people who know what they are looking
             | at. The language should be more clear to more people.
        
         | vidarh wrote:
         | Some to make them more distinct. Some because they treat
         | assignment as an expression, and so either can occur in the
         | same context.
         | 
         | In the former you _could_ combine them. In the latter you _can
         | 't_ (you need to be able to tell if "if (a = b) ..." contains a
         | comparison or assignment).
         | 
         | (EDIT: I agree with the sibling reply from klodolph there -
         | there are many cases where reusing the same operator would get
         | _really_ confusing, and so I 'd prefer the operators to be
         | distinct even if the language do not allow them in the same
         | context)
        
           | charonn0 wrote:
           | It's been my impression over the years that = vs. == is one
           | of the most common mistakes made in languages that use them.
           | In which case, can it really be said to be less confusing?
        
             | layer8 wrote:
             | Modern languages using that syntax tend to prevent that
             | mistake by either outright disallowing assignments in
             | boolean contexts, or by not having implicit conversion of
             | other types to boolean, meaning that the mistake would be
             | limited to the case of comparing a boolean variable to
             | another value, which is quite rare. Some languages further
             | limit the risk by making variables unmodifiable by default,
             | meaning that it would have to be an explicitly modifiable
             | boolean variable.
             | 
             | Assignment is one of the most frequent operations in
             | typical programming languages, so it makes sense for it to
             | be a single-character symbol, and '=' is about the only
             | fitting ASCII symbol for that. (With non-ASCII, there would
             | be '[?]' or '-' (the latter being used by APL), but those
             | are non-obvious to type.)
        
             | vidarh wrote:
             | There are two orthogonal issues here:
             | 
             | 1) Do you allow assignment as an expression?
             | 
             | 2) Do you use the same operator?
             | 
             | If you answer "yes" to #1, you must answer no to #2, but if
             | you answer no to #1 you can choose whether or not you use
             | the same operator. Consider these examples (assuming that
             | if they're different, we use =/==, but of course any other
             | set of operators could be substituted):                   #
             | A) if 'yes' to 1 this would be a "double assignment",
             | setting both a and b to c.         a = b = c              #
             | B) if 'no' to 1, and 'yes' to 2, this would be an
             | assignment of the comparison of b and c to a:         a = b
             | = c              # C) if 'no' to 1 and 'no' to 2, this
             | would be an assignment of the comparison of b and c to a:
             | a = b == c              # D) if 'no' to 1 and 'no' to 2,
             | this would most likely be a syntax error:         a = b = c
             | 
             | With respect to confusion, I'd argue that B) creates a lot
             | of potential for confusion. You'd want "a = b = c" to
             | _either_ be  "double assignment" (A) _or_ a syntax error
             | (D). If your language does not allow assignments as
             | expressions, I 'd go for C/D _exactly_ for the reason you
             | give, as the main reason not to allow assignments as
             | expressions tends to be exactly to avoid the mistake you
             | mention (it 's _trivial_ to support in a compiler
             | /interpreter, so it's a question of whether you believe
             | it's more helpful or more damaging)
        
         | layer8 wrote:
         | The C designers wanted to be able to write stuff like `while
         | ((ch = getchar()) != EOF) { ... }`, so assignment needed to be
         | an expression. Secondly, C had no boolean type, and instead
         | integers were used for boolean values (zero is false, nonzero
         | is true). The combination of these two facts entails that an
         | integer assignment is also a valid boolean expression.
         | 
         | To prevent accidental or malicious use of the assignment
         | operator in place of the equals operator in a language, you
         | either have to have a real boolean type, and no implicit
         | conversion of other types to boolean, or make assignments not
         | be an expression, or disallow assignment expressions in boolean
         | contexts.
         | 
         | Making both operators the same symbol is not a good solution
         | IMO, because it makes it harder to distinguish which is which
         | in arbitrary contexts. E.g. in `a = b = c`, presumably the
         | first is an assignment and the second a comparison? Or maybe
         | not? It would just be confusing. Not sure which languages you
         | are referring to that do this.
        
           | akira2501 wrote:
           | > or make assignments not be an expression,
           | 
           | Or just reverse the expression:                   0 ==
           | curent->uid
           | 
           | So that the bug case is an error:                   0 =
           | current->uid
        
             | layer8 wrote:
             | Yes, that is well known, but it doesn't prevent the issue
             | in TFA.
        
           | krylon wrote:
           | A common idiom to defang this was the "Yoda assignment":
           | if (0 == do_something(foo)) { ... }
           | 
           | If one accidentally omits one equals-sign, it makes the
           | compiler barf instead of becoming a silent-but-deadly kind of
           | bug (whether intentional or not).
           | 
           | In Go, an assignment is not an expression, so the whole thing
           | becomes illegal. I found this approach a bit offensive at
           | first, but I got used to it rather quickly.
        
       | a-dub wrote:
       | it still seems kinda weird to me that all it takes to elevate
       | privileges for a user process to "can arbitrarily write system
       | level memory or disk" is just the clearing of all the bits of a
       | single integer in kernel space which can be done by pretty much
       | any execution path in the kernel.
       | 
       | it just seems like there could be a more tamper resistant
       | mechanism around privilege elevations.
        
       ___________________________________________________________________
       (page generated 2023-12-29 23:00 UTC)