This is a breakdown of the exploit from the top comment of the hacker news thread on this bug, cleaned up by GPT 4.
This comment describes a complex and sophisticated security bug that exploits various characteristics of SSH agent forwarding, a feature provided by SSH (Secure Shell).
Here’s a simplified breakdown:
Background: SSH agent forwarding allows an SSH client (Alice) to give an SSH server (Bob) the ability to use the client’s SSH credentials. This is done through a special protocol for communicating with the SSH agent.
SSH_AGENTC_ADD_SMARTCARD_KEY bug: OpenSSH, a popular implementation of the SSH protocol, has a command (
SSH_AGENTC_ADD_SMARTCARD_KEY) that allows a client to access a smart card (a kind of hardware security device) by loading a library using
dlopen(). A security bug identified by Jann Horn in 2016 was that an SSH server could abuse this to make the SSH client load any library, including potentially malicious ones. OpenSSH fixed this bug by limiting which libraries could be loaded to a whitelist of safe directories.
Qualys bug: Building on Horn’s bug, Qualys identified a new vulnerability. When OpenSSH loads a library for
SSH_AGENTC_ADD_SMARTCARD_KEYand fails to find a required function (
PKCS#11entry point), it closes the library with
dlclose(). However, many libraries do “cleanup” tasks during closing, such as unregistering callbacks and signal handlers. Some libraries don’t handle this correctly, and this can cause issues when they are loaded and unloaded in unexpected ways.
Exploitation sequence: The attacker can force the client to load a library that registers a signal handler (like
SIGBUS). This library is immediately closed because it doesn’t have the required function, but the signal handler remains registered. The attacker then loads another library, which overwrites the memory previously used by the signal handler. Finally, a third library is loaded that causes the
SIGBUSsignal. If the attacker can control the overwritten memory, they can execute arbitrary code.
Address grooming with NODELETE: There’s an ELF flag called
NODELETEthat instructs the system not to unmap a library’s memory when it is closed. This can be used to “groom” the address space to make the exploitation more reliable.
Executable stacks: Some libraries set another ELF flag that instructs the system to make the stack executable. If such a library is loaded, and the attacker has control over the program execution, they can inject and execute arbitrary code on the stack.
Fuzzing to find exploitation sequences: The attacker can use a technique called “fuzzing” to automatically test many different sequences of library loads to find ones that lead to successful exploitation. The comment provides an example sequence of libraries that can be loaded to exploit the vulnerability.
Other unexpected control transfers: The comment mentions that the researchers identified additional ways to gain control over the program execution using similar techniques.
Heap-based buffer overflow: Finally, the researchers found a library that, when loaded, starts a server thread that listens on a TCP port. This server has a remotely exploitable heap-based buffer overflow vulnerability, providing yet another avenue for attack.
So, this comment is essentially describing a method of exploitation that relies on specific behaviors of libraries when they are loaded and unloaded, and how they interact with the memory space of the program and the system. It uses an initial vulnerability related to the loading of libraries to then cause a series of actions that ultimately result in the execution of arbitrary code.