MD5雜湊長度延展攻擊

尹子扬發表於2024-04-14

長度延展攻擊

長度延展攻擊介紹

定義:長度延展攻擊(Length Extension Attack)是一種利用雜湊函式的漏洞進行的攻擊,可以透過已知消耗部分的訊息中繼續拼接新的訊息並生成另一個雜湊的方法來偽造一個被認為是可信的雜湊,並且不需要訪問或瞭解原始簽名金鑰。

實現過程:

長度延展攻擊的具體實現根據使用的雜湊函式和攻擊場景而不同,這裡以MD5雜湊函式為例進行說明。

MD5是一種廣泛使用的雜湊函式,其輸入資料塊大小為512位,並且支援可變長度的輸入訊息。利用長度延展攻擊,攻擊者可以在已知雜湊值和訊息內容的情況下,實現根據雜湊值生成任意惡意訊息。下面是一個針對MD5雜湊函式的長度延展攻擊的具體實現步驟。
  1. 攻擊者擁有已知的雜湊值和部分明文訊息段。
  2. 攻擊者使用已知的雜湊值作為起點,計算雜湊函式的內部狀態。由於MD5雜湊函式的內部狀態是對每個512位資料塊的壓縮,因此攻擊者需要對部分已知訊息段進行填充,使其長度與512位資料塊大小對齊,以重建MD5狀態。
  3. 整個訊息包括任意長度的填充位元組和惡意資料。這些資料包括原始訊息的餘量和額外的惡意資料。攻擊者構造這個新訊息,在原始訊息之後追加惡意資料,同時確保新訊息的長度滿足對齊條件。
  4. 透過向填充訊息中追加偽造的資料塊,攻擊者可以計算在原始雜湊值之後追加惡意資料的新雜湊值。
  5. 攻擊者使用新的雜湊值,以及額外的訊息作為有效貢獻,實現對接收者的誤導和攻擊。
下面透過一個具體的例子,來說明MD5雜湊函式的長度延展攻擊的過程:
  1. 假設原始訊息為:"hello world"(11位元組),雜湊值為:"5eb63bbbe01eeed093cb22bb8f5acdc3"
  2. 首先,攻擊者使用該雜湊值作為起點並計算出MD5的狀態。
  3. 接下來,攻擊者構造一個新的訊息,並向其新增惡意資料。假設新增的資料為:" is vulnerable to length extension attack."
  4. 為了對齊新的訊息,攻擊者向訊息中新增位元組,直到它的長度滿足512位資料塊大小的要求。
  5. 攻擊者使用填充後的訊息資料、雜湊函式狀態以及惡意資料作為輸入,計算新的MD5雜湊值。在這種情況下,攻擊者追加的資料恰好符合雜湊函式的輸入標準,直接計算即可。
  6. 攻擊者使用新生成的雜湊值和惡意資料來欺騙接收者,使鍋爐內的後續操作受到影響。

結論:

在上述過程中,攻擊者利用了MD5雜湊演算法的計算邏輯,並且利用其自身處理資料的方式進行欺騙。實際上,關於長度延展攻擊的攻擊路徑是因具體的雜湊函式而異,並且實際操作中也需要攻擊者根據具體實現方式進行調整。然而,以上的例子說明了MD5雜湊演算法的漏洞,並展示了可以利用這些漏洞進行可利用的攻擊的基本操作過程。

使用openssl庫中的MD5_Update()函式來計算MD5雜湊值,並手動新增填充資料以及新的命令進行攻擊。以下是程式碼:

cCopy Code

#include <stdio.h>
#include <string.h>
#include <openssl/md5.h>

int main() {
    // 原始命令和簽名
    char original_cmd[] = "cmd=viewfile";
    unsigned char original_signature[MD5_DIGEST_LENGTH]; // 儲存簽名的陣列
    // 假設原始簽名已知,這裡用16進製表示
    sscanf("68617a652cf8ad912cef9bbbe8ddacf7", "%32x", original_signature);

    // 需要新增的命令
    char additional_cmd[] = "||padding||deletefile";

    // 計算新的簽名
    unsigned char new_signature[MD5_DIGEST_LENGTH]; // 儲存新簽名的陣列
    MD5_CTX ctx;
    MD5_Init(&ctx);
    MD5_Update(&ctx, original_cmd, strlen(original_cmd));
    // 新增填充資料
    MD5_Update(&ctx, additional_cmd, strlen(additional_cmd));
    MD5_Final(new_signature, &ctx);

    // 輸出新的命令和簽名
    printf("新的命令:%s\n", strcat(original_cmd, additional_cmd));
    printf("新的簽名:");
    for(int i = 0; i < MD5_DIGEST_LENGTH; i++) {
        printf("%02x", new_signature[i]);
    }
    printf("\n");

    return 0;
}

這段程式碼透過計算MD5雜湊值來構造新的簽名,其中包括了填充資料和新的命令。最終輸出新的命令和簽名。

執行截圖

相關文章