欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]一款勒索病毒的详细分析

[原创]一款勒索病毒的详细分析

0x01程序信息

  • 大小:2,132,992 字节
  • MD5:671ec2f2b246113f65a0afd1c53c5c3b
  • 壳:UPX 0.89.6 - 1.02 / 1.05 - 2.90
  • 编写语言:易语言

0x02程序行为

  • 开机自启
  • 修改浏览器信息
  • 禁用UAC
  • 进程检测
  • 加密文件
  • 发送数据到指定邮箱

0x03运行截图

0x04脱壳去花指令

  • 采用UPX加壳,通过ESP定律脱壳
  • 脱壳后: 从入口特征判断为VC++6.0编译[易语言]
  • 程序插入了大量花指令
  • 用OD插件E Junk Code 轻松去除
  • 去除花指令后

0x05分析思路

  • 从病毒的行为判断所调用的API,在所调用的API下断点,然后通过栈回溯找到关键函数。
  • 程序所用到的API:
    病毒运行后会隐藏自身文件(SetFileAttributes)
    修改注册表信息(RegOpenKey、RegSetValue)
    遍历文件(FindFirstFile)等等
  • SetFileAttributes设置断点,然后查看调用堆栈,回溯到关键函数

0x06关键函数分析

  • 函数功能:设置程序开机启动、隐藏程序文件、修改浏览器信息、禁用UAC、生成解密KEY(30位随机值)、创建加密线程.


  • 加密所有文件后,会在Temp目录下生成Victim.tmp文件,程序运行后会判断Temp目录下是否有Victim.tmp文件,没有则创建加密线程,如果已经存在Victim.tmp文件,则直接加载勒索窗口.
  • 创建线程后,程序执行消息循环,然后系统会调用线程回调函数

0x07线程回调函数分析

  • 函数功能:遍历全盘文件,加密指定后缀文件
    *.zip.*.rar.*.7z.*.txt.*.doc.*.pptx.*.wps.*.jpg.*.jpeg.*.gif.*.bmp.*.png.*.swf.*.wav.*.mp3.*.mp4.*.avi.*.rmvb.*.xis.*.htm.*.html.*.e.*.ec.*.bak.*.docx.*.ico.*.rtf.*.xlsx.*.c.*.h.*.cpp.*.php.*.pps.*.pdf.*.fla.*.asm.*.dot.
  • 加密后会生成对应后缀的文件
    *.zip ----- *.XiaoBa1
    *.rar ----- *.XiaoBa2
    ……

  • 线程回调函数0x40F82B设置断点

  • 进入线程主函数0x4065D8


  • 加密完成后

0x08勒索窗口事件分析

  • 函数功能:把用户的IP、CPU信息、屏幕截图、系统信息、解密信息发送到指定邮箱
  • InternetOpen设置断点,通过回溯找到关键函数




  • 发送的数据格式

0x09进程检测函数追踪

  • 函数功能:程序加载时,会创建一个定时器,每隔一秒调用一次进程检测的函数,通过CreateToolHelp32Snapshot创建进程快照的方式遍历进程,检测到指定进程后,会尝试结束进程。
  • SetTimer设置断点
  • Timerproc为NULL,说明调用的是系统默认的回调函数OnTimer(),DispatchMessage设置条件断点[[esp+4]+4](esp+4 是MSG对象的地址 [esp+4]+4是消息类型)
    WM_TIMER == 0x113
  • 断下时的堆栈如下:
  • 然后在代码段设置访问中断
  • F9运行,直接到窗口回调函数
  • 进入窗口回调继续分析,注意堆栈数据,
  • 跟进0x4AEDED
  • 跟进0x4AEE31
  • 继续跟踪分析onTimer,最终调用进程检测函数
  • 函数检测的进程列表:
    taskmgr.exe
    OllyDbg.exe
    吾爱破解[LCG].exe
    MSASCuiL.exe
    RAVmon.exe
    RAVtimer.exe
    rav.exe
    360Tray.exe
    360Safe.exe
    ZhuDongFangYu.exe
    360sd.exe
    KSafeSvc.exe
    KSafeTray.exe
    kxetray.exe
    kxescore.exe
    QQPCTray.exe
    QQPCRTP.exe
    BaiduSdSvc.exe
    BaiduSdTray.exe
    BaiduAnTray.exe
    BaiduAnSvc.exe
    avp.exe
    egui.exe
    ekrn.exe
    MsMpEng.exe
    msseces.exe

0x0A加密函数分析:

  • 用CPU序列号生成一个大小为0xFF的Key表
  • 通过计算得到一个Key表索引,取Key值异或数据
  • IDA分析生成Key表函数

  • IDA分析加密数据函数

  • 因为加密只采用了异或运算,所以加密算法也是解密算法。

  • 文件还原代码

#include "stdafx.h"

#include <windows.h>

BYTE *__cdecl unknown_libname_467(BYTE *a1, BYTE *a2)

{

    BYTE *result; // eax@1

    char v3; // cl@1

    result = a1;

    v3 = *a1;

    *a1 = *a2;

    *a2 = v3;

    return result;

}

int __cdecl MakeKeyTable(int a1, signed int a2, int a3)

{

    signed int v3; // eax@1

    int v4; // ebp@1

    int result; // eax@3

    int v6; // esi@4

    BYTE *v7; // ebx@4

    bool v8; // zf@5

    signed int v9; // [sp+4h] [bp-8h]@4

    unsigned __int8 v10; // [sp+18h] [bp+Ch]@4

    v3 = 0;

    v4 = a3;

    do

    {

        *(BYTE *)(v3 + a3) = v3;

        ++v3;

    } while (v3 < 256);

    result = a2;

    *(BYTE *)(a3 + 256) = 0;

    *(BYTE *)(a3 + 257) = 0;

    if (a2 > 0)

    {

        v10 = 0;

        v6 = 0;

        v7 = (BYTE *)v4;

        v9 = 256;

        do

        {

            v6 = (unsigned __int8)(*(BYTE *)(v10 + a1) + v6 + *v7);

            unknown_libname_467(v7++, (BYTE *)(v6 + v4));

            result = v9 - 1;

            v8 = v9-- == 1;

            v10 = (v10 + 1) % a2;

        } while (!v8);

    }

    return result;

}

unsigned __int8 __cdecl Decrypt(int a1, int a2, int a3)

{

    int v3; // esi@1

    int v4; // ebx@1

    unsigned __int8 result; // al@1

    unsigned __int8 v6; // cl@1

    unsigned __int8 v7; // di@2

    unsigned __int8 v8; // bp@2

    BYTE *v9; // ST20_4@3

    BYTE *v10; // ST1C_4@3

    unsigned __int8 v11; // [sp+8h] [bp-Ch]@3

    unsigned __int8 v12; // [sp+20h] [bp+Ch]@1

    unsigned __int8 v13; // [sp+20h] [bp+Ch]@3

    v3 = a3;

    v4 = 0;

    result = *(BYTE *)(a3 + 256);

    v6 = *(BYTE *)(a3 + 257);

    v12 = *(BYTE *)(a3 + 256);

    if (a2 <= 0)

    {

        *(BYTE *)(v3 + 256) = result;

        *(BYTE *)(v3 + 257) = v6;

    }

    else

    {

        v7 = v12;

        v8 = v6;

        do

        {

            v13 = v7 + 1;

            v7 = v13;

            v9 = (BYTE *)(v13 + v3);

            v11 = v8 + *v9;

            v8 = v11;

            v10 = (BYTE *)(v3 + v11);

            unknown_libname_467(v9, v10);

            *(BYTE *)(v4++ + a1) ^= *(BYTE *)(((*v9 + *v10) & 0xFF) + v3);

        } while (v4 < a2);

        result = v11;

        *(BYTE *)(v3 + 256) = v13;

        *(BYTE *)(v3 + 257) = v11;

    }

    return result;

}

int main()

{

    //加密文件

    HANDLE hEntyrptFile = CreateFile(L"D:\\1.XiaoBa1", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    DWORD dwFileSize = GetFileSize(hEntyrptFile, NULL);

    PBYTE pFileBuffer = new BYTE[dwFileSize];

    ZeroMemory(pFileBuffer,dwFileSize);

    DWORD dwRead = 0;

    ReadFile(hEntyrptFile, pFileBuffer, dwFileSize, &dwRead, NULL);

    //CPU序列号

    char cpuid[] = "0FABFBFF000306A9";

    //序列号长度

    int length = 0x10;

    BYTE KeyTable[257] = { 0 };

    MakeKeyTable((int)cpuid, length, (int)KeyTable);

    Decrypt((int)pFileBuffer, dwFileSize, (int)KeyTable);

    HANDLE hDecryptFile = CreateFile(L"D:\\1.zip",GENERIC_WRITE|GENERIC_READ,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

    WriteFile(hDecryptFile, pFileBuffer, dwFileSize, &dwRead, NULL);

    CloseHandle(hEntyrptFile);

    CloseHandle(hDecryptFile);

    delete pFileBuffer;

    system("pause");

    return 0;

}

另附上一份自己做的易语言的SIG文件

上传的附件 样本.zip
eSig.sig

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功