Binary patch for OpenSSH CVE-2024-6387 (EL9)
- 中
- en
An OpenSSH vulnerability CVE-2024-6387 has been disclosed, where a rare race condition can give an attacker root access to the server.
In RHEL and its derivative distributions, only EL9 was exploitable.
One of the mitigation was to configure LoginGraceTime
to 0
which may cause server to refuse connections in
circumstances, or wait for a new patched release. I can’t wait, so I made myself a binary patch while waiting for it.
Right now AlmaLinux has provided update to the package. However, for Rocky Linux, you need to install their Security SIG to have this update (yet).
Binary Patch
From the public technical details, all we need was to remove the sshlogv
call from the function sshsigdie
:
Because this fix is part of a large commit (
81c1099
), on top of an even larger defense-in-depth commit (03e3de4
, “Start the process of splitting sshd into separate binaries”), it might prove difficult to backport. In that case, the signal handler race condition itself can be fixed by removing or commenting out the async-signal-unsafe code from the sshsigdie() function; …
We locate it by open the sshd
binary file using Ghidra, then look for symbol sshsigdie
:
Once we’ve worked out the byte pattern and locate its offset, we can create a script to automate the patching.
This patch script was written for Python 3.
※ Alma Linux already provides a security patch. The binary patch script is not recommended and is for archival & study purpose only.
- Save the script as
patch.py
:
#!/usr/bin/python3
from hashlib import sha256
import sys
import os
print('''
openssh-server-8.7p1-38.el9 bin-patch for Alma/Rocky EL9 (x86-64 & aarch64)
Usage:
{} </path/to/sshd>
by Jixun <https://jixun.uk/>
'''.format(sys.argv[0]))
patches = [
dict(
name='AlmaLinux: openssh-server-8.7p1-38.el9.x86_64',
before='2526374c30da03dea655c0c5835882a7953d7179f3acf598a7de516a70e6b2d1',
after='d30cdcdd04ae5f60d295bdc07b6f8e1ce6e21321f48df4cd62c8a3b45883325b',
offset=0x81EF6,
payload=b'\x90\x90\x90\x90\x90',
),
dict(
name='AlmaLinux: openssh-server-8.7p1-38.el9.aarch64',
before='09130656a2dd53e19fdeb28b39aaef489191f7ae4c8f3e1b90a7a60f02bf143d',
after='8de58238fbef8cd5f879476a3690f28a8f7d41bb2f26cb89d6ddccc972ffcf79',
offset=0x7AD20,
payload=b'\x1F\x20\x03\xD5'
),
dict(
name='RockyLinux: openssh-server-8.7p1-38.el9.x86_64',
before='6bfc9552d9f976e5cbe01256ba43737cfdc6c9109ebb93d3ee4942a3669408c0',
after='1bcb71692078d7c95488e2bad3c1b0b0f525c178f033d1c875dc872ad554aef8',
offset=0x81EF6,
payload=b'\x90\x90\x90\x90\x90',
),
dict(
name='RockyLinux: openssh-server-8.7p1-38.el9.aarch64',
before='e869b20162cead2be4d83f1735f9ed119cf9c5e79e0c3e62e62c8200dca19b39',
after='caebae2953d438c1c9c7c631c1baa4006ef4d7efaf2f0341d8b4c5cf73964f1f',
offset=0x7AD20,
payload=b'\x1F\x20\x03\xD5'
),
]
file = sys.argv[1]
with open(file, 'rb') as f:
sshd_bin = f.read()
sshd_hash = sha256(sshd_bin).hexdigest()
for patch in patches:
print('[*] Checking {}...'.format(patch['name']))
if sshd_hash == patch['after']:
print(' Already patched!')
continue
if sshd_hash != patch['before']:
print(' No match')
continue
print(" validating patch...")
offset = patch['offset']
payload = patch['payload']
payload_len = len(payload)
patched_bin = bytearray(sshd_bin)
patched_bin[offset:offset+payload_len] = payload
patched_hash = sha256(patched_bin).hexdigest()
if patched_hash != patch['after']:
print('FATAL: hash does not match (got {}, expected {})'.format(
patched_hash, patch['after']))
sys.exit(1)
print(" backup...")
os.replace(file, file + '.bak')
print(" writing...")
with open(file, 'wb', opener=lambda path, flags: os.open(path, flags, mode=0o755)) as f:
f.write(patched_bin)
print(" ok, remember to restart sshd service!")
- Run the patch script:
sudo python3 patch.py /usr/sbin/sshd
- And finally, restart ssh server:
sudo systemctl restart sshd
Sources:
- Alma Linux:
- Rocky Linux:
Apply update provided by distribution
Force refresh cache with dnf makecache
, and then update it:
sudo dnf makecache
sudo dnf update
If we verify the version:
rpm -qa openssh-server
It should report openssh-server-8.7p1-38.el9.alma.2.your_arch
(Alma Linux)
or openssh-server-8.7p1-38.el9_4.security.0.5.your_arch
(Rocky Linux)
My rants
Alma is on the slower side to release security patches…
- Rocky seems to grab it automatically from… somewhere? (Released only to Security SIG)
- Debian started a week prior
- Alma had to wait for the community to supply security updates.
Though it’s still not bad to have it fixed within a day of disclosure (and it was a Monday!). RedHat seems to have only provided a mitigation yet.