惡意代碼分析之 RC4 算法學習

2021-03-02 看雪學院

本文為看雪論壇精華文章

看雪論壇作者ID:jishuzhain

RC4(Rivest Cipher 4)是一種基於密鑰流的加密算法,它的密鑰長度可變,密鑰長度在 1-256 字節範圍。它的特點是算法簡單、運算效率高,而且非線性度良好。

它加解密使用相同的密鑰,假設定義 RC4 的運算過程是RC4(key,data),那麼,密文=RC4(key,明文),明文=RC4(key,密文)。因此也屬於對稱加密算法,WEP 裡也用到了 RC4 算法。

近期分析多個勒索軟體時,會遇到使用 RC4 解密相應字符串或者配置的過程,加之之前閱讀過相關的分析報告後也發現存在勒索軟體使用 RC4 解密相應的內容的行為。

由於筆者之前並未學習過密碼學,於是對 RC4 算法進行學習,並相應記錄筆記。

RC4 由偽隨機數生成器和異或運算組成,RC4 一個字節一個字節地加解密。給定一個密鑰,偽隨機數生成器接受密鑰並產生一個 S 盒。S 盒用來加密數據,而且在加密過程中 S 盒會變化。

出現的幾個變量如下:S、K、T、k

S  S 盒,是一個 256 個字節大小的 char 類型數組,char S[256]

K  密鑰 K,長度限定在 1-256 個字節

T  臨時變量 T,大小也是 256 個字節的數組

k  輸出的密鑰流,大小與實際需要加密的內容一致。

S 盒與臨時變量 T 初始化,偽代碼如下:

for i=0 to 255 do
   S[i]=i;
   T[i]=K[ I % K_len ];

S 盒打亂過程會使用到上述初始化後的 S 與 T 變量,偽代碼如下:

j=0;
for i=0 to 255 do
   j= ( j+S[i]+T[i]) % 256;
   swap(S[i],S[j]); //交換

密鑰流的長度與需要加密的明文長度一致,輸出密鑰流 k[r],偽代碼如下:

i,j=0;
for r=0 to r_len do  //r為明文
   i=(i+1) % 256;
   j=(j+S[i]) % 256;
   swap(S[i],S[j]);
   t=(S[i]+S[j]) % 256;
   k[r]=S[t];

加密與解密是一致的,k[r]為之前輸出的密鑰流,d[r]為加密後的內容,偽代碼如下:

for r=0 to r_len do
   d[r] ^= k[r]

#include <stdio.h>
#include<Windows.h>
#include "RC4.h"
 
int main()
{
    unsigned char text[] = "UOIzVDP2Vzs=";
    unsigned char key[] = "flag{this_is_not_the_flag_hahaha}";
    unsigned int i;
    printf("加密前的數據:");
    for (i = 0; i < strlen((const char*)text); i++)
        printf("%c", text[i]);
    printf("\n");
    rc4_crypt(text, strlen((const char*)text), key, strlen((const char*)key));
    printf("加密後的數據:");
    for (i = 0; i < strlen((const char*)text); i++)
        printf("%X", text[i]);
    printf("\n");
    rc4_crypt(text, strlen((const char*)text), key, strlen((const char*)key));
    printf("解密後的數據:");
    for (i = 0; i < strlen((const char*)text); i++)
        printf("%c", text[i]);
    printf("\n");
    system("pause");
 
    return 0;
}

#include <string.h>
 
static void rc4_init(unsigned char* s_box, unsigned char* key, unsigned int key_len)
{
    unsigned char Temp[256];
    int i;
    for (i = 0; i < 256; i++)
    {
        s_box[i] = i;//順序填充S盒
        Temp[i] = key[i%key_len];//生成臨時變量T
    }
    int j = 0;
    for (i = 0; i < 256; i++)//打亂S盒
    {
        j = (j + s_box[i] + Temp[i]) % 256;
        unsigned char tmp = s_box[i];
        s_box[i] = s_box[j];
        s_box[j] = tmp;
    }
}
 
void rc4_crypt(unsigned char* data, unsigned int data_len, unsigned char* key, unsigned int key_len)
{
    unsigned char s_box[256];
    rc4_init(s_box, key, key_len);
    unsigned int i = 0, j = 0, t = 0;
    unsigned int Temp;
    for (Temp = 0; Temp < data_len; Temp++)
    {
        i = (i + 1) % 256;
        j = (j + s_box[i]) % 256;
        unsigned char tmp = s_box[i];
        s_box[i] = s_box[j];
        s_box[j] = tmp;
        t = (s_box[i] + s_box[j]) % 256;
        data[Temp] ^= s_box[t];
    }
}

#ifndef RC4_H
#define RC4_H
 
/*
導出rc4_crypt函數,參數為要加密的數據、數據長度、密碼、密碼長度
*/
void rc4_crypt(unsigned char* data, unsigned int data_len, unsigned char* key, unsigned int key_len);
 
#endif

上述代碼編譯後,得到 RC4.exe,直接載入 IDA 中進行分析,為了效果,使用 release 模式編譯,不加載 pdb 文件。先找到 main 函數,如下:雙擊進入 main 函數後,只關注 RC4 加密函數,如下:
再次雙擊進入,邏輯非常清晰,存在 3 個循環,如下:
最後一個循環是輸出加密密鑰流,最後與明文進行逐字節異或,得到加密的密文。

這裡選擇一個勒索樣本(64a1fbb51ab62f1aa012172b45c8ca15)作為例子,IDA 打開後分析如下:從最開始的兩個函數可以發現極有可能會解密資源,進入第一個函數看看,如下:
兩處循環,次數都為 256 次,第一次循環賦值是按照順序進行賦值的,相當於之前的初始化 S 盒。
第二個函數進入後發現也是循環後進行賦值,最後有一處是對之前第一個函數得到的值進行相應的異或操作,最後得到一個值。動態調試如下, 0x0040E000 開始的 128 個字節在函數執行後保持不變,而之後的字節數值已經被更改,猜測這 128 個字節是密鑰。執行完該函數後,相關的數據區域確實發生了變化,根據之前的分析猜測是 RC4 算法,本地提取相關區域數據後對其進行手工解密如下,發現結果確實是使用地址 0x0040E000 前 128 個字節(0x80)作為密鑰,然後採用 RC4 算法解密後的結果如下,與上圖執行完後得到的數據是一致的。
識別點:存在 3 個循環,前兩次循環的次數為 256 次,最後一次循環的次數以某個變量的值為限,實質是需要加密(解密)的內容長度,每次循環的最後有一個異或的操作代表加密該內容。

看雪ID:jishuzhain

https://bbs.pediy.com/user-678001.htm 

*本文由看雪論壇  jishuzhain  原創,轉載請註明來自看雪社區

好書推薦

相關焦點

  • 惡意代碼分析之Office宏代碼分析
    有時候,宏代碼會直接訪問攻擊者的C2,下載惡意文件到本地運行。有時候,宏代碼會解密釋放出一個powershell代碼,再調用powershell腳本,通過powershell腳本去實現環境檢測、文件下載等功能。宏代碼基於的是VB的語法,如果沒有混淆的宏代碼閱讀起來倒是比較方便,但是現在的大多數宏樣本都會有混淆和一些反調試手法,所以在遇到各類宏代碼的時候也要根據情況去分析。
  • 乾貨 | 惡意代碼分析之Office宏代碼分析
    在之前的文章中,講述了幾個常見的惡意樣本的一些常規分析手法。主要使用的工具有exeinfo(查殼)、IDA(靜態分析)、od&xdbg32(動態調試)、Systrace&火絨劍(行為分析)等。從本小節開始,文章將講述不同種類的非PE樣本和一些更複雜的PE樣本如何調試和分析。
  • 彌補傳統惡意代碼檢測短板,機器學習技術還能這樣做?
    為了應對上面的問題,基於機器學習的惡意代碼檢測方法一直是學界研究的熱點。由於機器學習算法可以挖掘輸入特徵之間更深層次的聯繫,更加充分地利用惡意代碼的信息,因此基於機器學習的惡意代碼檢測往往表現出較高的準確率,並且一定程度上可以對未知的惡意代碼實現自動化的分析。
  • 惡意代碼分析之APC進程注入學習
    50 51 52 53 56 57 55 54 58 66 83 e4 f0 50 6a 60 5a 68 63 61 6c 63 54 59 48 29 d4 65 48 8b 32 48 8b 76 18 48 8b 76 10 48 ad 48 8b 30 48 8b 7e 30 03 57 3c 8b 5c 17 28 8b 74 1f 20
  • 惡意代碼分析之調試.NET平臺dll
    這裡先自行提取下便於後續判定,提取的PE文件分析後為.NET平臺的dll文件,如下。接著往下分析,發現會內存加載dll並反射調用執行dll中的LOLY()方法,如下。本著不重複造輪子(其實是不太會寫代碼)的思想,於是網上搜了下,發現了如下工具(具體更多內容可以自行訪問項目地址查看,這裡不再過多介紹)。hexfati / SharpDllLoader:一個簡單的C#可執行文件,它調用任意C#DLL的任意方法。
  • 【無監督學習】K-means聚類算法原理介紹,以及代碼實現
    「腐敗」生活了這麼久,還是要找到自己一點樂趣吧,於是想了一想,決定把《機器學習》的算法研究過得都重新梳理一遍,於是就從無監督學習——聚類開始了 什麼是無監督學習?無監督學習也是相對於有監督學習來說的,因為現實中遇到的大部分數據都是未標記的樣本,要想通過有監督的學習就需要事先人為標註好樣本標籤,這個成本消耗、過程用時都很巨大,所以無監督學習就是使用無標籤的樣本找尋數據規律的一種方法聚類算法就歸屬於機器學習領域下的無監督學習方法。無監督學習的目的是什麼呢?
  • 惡意軟體檢測常見方法
    靜態分析法同一惡意軟體家族代碼復用導致惡意軟體作者或團隊編碼具有編碼相似性[4],因此當同一家族惡意軟體載入內存執行時其結構信息和數據也應該具有一定的相似性。鑑於上述相似性,靜態分析法通過對惡意軟體本身二進位文件、可執行文件或者通過反編譯文件提取到的靜態特徵進行分析,對比惡意軟體與正常軟體的靜態特徵的異同來發現惡意軟體。
  • 機器學習之分類算法K-Means介紹與代碼分析(篇四)
    k-平均聚類的目的是:把n個點(可以是樣本的一次觀察或一個實例)劃分到k個聚類中,使得每個點都屬於離他最近的均值(此即聚類中心)對應的聚類,以之作為聚類的標準。這個問題將歸結為一個把數據空間劃分為Voronoi cells的問題。這個問題在計算上是NP困難的,不過存在高效的啟發式算法。
  • 5大必知的圖算法,附Python代碼實現
    在這篇文章中將為大家介紹一些重要的圖算法,以及Python 的代碼實現。將上圖中的連通分量算法近似看作一種硬聚類算法,該算法旨在尋找相關數據的簇類。舉一個具體的例子:假設擁有連接世界上任意城市的路網數據,我們需要找出世界上所有的大陸,以及它們所包含的城市。我們該如何實現這一目標呢?
  • 一文淺析Office惡意宏代碼如何隱藏和破解
    含有惡意宏的Office附件在APT攻擊、勒索病毒等攻擊事件中被廣泛使用,黑客在製作惡意宏時通常會使用一些技巧來隱藏宏代碼,防止安全人員對宏代碼直接進行分析。
  • Python實現KMeans算法
    也就是說,我們的目標就是將這900多條數據用K-Means算法給分成4類。在這裡,我有必要把這幾行代碼簡要說一下。第1-3行,就是拿Step2中的數據用KMeans算法給聚類,不是會得到4個分類麼?每個分類不是會有一個中心點麼?如果忘記了,請回過頭去看看這篇文章:數據離散化及其KMeans算法實現的理解。拿這4個圓心也是存放在第2行創建的這個KMeans的對象kmodel中,確切說在它的cluster_centers_中。
  • 從反惡意代碼到對抗高級威脅
    該系統為我國監測大規模惡意代碼活動奠定了技術基礎,安天探海威脅檢測系統正是在該系統的基礎上研發而成。 安天在惡意代碼分析工作中推動了惡意代碼知識的體系化完善,形成了惡意代碼百科全書,並提供公眾查詢(Virusview.net)。
  • 4種常見的校驗算法
    下面就介紹幾種常見的校驗算法。校驗和是最基本,也是嵌入式工程師最常用的一種校驗算法,其實現方法很簡單,簡單到只有幾行代碼。當然,以上代碼僅供學習參考,實際應用需結合項目情況修改代碼。CRC:Cyclic Redundancy Check,即循環冗餘校驗。CRC是數據通信領域中最常用的一種查錯校驗碼,其特徵是信息欄位和校驗欄位的長度可以任意選定。
  • 手把手 | OpenAI開發可拓展元學習算法Reptile,能快速學習(附代碼)
    大數據文摘作品編譯:Zoe Zuo、丁慧、Aileen本文來自OpenAI博客,介紹一種新的元學習算法Retile。在OpenAI, 我們開發了一種簡易的元學習算法,稱為Reptile。MAML元學習算法:http://bair.berkeley.edu/blog/2017/07/18/learning-to-learn/元學習是學習如何學習的過程。
  • K-means 聚類算法及其代碼實現
    K-means算法是非監督學習(unsupervised learning)中最簡單也是最常用的一種聚類算法,具有的特點是:本文章介紹
  • 腳本類惡意程序分析技巧匯總
    作者論壇帳號:鬼手56前言惡意代碼分析的工作往往需要掌握各種類型的文件分析技巧
  • 應急響應中分析64位惡意dll的小故事
    下面想結合取證分析的過程,從取證經過、動靜態分析、破解加密等角度入手,與大家分享一些綜合性的惡意程序分析方法,相互啟發,相互學習。因此將惡意的midimap.dll文件放置在C:\windows\ 目錄下即可實現dll劫持。行為分析除了對惡意程序進行直接的靜態分析和動態跟蹤調試,我們還常使用其他工具和手段對惡意程序的行為進行監控和分析,尤其在對一些較難逆向的複雜程序進行分析時,結合行為監控將大大提高分析效率。這裡也簡單介紹2款工具。
  • iOS自動化代碼審查工具之OCLint
    OCLint是一款靜態代碼分析器,可用於分析C, C++ 和 Objective-C代碼中隱含的問題:…靜態代碼分析工具是偵測編譯器不可見的潛在缺陷的關鍵技術
  • 惡意代碼分析丨記一次勒索病毒分析處置
    接到客戶通知,有個PC中了勒索病毒,領導讓儘量分析一下給客戶個回復,著急的我趕緊翻書翻教程,一頓qwer,最終還是沒能將文件恢復,但是分析過程中又學習了一些知識,藉此分享。以下為文件加密後的截圖。b65014814bbbd09367df4a86c0d4204d在線檢測結果如下。
  • 分類算法之K近鄰算法(KNN)
    算法思路K最近鄰(k-Nearest Neighbor)算法是比較簡單的機器學習算法。它採用測量不同特徵值之間的距離方法進行分類。思路: 如果一個樣本在特徵空間中的k個最近鄰(最相似)的樣本中的大多數都屬於某一個類別,則該樣本也屬於這個類別。算法分析這裡我以javaml庫為例分析算法實現步驟。