2024-04-16 23:00:40

by Solar Designer

[permalink] [raw]
Subject: Re: [oss-security] backdoor in upstream xz/liblzma leading to ssh server compromise

Hi,

This is an update on some developments in the recent 2 weeks.

OpenSSH
=======

For upstream OpenSSH, Damien Miller and others have implemented systemd
notifications without reliance on libsystemd:

Bug 2641 - Add systemd notify code to to track running server
https://bugzilla.mindrot.org/show_bug.cgi?id=2641

"Committed as 08f579231cd38 and will be in OpenSSH-9.8, due around
June/July."

In response to Andres Freund's proposal, Damien also implemented a patch
to reduce OpenSSH's attack surface:

Bug 3675 - CASignatureAlgorithms should be verified before verifying signatures
https://bugzilla.mindrot.org/show_bug.cgi?id=3675

not yet committed?

systemd
=======

Upstream systemd's libsystemd has been modified to dlopen() many of its
dependency libraries on demand:

Reduce dependencies of libsystemd #32028
https://github.com/systemd/systemd/issues/32028

The issue above is fixed by pull requests "gcrypt: dlopenify for
libsystemd #32019", "Dynamically load compression libraries #31550",
"man: document that using sd_journal APIs might cause dlopen to happen
and add self-contained notify protocol example #32030", and other
related fix-ups.

xz backdoor analysis
====================

More findings were made about the backdoor's functionality, notably as
published on April 6 by blasty, who discovered that besides triggering
system() the backdoor also allows interactive sessions:

https://twitter.com/bl4sty/status/1776691497506623562

> the xz sshd backdoor rabbithole goes quite a bit deeper. I was just able
> to trigger some harder to reach functionality of the backdoor. there's
> still more to explore.. 1/n
> Image
> it requires sending a properly crafted command to the RSA_public_decrypt
> hook, which will then install another for the `mm_answer_keyallowed`
> sshd function. subsequently you offer N more fake ssh-rsa pubkeys which
> are crafted in a special way to chunk together .. 2/n
> a "magic buffer" which contains more backdoor commands, this buffer also
> has two additional ed448 signatures. which like the ones for the
> RSA_public_decrypt portion of the backdoor are salted with the SHA256
> digest of the hostkey
> the final signature also takes into account the session_id (0x20 bytes)
> that is derived during the initial key exchange (KEX) for the SSH
> session. my current PoC implementation uses a heavily monkey patched
> paramiko (ssh client) library to achieve this
> currently I'm just triggering command 0x03 in this part of the code,
> which allows for a basic RCE through system() again. (also lets you set
> uid/gid). but there's more code that needs to be understood. it looks
> like a full auth bypass (interactive session) is possible!
> (that conclusion is based on the fact that one of the
> mm_answer_keyallowed backdoor commands also hooks mm_answer_keyverify,
> eventually)
> whoever designed this stuff had to take a deep dive into openSSH(d)
> internals (and so did I for the past couple of days, oof) .. hats off,
> once again :)
> auth bypass confirmed!
>
> > INFO:paramiko.transport:Authentication (password) successful!
>
> mm_keyallowed_backdoor cmd 1 allows to override the response for
> mm_answer_authpassword with a custom one. if you set it to { u32(9),
> u8(13), u32(1), u32(0) } you can login with any pass

blasty also implemented a "simple SSH Agent that implements some of the
XZ sshd backdoor functionality":

https://github.com/blasty/JiaTansSSHAgent

On Sun, Mar 31, 2024 at 10:25:02PM +0200, Solar Designer wrote:
> There's further analysis of the binary payload here:
>
> https://gist.github.com/smx-smx/a6112d54777845d389bd7126d6e9f504
>
> I've attached the gist .md file above (as of "Revisions 52") to this
> message, but it's ongoing analysis as seen in the comments.

Updates of smx-smx's gist above have stopped at revision 60, which I'm
attaching here for archival. Not a lot was added since revision 52.

smx-smx also maintains xzre "that is linked against the malicious object
file in order to instrument and call into the malware code, particularly
the x64 disassembler":

https://github.com/smx-smx/xzre

and yes, there's a specialized disassembler inside the backdoor code.

The friends at Binarly have produced a later but very detailed analysis,
which I'm also attaching the main .md file of:

https://github.com/binarly-io/binary-risk-intelligence/tree/master/xz-backdoor

Other related repos with tools include:

xzbot "notes, honeypot, and exploit demo for the xz backdoor (CVE-2024-3094)"
https://github.com/amlweems/xzbot

xz-min "Minimal setup to trigger the xz backdoor"
https://github.com/felipec/xz-min

Timeline
========

In an otherwise inappropriate rejected posting, Steffen Nurpmeso wrote:

> Russ Cox had a writeup on this https://research.swtch.com/xz-timeline

which is a good presentation of the attack timeline, with references to
sources and analyses by others.

(The beginning of this oss-security thread until April 1st inclusive
went through in its entirety - nothing rejected - but I did reject a few
postings on April 2nd and on.)

OpenJS Foundation "Failed Credible Takeover Attempt"
====================================================

On April 15, the OpenJS and OpenSSF foundations released the following:

https://openjsf.org/blog/openssf-openjs-alert-social-engineering-takeovers
https://openssf.org/blog/2024/04/15/open-source-security-openssf-and-openjs-foundations-issue-alert-for-social-engineering-takeovers-of-open-source-projects/

I'll quote an excerpt:

> The OpenJS Foundation Cross Project Council received a suspicious series
> of emails with similar messages, bearing different names and overlapping
> GitHub-associated emails. These emails implored OpenJS to take action to
> update one of its popular JavaScript projects to "address any critical
> vulnerabilities," yet cited no specifics. The email author(s) wanted
> OpenJS to designate them as a new maintainer of the project despite
> having little prior involvement. This approach bears strong resemblance
> to the manner in which "Jia Tan" positioned themselves in the XZ/liblzma
> backdoor.
>
> None of these individuals have been given privileged access to the
> OpenJS-hosted project. The project has security policies in place,
> including those outlined by the Foundation's security working group.
>
> The OpenJS team also recognized a similar suspicious pattern in two
> other popular JavaScript projects not hosted by its Foundation, and
> immediately flagged the potential security concerns to respective OpenJS
> leaders, and the Cybersecurity and Infrastructure Security Agency (CISA)
> within the United States Department of Homeland Security (DHS).

Alexander


Attachments:
(No filename) (6.69 kB)
smx-smx-xz-backdoor_analysis.md (14.83 kB)
binarly-xz-backdoor-readme.md (84.25 kB)
Download all attachments

2024-04-17 12:46:46

by Jacob Bachmeyer

[permalink] [raw]
Subject: Re: [oss-security] backdoor in upstream xz/liblzma leading to ssh server compromise

Solar Designer wrote:
> [...]
>
> xz backdoor analysis
> ====================
>
> More findings were made about the backdoor's functionality, notably as
> published on April 6 by blasty, who discovered that besides triggering
> system() the backdoor also allows interactive sessions:
>
> https://twitter.com/bl4sty/status/1776691497506623562
>
>
>> [...]

There is almost certainly more yet to be uncovered: Andres Freund's
original report included timing for SSH client connections requesting a
nonexistent account using publickey auth. The backdoored SSH server was
found to require significantly longer to reject those requests than the
untampered sshd. I do not believe that the currently known backdoor
hooks are reachable by that means, so why did Andres Freund see that
particular slowdown? (Not the backdoor initialization making sshd take
longer to start up---a running sshd taking longer to reject a session
for a nonexistent account, unless Andres Freund forgot to tell us that
he was running sshd from inetd and thereby including sshd startup
latency in his measurements.)

> [...]
>
> OpenJS Foundation "Failed Credible Takeover Attempt"
> ====================================================
>
> On April 15, the OpenJS and OpenSSF foundations released the following:
>
> https://openjsf.org/blog/openssf-openjs-alert-social-engineering-takeovers
> https://openssf.org/blog/2024/04/15/open-source-security-openssf-and-openjs-foundations-issue-alert-for-social-engineering-takeovers-of-open-source-projects/
>
> I'll quote an excerpt:
>
>
>> The OpenJS Foundation Cross Project Council received a suspicious series
>> of emails with similar messages, bearing different names and overlapping
>> GitHub-associated emails. These emails implored OpenJS to take action to
>> update one of its popular JavaScript projects to "address any critical
>> vulnerabilities," yet cited no specifics. The email author(s) wanted
>> OpenJS to designate them as a new maintainer of the project despite
>> having little prior involvement. This approach bears strong resemblance
>> to the manner in which "Jia Tan" positioned themselves in the XZ/liblzma
>> backdoor.
>>
>> [...]

Concerning, yes, but not quite the "Jia Tan" /modus operandi/---"Jia"
seems to have been contributing patches for some time (with sockpuppets
pushing their acceptance as needed) before making a move to be appointed
co-maintainer of xz. This looks to me like the common cybercrooks have
seen the technique, decided that it sounds like a great idea, and are
now trying to use it, but do not have the patience that the "Jia Tan"
gang had. In other words, now the "Nigerian Princes" want to help you
maintain your project, just give them write access to the source
repository up front. :-P

I also want to call out a critical detail: claims of vulnerabilities
with no specifics that would aid in actually fixing them. This should
be a general red flag: *anyone* who makes such claims is probably up to
no good.

Lastly, thank you for making the summary.


-- Jacob

2024-04-17 15:10:09

by Loganaden Velvindron

[permalink] [raw]
Subject: Re: [oss-security] backdoor in upstream xz/liblzma leading to ssh server compromise

>
> Concerning, yes, but not quite the "Jia Tan" /modus operandi/---"Jia"
> seems to have been contributing patches for some time (with sockpuppets
> pushing their acceptance as needed) before making a move to be appointed
> co-maintainer of xz. This looks to me like the common cybercrooks have
> seen the technique, decided that it sounds like a great idea, and are
> now trying to use it, but do not have the patience that the "Jia Tan"
> gang had. In other words, now the "Nigerian Princes" want to help you
> maintain your project, just give them write access to the source
> repository up front. :-P
>
Hi. Not all Africans try to scam people. There are people in Africa
who contribute
to Linux and Open Source software such as auditing compression
libraries for similar backdoors.

(I'm from an African country - Mauritius - and we have a vibrant
community of FOSS contributors ...)

2024-04-18 00:12:04

by Matt Johnston

[permalink] [raw]
Subject: Re: [oss-security] backdoor in upstream xz/liblzma leading to ssh server compromise

On 2024-04-17 10:25 am, Jacob Bachmeyer wrote:

> see that particular slowdown? (Not the backdoor initialization making
> sshd take longer to start up---a running sshd taking longer to reject
> a session for a nonexistent account, unless Andres Freund forgot to
> tell us that he was running sshd from inetd and thereby including sshd
> startup latency in his measurements.)

Recent OpenSSH always re-execs for each incoming connection (for fresh
ASLR) so it's always similar to inetd startup.

Cheers,
Matt

2024-04-19 10:15:39

by Jacob Bachmeyer

[permalink] [raw]
Subject: Re: [oss-security] backdoor in upstream xz/liblzma leading to ssh server compromise

Matt Johnston wrote:
> On 2024-04-17 10:25 am, Jacob Bachmeyer wrote:
>
>> see that particular slowdown? (Not the backdoor initialization making
>> sshd take longer to start up---a running sshd taking longer to reject
>> a session for a nonexistent account, unless Andres Freund forgot to
>> tell us that he was running sshd from inetd and thereby including sshd
>> startup latency in his measurements.)
>
> Recent OpenSSH always re-execs for each incoming connection (for fresh
> ASLR) so it's always similar to inetd startup.

Aha! That explains it. There may not be another backdoor after all:
if sshd always reinitializes by exec, it would incur the full startup
delay for each connection, and the backdoor may actually be inert if the
client requests publickey auth.

Thank you for filling in the missing detail.


-- Jacob