Live data from Hacker News

The Linux Backdoor Attempt of 2003 (2013)

freedom-to-tinker.com

71–80 of 144 posts

Re: The Linux Backdoor Attempt of 2003 (2013)

#71

Earlier quoted context omitted.

Because of selection bias - if they had chosen something less subtle then we wouldn't be talking about it.

Maybe it is a smoke screen, put in something likely to be found and something that won't. Everyone pats themselves on the back for finding the obvious one...

Why not just include the thing that won't be found and call it a day?

Including a red herring to invite extra scrutiny doesn't seem wise if you're trying to hide something.

Re: The Linux Backdoor Attempt of 2003 (2013)

#72
post #47

A uid of 0 being root is just such a bad idea to begin with because 0 is a default value of so many data types. It’s an accident waiting to happen and, in this case, a good way to hide something malicious as an accident.

AFAIK only external and static variables are default initialized in C. For all other variables, the default value is undefined, so 0 is as good a choice as any other here.

There is also the issue that (at least on some platforms) ECC memory must be initialized before being read, or an exception will occur.

Re: The Linux Backdoor Attempt of 2003 (2013)

#73
post #59

Earlier quoted context omitted.

"(current_euid() is a macro but it's written to not be a permitted lvalue)" I'm not an expert at C. I followed up on this kernel macro out of curiosity, and it was a confusing learning experience because it turns out the forbidden assignment ({ x; }) = y; is silently permitted by GCC (for example, with -Wall --std={c99,c11,c18}), and does actually assign x=y. Even though that's expressly prohibited by the C standard…

Example #5984 of why I don't like the kernel's convention of masquerading macros as function by making them lowercase. I wasted so much time deciphering weird compile errors or strange behaviour only to finally realize that one of the function calls in the offending code was actually a macro in disguise. It's especially bad when some kernel macros, such as wait_event, don't even behave like a function would (evaluati…

The best one is "current" -- which is a macro that looks like a variable but becomes a function call and thus if you ever want to use the variable name "current" you will get build errors. :D

Re: The Linux Backdoor Attempt of 2003 (2013)

#74
This is an obvious backdoor attempt, as the code doesn't make sense otherwise. Yet, the attempt was far too unsubtle and underspecific for agencies such as the NSA. The payoff was low compared to the possibilities - local privilege escalations were a dime-a-dozen.

Worse, agencies such as the NSA have two missions: offence and defence. Adding in backdoors helps the offensive mission, but hurts the defensive mission, so it only makes sense if the backdoor isn't so easy to find. An obvious backdoor hurts the US far more than it helps the US. This one was too obvious.

Some ideas:

1) A script kiddie found some way to break-in and edit CVS. The entire idea being to have something to brag about. This was caught too early to be brag-worthy (breaking ancient CVS isn't something to brag about).

2) It was a warning shot from some Western agency meaning "tighten up your security".

Re: The Linux Backdoor Attempt of 2003 (2013)

#76
post #50

Earlier quoted context omitted.

I think you are not copying the terminating nul character.

Unless the first character was null, in which case it would be ignored by the condition... Also, you don't need to dereference a pointer in order to increase it. The grandparent post's code is just nonsensical.

haha, I was genuinely asking if it made sense, I don't usually do C. Maybe it helped illustrate that the code is too clever for me, at least.

e: I submit my revised code:

    do {
       *dst = *src;
       src++;
       dst++;
    } while(*(dst - 1));

Re: The Linux Backdoor Attempt of 2003 (2013)

#77
post #25

Earlier quoted context omitted.

These days it'd be harder to write code which is "easy to overlook" -- the innocent version would be something like if (/* ... */ || current_euid() == GLOBAL_ROOT_KUID) But the "backdoor" version would fail to compile (current_euid() is a macro but it's written to not be a permitted lvalue). You would need to write something more obvious like the following (and kernel devs would go "huh?" upon seeing the usage of cur…

"(current_euid() is a macro but it's written to not be a permitted lvalue)" I'm not an expert at C. I followed up on this kernel macro out of curiosity, and it was a confusing learning experience because it turns out the forbidden assignment ({ x; }) = y; is silently permitted by GCC (for example, with -Wall --std={c99,c11,c18}), and does actually assign x=y. Even though that's expressly prohibited by the C standard…

The C standard cannot expressly prohibit anything about a feature that isn't part of the C standard.

Re: The Linux Backdoor Attempt of 2003 (2013)

#78
post #74

This is an obvious backdoor attempt, as the code doesn't make sense otherwise. Yet, the attempt was far too unsubtle and underspecific for agencies such as the NSA. The payoff was low compared to the possibilities - local privilege escalations were a dime-a-dozen. Worse, agencies such as the NSA have two missions: offence and defence. Adding in backdoors helps the offensive mission, but hurts the defensive mission, s…

> 2) It was a warning shot from some Western agency meaning "tighten up your security".

That's an interesting theory that'd certainly make for a powerful message. Has anything like that been done before or is there any precedence for Western agencies to do these sorts of things covertly?

Re: The Linux Backdoor Attempt of 2003 (2013)

#79
post #74

This is an obvious backdoor attempt, as the code doesn't make sense otherwise. Yet, the attempt was far too unsubtle and underspecific for agencies such as the NSA. The payoff was low compared to the possibilities - local privilege escalations were a dime-a-dozen. Worse, agencies such as the NSA have two missions: offence and defence. Adding in backdoors helps the offensive mission, but hurts the defensive mission, s…

If memory serves me right the CVS bug was originally discovered and exploited by a member of an infamous file sharing site. After descriptions(?) of that bug were leaked in underground circles, an east European hacker wrote up his own exploit for it. This second exploit was eventually traded for hatorihanzo.c, a kernel exploit, which was also a 0-day at the time.

The recipient of the hatorihanzo.c then tried to backdoor the kernel after first owning the CVS server and subsequently getting root on it.

The hatorihanzo exploit was left on the kernel.org server, but encrypted with an (at the time) popular ELF encrypting tool. Ironically the author of that same tool was on the forensic team and managed to crack the password, which turned out to be a really lame throwaway password.

And that's the story of how two fine 0-days were killed in the blink of an eye.

Re: The Linux Backdoor Attempt of 2003 (2013)

#80

I admit that I read the code and completely overlooked the single equals sign. Makes me wonder why it would be so easy to change the userid. Shouldn’t there be some safeguards in place to stop the userid from being updated from unsafe places.

Absolutely. This is an example of the poor design of the C language. Other languages that were around at the time C was created choose `:=` as assignment and `=` for equality tests, making this type of typo quite impossible.

Common Lisp makes the Hamming distance even larger; equality tests are written as `(eq foo bar)`, while changing a value is `(setf foo bar)`. Common Lisp may have features which are undesirable in an OS kernel (garbage collection), but it does make the code wonderfully clear and easy to read.

Post reply on HN