火绒安全一面病毒样本分析

5 篇文章 0 订阅
2 篇文章 0 订阅

Summary

病毒高危行为:

  1. 请求一系列加密的未知IP的443端口,连接可能与其他恶意软件通讯;尝试HTTP但是全都失败了
  2. 使用了大量的微软提供的加密函数,已知是AES对称加密
  3. 过程中怀疑使用了代码混淆
  4. 存在多处绕检测,反调试行为:比如频繁分配内存调用native方法,存在用另一个用户开启线程;多处使用了RDTSC指令来比对执行时间检测虚拟化或反调试;存在大量延迟尝试绕检测;存在LdrLoadDll动态调用绕检测;可能读取PEB信息检测调试器;修改token权限

 

MD5

974d669e861896a0ebd61c7f2d6e8729

SHA-1

3166a8b05fab2c455586e717210bdf1dad621fc1

SHA-256

b00e7f74539cf39940c9044b6ac1d131a23c896c7905d71a087a01245232ada3

Vhash

0150366d556"z

Authentihash

85badbaa56eef4169eb3c0127d9dace88a0b65b5965ad5a146a3477ab38914d4

SSDEEP

3072:9Wql7iWCRq3JV0npTvzY7hEsZNhh8J3Wn:9DNiWn52k7hEsBh

TLSH

T1B8D3490AE7D782B1FE9601B0167EB73F997152216B159EC3C7A01C20AD512E3A33E76D

File type

Win32 EXE

Magic

PE32 executable for MS Windows (GUI) Intel 80386 32-bit

 

 

 

调试过程logs

查完文件基本信息之后发现不是常见的vc/C++程序,直接拉到OD里面跑起来,试了一下平时用的一些脱壳方法完全不凑效,发现该程序的PE比较奇怪导入和导出表地址均为0,

 

于是开始单步调试大法

 

程序一定需要运行时动态加载未加载完的dll,所以我打开内存映射窗口,看着主窗口,一遍单步一遍观察内存情况同时适当的跳过一些未知的加密循环,光标所在行的上一个call eax为Sleep大约3秒然后光标处加载剩余dll(function0040C2F0),随后马上进入一个Function 00416870,

 

 

 

Function 00416870大概应该可以确定是程序的主体逻辑了.(本来尝试过dump 但是dump之后还是无法运行 大概是动态解密的关系吧)

 

进来16870之后是一个包含大量Sleep,获取CPU时钟相关API的函数,除此之外还有一个子调用,其中主要功能大概为遍历某个文件夹下的所有文件

 

随后经过一系列Sleephe GetTickCount,再后面看到几个消息处理的API一直到RtlAddVectoredExceptionHandler。然后出现一个子调用call Function 405B30

 

进入之后看到上面有几个子调用然后出现一个ConvertStringSecurityDescriptorToSecurityDescriptorW  CreateMutexW

查阅MSDN之后,前者通常用于转换安全描述符,结合后面的CreateMutexW打开或者创建互斥量可以得出,这段代码大概率是在打开与当前病毒进程文件同名的信号互斥量,判断信号互斥量是否存在,防止病毒行为的二次执行。

 

 

 

那么我大胆推测病毒的主要功能就在这个代码的上方,结合ida的F5 我认为Function0041C6E0(v3 = mainfunction((int)v17, 0);) 包含了大量逻辑

 

  v3 = mainfunction((int)v17, 0);

  v4 = 1;

  if ( !v3 )

  {

    sub_4121B0(v16, 50);

    if ( ConvertStringSecurityDescriptorToSecurityDescriptorW(v16, 1, &v10, 0) )

    {

      v11 = v15;

    }

    else

    {

      v10 = 0;

      v11 = 0;

    }

    v5 = sub_41A120();

    v15[0] = 12;

    v15[2] = 0;

    LODWORD(v13) = -1640531527 * v5;

    HIDWORD(v13) = -1640531527 * sub_41A120();

    v15[1] = v10;

    v14 = sub_403020(v17, 2 * v2, v13, HIDWORD(v13));

    if ( dword_41F138(&v13, &v12) < 0 )

    {

      sub_4121B0(v17, 119);

      sub_401CB0(v17, 128, v17, v13, v14);

      v12 = v17;

    }

    v6 = sub_4121B0(v16, 27);

    sub_41DD90((char *)v16 + 2 * v6, v12, 100);

    v7 = createMute(v11, 1, v16);

    *this = v7;

    if ( v10 )

    {

      localFree(v10);

      v7 = *this;

    }

    if ( !v7 || (v8 = getLastError(), v4 = 1, v8 != 183) )

      v4 = 0;

  }

  return v4;

 

 

 

进入这个函数 发现非常非常的长,再逐行分析的话非常不容易,于是我查找所有的模块间调用同时查找所有模块中的名称,查看一下是否有一些敏感的api调用。

 

 

以下为我整理的可疑函数:

 

加密:

00406D10 CryptAcquireContextW,CryptImportKey,CryptSetKeyParam,CryptSetKeyParam,CryptDecrypt,CryptReleaseContext,CryptDestroyKey

 

0040E760 CryptAcquireContextW,CryptCreateHash,CryptHashData,CryptGetHashParam,CryptGetHashParam,CryptDestroyHash,CryptReleaseContext

 

0041A890 CryptStringToBinaryW,CryptStringToBinaryW

 

0040E300 CryptBinaryToStringW,CryptBinaryToStringW

 

网络:(函数在OD中并没有执行 可能是因为检测到调试器吧?unsure

00415C80 WSAStartup WSACleanup HeapCreate GetProcessHeap RtlAllocateHeap FreeAddrInfoW getaddrinfo FreeAddrInfoW RtlFreeHeap

004067A0 GetCurrentProcess,OpenProcessToken,LookupPrivilegeValueW,AdjustTokenPrivileges,FindCloseChangeNotification

00407870 GetCurrentProcess,OpenProcessToken,LookupPrivilegeValueW,AdjustTokenPrivileges,RevertToSelf,DuplicateTokenEx,CloseHandle,AdjustTokenPrivileges,CloseHandle

0040DB40 GetStartupInfoW,GetCurrentProcess,OpenProcessToken,LookupPrivilegeValueW,AdjustTokenPrivileges,OpenProcess,OpenProcessToken,GetTokenInformation,AllocateAndInitializeSid,EqualSid,OpenProcessToken,RevertToSelf,DuplicateTokenEx,GetTokenInformation,GetTokenInformation,LookupAccountSidW,CreateProcessAsUserW,GetLastError,CloseHandle,CloseHandle,CloseHandle,AdjustTokenPrivileges,CloseHandle

0040BFB0 GetCurrentProcess,OpenProcessToken,LookupPrivilegeValueW,AdjustTokenPrivileges,CloseHandle,

可能的反调试,绕检测

004021A0 RtlReAllocateHeap,NtDelayExecution,NtDelayExecution,

0041C6E0 NtQuerySstemInformation,NtQueryObject,GetCurrentProcess,NtQuerySystemInformation,OpenProcess,DuplicateHandle,NtQueryObject,NtQueryObject,NtQueryObject,FindCloseChangeNotification,FindCloseChangeNotification(CheckRemoteDebuggerPresent中会调用NtQueryInformationProcess函数)

 

004116E0 GetProcAddress,NtQueryInformationProcess

 

00408810 rdtsc  通过统计时间,判断当前环境是否是虚拟

 

0041B7A0      GetAdaptersInfo,GetAdaptersInfo  获取网络适配器信息

 

0040B4D0 LdrLoadDll,未公开的内核调用加载dll

 

大量的延迟函数:

419FD0  Sleep

4021D6   NtDelayExecution

403643   Sleep

4021D6   NtDelayExecution

4021D6   NtDelayExecution

408416   Sleep

4171A8   Sleep

4021D6   NtDelayExecution

 

 

可能用另一个用户启动线程:

0040DB40 GetStartupInfoW,GetCurrentProcess,OpenProcessToken,LookupPrivilegeValueW,AdjustTokenPrivileges,OpenProcess,OpenProcessToken,GetTokenInformation,AllocateAndInitializeSid,EqualSid,OpenProcessToken,RevertToSelf,DuplicateTokenEx,GetTokenInformation,GetTokenInformation,LookupAccountSidW,CreateProcessAsUserW,GetLastError,CloseHandle,CloseHandle,CloseHandle,AdjustTokenPrivileges,CloseHandle,

 

动态调用api

00405940 LoadLibraryW,GetProcAddress,

 

 

程序大致流程和逻辑

 

 

设置了一个计时器和消息处理,然后创建了heap,在最下面的if出call 405b30

 

来到405b30

 

遍历完目录之后进入41c6e0

 

 

 

综合上述信息可得v117的结果应该是通过rdtsc测量时间来检测虚拟化

那么从125行到172行一定是具体检测的逻辑,对于具体怎么测量我不是很清楚

 

变量v5处再次调用41a120应该是测量前后两次时间差作比较的

接下来又出现3个子调用

 

第一个

 

4195a0

 

408c30

存在循环和位运算,和上一个函数的入参密码相关

 

 

第二个

 

打开句柄调整token权限

 

第三个

408810是之前的rdtsc指令,getTickCount上下都存在多个rdtsc

 

执行完第三个函数之后的变量v106和v117存在大量相似的计算和比较

 

 

V106还额外执行了上图的3个函数,结合逻辑可以得出上述的推测应该是正确的,即通过106和117获取检测虚拟化,同时在第一个调用处尝试隐藏一些信息(4195a0每次进入循环虚拟机就卡死了,不知道具体是在做什么样的加密)

接下来到label58

 

4148c0

 

执行到返回

 

 

中间又是包含一堆数学计算

然后出现一个入参包括v24,即上面计算结果的一个复制对象句柄函数

 

 

进入41a120之后发现又是一堆rdtsc和位运算

 

 

跟v69执行同样的操作在下面还有个v72=sub_41a120();

 

函数结尾处 停止监视通知更改句柄

 

 

该函数执行完后if判断通过

 

 

V7后面的操作应该就是判断是否重复执行了,所以该函数分析结束

 

返回到外层函数

 

40e940

生成sid 判断sid相等

 

 

40e5d0

StrStrlW GetSystemDirectoryW

大致逻辑下图     

其中的41A840

 

返回a1不超过a2的第一个0地址

 

 

8460函数里面逻辑比价复杂

总体上应该就是一个获取目录比较确定目录同时包含加密解密的过程

 

 

 

 

在Function 00416870函数主体中一路分析

 

 

 

 

直到此处发现第一个网络连接httpAPiCalled,具体调用时数据如下图

 

 

跟进dword_41f044的函数看到出现了http相关的api

 

可以推测这个函数所在的循环 会循环请求ip地址列表中的ip,由于没有网络安全方面的工具,无法检测目标ip的安全性

继续调试

 

 

这个函数明显发送了请求 并且返回了请求失败

 

我在httpcall的地方留了断电 ,F9直接发现了第二个尝试请求的ip

 

继续F9

 

 

我在realrequest的地方F9至少等待了5次以上,不清楚这个

 

于是我打开wireshark对目标ip进行监视

 

 

192.168.88.135     51.77.112.255 TCP 66   49942 → 443 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1

 

关于其连接知道的信息只有这么多了,未知的具体网络行为

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值