Live data from Hacker News

Xz/liblzma: Bash-stage Obfuscation Explained

gynvael.coldwind.pl

31–40 of 137 posts

Re: Xz/liblzma: Bash-stage Obfuscation Explained

#31
post #17

How on earth did any of this make it through a code review and get merged in? It seems absurdly careless, unless I am missing something.

the bad actor was a co-maintainer of the repo (and even more active than the original maintainer for quite some time) with full commit rights. This was strait committed to master, no PR and no review required. edit: also this was heavily obfuscated in some binary files that were marked as test files ("good" and "bad" xz compressed test file). No way to spot this if you don't know what you're looking for.

This is the problem of projects that allow direct access and lack code review.

Re: Xz/liblzma: Bash-stage Obfuscation Explained

#32
post #17

Earlier quoted context omitted.

the bad actor was a co-maintainer of the repo (and even more active than the original maintainer for quite some time) with full commit rights. This was strait committed to master, no PR and no review required. edit: also this was heavily obfuscated in some binary files that were marked as test files ("good" and "bad" xz compressed test file). No way to spot this if you don't know what you're looking for.

In addition… if your build system has things like this as OK: > xz -dc $top_srcdir/tests/files/$p | eval $i | LC_ALL=C sed "s/\(.\)/\1\n/g" | LC_ALL=C awk 'BEGIN{FS="\n";RS="\n";ORS="";m=256;for(i=0;i You should probably expect the potential for abuse? We’re moving towards complexity that is outpacing human ability for any one person to understand, explain, and thus check an entire object. And for what? Build efficie…

To be clear: the build system did not use the code fragment you quoted. This complex awk code is a later stage of the backdoor.

Re: Xz/liblzma: Bash-stage Obfuscation Explained

#33
post #27

Earlier quoted context omitted.

In addition… if your build system has things like this as OK: > xz -dc $top_srcdir/tests/files/$p | eval $i | LC_ALL=C sed "s/\(.\)/\1\n/g" | LC_ALL=C awk 'BEGIN{FS="\n";RS="\n";ORS="";m=256;for(i=0;i You should probably expect the potential for abuse? We’re moving towards complexity that is outpacing human ability for any one person to understand, explain, and thus check an entire object. And for what? Build efficie…

I’m not sure why you’d say that we’re “moving towards” this sort of build system complexity. This is 1990s autoconf bs that has not yet been excised from the Linux ecosystem. Every modern build system, even the really obtuse ones, are less insane than autoconf. And the original purpose of this was not for efficiency, but to support a huge variety of target OSes/distros/architectures, most of which are no longer used…

This is not part of autotools output. This is part of the backdoor. Not arguing about autotools drawbacks though.

Re: Xz/liblzma: Bash-stage Obfuscation Explained

#34
The whole XZ drama reminds me of this[1], in another words, verify the identity of open source maintainer/s and question their motive for joining the open source project. Also reminded me of the relevant XKCD meme[2].

Speaking of obfuscation; I'm not a programmer but I did some research in Windows malware RE and what stuck with me is that every code that is obfuscated or every code that is unused is automatically suspicious. There is no purpose for obfuscated code in the open source non-profit software project and there is no purpose for extra code that is unused. Extra/redundant code is most likely junk code meant to confuse the reverse engineer when s/he is debugging the binary.

[1] https://lwn.net/Articles/846272/ [2] https://xkcd.com/2347/

Re: Xz/liblzma: Bash-stage Obfuscation Explained

#35

Never allow complexity in code or so-called engineers who ask to merge tons of shitty code. Get rid of that shit and don't trust committers blindly. Anyone who enables this crap is also a liability.

You do realize that "that shit" was part of the obfuscated and xz-compressed backdoor hidden as binary test file, right? It was never committed in plain sight. You can go to https://git.tukaani.org/xz.git and look at the commits yourself – while the commits of the attacker are not prime examples of "good commits", they don't have glaringly obvious red flags either. This backdoor was very sophisticated and well-hidden, so your comment misses the point completely.

Re: Xz/liblzma: Bash-stage Obfuscation Explained

#36

How are the binary files passed to those stage-0 commands?

The macro defined in build_to_host.m4 is probably called on the tests subdirectory, so it gets these files as a parameter.

EDIT: It is called here and will do the extraction of the backdoor when run in the 'tests' subdirectory:

https://salsa.debian.org/debian/xz-utils/-/blob/debian/unsta...

EDIT2: So it will get the directory as a parameter, the actual file is encoded indirectly here:

https://salsa.debian.org/debian/xz-utils/-/blob/debian/unsta...

This grep will only match bad-3-corrupt_lzma2.xz

Re: Xz/liblzma: Bash-stage Obfuscation Explained

#37

How on earth did any of this make it through a code review and get merged in? It seems absurdly careless, unless I am missing something.

The commit messages for the test files claim they used an RNG to generate them. The guy making the release tarball then put the final line in the right place without checking it in.

What is the reason distros are still building from release tarballs rather than a git checkout that can be verified against a public git repo?

Re: Xz/liblzma: Bash-stage Obfuscation Explained

#38

Earlier quoted context omitted.

OMG that's evil. The diff just shows: + +. + and the dot goes unnoticed

I wonder why they didn't use a non-breaking space or similar. I guess it's possible a nbsp would stand out even more.

They could have just misspelt one of the constants. Even less obvious and more deniable.

There's multiple things like this in this backdoor that seems like they've been super sneaky (using a compile check to disable Landlock is genius) but then half-assed the last step.

Re: Xz/liblzma: Bash-stage Obfuscation Explained

#39
post #17

How on earth did any of this make it through a code review and get merged in? It seems absurdly careless, unless I am missing something.

the bad actor was a co-maintainer of the repo (and even more active than the original maintainer for quite some time) with full commit rights. This was strait committed to master, no PR and no review required. edit: also this was heavily obfuscated in some binary files that were marked as test files ("good" and "bad" xz compressed test file). No way to spot this if you don't know what you're looking for.

> No way to spot this if you don't know what you're looking for.

I would expect most people to at least ask for more clarification on random changes to `head` offsets, honestly - or any other diff there.

If they had access to just merge whatever with no oversight, I guess the blame is more on people using this in other projects without vetting their basic security of projects they fully, implicitly trust, though. As bad as pulling in "left-pad" in your password hashing lib at that point.

The "random binaries in the repo" part is also egregious, but more understandable. Still not something that should have gotten past another pair of eyes, IMHO.

Re: Xz/liblzma: Bash-stage Obfuscation Explained

#40
post #20

Earlier quoted context omitted.

That's for 2 reasons: 1. It might not be there in the place where you're looking. It exists in the m4 in the release tarballs, not in the git repo. 2. It's highly obfuscated.

m4 is somewhat obfuscated by default, that's a part of the problem IMO

Looks pretty much like bash to me. Which means... yeah.
Post reply on HN