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