记一次钓鱼邮件-分析(上)

admin 2023年6月15日09:12:15评论27 views字数 5862阅读19分32秒阅读模式

前言

最近项目上收到了许多钓鱼邮件,部门大佬对其进行分析后,本文是对部门大佬的分析进行一个复现。从中学习到了很多。这里团队的Snab师傅就带大家一起学习一下,如若有错请指正,一起学习进步。

一共分为两篇:

针对于钓鱼邮件当中的原文件进行分析

针对释放后的木马文件进行分析

思路

1、先将其解压,上传沙箱帮助分析
2、通过ida、xdebug进行分析
3、首先判断其语言
4、分析其所调用的api函数
5、分析应用行为
6、找到外联地址

沙箱分析

在线沙箱地址

https://s.threatbook.com/ --微步
记一次钓鱼邮件-分析(上)
可以看到该exe释放了3个文件
分别是:
Bplnfg.exe
xxxx.pdf
wsqmcons.exe

其中 使用了Bplnfg.exe 调用了wsqmcons.exe 和 ping.exe
看一下微步沙箱的进程分析

记一次钓鱼邮件-分析(上)

该钓鱼文件执行了以下步骤
1、利用释放的Bplnfg.exe 运行了 释放的 xxx.pdf
2、Bplnfg.exe 运行了 释放的wsqmcons.exe
3、ping -5 8.8.8.8 并删除了自生


通过 BpLnfg.exe /c start、BpLnfg.exe /c ping、del 等命令
可以大致猜测BpLnfg.exe 大概率是一个类似commond.exe的东西

而沙箱没有分析出来外联的地址
则可能存在以下情况:
1、反沙箱

通过检测当前运行环境是否正常,如果不正常则直接结束线程
调用sleep函数进行延时,沙箱的分析是有时间限制的,sleep延时个30分钟就能过沙箱检测
2、该初始的钓鱼文件并不是藏有shellcode的文件

而其释放的wsqmcons.exe可能才是最终的木马文件

判断该木马所使用的语言

使用工具:
ExeinfoPe、idea、CFF exploer等

ExeinfoPe

记一次钓鱼邮件-分析(上)

可以看到其是使用 Golang语言编写的 一个exe

Ida

记一次钓鱼邮件-分析(上)

记一次钓鱼邮件-分析(上)

通过idea反编译的到的符号表可以看到 有很多 golang的特征
可以完全确定其使用的语言就是golang

静态分析

以下是通过ida对木马进行 反编译得到的代码进行大致的猜测

一个程序需要运行起来都必须需要一个 主函数入口
一般都为main函数
该木马没有混淆可以直接通过反编译看到其使用的函数

记一次钓鱼邮件-分析(上)

Main()

main_Hvdf_HCzKr() --隐藏窗口

先从 main函数入手

打开看到其main函数的内容长这样

void __cdecl main_main(){  main_Hvdf_HCzKr();  main_Start_Func_HCzKr((__int64)&byte_55859B, 40LL, (__int64)&byte_54F93F, 6LL, 0LL, 0LL, 30LL, 60LL, 10LL);  从第一个main_Hvdf_Hczkr() 开始void main_Hvdf_HCzKr(){  main_ShowConsoleAsync(0LL);}ShowConsoleAsync是golang里面隐藏/显示windows系统下的黑色命令窗口



以下是钓鱼文件中 main_ShowConsoleAsync 具体的实现方法
但他要怎么做 做什么我们只需要知道 他是为了隐藏窗口就足够了,我们的目的不在这里

void __golang main_ShowConsoleAsync(__int64 a1)                {                  github_com_gonutz_ide_w32_GetConsoleWindow();                  if ( v1 )                  {                    v4 = v1;                    github_com_gonutz_ide_w32_GetWindowThreadProcessId(v1);                    github_com_gonutz_ide_w32_GetCurrentProcessId();                    if ( v2 == v3 )                      github_com_gonutz_ide_w32_ShowWindowAsync(v4, a1);                  }

main_Start_Func_HCzKr() --核心

记一次钓鱼邮件-分析(上)

Copy_cmd_pLTZN() --复制cmd

可以看到这个函数前面声明了很多变量 做了一些判断
我们可以很清楚的看到图里有一个函数

Copy_cmd_pLTZN();                                    __int128 main_Copy_cmd_pLTZN()                  {                    main_Get_Home_pLTZN();                    v5 = v1;                    v7 = v0;                    v2 = main_RandStringBytesRmndr_pLTZN(6LL);                     v6 = runtime_concatstring4(0LL, v7, v5, (__int64)&byte_55204B, 17LL, v2, v3, (__int64)&byte_54F497, 4LL);                    main_CopyFileddd_pLTZN(v6, v4, (__int64)&dword_5551A4, 27LL);                    *(_QWORD *)&result = v6;                    *((_QWORD *)&result + 1) = v4;                    return result;                  }                                   main_Get_Home_pLTZN --获取环境变量当中的值                  {                    v6 = os_Getenv((__int64)&byte_5500E5, 9LL);                    v2 = os_Getenv((__int64)&byte_54FD9B, 8LL);                    v0 = runtime_concatstring2(0LL, v6, v3, v2, v3);                    v1 = v5;                    if ( !v5 )                    {                      v0 = os_Getenv((__int64)&word_55084A, 11LL);                      v1 = v4;                    }                    *(_QWORD *)&result = v0;                    *((_QWORD *)&result + 1) = v1;                    return result;                  }     

RandStringBytesRmndr_pLTZN --生成一个随机字符串
runtime_concatstring--将生成的随机字符串与其他进行拼接
CopyFileddd_pLTZN--将文件复制文件

结合反编译代码和其函数名字 Copy_cmd可以大致猜测:
生成一串随机字符串xxx,并将cmd复制到某个目录下重命名为xxx.exe

GetCurrentAbPathByExecutable() --读取文件路径目录遍历

回到main_Start_Func_HCzKr()当中 来看这个函数

main_GetCurrentAbPathByExecutable_pLTZN();                  {                    os_Executable(); --获取当前运行环境的路径                    v6 = v2;                    v7 = v1;                    if ( v3 )                    {                      v8[0] = *(_QWORD *)(v3 + 8);                      v8[1] = v5;                      v5 = log_Fatal((__int64)v8, 1LL, 1LL);                    }                    v4 = path_filepath_Dir(v7, v6); --获取当前运行环境的上级目录                    path_filepath_EvalSymlinks(v4, v5); --获取所执行的文件的绝对路径                    return v6;                  }                  


通过几个golang当中"path/filepath"包下的函数 os.Executable()、filepath.Dir()、filepath.EvalSymlinks()
大致可以猜测其是在读取文件路径目录遍历

main_Run_normal_file_HCzK() --写文件->打开文件
 {                    v9 = runtime_concatstring2(0LL, (__int64)&byte_54F873, 6LL, a5, a6); --字符串拼接                    v6 = HCzKr_Asset(v9, v10);                    io_ioutil_WriteFile(a3, a4, v6, v7, v8, 493);                    main_Open_normal_file_pLTZN(a1, a2, a3, a4, 0LL, 0LL);                   }

HCzKr_Asset --暂时没看懂

记一次钓鱼邮件-分析(上)

io_ioutil_WriteFile --创建文件写入数据

记一次钓鱼邮件-分析(上)

main_Open_normal_file_pLTZN --打开创建的文件

记一次钓鱼邮件-分析(上)

main_Run_and_Task_HCzKr --释放木马文件并执行
{                    random_path_HCzKr = main_Get_random_path_HCzKr((__int64)&dword_55300C, 20LL, 0LL, 0LL);                    main_Get_muma_file_HCzKr(a1, a2, random_path_HCzKr);                    main_Update_task_HCzKr(random_path_HCzKr);                  }
main_Get_random_path_HCzKr
  main_Get_Home_HCzKr();                    v4 = runtime_concatstring2(0LL, v8, v10, a1, a2);                    if ( !a4 )                    {                      main_Get_random_name_HCzKr();                    }                    *(_QWORD *)&result = path_filepath_Join((__int64)v15, 2LL, 2LL);                    *((_QWORD *)&result + 1) = v12;                                    main_Get_Home_HCzKr 与上面的GetCurrentAbPathByExecutable.Get_Home大致一样                  main_Get_random_name_HCzKr 与GetCurrentAbPathByExecutable.RandStringBytesRmndr大致一样                  path_filepath_Join golang当中"path/filepath"的函数 用于路径拼接
main_Get_muma_file_HCzKr --创建木马文件
 {                    v11 = runtime_concatstring2(0LL, (__int64)&byte_54F873, 6LL, a5, a6);                    HCzKr_Asset(v11, v12);                    io_ioutil_WriteFile(a3, a4, v8, v9, v10, 493);                    if ( a8 )                      main_Open_normal_file_pLTZN(a1, a2, a3, a4, a7, a8);                    else                      main_Open_normal_file_pLTZN(a1, a2, a3, a4, 0LL, 0LL);                    }
main_Update_task_HCzKr --创建计划任务

记一次钓鱼邮件-分析(上)

可以看到Update_task_HCzKr当中多处引用了来自github上面的函数

github_com_capnspacehook_taskmaster_Connect                      // Connect connects to the local Task Scheduler service, using the current                      连接到本地任务计划程序服务                      // token for authentication. This function must run before any other functions                      用于身份验证的令牌                                   github_com_capnspacehook_taskmaster__ptr_TaskService_GetRegisteredTasks                            // GetRegisteredTasks enumerates the Task Scheduler database for all currently                     registered tasks.                            所有当前注册的任务枚举任务计划程序数据库                                   github_com_capnspacehook_taskmaster_TaskService_NewTaskDefinition                            // NewTaskDefinition returns a new task definition that can be used to register a new task.                            返回可用于注册新任务的新任务定义                            // Task settings and properties are set to Task Scheduler default values.                            任务设置和属性设置为“任务计划程序”默认值                                              github_com_capnspacehook_taskmaster__ptr_TaskService_UpdateTask                            //UpdateTask updates a registered task.                            更新注册表                                   github_com_capnspacehook_taskmaster__ptr_TaskService_CreateTask                            //CreateTask creates a registered task on the connected computer.                            在连接的计算机上创建一个已注册的任务

具体做了什么事情,还是得通过调试去看

main_Hide_clean_pLTZN --执行命令
 {                    v6 = os_exec_Command(a1, a2, (__int64)v7, 10LL, 10LL);                    v4 = (_BYTE *)runtime_newobject((__int64)&RTYPE_syscall_SysProcAttr);                    *v4 = 1;                    v5 = v6;                    if ( dword_7B7D70 )                      runtime_gcWriteBarrier();                    else                      *(_QWORD *)(v6 + 152) = v4;                    os_exec__ptr_Cmd_Start(v5);                    }

动态调试

隐藏窗口

可以看到当我们将木马文件丢到 x64dbg里面的时候他有一个窗口

记一次钓鱼邮件-分析(上)

在任意一处下断点后运行后 窗口不见了
但是程序还在运行
那么则证实了对静态分析当中的 main_Hvdf_HCzKr 将窗口进行了隐藏

记一次钓鱼邮件-分析(上)

按照反编译出来得到的地址,这里就是木马文件主函数的入口地点

记一次钓鱼邮件-分析(上)

获取计算机当前用户目录

记一次钓鱼邮件-分析(上)

复制CMD.exe

获取了一个字符串

记一次钓鱼邮件-分析(上)

将其释放到 C:UserswowfkAppDataRoaming 下面

记一次钓鱼邮件-分析(上)

将Cwindowssystem32cmd.exe复制到C:UserswowfkAppDataRoamingBpLnfg.exe

记一次钓鱼邮件-分析(上)

往下走可以看到此处调用了 readfile和writeFile
读取cmd.exe,将内容写进BpLnfg.exe

在 Win64 里使用下面寄存器来传递参数:
rcx - 第 1 个参数
rdx - 第 2 个参数
r8 - 第 3 个参数
r9 - 第 4 个参数

记一次钓鱼邮件-分析(上)

记一次钓鱼邮件-分析(上)

记一次钓鱼邮件-分析(上)

记一次钓鱼邮件-分析(上)

记一次钓鱼邮件-分析(上)

创建xxx.PDF文件

记一次钓鱼邮件-分析(上)

记一次钓鱼邮件-分析(上)

通过复制cmd后得到的BpLnfg.exe 打开该pdf文件

记一次钓鱼邮件-分析(上)

创建木马文件

记一次钓鱼邮件-分析(上)

记一次钓鱼邮件-分析(上)

启动木马文件

记一次钓鱼邮件-分析(上)

查看该环境是否联网并删除自身

记一次钓鱼邮件-分析(上)

总结

本次对这个释放文件的木马也就是出售的木马的分析到这也就结束了,如果要说这个木马文件有什么缺点的话:就是太过明显了,释放出来的pdf文件和原来的文件名称都不一致。下篇文章会对初始木马释放的shellcode木马进行分析。如果在日常防护当中,有人中了钓鱼邮件并点击了,请第一时间进行断网处理(断开互联网,有插入网线的也拔了)!!!

原文始发于微信公众号(渗透安全团队):记一次钓鱼邮件-分析(上)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年6月15日09:12:15
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   记一次钓鱼邮件-分析(上)http://cn-sec.com/archives/1808645.html

发表评论

匿名网友 填写信息