You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Netcat连接服务器时自动执行指定二进制程序?

实现方式解析

这种通过Netcat连接端口后自动执行程序并绑定标准流的功能,核心是将网络套接字(Socket)与程序的标准输入/输出/错误流(stdin/stdout/stderr)做重定向,常见实现方式有两种:

1. 借助inetd/xinetd服务(CTF平台最常用)

inetd是类Unix系统上的超级守护进程,xinetd是它的增强版,专门用来管理基于网络的服务。配置后,当有客户端连接指定端口时,它会自动fork子进程并将Socket的文件描述符重定向到子进程的标准流,最后执行目标程序。

配置示例(xinetd)

创建一个配置文件(比如/etc/xinetd.d/pwn_challenge):

service pwn_challenge
{
    type        = UNLISTED
    socket_type = stream
    protocol    = tcp
    wait        = no
    user        = nobody  # 用低权限用户运行,避免权限风险
    server      = /home/pwn/your_challenge_binary
    port        = 9004    # 对应nc连接的端口
    disable     = no
}

配置生效后,xinetd会监听9004端口:当你用nc pwnable.kr 9004连接时,xinetd会:

  • 接受Socket连接
  • fork一个子进程
  • 将子进程的0(stdin)、1(stdout)、2(stderr)文件描述符替换为Socket的fd
  • 调用execve执行指定的二进制程序

此时程序的所有IO操作都会直接通过网络连接和你的本地终端交互。

2. 自定义监听程序(灵活可控)

如果需要更定制化的逻辑,也可以自己写一个Socket监听程序,手动处理连接和流重定向。以下是简化示例:

Python实现

import socket
import os
import sys

def handle_connection(conn):
    # 将Socket的fd复制到标准流的fd(0,1,2)
    os.dup2(conn.fileno(), 0)
    os.dup2(conn.fileno(), 1)
    os.dup2(conn.fileno(), 2)
    # 执行目标二进制程序,替换当前进程
    os.execve('/home/pwn/challenge', ['challenge'], os.environ)

def main():
    server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_sock.bind(('0.0.0.0', 9004))
    server_sock.listen(5)
    
    while True:
        client_conn, client_addr = server_sock.accept()
        # fork子进程处理连接,父进程继续监听
        pid = os.fork()
        if pid == 0:
            server_sock.close()
            handle_connection(client_conn)
            client_conn.close()
            sys.exit(0)
        else:
            client_conn.close()

if __name__ == '__main__':
    main()

C语言实现(核心逻辑)

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

int main() {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in serv_addr = {
        .sin_family = AF_INET,
        .sin_port = htons(9004),
        .sin_addr.s_addr = INADDR_ANY
    };
    bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
    listen(sockfd, 5);

    while (1) {
        int connfd = accept(sockfd, NULL, NULL);
        if (fork() == 0) {
            close(sockfd);
            // 重定向标准流到Socket
            dup2(connfd, 0);
            dup2(connfd, 1);
            dup2(connfd, 2);
            close(connfd);
            // 执行目标程序
            execl("/home/pwn/challenge", "challenge", NULL);
            exit(0);
        }
        close(connfd);
    }
    return 0;
}

关键原理

无论是用inetd还是自定义程序,核心都是**dup2系统调用**:它会将指定的文件描述符(这里是Socket的连接fd)复制到目标fd(0、1、2对应标准流),使得程序后续的IO操作都直接指向网络连接,而非终端。

内容的提问来源于stack exchange,提问作者natitati

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 05:42:42