Code:
/* Author: 0xception
* Date: Win, 2004
* Title: Pogo
* File: pogo.c
* Purpose: To allow a client to connect to this server
* and then pogo will forward any incoming
* shell commands to the target computer running
* a shell, bash, command prompt.
*/
#include <stdio.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#define MAXBUFSIZE 65535
#define MAXPENDING 5
void pogo(int,int);
int main(int argc, char*argv[])
{
int servSock;
int clntSock;
int trgtSock;
int bytesRcvd;
int setFork = 0;
struct sockaddr_in serv;
struct sockaddr_in clnt;
struct sockaddr_in trgt;
unsigned short servPort;
unsigned short trgtPort;
unsigned int clntLen;
unsigned int trgtLen;
unsigned int childProcCount = 0;
char *trgtIP;
pid_t pid;
int flag;
while((flag = getopt(argc,argv,"fp:t:r:")) != -1)
{ switch(flag)
{ case 'f':
setFork = 1;
break;
case 'p':
servPort = atoi(optarg);
/* DEBUG /* printf("\t -p: %d\n",servPort); */
break;
case 't':
trgtIP = optarg;
/* DEBUG /* printf("\t -t: %s\n",trgtIP); */
break;
case 'r':
trgtPort = atoi(optarg);
/* DEBUG /* printf("\t -r: %d\n",trgtPort); */
break;
default:
fprintf(stderr, "Usage: %s [-f] -p <Server Port> -t <Target IP> -r <Target remote Port> \n\t See Also: README\n",argv[0]);
exit(1);
}
}
/*
* Server Setup
*/
if((servSock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0)
{ fprintf(stderr, "ERROR: Incomming socket Error\n");
exit(1);
}
memset(&serv,0,sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_addr.s_addr = htonl(INADDR_ANY);
serv.sin_port = htons(servPort);
if(bind(servSock, (struct sockaddr*)&serv, sizeof(serv)) < 0)
{ fprintf(stderr, "Error: bind() faild\n");
exit(1);
}
/*
* Server Listen
*/
if(listen(servSock,MAXPENDING) < 0)
{ fprintf(stderr, "Error: listen() failed\n");
exit(1);
}
for(;;)
{ clntLen = sizeof(clnt);
if((clntSock = accept(servSock, (struct sockaddr*)&clnt, &clntLen)) < 0)
{ fprintf(stderr, "Error: accept() failed\n");
exit(1);
}
printf("Client Connected: %s\n",inet_ntoa(clnt.sin_addr));
if(setFork == 1)
{ /* Fork the process to allow multiple clients IE: Threading */
if((pid = fork()) < 0)
{ fprintf(stderr, "Error: fork() failed\n");
exit(1);
}
else if(pid == 0)
{ close(servSock); /* Child process closes listening socket */
/*
* Target Setup
*/
if((trgtSock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0)
{ fprintf(stderr,"Error: target.socket() failed\n");
exit(1);
}
memset(&trgt,0,sizeof(trgt));
trgt.sin_family = AF_INET;
trgt.sin_addr.s_addr = inet_addr(trgtIP);
trgt.sin_port = htons(trgtPort);
/*
* Connects to target server
*/
if(connect(trgtSock,(struct sockaddr*)&trgt,sizeof(trgt)) < 0)
{ fprintf(stderr,"Error: target.connect() failed\n");
exit(1);
}
pogo(clntSock, trgtSock);
exit(0);
} /* END ELSE IF */
printf("Child Process: %d\n", (int)pid);
/* Close Current sockets */
close(clntSock);
printf("\tConnection Closed\n");
childProcCount++;
/* Clean up all zombie processes */
while(childProcCount)
{ pid = waitpid((pid_t) -1,NULL,WNOHANG);
if(pid < 0)
{ fprintf(stderr,"Error: waitpid() failed\n");
exit(1);
}
else if(pid == 0)
{ break; }
else
{ childProcCount--; }
}
} /* END IF */
else
{ /*
* Target Setup
*/
if((trgtSock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0)
{ fprintf(stderr,"Error: target.socket() failed\n");
exit(1);
}
memset(&trgt,0,sizeof(trgt));
trgt.sin_family = AF_INET;
trgt.sin_addr.s_addr = inet_addr(trgtIP);
trgt.sin_port = htons(trgtPort);
/*
* Connects to target server
*/
if(connect(trgtSock,(struct sockaddr*)&trgt,sizeof(trgt)) < 0)
{ fprintf(stderr,"Error: target.connect() failed\n");
exit(1);
}
pogo(clntSock, trgtSock);
exit(0);
} /* END ELSE */
} /*END WHILE */
close(servSock);
close(clntSock);
close(trgtSock);
return 0;
} /* END MAIN */
void pogo(int clntSock, int trgtSock)
{
char *buffer;
buffer = (char*)calloc(1,MAXBUFSIZE);
int recvMsgSize;
int lcv;
int wait = 0;
pid_t cPID = getpid();
/* Grab first client request */
if((recvMsgSize = recv(clntSock,buffer,MAXBUFSIZE,0)) < 0)
{ fprintf(stderr,"\tError: [%d] client.recv() failed\n",(int)cPID);
printf("buffer: \n %s",buffer);
exit(1);
}
while(recvMsgSize > 0)
{
/* DEBUG */ printf("\tclnt-trgt Buffer: %s",buffer);
/* Sends the Target the Clients message */
if(send(trgtSock,buffer,recvMsgSize,0) != recvMsgSize)
{ fprintf(stderr,"\tError: [%d] target.send() failed\n",(int)cPID);
exit(1);
}
/* MAY NEED TO CLEAR BUFFER HERE */
free(buffer);
buffer = (char*)calloc(1,MAXBUFSIZE);
while(recvMsgSize > 0)
{ /* Recv message from the target */
if((recvMsgSize = recv(trgtSock,buffer,MAXBUFSIZE,MSG_DONTWAIT)) < 0)
{ printf("\ttrgt-clnt Buffer in if: %s\n",buffer);
fprintf(stderr,"\t\tError: [%d] target.recv() failed\n",(int)cPID);
}
else
{
/* DEBUG /* printf("\ttrgt-clnt Buffer in else: %d, size: %s",strlen(buffer),buffer);*/
/* Sends the client the message recieved from the target */
if((send(clntSock,buffer,recvMsgSize,0) != recvMsgSize))
{ fprintf(stderr,"\t\tError: [%d] client.send() failed\n",(int)cPID);
exit(1);
}
free(buffer);
buffer = (char*)calloc(1,MAXBUFSIZE);
printf("\tbuffer size: %d\n",strlen(buffer));
}
} /* END WHILE */
/* Grab first client request */
if((recvMsgSize = recv(clntSock,buffer,MAXBUFSIZE,0)) < 0)
{ fprintf(stderr,"\tError: [%d] client.recv() failed\n",(int)cPID);
exit(1);
}
} /* END WHILE */
} /* END POGO */