彩虹貓分析
彩虹貓分析過程,一天半時間算是分析完了,有一部分的代碼IDA沒有顯示出來,所以得動態分析
概述
程序分為三種啟動方式
-
一種是不帶任何參數的啟動
-
第二種是帶
/main
參數啟動 -
第三種是帶
/watchdog
參數啟動
這部分是每個啟動方式都會執行的代碼
- 通過
GetSystemMetrics()
獲取屏幕的寬高 但之后似乎並沒有用到這部分? - 然后通過
GetCommandLineW()
獲取命令行參數 - 最后再通過
CommandLineToArgvW()
函數解析參數得到參數數組(可以按照數組方式使用) - 根據參數確定兩種帶參執行行為
無參啟動
首先用戶在運行
MEMZ.exe
文件之后 是不帶參數的執行, 我猜我得到的樣本應該是被大佬修改過的,會進行兩次提醒,然后病毒代碼才會真的開始執行
上圖是不帶參數執行的代碼
- 首先申請一段內存,之后通過
GetModuleFileNameW
函數獲取到自己的可執行文件文件名 - 然后使用循環啟動5個帶
/watchdog
參數的副本 - 接下來構造
SHELLEXECUTEINFOW
結構體 用於創建一個副本,並且帶/main
參數,與本身不同的是,會提高CPU的優先級,占用更多CPU時間,位后面占用系統資源做鋪墊 - 然后退出進程
帶/main
參數啟動
該啟動方式主要作用是為了將
MBR扇區
引導部分覆蓋掉,並且寫入重啟之后的彩虹貓動畫代碼
- 這里通過API
CreateFileA
打開了磁盤,如果打開失敗會退出,程序還是比較健壯的 - 接下來就是准備寫入MBR的數據了,首先是
304字節
的引導程序(見下方) - 然后往后偏移510字節,就是1920字節的第二段,要注意動畫程序最前面是
AA55
用來給MBR做結尾標志,所以前面總共512字節 - 最后將組合好的數據通過
WirteFile
寫入磁盤,此時重啟電腦已經掛了 - 創建一個
note.txt
文件並且寫入囂張的字符串,然后打開notepad
顯示這個內容 - 定義一個結構體,其中一個函數指針,所指向的函數,作用是得到一個隨機數,然后隨機啟動一個程序或者網址
最終返回一個隨機的整數,但是不明白為什么會有一個式子沒想明白
獲取隨機數的函數我也是使用了CryptGenRandom()
不明白為什么獲取一個隨機數這么麻煩
可能會隨機到的網址和程序,很多
- 通過循環創建了十個線程,線程函數如下,執行了傳進來的指針函數,但是沒看懂這個和上面那個指針函數是不是同一個,因為正常來說,傳遞進來的結構體應該第一步是還原成一個結構體,而這里直接當作函數指針用了,沒看懂,而且參數數量對不上,但是代碼至少是執行了
- 創建完十個線程之后,就進入死循環狀態,主線程不退出上面創建的子線程就不會退出
帶/watchdog
參數啟動
該啟動方式如同他的名字一般 (看門狗) ,是用來檢測用戶是否主動結束自身進程的,若結束了,則開始破壞用戶電腦(其實
/main
參數已經把MBR扇區覆蓋了)
- 創建一個新的線程,經過進入分析,得知該進程會監控進程列表,
- 需要注意的是第18行的
sleep()
睡眠了一秒,目的應該是為了等待/main
運行完副本 - 一個死循環,作用是遍歷所有的進程,然后判斷是不是進程的副本,如果發現副本的數量減少了(也即是被任務管理器關閉了),則執行
sub_401021()
,經過分析,這個函數是實現了藍屏和重啟
- 進入這個函數之后,首先會創建20個線程,但是線程函數不知道是那個,不過根據我運行病毒的結果來看,應該是彈出的那幾個警告窗口。
- 加載
ntdll
獲取RtlAdjustPrivilege()
、NtRaiseHardError()
兩個函數,在查詢這兩個函數的時候,注意到NtRaiseHardError()
在上一個函數提權之后執行會導致藍屏(應該是操作系統的bug win10不見的有效) - 判斷有沒有加載成功那兩個函數,成功了就嘗試造成藍屏,失敗了繼續
- 打開自己的進程,獲取訪問令牌,然后通過
LookupPrivilegeValueW()
獲取到關機權限(大佬寫的程序就是不一樣,我的話直接system("shutdown -r -t 0")😉 AdjustTokenPribileges()
通知系統權限已經更改- 通過
ExitWindowsEx()
退出,指的注意的是,根據參數判斷是強制重啟 - 返回到主程序30行,這里創建了一個結構體,通過強轉之后結果應該是
00000030
但是查詢了這個結構體之后,並沒有弄清楚他的意圖。 - 31行這里放進去了一個窗口回調函數
sub_401000()
,但是講道理,我沒弄懂這樣寫法是怎么回事...
-
從函數參數上面判斷,這應該是處理下面要注冊的窗口的事件函數,作用依舊是判斷是否會被關閉,如果用戶意圖關閉,就執行第三步那個藍屏函數。
-
然后注冊窗口類,但是參數是強轉的
SHELLEXECUTEINFOW
結構體,經過查詢我實在不知道這兩個結構體的相似處,但是結合上面對lpVerb
成員的賦值,覺得確實有可能,稍后研究一些這樣的寫法 -
創建一個窗口,但是沒有顯示出來
-
一個循環,其中獲取一條消息,通過 如果遇到
WM_QUIT
消息或者發生錯誤就會退出循環(應該還是防止關閉?) -
循環中兩個函數,一個作用是將按鍵消息轉變為字符消息,另一個是分發消息給窗口程序,這樣窗口的回調函數可以處理相關消息,正常來說這個循環不會終止,但是為什么寫這個有點懵逼。覺得可能是為了做出死循環 但是又不會讓程序未響應,類似的手段在Qt中使用過。稍后再測試正常情況下循環會不會結束
-
如果
while()
退出了,則會執行到/main
的代碼
MBR引導程序和動畫程序
寫入的程序分為兩段
第一段 引導代碼
長度是304 這個應該是引導代碼
第二段 動畫代碼
長度是 1952
這個應該是彩虹貓動畫程序本體
這個地址開始 往下很長一段都是內容 要注意 那個 AA55 是MBR扇區的結束標志
這里據我了解,MBR扇區總共512字節
其他函數
按照執行過程,分析了上面的代碼,但是還有些代碼並被調用,IDA中沒有找到調用他們的代碼
扭曲桌面
IDA的函數列表中有這個函數 但是 沒有找到調用他的地方 代碼實現效果 惡搞效果滿滿 啊哈哈哈!!
擾亂鼠標
實際運行的時候有運行到,但是IDA中沒有找到調用它的代碼
鈎子函數
- 設置了一個鈎子,鈎子類型是
WH_CBT
WH_CBT Hook
在以下事件之前,系統都會調用WH_CBT Hook子程,這些事件包括:
1)激活,建立,銷毀,最小化,最大化,移動,改變尺寸等窗口事件;
2)完成系統指令;
3)來自系統消息隊列中的移動鼠標,鍵盤事件;
4)設置輸入焦點事件;
5)同步系統消息隊列事件。
Hook子程的返回值確定系統是否允許或者防止這些操作中的一個。
- 把窗口位置弄亂 (具體效果我得再運行一次)
桌面繪制圖標
從代碼來看,運行之后鼠標所在之處都是叉叉圖標 下面是測試代碼(學到了 : - )
#include <stdio.h> #include <windows.h> #include <iostream> using namespace std; int main() { struct tagPOINT Point; int v1 = GetSystemMetrics(11) / 2; int v2 = GetSystemMetrics(12) / 2; //LPCWSTR wstr = (LPCWSTR)0x7F01; cout << v1 << endl; HWND hWnd = GetDesktopWindow(); HDC v3 = GetWindowDC(hWnd); HICON v4 = LoadIconW(0, (LPCWSTR)0x7F01); GetCursorPos(&Point); DrawIcon(v3, v1, v2, v4); getchar(); ReleaseDC(hWnd, v3); return 0; }
枚舉所有窗口
但是調用他的代碼沒找到,所以,應該是再某個線程中,枚舉完了之后 每個都來扭曲一下 改變大小什么的
百花齊放的效果哇
桌面負片效果顯示
跑完之后 桌面變成負片顯示... 像是見了鬼一樣
播放系統音效
強烈懷疑這個應該是在某個循環里面的 然后 就像是一個神奇的曲子一樣
亂七八糟輸入東西
提交消息到窗口 目測應該會亂輸入東西
額外的
win10運行
手頭暫時沒有win10的虛擬機,所以我猜測一下 GPT分區運行之后,重啟應該不能顯示那個動畫了,
在支持從GPT啟動的操作系統中,這里也用於存儲第一階段的啟動代碼。在這個MBR中,只有一個標識為0xEE的分區,以此來表示這塊硬盤使用GPT分區表。
在使用MBR/GPT混合分區表的硬盤中,這部分存儲了GPT分區表的一部分分區(通常是前四個分區),可以使不支持從GPT啟動的操作系統從這個MBR啟動,啟動后只能操作MBR分區表中的分區。
原文鏈接:https://blog.csdn.net/li33293884/article/details/50562527