【病毒分析】phobos家族2700变种加密器分析报告

1.样本信息

⽂件名Fast.exe
SHA2563c95bd8e14f6aa92e94ec3318d23a8cc34192259
MD528c6c0b4f54912ec73c9bfeb3f2a8f07
运行平台Windows

2.感染迹象

2.1 文件结构分析

整体文件大小为200+k,把冗余数据去掉,发现仍然可以运行,大小变为56k。与phobos家族的标准一致。

图片

2.1.1 勒索信

图片

2.1.2 勒索壁纸

图片

2.1.3 密钥

加密aes256 key(此key用于加密文件)的rsa公钥为

[0xB7,0x0AA,0x5B,0x0CB,0x0EC,0x0B8,0x1C,0x0E8,0x0B0,0x0EE,0x5,0x0D9,0x8E,0x92,0x67,0x8F,0x0B0,0x11,0x0D9,0x0E0,0x42,0x50,0x0C,0x2A,0x0B1,0x65,0x30,0x23,0x8C,0x0D7,0x0E7,0x6F,0x60,0x0,0x0A4,0x0FA,0x77,0x0DE,0x0C6,0x11,0x6B,0x0DF,0x0E5,0x2D,0x94,0x0E4,0x67,0x0D8,0x1E,0x74,0x0A3,0x0F6,0x53,0x0AB,0x0FE,0x0AA,0x0E9,0x0CC,0x2A,0x0BF,0x5,0x4D,0x7E,0x2A,0x18,0x9F,0x34,0x87,0x9,0x99,0x0AB,0x46,0x7D,0x0D8,0x66,0x4D,0x9,0x55,0x2D,0x0C9,0x8E,0x6C,0x90,0x75,0x0B5,0x0ED,0x6C,0x46,0x77,0x55,0x48,0x38,0x70,0x0CC,0x0DC,0x0F3,0x12,0x1B,0x88,0x44,0x24,0x0C,0x0E9,0x6,0x0A0,0x0C0,0x68,0x33,0x0C,0x95,0x0DB,0x0D,0x5D,0x0EC,0x0D8,0x15,0x92,0x0D1,0x3D,0x0D4,0x44,0x0FA,0x2E,0x73,0x1A,0x49,0x0C1,0x0BD]

写入文件的配置中的iv(变化的)后面固定的16字

[0xD,0x0DB,0x95,0x0C,0x33,0x68,0x0C0,0x0A0,0x6,0x0E9,0x0C,0x24,0x44,0x88,0x1B,0x12]

加密字符串的aes128 key

[0xC3,0x70,0x0D7,0x0CC,0x94,0x27,0x77,0x70,0x0DF,0x2,0x0DF,0x0CE,0x0E2,0x0D5,0x32,0x14]

2.1.4 加密文件结构

文件被加密并重命名如下格式1.png.id[8E1EA49A-3524].[sqlback@memeware.net].2700

图片

图片

被加密的文件的后8 Byte为固定值。

2.1.5 加密文件样式

模拟客户中招后环境

加密后

图片

图片

解密后

图片

2.2 软件运行分析

2.2.1 函数sub_4054BF(内存初始化)

文件加密部分可以从sub_4054BF函数开始分析,此函数的关键部分如下

if ( ntfs_get_names(newfilename, 0x7FFFu, 2) )
{
  GenerateRandomBytes_SHA224_256Pad(16, key);
  v6 = *lpThreadParameter;
  if ( !sub_40868F() )
    break;
  sub_408EBE(lpMem, v3, key, newfilename, *(*v6 + 9));
}
BOOL __usercall sub_40868F@<eax>(int a1@<esi>)
{
  int v1; // eax
  v1 = CRC32_ProcessInteger(0, a1, 32);
  return *(a1 + 160) == CRC32_ProcessInteger(v1, (a1 + 32), 128);
}
  • 首先调用函数ntfs_get_names生成了新的文件名,存放在newfilename中;

  • 调用函数GenerateRandomBytes_SHA224_256Pad随机生成加密此文件的密钥,命名此数据为filekey;

  • 调用函数sub_40868F,通过计算CRC32值并比较,判断给定块中的数据是否与文件的第一个块相匹配,以此来确定该块是否是文件的开头;

  • 最后调用函数sub_408EBE进行加密的其他步骤,下文将函数sub_408EBE重命名为encode;

  • 函数ntfs_get_names仅实现了字符串拼接功能,ID的生成逻辑id[8E1EA49A-3354]不在此函数中,id是通过sub_4054BF的参数传递到此函数中。

2.2.2 ntfs_get_names函数(新文件名字)

ida反编译时参数缺失

mov     esi, [ebp+lpThreadParameter]
...
mov     eax, [esi]
mov     eax, [eax]
push    dword ptr [eax+8]
push    [esp+34h+lpMem]
push    2
push    7FFFh
push    [esp+40h+newfilename]
call    ntfs_get_names

其中push    dword ptr [eax+8]即为.id[8E1EA49A-3524].[sqlback@memeware.net].2700

此函数仅实现字符串拼接功能。

2.2.3 sub_408EBE函数(encode)

int __usercall sub_408EBE@<eax>(const WCHAR *a1@<edi>, _DWORD *a2, int a3, const WCHAR *lpFileName, char a5)
{
  int FileW; // ebx
  DWORD FileAttributesW; // eax
  int v7; // eax
  LARGE_INTEGER FileSize; // [esp+8h] [ebp-20h] BYREF
  LARGE_INTEGER v10; // [esp+10h] [ebp-18h]
  DWORD dwFileAttributes; // [esp+1Ch] [ebp-Ch]
  DWORD v12; // [esp+20h] [ebp-8h]
  int v13; // [esp+24h] [ebp-4h]

  v13 = 0;
  FileW = (int)CreateFileW(a1, 0x80000000, 7u, 0, 3u, 0, 0);
  if ( FileW == -1 )
    return v13;
  if ( !GetFileSizeEx((HANDLE)FileW, &FileSize) )
    goto LABEL_15;
  CloseHandle((HANDLE)FileW);
  FileW = -1;
  v10 = FileSize;
  if ( FileSize.QuadPart )
  {
    FileAttributesW = GetFileAttributesW(a1);
    dwFileAttributes = FileAttributesW;
    if ( FileAttributesW != -1 )
    {
      v12 = FileAttributesW & 1;
      if ( (FileAttributesW & 1) != 0 )
        SetFileAttributesW(a1, FileAttributesW & 0xFFFFFFFE);
      v7 = (a5 & 1) != 0 || v10.QuadPart < 0x180000ui64
         ? sub_408782(a2, a3, a1, lpFileName, a5)
         : sub_408C42(a3, a1, lpFileName, a5);
      v13 = v7;
      if ( v12 )
      {
        if ( v7 )
        {
          SetFileAttributesW(lpFileName, dwFileAttributes);
          return v13;
        }
        SetFileAttributesW(a1, dwFileAttributes);
LABEL_15:
        if ( FileW != -1 )
          CloseHandle((HANDLE)FileW);
      }
    }
  }
  return v13;
}

此函数大致逻辑为:

  • 函数尝试使用CreateFileW打开文件,并检查操作是否成功。如果不成功,则返回;

  • 然后使用GetFileSizeEx获取文件大小,若文件为空,则关闭句柄并返回;

  • 使用GetFileAttributesW检索文件属性,检查文件属性中的只读标志,如果文件是只读的,接下来的代码会使用SetFileAttributesW函数将只读标志清除;

  • 根据文件大小是否小于 0x180000,调用sub_408782或sub_408C42函数;

  • 此代码通过加密现有文件来创建一个新文件。该函数接受现有文件的文件名、密码和要创建的新文件的文件名称。该函数分块读取现有文件,对每个块进行加密,并将加密的块写入新文件。加密是通过使用密码和文件属性计算哈希值来完成的。哈希值用于对文件数据进行块加密。该函数还将新文件的文件属性设置为与现有文件匹配;

  • sub_408782与sub_408C42函数的区别为,一个为全加密,一个为部分加密。

2.2.4 sub_408782函数(全加密)

if ( hObject != (HANDLE)-1 && !sub_40669B(v16, a1->mainkey, a2) )
{
    while ( ReadFile(hFile, (LPVOID)a1->buffer, nNumberOfBytesToRead, &nNumberOfBytesToWrite, 0) )
    {
    if ( nNumberOfBytesToWrite < nNumberOfBytesToRead )
    {
        dwFlagsAndAttributes = 16 - (nNumberOfBytesToWrite & 0xF);
        sub_408FA9((char *)(nNumberOfBytesToWrite + a1->buffer), 0, dwFlagsAndAttributes);
        nNumberOfBytesToWrite += dwFlagsAndAttributes;
    }
    if ( !sub_406432((int)v16, a1->buffer, a1->buffer)
        || !WriteFile(hObject, (LPCVOID)a1->buffer, nNumberOfBytesToWrite, &NumberOfBytesWritten, 0)
        || NumberOfBytesWritten != nNumberOfBytesToWrite )
    {
        break;
    }
    if ( nNumberOfBytesToWrite < nNumberOfBytesToRead )
    {
        v15 = v18;
        *buffer = 0;
        v14 = v19;
        buffer[1] = 2;
        v13 = (int)v20;
        buffer[2] = -257466862;
        buffer[6] = 32;
        sub_408FD7(v13, v14, v15);
        sub_408FD7(v9, (int)a1->zero, 20);
        sub_408FD7(v9 + 20, a2, 16);
        sub_408FD7(v9 + 40, a1->mainkey + 32, 128);
        sub_408FD7(v9 + 172, (int)a1->ident, 6);
        v11 = v22;
        *(_DWORD *)(v9 + 36) = dwFlagsAndAttributes;
        *(_DWORD *)(v9 + 168) = v11 + 178;
        if ( !sub_40669B(v17, a1->mainkey, a2) )
        {
        if ( sub_406432((int)v17, a1->buffer, a1->buffer) )
        {
            sub_408FA9(v17, 0, 0x128u);
            if ( WriteFile(hObject, (LPCVOID)a1->buffer, *(_DWORD *)(v9 + 168), &NumberOfBytesWritten, 0) )
            {
            if ( NumberOfBytesWritten == *(_DWORD *)(v9 + 168) )
            {
                if ( (a5 & 4) != 0 )
                sub_4086B7(hFile);
                if ( (a5 & 2) != 0 )
                {
                FlushFileBuffers(hFile);
                FlushFileBuffers(hObject);
                }
                v23 = 1;
            }
            }
        }
        }
        break;
    }
    }
    sub_408FA9(v16, 0, 0x128u);
}

其中函数sub_406432为加密函数,v16与v17为加密时需要使用的数据,包括密钥与初始IV等,通过函数sub_40669B生成加密需要使用的数据,加密后的数据写入新文件,最后会删除原文件。

在函数sub_C6669B中的a1为重要结构体,包括加密缓冲区与加密需要的信息,分析结构如下:

struct a1{
    Byte* mainkey;//指向164 Byte的地址
    Byte zero[20];//暂未发现作用
    Byte ident[8];//存放机器的唯一标识
    Byte* buffer;//指向一块1114370h大小的内存,用作加密时的缓冲区
    int buffer_size=1114370;//缓冲区大小
}

图片

加密完文件内容后会加密文件的基础信息,包括文件名等信息,其中,a2也会被加密后放入文件末尾(a2为之前生成的filekey)。

在此处下断点:

图片

图片

被加密的数据如下

0348F020  00 00 00 00 02 00 00 00  12 5E A7 F0 79 6F A5 46  .........^.....F
0348F030  37 80 23 35 7A 83 51 3B  20 00 00 00 9E 3F 4F 64  7.#5z.Q; ....?Od
0348F040  43 00 55 00 41 00 73 00  73 00 69 00 73 00 74 00  C.U.A.s.s.i.s.t.
0348F050  61 00 6E 00 74 00 54 00  61 00 73 00 6B 00 2E 00  a.n.t.T.a.s.k...
0348F060  78 00 6D 00 6C 00 00 00  F8 FC 14 D4 F7 93 92 4A  x.m.l..........J

其中包括当前文件的文件名CUAssistantTask.xml

查看此函数sub_C6669B的其余变量可得到被加密的文件路径为C:\Program Files\CUAssistant\CUAssistantTask.xml。

函数sub_408C42的加密流程与函数sub_408782一致,区别是sub_408C42是部分加密,2个函数都会调用同一个加密核心函数sub_406432。

2.2.5 sub_406432函数(加密核心函数)

int aes_crypt_cbc( aes_context *ctx,
                    int mode,
                    const unsigned char iv[16],
                    const unsigned char *input,
                    unsigned char *output,
                    unsigned int length )
{
    int i;
    unsigned char temp[16];
    if( length % 16 )
        return( POLARSSL_ERR_AES_INVALID_INPUT_LENGTH );
    if( mode == AES_DECRYPT )
    {
        while( length > 0 )
        {
            memcpy( temp, input, 16 );
            aes_crypt_ecb( ctx, AES_DECRYPT, input, output );
            for( i = 0; i < 16; i++ )
                output[i] = (unsigned char)( output[i] ^ iv[i] );
            memcpy( iv, temp, 16 );
            input  += 16;
            output += 16;
            length -= 16;
        }
    }
    else
    {
        while( length > 0 )
        {
            for( i = 0; i < 16; i++ )
                output[i] = (unsigned char)( input[i] ^ iv[i] );
            aes_crypt_ecb( ctx, AES_ENCRYPT, output, output );
            memcpy( iv, output, 16 );
            input  += 16;
            output += 16;
            length -= 16;
        }
    }
    return( 0 );
}

2.2.6  killsystemprocesses函数(杀死不利进程)

图片

图片

2.2.7 eternal_blue函数(永恒之蓝)

使用永恒之蓝漏洞,通过445端口横向感染内网其他主机,达到利用的目的:

图片

图片

尝试连接其他主机的445端口:

图片

复制令牌:

图片

2.2.8 self_copy函数(自我复制)

自我复制并隐藏.目录如下

C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\StartMenu\Programs\Startup
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
C:\Users\Administrator\AppData\Local

写入注册表启动项

Software\Microsoft\Windows\CurrentVersion\Run

图片

图片

2.2.9 write_black_page函数(线程执行函数)

写入黑页.通过执行cmd,将所有用户桌面改为全黑色,并生成勒索页面和勒索信息,地址等等。

图片

图片

3.病毒分析概览

根据对样本的深入逆向工程分析,得出该勒索病毒分析结果概览:

主要功能

自我复制、提升权限、开机自启、利用永恒之蓝漏洞进行传播、文件加密、生成勒索提示页(黑页)、创建任务完成监视线程

安全特征

CRC32校验:用于自校验

字符串混淆

采用6347模式,输入49作为ID号解密字符串

AES ECB加密

使用明确指定的Key

子进程操作

创建子进程关闭防火墙

系统操作

修改注册表、添加自启动项目、获取硬盘信息,并进行SHA-256尝试发送HTTP POST请求(未指定参数)

网络与传播

内网扫描,寻找开放445端口的主机利用永恒之蓝漏洞进行攻击,创建攻击线程

进程操作

枚举并终止特定进程,如一些系统应用、数据库服务等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/554202.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python笔记 | 哥德巴赫猜想

哥德巴赫猜想&#xff1a;每个不小于6的偶数都可以表示成两个素数之和。 素数&#xff1a;只能被1和自身整除的正整数。就是大于1且除了1和它本身之外没有其他因数的数。例如&#xff0c;2、3、5、7、11等都是素数&#xff0c;而4、6、8、9等则不是素数。 下面这段Python代码…

Day 16 Linux服务管理和日志管理

服务管理 启动服务&#xff1a;systemctl start 服务名 停止服务&#xff1a;systemctl stop 服务名 重启服务&#xff1a;systemctl restart 服务名 重新加载配置文件&#xff1a;systemctl reload 服务名&#xff08;期间并不停止服务进程&#xff09; 查看服务运行状态…

十、OOP面向对象程序设计(五)

1、什么是接口以及接口的运用 1)接口定义 Java接口(Interface),是一些列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能。) 2)接口定义的一般形式 修饰符:…

git使用(上传自己的项目到github上)

之前最早使用的方式是使用as上面的菜单功能VCS——>share project on github,,, 现在我们使用命令的方法上传。 第一步&#xff1a;在github上面Create a new repository 这里输入仓库的名称和描述&#xff0c;勾选Add a README file&#xff0c;这会在创建仓库的时候添加…

一些重新开始面试之后的八股文汇总

一、内存中各项名词说明 1、机器内存概念说明 linux中的free命令可以查看机器的内存使用情况&#xff0c;vmstat命令也可以 其中不容易被理解的是&#xff1a; 内存缓冲/存数&#xff08;buffer/cached&#xff09; 1.buffers和cache也是RAM划分出来的一部分地址空间 2.buff…

css div添加滚动条(附加源码)

问题描述 先看效果图。 每个商品通过后台接口查询出来&#xff0c;前端v-for进行显示&#xff0c;所以这块我要添加一个滚动条&#xff0c;我不确定有多少个商品。 解决方案 实现思路&#xff1a;div设置高度为1000rpx&#xff08;我这边是举例&#xff0c;根据实际场景去设…

Jenkins 流水线多阶段构建

Jenkins流水线配置遇到 无法识别的。需要使用 自定义环境 项。 比如官网的在流水线中使用Docker Started by remote host 172.17.0.1 Obtained Jenkinsfile from git http://10.99.20.51:8082/root/java-devops-demo.git org.codehaus.groovy.control.MultipleCompilationErro…

Ribbon 添加右侧区域菜单项

效果图如下所示&#xff1a; 类似与上图效果所示&#xff0c;代码如下&#xff1a; RibbonPage* pageHome1 ribbonBar()->addPage(tr("Home")); //实现代码&#xff1a; { QMenu* menuOptions ribbonBar()->addMenu(tr("Options"))…

节点加密技术:保障数据传输安全的新利器

随着信息技术的快速发展&#xff0c;网络数据的安全传输问题日益凸显。节点加密技术作为一种新兴的加密手段&#xff0c;正逐渐成为保障数据传输安全的重要工具。本文将探讨节点加密技术的原理、应用及其优势&#xff0c;并分析其未来的发展趋势。 节点加密技术的原理 节点加密…

腾讯InstantMesh30秒图片生成3D模型;微软实时生成会说话的头像VASA;由 AI 创作的恶搞视频片段Sitcom Simulator

✨ 1: InstantMesh 30 秒内从一张图片生成 3D 模型 InstantMesh是一个基于单张图片&#xff0c;利用先进的稀疏视图大型重建模型&#xff08;LRM&#xff09;架构&#xff0c;快速生成3D网格&#xff08;Mesh&#xff09;的工具。这个框架允许用户将2D图片转换成3D模型&#…

学习笔记------时序约束之时钟周期约束

本文摘自《VIVADO从此开始》高亚军 主时钟周期约束 主时钟&#xff0c;即从FPGA的全局时钟引脚进入的时钟或者由高速收发器输出的时钟。 对于时钟约束&#xff0c;有三个要素描述&#xff1a;时钟源&#xff0c;占空比和时钟周期。 单端时钟输入 这里我们新建一个工程&#x…

如何使用Flask搭建web程序框架并实现无公网IP远程访问本地程序

文章目录 前言1. 安装部署Flask并制作SayHello问答界面2. 安装Cpolar内网穿透3. 配置Flask的问答界面公网访问地址4. 公网远程访问Flask的问答界面 前言 Flask是一个Python编写的Web微框架&#xff0c;让我们可以使用Python语言快速实现一个网站或Web服务&#xff0c;本期教程…

HarmonyOS NEXT 使用XComponent + Vsync 实现自定义动画

介绍 XComponent 提供了应用在 native 侧调用 OpenGLES 图形接口的能力&#xff0c;本文主要介绍如何配合 Vsync 事件&#xff0c;完成自定义动画。在这种实现方式下&#xff0c;自定义动画的绘制不在 UI 主线程中完成&#xff0c;即使主线程卡顿&#xff0c;动画效果也不会受…

汽车充电桩充电效率的四大决定因素

随着电动汽车的快速普及&#xff0c;交流充电桩作为电动汽车的充电基础设施&#xff0c;其充电效率受到了广泛的关注。接下来&#xff0c;我们将深入探讨交流充电桩的充电效率&#xff0c;包括充电效率的定义、影响因素以及提升方法。 充电效率的定义 交流充电桩的充电效率指的…

基于Springboot+Vue的Java项目-网上超市系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

构建现代网页的引擎:WebKit架构揭秘

在网络信息迅猛增长的今天&#xff0c;浏览器已经成为我们接触世界的重要窗口。而在浏览器的核心&#xff0c;有一个强大的引擎在默默地支撑着网页的渲染和执行&#xff0c;这就是WebKit。 WebKit的核心组件 WebKit作为开源浏览器引擎&#xff0c;由苹果公司发展而来&#x…

前端编程环境配置

目录 vscode插件的安装快捷键常用的快捷键自定义快捷键 vscode 插件的安装 汉化&#xff0c;将vscode改为中文版 Chinese (Simplified)修改开始标签&#xff0c;结束标签跟着一起变化 Auto Rename Tag颜色主题 One Dark Pro格式化代码(建议使用系统自带) 配置&#xff1a…

二叉树和数据结构

小红的完全二叉树构造 题目描述 小红想构造一个总共 n 个节点完全二叉树&#xff0c;该二叉树满足以下两个性质&#xff1a; 1. 所有节点的权值值为 1 ~ n 的一个排列。 2. 除了根节点以外&#xff0c;每个节点的权值和它父亲的权值的乘积为偶数。 请你帮小红构造出这个二叉树…

Docker容器逃逸-特权模式-危险挂载-Procfs

Docker容器逃逸-特权模式-危险挂载&#xff08;95天&#xff09; Docker这个概念&#xff1a; Docker 容器与虚拟机类似&#xff0c;但二者在原理上不同&#xff0c;容器是将操作系统层虚拟化&#xff0c;虚拟机则是虚拟化硬件&#xff0c;因此容器更具有便携性、高效地利用服务…

1.Chinese Tiny LLM_ Pretraining a Chinese-Centric Large Language Model

文章目录 摘要一、背景二、预训练数据统计信息数据处理 模型架构 三、SFT四、Learning from Human Preferences五、评估数据集和指标训练过程和比较分析安全性评估中文硬指令理解与遵循评价 六、结论 https://arxiv.org/abs/2404.04167https://github.com/Chinese-Tiny-LLM/Chi…