[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)