<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    一道簡單Chacha20_RC4算法CTF題目

    VSole2023-01-03 15:40:45

    前言

    本道逆向題涉及的知識點如下:

    • 反調試
    • 花指令
    • chacha20加密
    • rc4加密

    這是今年12月份幫一朋友做的一道CTF題,看題目描述是某春秋平臺的,做這道題也花了2小時,因為以前沒遇到過chacha20加密,做題的時在論壇也沒有搜到chacha20算法,故而寫一篇文章記錄一下,供大家參考。

    首先我們觀察下這道題目,解壓后如下,看樣子加密后的flag就在flag.enc中:

    按照做題慣例,先查個殼,發現就是普通的32位程序,使用VC++編譯器編譯,沒殼:

    我們直接拖到IDA中進行靜態分析。

    靜態分析

    初步函數流程的分析

    進去之后,沒什么好說的,直接找main函數按F5開始分析整個程序邏輯;我們先大略的分析一下,見下圖注釋,函數名都還沒有修改,都是IDA自動生成的。

    如上注釋,通過初步的分析,我們大致了解到,整個程序就是將flag讀入,然后經過中間一系列未識別到的函數,最后把文件改名為flag.enc并將加密后的內容覆蓋輸出到flag.enc。要注意在上圖的第23行有一個全局變量的字節序列,這個序列是在函數sub_401610生成的,這里的內容我們最后再分析,接下來先分析最主要的中間那三個函數。

    加花函數的分析與還原

    我們看到在22行,有一個名為loc_401450的函數,我們點進去看看為什么該函數沒有被IDA正確識別,如下圖:

    點進去之后,發現左邊的地址部分一片紅,有經驗的逆向人員一看0x401468~0x40146C這部分,就是明顯的花指令特征,在地址0x40146A處的跳轉無論如何都會跳轉到0x40146F處,使得IDA未能識別這種跳轉破壞了函數的棧幀,因此IDA沒有將該部分正確識別為函數。

    看過我另一篇文章的大家應該清楚花指令的還原,也可以用腳本,但是這里的花指令不多,故而我們直接手動來快速還原。將光標定位在地址0x40146E,然后直接按鍵盤上的D,即可將該部分轉換為數據。

    彈出如下框,這是在IDA在質問我們人類智慧的一個警告,直接Yes就可以。

    然后在正確的代碼地址0x40146F處按C鍵,使得該處的數據轉變為正確的代碼。

    此外,由于0x40146A~0x40146E都是人工添加的無用代碼,我們可以直接將該部分數據全部轉為空指令nop,即0x90,如下圖:

    將這5個無用的字節替換為0x90,然后點OK。

    至此,上述去花操作完成。

    然后,我們選中整個函數的部分0x401450~0x401566,然后按快捷鍵P,讓整個函數能被IDA正確識別。此時我們再次回到main函數的偽代碼窗口,看到該部分函數已經被正確識別了,如下圖:

    剩下的loc_401940和loc_401AA0處的函數還原,和上述處理方法相同,需要注意的是函數的結尾一般是以retn結束。

    chacha20算法的分析

    接下來我們雙擊點進去sub_401450,開始分析該函數的算法,進去之后也是一臉茫然,看不明白;

    繼續點進去sub_401380函數看看,我們發現其中有這樣一個字符串expand 32-byte k,如下圖:

    經過一番搜索,才知道這個加密函數是chacha20加密,找到了這個算法的C代碼實現,https://github.com/shiffthq/chacha20,算法大致先進行初始化,矩陣置換,然后再是輪函數,最后生成了密鑰流,以下是被調用加/解密函數接口:

    void ChaCha20XOR(uint8_t key[32], uint32_t counter, uint8_t nonce[12], uint8_t *in, uint8_t *out, int inlen) {    int i, j;     uint32_t s[16];    uint8_t block[64];     //static void chacha20_init_state(uint32_t s[16], uint8_t key[32], uint32_t counter, uint8_t nonce[12])    chacha20_init_state(s, key, counter, nonce);     for (i = 0; i < inlen; i += 64) {        //static void chacha20_block(uint32_t in[16], uint8_t out[64], int num_rounds)        chacha20_block(s, block, 20);        s[12]++;         for (j = i; j < i + 64; j++) {            if (j >= inlen) {                break;            }            out[j] = in[j] ^ block[j - i];        }    }}
    


    經過對比,我們發現這個函數就是chacha20的加解密算法,對比我們找到的源碼,把這個算法拿過來稍微改改,只要把原來函數的in[j]參數直接換作是out[j]即可和題目一樣,該參數既當作輸入又當作輸出。

    注:我們使用的話,將github源碼下載下來,把cpp和h文件導入即可;ChaCha20是一種流密碼,可以將其理解為對稱加密算法。

    RC4算法

    然后剩下的兩個函數,如果有一定逆向題目積累的話,就不難猜測出這是RC4流密碼。該算法先是對S盒的一個初始化,然后進行加解密操作,對該密碼算法的詳情可參考文末附帶的鏈接。

    分析隨機數生成序列

    加解密算法分析完了,接下來我們呼應一下本題的題目名稱Random,看看前邊遺留的sub_401610()函數,該函數生成了一個加密密鑰,如下圖:

    我們發現這是一個偽隨機生成的,關鍵是要知道其偽隨機生成的種子Seed,v0是根據當前時間的時間戳生成的,所以本題的一個坑點應該是在這里,當前的進程ID我可以猜測他的區間為1~9000。

    做題的時候,剛開始我以為時間戳就是flag.enc文件的時間戳,后來發現怎么都出不來,于是從題目的出題時間開始算起(也就是? 2022?年?9?月?11?日,??23:22:02),寫了一個爆破,由于流密碼的速度非常快,所以我很快就爆破出來了。

    寫wp代碼

    根據以上分析,我們寫出其主要的wp代碼,完整wp代碼我放在了文末的附件,大家打開就能運行。

    void get_flag(unsigned char* mykey, int v0, int pid){    unsigned char s[256] = { 0 };    unsigned char key[12] = "Encrypted!!";     char hexData[48] = {        0xFC, 0xD4, 0x19, 0x74, 0x51, 0x67, 0xED, 0x4B, 0x9C, 0x48, 0xC6, 0x5F, 0x9B, 0x5D, 0xB4, 0xF0,        0x44, 0x02, 0xAF, 0xAC, 0x66, 0x01, 0x06, 0xA5, 0xBE, 0xBC, 0xD0, 0x77, 0x29, 0x64, 0x8D, 0x5E,        0x41, 0xD4, 0x77, 0x31, 0x40, 0xB4, 0x92, 0x22, 0xF9, 0x9F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00    };  //flag.enc字節序列     int enc_len = strlen(hexData);    rc4_init(s, key, strlen((const char *)key));    rc4_crypt(s, (uint8_t *)hexData, enc_len);     ChaCha20XOR((uint8_t *)mykey, 1, key, (uint8_t *)hexData, strlen(hexData));     if (hexData[0] == 'f' && hexData[1] == 'l' && hexData[2] == 'a') {  //判定前三個字母是fla輸出即可        printf("timestamp:%d,pid:%d ", v0, pid);        for (int i = 0; i < 48; i++){            printf("%c", hexData[i]);        }        printf("");        exit(0);    }} int main() {    unsigned char mykey[32];    int timestamp;    DWORD Seed;     timestamp = 1662973302;  // time(0);  2022-09-12 17:01:42    for (int pid = 1; pid < 9000; pid++){        for (timestamp = 1662909722; timestamp <= 1662973302; timestamp++) {   //最坑的點在這里,時間戳要從出題時間點開始算起            Seed = timestamp ^ pid;            srand(Seed);            for (int i = 0; i < 32; ++i)                mykey[i] = (unsigned __int16)rand() >> 8;             get_flag(mykey, timestamp, pid);  //傳入timestamp和pid純屬好奇        }    }     printf("end");    return 0;}
    

    解得flag

    為了防止該題目再次出現,flag我就不以文本形式展現了。

    小結

    另外本文中對另外一個反調試的函數沒有進行過多分析,這類文章很多,大家搜一下就知道了,繞過方式也很簡單。因為本題目的難度還沒有用到動態分析。此外,雖是一道CTF題目,但是其中包含的反調試、ChaCha20、RC4流密碼、花指令以及函數的識別,也值得我們多多去學習。

    算法ctf
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    看過我另一篇文章的大家應該清楚花指令的還原,也可以用腳本,但是這里的花指令不多,故而我們直接手動來快速還原。彈出如下框,這是在IDA在質問我們人類智慧的一個警告,直接Yes就可以。至此,上述去花操作完成。然后,我們選中整個函數的部分0x401450~0x401566,然后按快捷鍵P,讓整個函數能被IDA正確識別。
    看雪論壇作者ID:roadicing
    CTF盲水印詳解
    2022-01-18 14:42:20
    盲水印的出現頻率是相當高
    CTF密碼學-加解密總結
    2021-10-18 15:14:29
    密碼學(在西歐語文中,源于希臘語kryptós“隱藏的”,和gráphein“書寫”)是研究如何隱密地傳遞信息的學科。 在現代特別指對信息以及其傳輸的數學性研究,常被認為是數學和計算機科學的分支,和信息論也密切相關。 著名的密碼學者Ron Rivest解釋道:“密碼學是關于如何在敵人存在的環境中通訊”,自工程學的角度,這相當于密碼學與純數學的異同。 密碼學是信息安全等相關議題,如認證、訪問控
    前言本文主要著眼于glibc下的一些漏洞及利用技巧和IO調用鏈,由淺入深,分為 “基礎堆利用漏洞及基本IO攻擊” 與 “高版本glibc下的利用” 兩部分來進行講解,前者主要包括了一些glibc相關的基礎知識,以及低版本glibc下常見的漏洞利用方式,后者主要涉及到一些較新的glibc下的IO調用鏈。
    單純的通過覆蓋seh handler跳轉是不夠的,我們首先需要bypass safeseh。
    CTF 中如何欺騙 AI
    2021-08-25 18:00:00
    近年來,筆者在國內外 CTF 競賽中見到不少與 AI 相關的題目。有一些是需要選手自行實現一個 AI,來自動化某些操作;有些是給出了一個目標 AI 模型,要求選手進行破解。本文主要談論后者——在 CTF 競賽中,我們如何欺騙題目給出的 AI?
    該篇文章將會從我學習這項技術的視角,講述我屢次失敗的經歷,一點點深入。
    ChainFlag是一個區塊鏈主題的CTF OJ平臺,個人感覺現有題目質量很高,值得一做,這里分享下自己做題的過程。
    前言前段時間在刷CTF題目的時候碰到了各種過濾,其中給我印象最為深刻的是無字母數字Webshell,但是刷題的時候總覺得理解不是那么透徹,于是考慮寫一篇總結文章好好總結一下。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类