日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Algorithm, Secret key and Protocol

發(fā)布時(shí)間:2025/3/15 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Algorithm, Secret key and Protocol 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最近在對基于區(qū)塊鏈構(gòu)建的信任社會(huì)(未來社會(huì)形態(tài))非常感興趣,區(qū)塊技術(shù)去中心化的特性,讓沒有金融機(jī)構(gòu)成為了可能(包括央行,以及各種商業(yè)銀行)。

除了在數(shù)字貨幣領(lǐng)域大放異彩外,在包括供應(yīng)鏈,網(wǎng)絡(luò)購物,公平合約等方面的應(yīng)用也非常廣泛。其中智能合約的特性十分的吸引我。

不過我今天并不想討論區(qū)塊技術(shù),因?yàn)閰^(qū)塊技術(shù)建立在密碼學(xué)的技術(shù)之上,通過最近兩周對密碼學(xué)以及數(shù)論基礎(chǔ)的研究,分享一些知識(shí),主要關(guān)于如何攻擊一個(gè)宣稱安全的密碼系統(tǒng)。

在密碼學(xué)中,算法,秘鑰以及協(xié)議構(gòu)成了一個(gè)完整的密碼系統(tǒng)。

算法是密碼系統(tǒng)的基礎(chǔ),它是將一組或多組輸入信息轉(zhuǎn)化成一組或多組輸出信息的數(shù)學(xué)方法,算法的輸出會(huì)被秘鑰影響,秘鑰不同,輸出也不同。因此,加密同樣的信息,A用秘鑰Ka加密與B用秘鑰Kb加密輸出的信息是完全不同的。

秘鑰是密碼系統(tǒng)的核心,奧秘在于算法存在一個(gè)最優(yōu)解(最優(yōu)解有很多種解釋,例如超遞增序列,因式分解兩素?cái)?shù)之和等),這個(gè)秘密就是秘鑰。如果一個(gè)人想要解密別人的密文,在不知道秘鑰的情況下,他只能嘗試解數(shù)學(xué)難題,這對于普通人擁有的資源來說,直到宇宙毀滅也無法得出答案。

有了算法和秘鑰,沒有協(xié)議就不是一個(gè)密碼系統(tǒng)。協(xié)議是指由多方參與的,確定要去完成一些事情。如果沒有多方參與,或者沒有去完成一些目標(biāo)就不叫協(xié)議。協(xié)議有很多種,最明顯比如秘鑰交換協(xié)議(例如A和B要在一個(gè)加密的通道中傳遞信息,在這之前A和B要協(xié)商一個(gè)秘鑰并交換,使得A可以加密消息發(fā)送給B并確保B可以解密信息)。

在一個(gè)安全的密碼系統(tǒng)中,必須是算法,秘鑰,協(xié)議都安全,如果其中一個(gè)是不安全的,那么整個(gè)系統(tǒng)就是不安全的。

大多數(shù)流行的公開算法,已經(jīng)被廣泛的證明是安全的,它們經(jīng)歷過很多理論數(shù)學(xué)家的分析。秘鑰的安全性由秘鑰長度,以及你是否妥當(dāng)?shù)谋9苣愕拿罔€決定。如果你做的不錯(cuò),那么秘鑰也是安全的。

協(xié)議卻不是如此了,協(xié)議很脆弱。舉個(gè)例子,A將重要的信息加密發(fā)送給B,只有B有秘鑰可以解密這些信息,C在網(wǎng)路上監(jiān)聽到了A發(fā)送給B的秘密,但是C沒有秘鑰無法解密信息,怎么辦。上面說過,秘鑰是這個(gè)數(shù)學(xué)難題的最優(yōu)解,如果沒有秘鑰,C就只能嘗試解數(shù)學(xué)難題,恐怕C這一生都無法解開,但是C的老板要求他必須在72小時(shí)內(nèi)解密信息,不然C所在的公司就要遭受重大損失。于是C決定鋌而走險(xiǎn),他綁架了B,并對B進(jìn)行嚴(yán)刑拷打,B扛不住,交出了他的秘鑰,C拿著B的秘鑰解密了秘密,并干掉了B。

上面的例子說明了協(xié)議在整個(gè)密碼系統(tǒng)中是一個(gè)易攻擊的薄弱環(huán)節(jié),這樣的攻擊類型很多(賄賂,美色誘惑,威脅等)。

我們來嘗試把這種攻擊帶入到軟件破解上來,同樣的結(jié)論也是攻擊協(xié)議,而非攻擊算法和秘鑰。同樣來舉個(gè)例子,軟件D采用RSA公開秘鑰算法來對用戶的信息以及軟件產(chǎn)品序列號摘要進(jìn)行加密,并發(fā)送給軟件D公司的注冊服務(wù)器,軟件公司D的計(jì)算機(jī)收到用戶A發(fā)送給它的加密信息,用自己的私鑰解密并把用戶信息與數(shù)據(jù)庫中的信息進(jìn)行對比,如果序列號不在D公司的數(shù)據(jù)庫中說明這個(gè)產(chǎn)品的不是D公司銷售的產(chǎn)品,如果序列號在D公司的數(shù)據(jù)庫中,并且A用戶信息不在數(shù)據(jù)庫中,那么A是第一次注冊,將A的信息與序列號綁定在一起保存在數(shù)據(jù)庫中,此序列號將不能再給其他人使用。如果序列號和A都在數(shù)據(jù)庫中,并且序列號與A綁定,那么D公司用私鑰加密一段許可信息發(fā)送給A,A每次使用D軟件的時(shí)候驗(yàn)證這段信息,如果是D公司發(fā)送的許可信息允許使用,如果不是不允許登陸。

看起來很不錯(cuò),RSA是安全的公開密鑰算法,并且秘鑰被D公司保存起來,除非你能賄賂D公司的員工獲得秘鑰,或者攻破D公司的網(wǎng)路,否則秘鑰也是安全的。因此攻擊算法和秘鑰是不現(xiàn)實(shí)的。那么,我們可以從協(xié)議的角度入手,看看有沒有弱點(diǎn)。

先簡單說一下RSA算法:

  • 選擇兩個(gè)大素?cái)?shù) p 和 q,假設(shè) p=3,q=11
  • 計(jì)算 n = p?× q = 3 ×?11 = 33
  • 計(jì)算??(n) = (p – 1)?× (q – 1) = 2?× 10 = 20
  • 選擇 e 且 1 < e <??(n) , e 與 n 互為素?cái)?shù). 假設(shè) e = 7
  • 計(jì)算 d,使 (d?× e) %??(n) = 1. 假設(shè) d = 3,且 d = (3?× 7) % 20 = 1,滿足條件
  • 公開 e, n => (7, 33)
  • 保密 d => 3
  • 加密公式 C = Me?% n
  • 解密公式 M = Cd?% n
  • 用上面的公式加密,假如消息是2,C = 27?% 33 = 29,密文就是29。解密的話就是M = 293?% 33 = 2。

    回到剛才的軟件破解問題上,軟件產(chǎn)品中有e和n,如果能夠分解n我們就能夠構(gòu)造d,也就知道了D公司的秘鑰,由于分解n是一個(gè)數(shù)學(xué)難題,我們不知道最優(yōu)解很難解出答案。我們采用另一種方法,破壞協(xié)議,首先我們自己選擇2個(gè)大素?cái)?shù),構(gòu)造另一個(gè)n,并分別求出對應(yīng)的e和d。然后我們架設(shè)一個(gè)服務(wù)器,用來模仿D公司的驗(yàn)證服務(wù)器。

    我們侵入D公司的軟件,用我們自己的n和e替換D公司的n和e,這時(shí)軟件D會(huì)用我們的公開秘鑰加密用戶信息以及序列號,這段信息是無法送給D公司驗(yàn)證的,因?yàn)镈公司沒有我們的保密秘鑰,無法解密信息,因此這樣還無法完成軟件的驗(yàn)證。

    下一步,我們使軟件D將加密好的信息發(fā)送給我們剛才架設(shè)的模仿D公司的服務(wù)器,這臺(tái)機(jī)器擁有我們的保密秘鑰,它成功的解密信息,并直接構(gòu)造一個(gè)驗(yàn)證通過的數(shù)據(jù)塊,并用保密秘鑰加密發(fā)送給D軟件。D軟件用我們的公開秘鑰解密信息,驗(yàn)證一切正常,并將這段信息保存到計(jì)算機(jī)中。每次D軟件啟動(dòng)時(shí),重新檢查是否存在驗(yàn)證通過信息塊,并用我們設(shè)給它的公開秘鑰解密,解密成功后通過驗(yàn)證,啟動(dòng)D軟件。只要通過一次驗(yàn)證,D軟件就無需再次與D公司服務(wù)器進(jìn)行交互,因此完成了破解。

    再次說明,算法,秘鑰,協(xié)議是一個(gè)密碼系統(tǒng)的組成部分,任何一個(gè)方面不安全,整個(gè)系統(tǒng)就是不安全的。當(dāng)下,很多廠商對算法和秘鑰很關(guān)注,在算法的選擇與秘鑰的長度上下足了功夫。但他們的系統(tǒng)并不像他們想象的那么安全,因?yàn)樗麄兒鲆暳藚f(xié)議。

    好了,今天就聊到這,歡迎@我的email與我交流。

    TedZhang2891@gmail.com

    Posted onAugust 25, 2016 CategoriesCryptography TagsCryptography Leave a commenton Algorithm, Secret key and Protocol

    Ransomware Locky Analysis

    ?Locky的變種非常的多,這個(gè)樣本來自下面的Url,是最新的一種變種。?

    這是程序在剛開始執(zhí)行時(shí)與釋放了Image并替換了之后的對比,很明顯發(fā)生了進(jìn)程替換,因此進(jìn)行分析之前有必要把它內(nèi)部釋放出來的image提取出來,分析這個(gè)image才能搞清楚它是如何做加密的。

    ?

    ?Locky存在一個(gè)未知的殼,IDA并不能檢測出這個(gè)殼,因?yàn)樗膶?dǎo)入表等信息并沒有被破壞。它在運(yùn)行起來后
    ,執(zhí)行相當(dāng)大量的垃圾代碼干擾調(diào)試,依據(jù)是在調(diào)試的過程中它進(jìn)行相當(dāng)多的寄存器操作但6個(gè)通用寄存器的值始終是0。

    這這些垃圾代碼中隱藏著它獲取Kernel32.dll的Addr的邏輯,它會(huì)獲取Kernel32的BaseAddress并通過偏移計(jì)算出API的地址。

    它會(huì)調(diào)用VirtualAlloc分配一塊可寫可執(zhí)行的內(nèi)存塊,大小是61BB,可執(zhí)行意味著會(huì)釋放代碼到這塊內(nèi)存區(qū)中,應(yīng)該著重分析。(0x404587

    TextSegment中存在一部分未被IDA識(shí)別的func,位置在(0x402940)。這部分代碼的作用是將一些數(shù)據(jù)(在TextSegment中)釋放到剛才通過VirtualAlloc分配的內(nèi)存中去。

    GenerateShellCodes(PVOID?lpShellCodes,?BYTE* pDataInTextSegment,?DWORD?dwLen,?DWORD?dwHEX);

    其中bl寄存器用來作為臨時(shí)存儲(chǔ)一個(gè)字節(jié)的寄存器,ebx寄存器用作計(jì)數(shù)器,它從函數(shù)參數(shù)中獲得Data的Length,然后遞減,如果等于0就跳出循環(huán),esi是指向VirtualAlloc返回的內(nèi)存地址。處理完畢后,會(huì)在指定的位置寫入一堆數(shù)據(jù),這些數(shù)據(jù)還需要進(jìn)行異或處理才能變成真正可以被執(zhí)行的代碼。

    以下是沒有被處理的數(shù)據(jù),只是單純的填充了緩沖區(qū)。

    它的解這部分Code的算法如下:

    其中dwHEX是這個(gè)處理函數(shù)的第四個(gè)參數(shù)。解完了以后的數(shù)據(jù)如下:

    下面已經(jīng)完成了部分ShellCodes的釋放,接下來將跳轉(zhuǎn)到ShellCode去執(zhí)行代碼。

    這段ShellCode的目的釋放一個(gè)被壓縮的PE文件,并加載這個(gè)PE文件,整個(gè)過程沒有釋放任何文件出來,無法被監(jiān)控軟件發(fā)現(xiàn),釋放PE文件使用了非常精巧的方式加載到當(dāng)前進(jìn)程中,并完成了進(jìn)程替換。

    被釋放的ShellCode本身還有很多代碼沒有釋放出來,在ShellCode的Offset=247處有一個(gè)func用于釋放ShellCode中的代碼(釋放不太嚴(yán)謹(jǐn),應(yīng)該是通過一些異或操作把原來不是代碼的數(shù)據(jù)轉(zhuǎn)換成代碼)。

    這個(gè)操作會(huì)將ShellCode頭部的一些代碼釋放出來。在后面經(jīng)過調(diào)試發(fā)現(xiàn),這個(gè)func會(huì)被反復(fù)的多次調(diào)用,用于釋放存在ShellCode中的數(shù)據(jù)(轉(zhuǎn)換成可以被執(zhí)行的CPU代碼)。因此這里應(yīng)該是釋放ShellCode自身代碼的邏輯。

    sub_1D1020用來獲得Kernel32的BaseAddr:

    GetModuleHandle

    ?

    ?

    再被釋放的ShellCode+1020處有一個(gè)Func(SC_GetModuleAddr)它用來根據(jù)傳入的HardCode得到對應(yīng)的Module的基地址,例如Kernel32.dll Advapi32.dll等。

    LPVOID SC_GetModuleAddr(DWORD dwHEX);

    對應(yīng)的在ShellCode+1122處有一個(gè)Func(SC_GetFuncAddr)它用來根據(jù)傳入的HardCode得到對應(yīng)的func的基地址,例如Kernel32的GetProcAddress等。

    PFUNC?SC_GetFuncAddr(DWORD?dwHEX,?LPVOID?lpModuleBaseAddr);

    如下圖:

    ShellCode會(huì)調(diào)用這段代碼GetProcAddress,并傳入Module的基地址以及要獲取的函數(shù)名。這里函數(shù)的名字被嵌入到了ShellCode中,被解釋稱代碼了,需要重新解析成字符串。注冊服務(wù),隱藏自己的行為。

    后面的邏輯大致符合如下描述:

  • 首先通過壓入一些特定的HEX值獲取GetProcAddr的地址。
  • 然后傳入要用到的API所在的dll的基地址以及在ShellCode中隱藏的函數(shù)名。
  • 使用獲得的API,不緩存,下次再用還要走這個(gè)邏輯。
  • 例如:用同樣的方法獲得了EnumServicesStatusExA的函數(shù)地址。

    這里調(diào)用GlobalAlloc(ShellCode+001D0686)在堆上分配內(nèi)存分配的內(nèi)存用0初始化,大小是0x4214。(可能是一個(gè)結(jié)構(gòu))因?yàn)楸会尫诺袅恕?/p>

    這里又使用API分配了一塊內(nèi)存,大小是1799C。頁屬性是可讀寫不可執(zhí)行。這個(gè)函數(shù)的參數(shù)很值得注意,居然是當(dāng)前進(jìn)程的基地址。

    這里從當(dāng)前的進(jìn)程中釋放了一堆壓縮數(shù)據(jù)到剛才分配的內(nèi)存中,然后又繼續(xù)調(diào)用VirtualAlloc分配了一塊大小1AE00的內(nèi)存,頁屬性依然是可讀寫不可以執(zhí)行,這塊內(nèi)存用于解壓縮剛才釋放的壓縮數(shù)據(jù)。

    程序接下來調(diào)用了RtlDecompressBuffer這個(gè)Undocument的API。用于釋放壓縮的數(shù)據(jù)到指定的Buffer中。釋放出來的文件是一個(gè)PE Image。(ShellCode+318E)

    把這個(gè)PE dump出來之后可以從導(dǎo)入表中發(fā)現(xiàn)一堆Crypt相關(guān)的API,它就是真正加密用戶數(shù)據(jù)的PE。

    到這里后面的分析都與Ransomware沒有關(guān)系了,只要能拿到內(nèi)部的加密數(shù)據(jù)的文件進(jìn)行分析就可以了。下面是這段ShellCode作為加載器還有一些什么具體行為的分析。

    這里釋放了壓縮數(shù)據(jù)所占用的內(nèi)存。

    這里打開了通過獲取當(dāng)前殼進(jìn)程的ImagePath,然后調(diào)用CreateFile打開文件并計(jì)算文件的Size。

    計(jì)算出來的文件大小是31000,然后調(diào)用VirtualAlloc分配相同大小的空間。下面是VirtualAlloc的參數(shù)。可讀可寫不可以執(zhí)行。

    ?

    然后調(diào)用ReadFile從當(dāng)前Image的文件中讀取數(shù)據(jù),一次讀取完畢。

    然后關(guān)閉文件。

    現(xiàn)在內(nèi)存中有2份PE文件了,一份原始的殼的Image,還有一個(gè)被脫殼后真正做加密工作的Image。

    上面是原始?xì)さ腜E數(shù)據(jù)

    上面是被脫殼后的PE數(shù)據(jù)

    判斷它最后會(huì)還原回去,不然沒有必要保存一份在內(nèi)存中。這樣可以不用釋放文件,監(jiān)控軟件監(jiān)控不到,非常精明的設(shè)計(jì)。

    這里調(diào)用VirtualProtect來對0x400000位置的當(dāng)前Image設(shè)置可寫權(quán)限,要開始覆蓋當(dāng)前的數(shù)據(jù)了。

    開始將Image的內(nèi)容清空:

    然后從debug021:001D17E9開始的一大段代碼用于填充新數(shù)據(jù)到當(dāng)前的Image中去。好大的一段代碼,因?yàn)閮?nèi)存中的PEOffset與加載到內(nèi)存后的Offset不一樣,所以需要小心的分段加載PE數(shù)據(jù),這里的代碼類似一個(gè)進(jìn)程加載器。

    寫完后的數(shù)據(jù)已經(jīng)與上面釋放出來的PE一樣了(對照0x200000地址數(shù)據(jù)),這里發(fā)生了進(jìn)程替換,它肯定還要找到新的PEEntryPoint開始新的調(diào)用。

    調(diào)用RtlZeroMemory把釋放出來的在內(nèi)存中的做加密的PEImage擦除掉。

    然后調(diào)用VirtualFree釋放掉內(nèi)存(清理現(xiàn)場)。

    ?

    現(xiàn)在調(diào)用VirtualProtect把在0x400000位置的新的PEImage頁屬性設(shè)為只讀。

    PEHeader,第一個(gè)頁面。繼續(xù)設(shè)置代碼段為可執(zhí)行可讀。

    到這里,新的PE已經(jīng)加載完畢了,應(yīng)該可以準(zhǔn)備執(zhí)行了。

    這里會(huì)把一些API用到的都取出來保存在棧上,后面用。有一些,不過我最關(guān)注的是CreateThread,然后它會(huì)清理ShellCode,清理犯罪現(xiàn)場。通過使用下面的API調(diào)用。清理的過程分幾個(gè)階段,頭部的ShellCode還保留,只是把除了頭部以外的都清理成0.

    可以看到從F6之后都是0了。

    然后調(diào)用VirtualFree把這整段Code刪除掉。到這里ShellCode的使命已經(jīng)完成,簡單來說它的目的就是將內(nèi)部的一個(gè)PE釋放出來,并替換當(dāng)前進(jìn)程,并把當(dāng)前進(jìn)程的數(shù)據(jù)緩存到內(nèi)存中。

    然后,程序會(huì)執(zhí)行CreateThread,執(zhí)行新的PE代碼。

    405152就是新的進(jìn)程的EntryPoint,可以通過對提取的PEImage的分析佐證。

    至此,脫殼完成并且成功的分析到了這個(gè)殼的運(yùn)作機(jī)制。

    Continue reading?Ransomware Locky Analysis

    Posted onAugust 7, 2016 CategoriesTech Blog TagsAssembly,?C++,?Reversing Leave a commenton Ransomware Locky Analysis

    Ransomware Cerber Analysis

    Cerber是一個(gè)可執(zhí)行程序,它的感染后行為沒有CryptXXX這么隱蔽,可以說分析它的行為并不困難,但是它對內(nèi)部數(shù)據(jù)的保護(hù)比CryptXXX做的好。例如:?我可以寫一個(gè)簡單反向算法就可以將CryptXXX中的所有加密數(shù)據(jù)提取出來,但是對于Cerber它顯然在對內(nèi)部數(shù)據(jù)的保護(hù)上下足了功夫,但這并沒有阻擋我提取出它所有的內(nèi)部數(shù)據(jù)。下面會(huì)詳細(xì)的分析它如何保護(hù)內(nèi)部數(shù)據(jù)的邏輯。

    還需要了解的是,CerberC語言實(shí)現(xiàn)的,并且它并沒有使用微軟的運(yùn)行庫,換句話說它沒有采用微軟的編譯器,很有可能是Intel的編譯器或者是Cross-Compilergcc,我不確定。能夠肯定的是2點(diǎn),沒有采用微軟編譯器,沒有使用C++標(biāo)準(zhǔn)庫。

    2016-7-8

    更新一下,我原本通過分析CryptXXX,感覺CryptXXX的邏輯設(shè)計(jì)的非常巧妙,它的感染方式被分散到很多個(gè)Export函數(shù)中。現(xiàn)在通過最新對Cerber的分析,發(fā)現(xiàn)Cerber也是設(shè)計(jì)的非常巧妙,它去做一些具體的操作時(shí)會(huì)調(diào)用其它命令行進(jìn)程隱蔽自己??梢钥闯鲎髡邔?/span>windows系統(tǒng)的理解程度非常之深,應(yīng)該是個(gè)高級玩家。

    CryptXXX有各種設(shè)計(jì)精美的Blackmail,它們是HtmlBmpTxt,有2個(gè)web服務(wù)器節(jié)點(diǎn),與web的交互非常頻繁,相互做backup。維護(hù)這些都需要人員和精力,它很像是一個(gè)團(tuán)隊(duì)在做。

    Cerber更像是一個(gè)人在做,它的勒索頁面很簡單也不美觀,它也沒有與web交互,應(yīng)該是沒有精力維護(hù)web站點(diǎn),或者更好的隱藏自己。但作者應(yīng)該是個(gè)windows資深玩家。

    為什么這么講,因?yàn)槲野l(fā)現(xiàn)cerber會(huì)給自己提權(quán),也會(huì)去check UAC當(dāng)前的狀態(tài),還用了很多windows的內(nèi)置變量(%xxxx%)這種形式的,我感覺作者以前就是做病毒的。

    Global Data Structure

    Named ImageOffset Size Description
    g_lpModuleFullPath 0x41B760 4 Cerber所在的當(dāng)前目錄加文件名
    g_lpModulePath 0x41B440 4 Cerber所在的目錄
    g_pAddrContainMeta 0x41B43C 0x124 一個(gè)數(shù)據(jù)結(jié)構(gòu)包含Meta信息
    g_hEvent 0x41B438 4 全局Event,手動(dòng)Set初始無信號
    g_szCerCoProtMutex 0x41B648 4 全局Mutex的name
    g_hHeap 0x419A50 4 全局對象,私有堆句柄
    g_dwCurrentPID 0x419A54 4 當(dāng)前進(jìn)程ID
    g_dwImmMap 0x419A3C 0x10 一組常量,用于計(jì)算字符串
    g_bEncryptDone 0x41BF61 4 加密是否完成標(biāo)志
    g_hCryptProv 0x41A168 4 cryptographic service provider
    g_szModuleFileName 0x41B970 4 當(dāng)前進(jìn)程的文件名
    g_tedGlobalMeta 0x41A0F8 ? 全局Meta數(shù)據(jù)結(jié)構(gòu)
    g_bMultiThread 0x41A12C 4 全局標(biāo)志,是否多線程加密
    g_dwMaxBlockSize 0x41A14C 4 最大塊的大小
    g_dwMaxBlocks 0x41A12D 4 最大塊數(shù)量
    g_dqMinFileSize 0x41A138 8 最小文件大小
    g_dwRsaKeySize 0x41A154 4 RsaKey的大小
    g_Cerber_key_place 0x41BEB8 4 ?
    g_pJsonObject 0x41A134 4 全局json對象
    g_pfnIsWow64Process 0x41BFFC ? API
    g_InitEnvpPrograms 0x41BFF8 4 判斷以下4個(gè)全局變量是否初始化
    g_envpPCPFile 0x419AA4 4 %CommonProgramFiles%
    g_envpPCPW6432 0x419AA8 4 %CommonProgramW6432%
    g_envpProgramFile 0x419AAC 4 %ProgramFiles%
    g_envpProgramW6432 0x419AB0 4 %ProgramW6432%
    g_dwStopReason 0x41952C 4 程序不執(zhí)行的原因
    g_bStartNoParam 0x41BF60 4 標(biāo)志是否沒有命令行參數(shù)
    g_lpNewExtension 0x41BC98 4 加密后新的擴(kuò)展名
    g_szWatchdogMutex 0x41BB78 4 Watchdog的mutex
    g_byteDebug 0x41A12E 4 全局的調(diào)試標(biāo)記,打開可以在DbgView中收到調(diào)試信息
    g_byteNetWork 0x41A12F 4 設(shè)置為1加密網(wǎng)絡(luò)文件
    g_AvgReadBytes 0x41A150 4 平均每個(gè)塊的Bytes數(shù)量

    Meta數(shù)據(jù)機(jī)構(gòu)

    包含一個(gè)初始化的臨界區(qū)變量,一個(gè)當(dāng)前進(jìn)程PID,當(dāng)前進(jìn)程的TID。

    Export Function

    funcName ImageOffset Description
    Start 0x406BED EP 沒有什么特別,PE的主入口
    RSA Key
    LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF2a3R5NXFocUV5ZFI5MDc2RmV2cAowdU1QN0laTm1zMUFBN0dQUVVUaE1XYllpRVlJaEJLY1QwL253WXJCcTBPZ3Y3OUsxdHRhMDRFSFRyWGdjQXAvCk9KZ0JoejlONThhZXdkNHlaQm0yY29lYURHdmNHUkFjOWU3Mk9iRlEvVE1FL0lvN0xaNXFYRFd6RGFmSThMQTgKSlFtU3owTCsvRytMUFRXZzdrUE9wSlQ3V1NrUmI5VDh3NVFnWlJKdXZ2aEVySE04M2tPM0VMVEgrU29FSTUzcAo0RU5Wd2ZOTkVwT3BucE9PU0tRb2J0SXc1NkNzUUZyaGFjMHNRbE9qZWsvbXVWbHV4amlFbWMwZnN6azJXTFNuCnFyeWlNeXphSTVEV0JEallLWEExdHAyaC95Z2JrWWRGWVJiQUVxd3RMeFQyd01mV1BRSTVPa2hUYTl0WnFEMEgKblFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==

    解密Cerber的內(nèi)部數(shù)據(jù)非常麻煩,它用了很多層技術(shù)防止提取出它的內(nèi)部數(shù)據(jù),這些數(shù)據(jù)雖然可以在調(diào)試時(shí)動(dòng)態(tài)的跑出來但是對于靜態(tài)分析代碼效率太低下。因此我實(shí)現(xiàn)了這個(gè)解密算法。

    The assembly list was implemented by me
    ?decrypt
    The file be generated automatically
    ?GenerateCodes

    下面是解密后與解密前的數(shù)據(jù),解密之前的數(shù)據(jù)我并沒有 dump出來,因?yàn)槲依塾?jì)在這部分已經(jīng)花去了超過24個(gè)小時(shí)(包括編寫匯編算法,抽取腳本,分析等),我不想再花更多的時(shí)間完善它(后來強(qiáng)迫癥犯了,提供了一個(gè)diff版方便看代碼)。

    Encrypt Decrypt
    ?encrypt ?decrypt

    通過分析decrypt.txt文件,可以發(fā)現(xiàn)cerber隱藏的很多細(xì)節(jié),包括我并沒有發(fā)現(xiàn)的細(xì)節(jié)。因此解密內(nèi)部數(shù)據(jù)這項(xiàng)工作應(yīng)該更早的展開。

    通過閱讀解密后的數(shù)據(jù),可以了解它使用了那些技術(shù)。挑選一些主要的寫在下面。

    select * from %s 難道有內(nèi)部數(shù)據(jù)庫,這是不可能的,有可能是應(yīng)用了WMI。
    FirewallProduct 這個(gè)好像不言自明
    AntiVirusProduct
    cerber_startup_fake_service Fake?
    wireshark.exe 看起來會(huì)反調(diào)試反監(jiān)控,但是事實(shí)上好像沒有work
    dumpcap.exe
    ollydbg.exe
    SOFTWARE\Oracle\VirtualBox 看起來是虛擬機(jī)檢查,不過貌似也沒有work
    VBoxMouse.sys
    VMWARE
    SOFTWARE\VMware, Inc.\VMware Tools
    CERBER_WATCHDOG_PROTECTION_MUTEX 這些串放到這里讓人一看就知道他的行為,如果我寫我會(huì)Debug和Release分別放置不同的值
    CERBER_CORE_PROTECTION_MUTEX
    CERBER_STATISTICS_PROTECTION_MUTEX
    bcdedit.exe

    /set {default} recoveryenabled no

    這個(gè)…?很賤
    Software\Microsoft\Windows\CurrentVersion\Run 看起來要自啟動(dòng)
    AutoRun ?
    ? ?

    這是一個(gè)Json格式文件,被解密后釋放出來。是一個(gè)配置文件

    The file type of JSON which Extracted from decrypt
    ?config

    這個(gè)Json后面會(huì)釋放出3個(gè)勒索文件出來

    ?help_cerber注意,這個(gè)包沒有病毒,但是在Windows10上會(huì)被Windows Defender警告,因?yàn)樗鼨z測到模式匹配

    主程序行為詳細(xì)分析。

    先看一下下面鏈接的代碼:

    start

    Cerber程序被執(zhí)行后,會(huì)先解密一個(gè)內(nèi)部數(shù)據(jù)并計(jì)算一個(gè)四字節(jié)的值存放到全局變量中。然后通過當(dāng)前進(jìn)程的Pid創(chuàng)建一個(gè)全局唯一的Mutex命名字符串并用它構(gòu)造命名的Mutex對象(MSCTF.Shared.MUTEX.575906ab)。

    緊接著將當(dāng)前全路徑提取出來,同時(shí)將文件名去掉只保留路徑,并把這兩個(gè)值保存到全局變量中去。

    接著,開始嘗試啟動(dòng)新的cerber進(jìn)程。這個(gè)過程比較隱晦,它先枚舉系統(tǒng)所有的窗口站,并查找有沒有交互式窗口,如果找到了,將這個(gè)交互式窗口鏈接到當(dāng)前進(jìn)程,然后注冊并啟動(dòng)一個(gè)Windows Service,這個(gè)服務(wù)只做一件事情,就是不停的嘗試再啟動(dòng)一個(gè)Cerber進(jìn)程。如果啟動(dòng)服務(wù)沒有成功,那么就直接創(chuàng)建一個(gè)Cerber進(jìn)程,這個(gè)過程也很麻煩,它會(huì)先獲取當(dāng)前活動(dòng)的SessionID,并進(jìn)而獲得用戶的Token,用用戶的身份去創(chuàng)建一個(gè)新的Cerber,無論兩種方法只要?jiǎng)?chuàng)建成功,那就不會(huì)返回,進(jìn)程退出。

    TED_CreateCerberAgain

    CB_CreateThreadOnSCM

    TR_CreateProcessUtillSucess

    TED_CreateProcess

    wrap_CreateProcessAsUser

    這是程序的Self-Spawn流程。

    ?

    ?

    ?

    解密內(nèi)部數(shù)據(jù)流程

    在進(jìn)入真正搞破壞之前,程序還有些準(zhǔn)備工作要做,其中就包括從自身的資源文件中提取一個(gè)Json文件出來,并用一個(gè)JsonParser生成一個(gè)Json對象出來。這里有可能使用了第三方的Json解析庫,我不確定是Jsonc還是Jansson。因?yàn)槲乙呀?jīng)把Json內(nèi)部的一些方法分析出來了,才判斷出那是在構(gòu)造一個(gè)Json對象,因此如果早一點(diǎn)介入調(diào)查第三方庫會(huì)效率更高一些。

    Ok,回到初始化JsonObject的部分,首先程序會(huì)把自己Image中的資源段文件讀取出來,然后通過自定義的算法計(jì)算出Json文件的串并Hold在內(nèi)存中。下面我來分析一下這個(gè)過程。

    首先,它會(huì)用一個(gè)神奇的算法解密出制定的字符串,這個(gè)神奇的算法被普遍應(yīng)用于解密字符串在這個(gè)程序中(我已經(jīng)實(shí)現(xiàn)了這個(gè)算法,1000行匯編代碼)。

    前面我說過cerber對內(nèi)部數(shù)據(jù)的保護(hù)比CryptXXX做的更好就是由于它的解密內(nèi)部數(shù)據(jù)的算法需要固定3個(gè)值才能解密出對應(yīng)的數(shù)據(jù),而CryptXXX的算法是固定,只要有輸入就可以解密內(nèi)部數(shù)據(jù)。

    PCTSTR __cdecl TED_MakeRealTString(BYTE *byteUnknown, int nResSize, DWORD dwHex, char bUseWStr);

    TED_MakeRealTString

    上面是解密內(nèi)部數(shù)據(jù)的func原型,其中需要固定的數(shù)據(jù)有保存在rdata中的字節(jié),字節(jié)長度,一組解密用的key(4字節(jié)16進(jìn)制數(shù)據(jù))。

    這個(gè)解密函數(shù)非常復(fù)雜,首先如果是第一次調(diào)用需要要進(jìn)行一下初始化,工作包括將內(nèi)部數(shù)據(jù)的鏈表頭指向空,初始化meta信息,meta信息中包括了臨界區(qū)變量,進(jìn)程PID,TID。

    然后,根據(jù)傳入的rdata中的字節(jié)和字節(jié)長度計(jì)算一個(gè)CRC,然后遍歷鏈表,如果匹配到了相同的CRC,就把當(dāng)前鏈表中的item取出來,返回保存在item中WStr或者Str,這個(gè)是根據(jù)上面原型的第四個(gè)參數(shù)指定的。

    如果通過CRC沒有找到數(shù)據(jù),那說明數(shù)據(jù)還沒有被緩存,執(zhí)行計(jì)算過程。首先為鏈表分配一個(gè)新的節(jié)點(diǎn),并把CRC放到新的item里面,然后開始執(zhí)行計(jì)算。

    計(jì)算的過程也很復(fù)雜,首先在棧上構(gòu)造一個(gè)ASCII碼表,然后把輸入的字節(jié)解釋稱0-255的整數(shù)數(shù)組,并用一個(gè)會(huì)自動(dòng)循環(huán)并且最大值不會(huì)超過輸入字節(jié)長度的索引值不停的循環(huán)的取出輸入數(shù)據(jù)中的值并當(dāng)成整形與ASCII碼表中整數(shù)計(jì)算出一個(gè)可變的數(shù)值,這個(gè)數(shù)值會(huì)與ASCII碼表中的數(shù)據(jù)交換,經(jīng)過這樣循環(huán)的處理,會(huì)因?yàn)檩斎氲牟煌贸霾煌慕Y(jié)果。(復(fù)雜代碼用語言描述太難了,還是看代碼吧)

    TED_CalculateSpecialString

    然后,它用被交換,或者說是擾亂過的ASCII碼表與輸入的加密后的數(shù)據(jù)做異或操作(一個(gè)復(fù)雜的異或操作,加減偏移什么的),計(jì)算出Real的數(shù)據(jù)出來。

    我這里講的是它解密出了一塊Json的數(shù)據(jù),下一步還要解析這個(gè)Json數(shù)據(jù)把它轉(zhuǎn)換成內(nèi)部的數(shù)據(jù)結(jié)構(gòu)。

    鏈表在這里的作用是緩存內(nèi)部數(shù)據(jù)。

    構(gòu)造Json Object流程

    在生成Json對象之前首先要了解Json的基本數(shù)據(jù)類型,json共有5種基本數(shù)據(jù)類型,它們是邏輯值,字符串,數(shù)值,數(shù)組和對象。其它信息如果想了解就去google一下吧。

    程序首先構(gòu)造了一個(gè)json對象:

    TED_GetJsonMem

    然后把這個(gè)對象和json串一起送入Parser中,Parser根據(jù)輸入的Json會(huì)去填充這個(gè)JsonObject。這像是某一種第三方Json Parse庫,因此我沒有必要繼續(xù)分析它的作用??匆幌戮椭朗窃诮馕鯦son。

    JSON_Parse

    看的出來,這個(gè)JSON_Parse被多個(gè)函數(shù)調(diào)用,但我們這里只需要關(guān)注Start這條線就可以了。

    因?yàn)樗厦嬲{(diào)用它的生成Json對象的方法是一個(gè)通用方法,程序的其它位置會(huì)調(diào)用它來生成其它的Json對象。

    ?

    ?

    TED_GenerateJsonObject

    TODO:JsonStructure

    JsonObject被初始化完畢后,在程序中提取配置信息等操作就由相應(yīng)的操作函數(shù)來完成。這個(gè)對象是在內(nèi)存中分配出來的,因此在全局?jǐn)?shù)據(jù)區(qū)是發(fā)現(xiàn)不到它的。這個(gè)對象會(huì)再接下來的程序生命期中被多次使用到。

    配置全局變量

    接下來程序需要初始化一些全局?jǐn)?shù)據(jù)成員,通過從Json中提取出key對應(yīng)的value。這些全局變量是加密用戶數(shù)據(jù)所需要指定的配置信息,它們包括:多線程加密標(biāo)志,最大塊尺寸,最大塊數(shù)量,最小文件尺寸,RSAkey的size。

    ?

    接下來,程序要進(jìn)行一些加密前的檢查工作,它先要去檢查一下指定的注冊表位置,第一次執(zhí)行時(shí)這個(gè)位置是空的,因此這段code會(huì)直接返回,還不會(huì)開始加密用戶的數(shù)據(jù)。

    “Printers\Defaults\{89873163-8DC1-7563-E594-6622BDBB1978}”這個(gè)注冊表位置會(huì)被檢查,如果不是第一次運(yùn)行,在這個(gè)位置會(huì)有幾堆數(shù)據(jù),這些數(shù)據(jù)包含是一個(gè)被序列化的Json對象,一組RsaKey,那么程序的就會(huì)解析這個(gè)Json對象,解析后的Json對象指針會(huì)被放到g_pJsonObject(看最開頭有列表)這個(gè)位置,并且程序會(huì)提取出RasKey并計(jì)算一個(gè)hash并放到全局變量中去,完成這些工作后程序返回。

    上面這個(gè)過程就是加快操作的功能,如果從注冊表中提取不到Rsa信息,那么就從全局的json對象中構(gòu)造,首先從json對象中提取一個(gè)用來加密的Key,這個(gè)key實(shí)際上可以從資源文件中提取出來(最上面有列出)。然后把這些信息寫到注冊表中,讓下一次操作可以從注冊表中提取數(shù)據(jù)。整個(gè)的流程如下:

    TED_GetCerberKeyFromRegister

    完整的加密配置準(zhǔn)備工作的流程如下:

    TED_PrepareEncrypt

    CoreProtectionMutex

    接下來程序初始化了一個(gè)全局mutex,這個(gè)mutex被Cerber當(dāng)作Core Protection Mutex,然后創(chuàng)建了一個(gè)。

    然后還會(huì)創(chuàng)建一個(gè)全局的Event。

    GlobalMeta

    然后程序開始分配一些內(nèi)存,為創(chuàng)建全局的數(shù)據(jù)結(jié)構(gòu),這個(gè)結(jié)構(gòu)包含一個(gè)meta信息,一組句柄,還有標(biāo)記句柄數(shù)據(jù)中保存了多少句柄的數(shù)值。Meta信息是另一個(gè)數(shù)據(jù)結(jié)構(gòu),包含當(dāng)前進(jìn)程Pid,線程的tid,以及一個(gè)臨界區(qū)對象。

    struct tedStruData {

    int dwCount;

    tedGlobalMeta meta;

    HANDLE* pObjHandle[64];

    };

    緊接著,他會(huì)創(chuàng)建一個(gè)線程,并把這條線程加入到全局?jǐn)?shù)據(jù)結(jié)構(gòu)的句柄數(shù)組中去。這條線程啟動(dòng)了之后會(huì)創(chuàng)建一個(gè)隱藏的窗口,這個(gè)窗口的窗口過程接收END_SESSION消息,當(dāng)收到這條消息后,會(huì)對全局Event設(shè)置信號,這個(gè)事件是為了保證系統(tǒng)中其它的Cerber進(jìn)程能夠有效的退出。

    CB_WindowProc

    接下來,程序處理一下命令行參數(shù),因?yàn)槌绦蚴敲钚袘?yīng)用,第一次執(zhí)行時(shí)不帶參數(shù),當(dāng)啟動(dòng)后,會(huì)釋放程序內(nèi)的加密數(shù)據(jù),這些數(shù)據(jù)包含了很多命令行參數(shù)。當(dāng)cerber spawn一堆cerber的時(shí)候它們都會(huì)帶一些特殊的參數(shù)進(jìn)來,在這里,程序的行為將發(fā)生變化。它的核心邏輯就在這里了,分析這部分代碼還是很有收獲的,提權(quán)功能,關(guān)閉UAC功能,反AV產(chǎn)品功能,反虛擬機(jī)功能,判斷是不是Admin功能,在64位操作系統(tǒng)上禁用文件系統(tǒng)重定向等在這里被大量使用,也導(dǎo)致了程序在不同的平臺(tái)上行為不一樣,學(xué)習(xí)到很多病毒的做法。也正是因?yàn)榉治隽诉@部分代碼,我才感覺作者在windows領(lǐng)域浸淫已久,很牛逼。這些技術(shù)CryptXXX并沒有出現(xiàn)。

    ?TED_ProcessCommand

    ProcessCommand里面的內(nèi)容非常多,一一展開很費(fèi)心力,我們先跳過這里,看看后面做了什么,最后在回過頭看這部分。

    2016-7-12 back to here

    這個(gè)Func被重命名為TED_ProcessCommand,因?yàn)槌绦驎?huì)根據(jù)不同的執(zhí)行流選擇做具體的操作,而具體的操作都是通過創(chuàng)建自身的一個(gè)副本,并提供一些不同的參數(shù)從而實(shí)現(xiàn)了同一個(gè)程序的不同行為,因此代碼中需要有一個(gè)解析并處理Command Argv的地方,這個(gè)地方就是ProcessCommand函數(shù)。

    這個(gè)函數(shù)被調(diào)用后,首先嘗試啟動(dòng)調(diào)試權(quán)限,然后會(huì)判斷當(dāng)前的啟動(dòng)路徑是不是一個(gè)特殊的路徑(C:\Users\Administrator\AppData\Roaming\{64E3EBE0-DAE1-314A-731D-B7440DC4E389})在我機(jī)器上如上述路徑,如果不是,就把程序拷貝到這里面去,并創(chuàng)建一個(gè)Process再次執(zhí)行,當(dāng)前Process退出。

    如果是的話,接下來會(huì)去判斷傳入的參數(shù)數(shù)量,進(jìn)入不同的if塊中,這里有3種選擇,沒有參數(shù),有2個(gè)參數(shù),以及超過3個(gè)參數(shù)的條件。

    沒有參數(shù)的情況是直接執(zhí)行本程序,這時(shí)候他會(huì)去簡單當(dāng)前是不是Admin的權(quán)限,如果是它嘗試用管理員的身份重新啟動(dòng)cerber并帶上-eval {dwCurrentPid}參數(shù),但是它在這么做之前會(huì)先檢查一下UAC的狀態(tài),如果UAC沒有工作,那么它會(huì)這么做。如果UAC正在工作中,它會(huì)用cmd去啟動(dòng)當(dāng)前的Process的鏡像文件。{cmd /d /c start c:\tmp\cerber.exe –eval pid}.?這個(gè)原因?qū)е抡{(diào)試?yán)щy。

    如果程序啟動(dòng)后被傳入了2個(gè)參數(shù),這里有好幾個(gè)可選項(xiàng)(eval,shadow,watchdog,stat,antiav)。如果shadow,那么將刪除卷快照,并將啟動(dòng)恢復(fù)設(shè)置為no。

    TED_PC_shadow

    如果參數(shù)是watchdog,程序先初始化watchdog的專用mutex,先啟動(dòng)一個(gè)watchdog創(chuàng)建線程,創(chuàng)建watchdog process,然后這個(gè)線程會(huì)每隔1秒監(jiān)控watchdog process是否始終活動(dòng),如果超過4秒watchdog process仍然活躍,那么久殺了這個(gè)process再創(chuàng)建一個(gè),這么做是不是為了防止watchdog process被輕易的發(fā)現(xiàn)?

    TED_PC_watchdog

    TR_Watchdog

    如果不是第一次運(yùn)行,那么watchdog可能已經(jīng)被創(chuàng)建了,程序打開watchdog的全局mutex,如果發(fā)現(xiàn)mutex的句柄不存在,說明程序可能出現(xiàn)了問題,例如被調(diào)試等,那么程序會(huì)繼續(xù)檢查Core Protection Mutex在不在,如果也不存在,那么殺死所有在系統(tǒng)中的cerber進(jìn)程,隱蔽它的行為。

    如果參數(shù)是antiav,它會(huì)檢查是不是具有管理員權(quán)限,然后執(zhí)行AntiAVProduct函數(shù),內(nèi)部邏輯異常復(fù)雜,涉及到權(quán)限,SID,Boot等設(shè)置,放代碼讀下不解釋了。

    TED_AnitAv

    如果參數(shù)是stat,那么它開始執(zhí)行真正的加密工作,在開始加密之前,需要進(jìn)行一些準(zhǔn)備工作。首先把json中的encrypt對象中的數(shù)據(jù)全部load到內(nèi)存中,包括一組擴(kuò)展名列表,然后打開注冊表Printers\Defaults\{89873163-8DC1-7563-E594-6622BDBB1978},在這個(gè)位置把RsaKey取出來,如果取不到,它會(huì)先從內(nèi)存中把Key給弄進(jìn)去,下次就會(huì)取到Key了。

    然后,進(jìn)入Encrypt函數(shù),開始執(zhí)行真正的加密工作。這里有個(gè)debug標(biāo)志,如果把這個(gè)標(biāo)志打開,會(huì)把一些調(diào)試信息寫到文件中,可能得到一些有效的信息。如果json文件中指定多線程加密,那么就會(huì)根據(jù)指定的數(shù)量創(chuàng)建多條線程進(jìn)行加密。

    TED_Encrypt

    TR_DoEncrypt

    TED_EncryptData主要加密函數(shù),入?yún)⑹锹窂?/span>+文件名,加密的核心算法就在這個(gè)func里面

    在加密之前還有一寫邏輯用來枚舉所有驅(qū)動(dòng)器,網(wǎng)絡(luò)驅(qū)動(dòng)器的,把需要加密的磁盤遞歸的加入一個(gè)鏈表中(這個(gè)鏈表數(shù)據(jù)結(jié)構(gòu)很復(fù)雜,我很想弄出來,不過由于太耗費(fèi)時(shí)間放棄了)。

    TED_EnumDevice?枚舉所有可以訪問并有寫權(quán)限的驅(qū)動(dòng)器

    TED_RecursionFolder?遞歸的將所有文件加入鏈表

    退出部分

    經(jīng)過上面的邏輯后,程序會(huì)拋出很多的Process,函數(shù)返回后用戶的數(shù)據(jù)也已經(jīng)被加密了,剩下的部分是準(zhǔn)備推出部分,這部分不是特別重要,但是它卻展示了程序內(nèi)部數(shù)據(jù)結(jié)構(gòu)的構(gòu)成,以及如何管理大量的句柄。

    這次先放代碼,看后分析

    TED_PrepareLeave?主調(diào)

    TED_WaitAllObject?具體

    主調(diào)函數(shù)先進(jìn)入臨界區(qū),然后調(diào)用waitAllObject去等待所有的句柄相應(yīng)。句柄中大量的process和thread。WaitAllObject函數(shù)已經(jīng)被我分析好了,這部分代碼很有意思,理解它需要有一些領(lǐng)域知識(shí),如果沒有寫過高并發(fā)服務(wù)器的話,估計(jì)很難看得懂這部分代碼(指未翻譯之前的代碼)。

    首先有一個(gè)背景知識(shí),就是一個(gè)WaitForMutliObject句柄組上限是64個(gè),超過這個(gè)數(shù)量就沒法管理了(不信可以去google)。那么如果需要在wait中管理超過64個(gè)句柄怎么辦,有一個(gè)辦法,類似虛擬地址映射(頁表,頁目錄),可以創(chuàng)建一些管理線程,這些線程每一個(gè)管理另外64個(gè)句柄,這樣可以無限放大(二級,三級這樣)。有了這些知識(shí)再看代碼就清晰了,可以讀一下我翻譯過的代碼。

    繼續(xù)往下,都是一些釋放操作沒什么好說的。最后如果加密完成,它要通知其他系統(tǒng)中的cerber進(jìn)程退出,這些進(jìn)程可能是上面wait不到的。反正要退出了,這里也比較暴力,枚舉所有cerber然后調(diào)用Terminate。后面還有一個(gè)force的做backup,是通過cmd.exe調(diào)用taskkill來殺。最后在自殺。放一個(gè)小片段吧。

    SR_start

    ?

    Posted onJuly 15, 2016 CategoriesTech Blog Tagsmalware virus reversing Leave a commenton Ransomware Cerber Analysis

    Ransomware CryptXXX Analysis

    Global Data Structure

    Named ImageOffset Description
    pConfig 0x4259A0 全局配置信息,窗口句柄,全局標(biāo)志位,當(dāng)前進(jìn)程是否是Svchost本身等。
    szMutexCrypt pConfig+0x100 全局互斥對象的名稱,
    szModuleFullPath pConfig+0x121 Crypt.dll的當(dāng)前完整路徑 (C:\Tmp\Crypt_Patched.dll)
    dwOSVer pConfig+0x26B 操作系統(tǒng)的主版本號和次要版本號
    szModuleDirectory pConfig+0x663 Crypt.dll的當(dāng)前所在目錄
    dwPlatform pConfig+0x26C 64 or 32 代表不同的平臺(tái)
    dwWebServerID pConfig+0x26A 0x13524C90 or 0x40BBAA5D
    ? pConfig+0x563 ?
    ? pConfig+0x8A5 ?
    szWebserverIp pConfig+0x26A “144.76.82.19” or “93.170.187.64”
    lpPubKeyString 0x4272B8 .BSS 運(yùn)行時(shí)釋放到這里
    dwRandomSeed 0x423008 .data 隨機(jī)數(shù)種子,每次運(yùn)行都不一樣

    Export Function

    funcName ImageOffset Description
    DllEntryPoint 0x422028 這個(gè)入口會(huì)根據(jù)當(dāng)前執(zhí)行的進(jìn)程名稱來判斷是第一次被調(diào)用(rundll32.exe),還是之后的偽裝調(diào)用(svchost.exe)。如果是第一次調(diào)用,做一些初始化的工作,將rundll.exe從系統(tǒng)目錄拷貝到當(dāng)前module目錄中并重命名為svchost.exe,然后用偽裝的svchost加載crypt.dll并調(diào)用MS111。這回導(dǎo)致新進(jìn)程再去load crypt.dll進(jìn)而反復(fù)啟動(dòng)新的進(jìn)程,這是系統(tǒng)中出現(xiàn)一大堆svchost.exe的原因。

    0x41FFFF位置打patch 90 81 C4 28 00 00 00讓它無法啟動(dòng)好多的進(jìn)程方便調(diào)試。只要不是svchost啟動(dòng)的,暫時(shí)就不會(huì)干不好的事情。

    MS111 0x421E1C 首先判斷一下是否已經(jīng)在入口中執(zhí)行了偽裝svchost加載模塊的流程,如果沒有創(chuàng)建一個(gè)新的進(jìn)程調(diào)用MS112。如果執(zhí)行了,先等6分鐘,然后啟動(dòng)2條線程TR_ProcessWindow和TR_PerformCheck,然后進(jìn)入消息循環(huán)等待進(jìn)程退出的消息。
    MS112(Encrypt) 0x4213C0 首先從全局信息中取出互斥對象的名稱,然后打開這個(gè)互斥對象。根據(jù)后面的分析這個(gè)互斥對象應(yīng)該是每個(gè)Process都是唯一的,沒有確認(rèn)。成功創(chuàng)建了Mutex后先組裝一個(gè)神秘的字符串沒有調(diào),然后根據(jù)一個(gè)標(biāo)志來決定是否創(chuàng)建一個(gè)Process去執(zhí)行MS113. 然后檢查全局?jǐn)?shù)據(jù)結(jié)構(gòu),取出一個(gè)特殊文件的路徑,判斷這個(gè)文件存在不存在。
    MS113(FillConfig) 0x421384 這個(gè)函數(shù)只做一件主要的事情,就是去webserver上面下載一個(gè)危險(xiǎn)的dll。

    https://www.proofpoint.com/tw/threat-insight/post/cryptxxx-ransomware-learns-samba-other-new-tricks-with-version3100

    MS114 0x421E0C Set一個(gè)全局標(biāo)志后,調(diào)用MS112. MS112會(huì)根據(jù)是否設(shè)置了這個(gè)全局標(biāo)志來決定是否調(diào)用MS113.
    MS115(Deamon) 0x421254 每隔200ms檢查一下系統(tǒng)中是否存在WerFault.exe(CrashReport),如果存在就殺掉這個(gè)進(jìn)程。同時(shí)檢查當(dāng)前進(jìn)程的父進(jìn)程是否已經(jīng)退出了,如果退出了就用系統(tǒng)中保存的偽裝的svchost加載crypt.dll并調(diào)用MS112,然后退出。

    ?

    RSA Key
    —–BEGIN CERTIFICATE—–

    BgIAAACkAABSU0ExAAQAAAEAAQBfFTOUbZiP6u9PppNyTSXM+Y5W9pEcKe68HJYq

    dLYpXL+XCzXTUgsSRJ1iNmXqrhUEqz3hOi93Bw53U28gvnJTHRboA32xzli688MQ

    eJz7kis1d2G+o8bz+VHO/7qsX+jlBLkP86a6+MYvvhZW+Z0HcsZbMjn6/yCgbhF8

    BhpvuQ==

    —–END CERTIFICATE—

    ?

    寫了個(gè)程序把image中的所有加密字符串解密出來。

    Encrypt Decrypt
    ?EncryptString DecryptString

    ?

    這是一個(gè)html,被解密后釋放出來。是一個(gè)勒索頁面

    The blackmail html which Extracted from decrypt
    ?blackmail

    DllEntryPoint

    ?DllEntryPoint

    MS111?主要邏輯

    MS111

    TR_ProcessWindow:遍歷所有的隱藏窗口,并且不屬于系統(tǒng),并查找窗口所屬的進(jìn)程名,如果match到了一個(gè)特殊的進(jìn)程名,就給他發(fā)一個(gè)消息讓他恢復(fù)出來。

    TR_ProcessWindow

    TR_PerformCheck:創(chuàng)建一個(gè)Process開始調(diào)用MS112

    TR_PerformCheck

    如果不是Svchost.exe創(chuàng)建新的Process開始調(diào)用MS112,進(jìn)程退出。

    執(zhí)行的Commandline如下:

    C:\Users\ADMINI~1\Desktop\_00310~1\svchost.exe C:\Users\ADMINI~1\Desktop\_00310~1\_00310000_pe.dll, MS112

    MS112?主要邏輯

    MS112

    根據(jù)最新的分析,這個(gè)Func是用來加密用戶文件,并顯示勒索信息的。

    首先從全局信息中取出互斥對象的名稱,然后打開這個(gè)互斥對象。根據(jù)后面的分析這個(gè)互斥對象應(yīng)該是每個(gè)Process都是唯一的,沒有確認(rèn)。成功創(chuàng)建了Mutex后先組裝一個(gè)神秘的字符串,根據(jù)是否已經(jīng)獲得了全局?jǐn)?shù)據(jù)結(jié)構(gòu)來決定是否創(chuàng)建一個(gè)Process去執(zhí)行MS113,MS113會(huì)去webserver請求全局?jǐn)?shù)據(jù)結(jié)構(gòu).

    然后檢查全局?jǐn)?shù)據(jù)結(jié)構(gòu),取出一個(gè)特殊文件的路徑,判斷這個(gè)文件存在不存在。

    如果存在,就把文件中的內(nèi)容讀取到一個(gè)Buffer中,這個(gè)Buffer是有結(jié)構(gòu)的,它的0x20C偏移是0x3E8這是一個(gè)Marker。

    如果這個(gè)文件不存在,那么請求webserver給它發(fā)送一個(gè)這份文件內(nèi)容的數(shù)據(jù)。它會(huì)初始化一個(gè)請求數(shù)據(jù)結(jié)構(gòu),其中前4個(gè)字節(jié)是請求的command,最后四個(gè)字節(jié)是marker。中間的內(nèi)容根據(jù)全局?jǐn)?shù)據(jù)結(jié)構(gòu)填充。

    請求的數(shù)據(jù)使用Https安全協(xié)議加密,它有兩個(gè)webserver(”144.76.82.19″ or “93.170.187.64”),當(dāng)一個(gè)請求失敗時(shí)會(huì)嘗試第二個(gè)webserver。

    首先發(fā)送校驗(yàn)包,用于服務(wù)器確認(rèn)通信合規(guī)。先發(fā)送4個(gè)字節(jié)包含通信包長度的頭包,然后繼續(xù)發(fā)送包含實(shí)際驗(yàn)證數(shù)據(jù)的包。

    TED_SendAuthenticationPackage

    實(shí)際上在發(fā)送這兩個(gè)包之前還發(fā)送了一個(gè)52字節(jié)的包,

    發(fā)送完驗(yàn)證包后,開始接受返回?cái)?shù)據(jù)。協(xié)議相同,先接受4個(gè)字節(jié)的包,確認(rèn)要返回的實(shí)際數(shù)據(jù)的長度。然后分配一個(gè)帶結(jié)構(gòu)的Buffer,用來接收返回的數(shù)據(jù),如果返回的數(shù)據(jù)太多,就一次只接收8k的數(shù)據(jù)。接收成功后把這些數(shù)據(jù)壓縮保存到Buffer中。

    接收的第一個(gè)包是返回的校驗(yàn)包,與先前發(fā)送的校驗(yàn)包大小一致。校驗(yàn)包的前4個(gè)字節(jié)是命令,第4-8個(gè)字節(jié)大概是一個(gè)唯一碼,并把這個(gè)唯一碼寫到全局?jǐn)?shù)據(jù)結(jié)構(gòu)中去。然后開始接收真正的數(shù)據(jù)。并把265個(gè)字節(jié)寫到全局?jǐn)?shù)據(jù)結(jié)構(gòu)中。

    TED_RequestForSpecialInfo

    然后,接著從全局結(jié)構(gòu)中取回Buffer構(gòu)造一個(gè)新的數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu)的前265字節(jié)是剛才請求回來的數(shù)據(jù)(這個(gè)數(shù)據(jù)在后面分析是一個(gè)PublicKey),接著4個(gè)字節(jié)是一個(gè)flag,最后四個(gè)字節(jié)是0x3E8。中間是0。數(shù)據(jù)結(jié)構(gòu)的大小是0x210。通過從全局?jǐn)?shù)據(jù)結(jié)構(gòu)中取一個(gè)字符串,并使用上面的Buffer創(chuàng)建這個(gè)特殊文件。

    SR_WriteSpecialFile

    接下來開始解密很多的本地加密字符串,然后組裝在一起。后面分析到這實(shí)際上是在組裝一個(gè)勒索的html文件。用瀏覽器加載這個(gè)html。

    中間會(huì)刪除一些文件,同時(shí)創(chuàng)建一個(gè)Process并向這個(gè)Process注入一段代碼執(zhí)行寫文件的操作。

    TED_CreateAWriteFileProcessThenExit

    最后它會(huì)創(chuàng)建一個(gè)Windows窗口,這個(gè)窗口的尺寸等同于客戶的屏幕大小,并將信息(大概是勒索信息)打印到窗口上。

    這部分會(huì)根據(jù)是否有全局的窗口句柄來判斷是否將信息打印到用戶屏幕上去,或者是寫入到一個(gè)Bmp文件中去。

    SR_PrintScreenAndSave2File

    之后會(huì)等待WM_QUIT消息,隨后釋放Mutex退出進(jìn)程。這個(gè)Mutex應(yīng)該是為了防止重入,進(jìn)而在用戶屏幕上繪制太多的信息。

    0x41A77C應(yīng)該是打印在用戶屏幕上面的勒索信息,這個(gè)function涉及了大量的加密字符串的解密工作。

    MS113主要邏輯

    這個(gè)導(dǎo)出函數(shù)的主要邏輯是去Webserver上面下載數(shù)據(jù)并生成一個(gè)邪惡的dll。它首先會(huì)去嘗試連接”144.76.82.19″的443端口SSL,如果這個(gè)server訪問失敗還有一個(gè)后備server地址是 “93.170.187.64”。

    連接并校驗(yàn)成功后會(huì)先發(fā)送一個(gè)請求文件大小的包,根據(jù)請求到的文件大小創(chuàng)建一個(gè)緩沖區(qū),并接收數(shù)據(jù),完畢后會(huì)把這個(gè)數(shù)據(jù)寫成一個(gè)image文件存放到本地磁盤上。

    TED_DownloadStillerx_dll

    下面是卡巴斯基對這個(gè)dll的分析介紹

    StillerX

    In order to further monetize the infections, CryptXXX downloads a DLL which acts as a credential stealing module. Internally referenced as “stiller.dll”, “stillerx.dll” and “stillerzzz.dll”, this DLL works as a plugin, but can also be used as a standalone stealer. The stealer, like the ransomware, is written in Delphi, and uses the object-oriented capabilities offered by the language. Its relatively large size on disk (around 1.2mb) is due to the static linking of several third party libraries such as DCPcrypt used for retrieving and decrypting locally stored credentials.

    https://www.proofpoint.com/tw/threat-insight/post/cryptxxx-ransomware-learns-samba-other-new-tricks-with-version3100

    我嘗試下載這個(gè)dll但是失敗了,我不知道是不是webserver端的程序修改了還是什么其他原因。當(dāng)我請求文件大小的時(shí)候webserver返回了一個(gè)比代碼中size還要大的尺寸,以至于程序總是沒有進(jìn)行實(shí)際的請求工作就退出了。

    我Patch了個(gè)size,提供了一個(gè)更大的size,第一次請求實(shí)際的數(shù)據(jù)時(shí)能夠得到數(shù)據(jù),但是第二次繼續(xù)請求的時(shí)候沒有任何數(shù)據(jù)到達(dá)。因此實(shí)際獲取的數(shù)據(jù)長度與請求得到的文件長度不同,程序沒有繼續(xù)構(gòu)建這個(gè)dll出來。Webserver邏輯變更也是有可能的,所以我無法釋放出這個(gè)文件加以分析。

    MS115主要邏輯

    這個(gè)導(dǎo)出函數(shù)的工作就是monitor WerFault.exe,不停的殺這個(gè)process。然后判斷它的父進(jìn)程是否已經(jīng)退出了,如果退出的話創(chuàng)建一個(gè)Process用偽裝的svchost去loadCrypt然后調(diào)用MS112。看起來是一個(gè)守護(hù)進(jìn)程。

    MS115_TerminateWerfault

    加密用戶數(shù)據(jù)的邏輯

    這個(gè)邏輯主要在MS112中,從下面這個(gè)圖可以看出來它會(huì)用隨機(jī)算法build一個(gè)隨機(jī)串出來,這個(gè)隨機(jī)串用來給文件加密,這樣它就不需要調(diào)用其它加密的API,保證了它的加密速度。Build這個(gè)隨機(jī)串在生成勒索信息和真正加密用戶文件中都有用到。當(dāng)然它還會(huì)每隔8191個(gè)字節(jié)加密前64個(gè)字節(jié)用非對稱RC4加密。

    加密的邏輯是先將文件讀到一個(gè)緩沖區(qū)中,然后進(jìn)入一個(gè)循環(huán)中,循環(huán)每次增加8255個(gè)字節(jié)。在這個(gè)循環(huán)中拷貝緩沖區(qū)中的前64個(gè)字節(jié)到一個(gè)臨時(shí)buffer中,然后用非對稱的PublicKey進(jìn)行RSA加密,然后將這個(gè)buffer拷貝到另外一個(gè)緩沖區(qū)中,由于加密后數(shù)據(jù)會(huì)變大,因此拷貝到另外的緩沖區(qū)中選擇的size的大小是128字節(jié)。接下來的8191字節(jié)采用一個(gè)數(shù)學(xué)算法,利用隨機(jī)生成的44字節(jié)的串對這部分?jǐn)?shù)據(jù)進(jìn)行加密,速度很快。完成后將這8191個(gè)字節(jié)拷貝到另外的緩沖區(qū)中。8191+64=8255

    如果這一切完成了,它會(huì)寫個(gè)0x3E8到文件末尾。還會(huì)把使用到的隨機(jī)串用PublicKey加密了。

    這塊邏輯比較復(fù)雜,如果要準(zhǔn)確的分析還需要?jiǎng)討B(tài)調(diào)試驗(yàn)證一下,這里我還沒有去做。把代碼貼出來,大家自己感受吧。

    TED_EncryptUserFile

    TED_EncryptBytesByRC4每隔8255加密64字節(jié)頭,強(qiáng)加密

    TED_EncryptBytesByAlgorithm? 剩下的8191采用隨機(jī)串用數(shù)學(xué)算法加密,速度快,沒有看到AES對稱加密算法,和AESkey。

    ?

    Random隨機(jī)數(shù)生成一個(gè)64位的key的算法分析

    這個(gè)算法的邏輯簡單說就是,用兩個(gè)Random函數(shù)生成2個(gè)隨機(jī)數(shù),一個(gè)是0-3用于選擇使用哪一個(gè)字符數(shù)據(jù),另一個(gè)0-44用戶定位數(shù)組中哪一個(gè)字符。這樣就組裝除了一個(gè)64位的Key字符數(shù)組。放代碼看的清楚。

    TED_BuildKeyWithRandom

    種子算法:

    SR_System__Randomize

    偽隨機(jī)算法:

    SR_Random

    Other

    ?

    由于惡意軟件是delphi寫的,因此了解一下delphi使用的字符串的結(jié)構(gòu)對分析代碼有些幫助。

    AnsiString的內(nèi)部結(jié)構(gòu)

    被感染后會(huì)將rundll32.exe從windows目錄中拷貝過來并改名為svchost,然后都用svchost啟動(dòng),起到偽裝迷惑的作用。

    然后創(chuàng)建一個(gè)Process,進(jìn)程的Commandline如下:

    C:\Users\ADMINI~1\Desktop\_00310~1\svchost.exe C:\Users\ADMINI~1\Desktop\_00310~1\_00310000_pe.dll, MS111

    ?

    這個(gè)過程是在Dll load的時(shí)候做的,所以它只要一load就會(huì)創(chuàng)建一個(gè)Process再去load自己,這樣就會(huì)存在很多個(gè)Process在系統(tǒng)中。為了調(diào)試方便,可以打patch,讓它不要去創(chuàng)建進(jìn)程。

    ?

    由于會(huì)寫一個(gè)bmp文件出來,這個(gè)bmp文件的內(nèi)容也是勒索信息,被用于屏幕保護(hù)。所以需要知道bmp的結(jié)構(gòu)才能分析對應(yīng)的代碼。

    原文地址:?http://ec2-52-196-167-189.ap-northeast-1.compute.amazonaws.com/wordpress/index.php/category/tech-blog/

    總結(jié)

    以上是生活随笔為你收集整理的Algorithm, Secret key and Protocol的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。