一、前言

一般来说,木马是既有客户端也有服务器端的。上次讨论的不过是一种特殊情况,毕竟不是人人都懂得DOS命令,因此现在木马的客户端也都是做成非常直观的界面形式,方便操作。本篇文章会从客户端与服务器端两个方面进行讨论,与上次的讨论不同的是,这次我会直接把用来模拟病毒的对话框程序放入服务器端,这样只要成功连接,那么就可以通过由客户端所发出的命令来让服务器端直接执行对话框程序。用这种思想,可以给服务器端增加很多功能,但是在这里仅仅讨论对话框的打开。

二、服务器端的实现

这里所讨论的木马依旧是命令行下的木马,如果当实现的命令不断增多,那么就会很容易忘记。所以为了便于使用,可以在木马服务器端加入一个简单的帮助信息,就是说,在客户端输入帮助命令后,服务器端就会把相应的帮助信息发送到客户端。另外,由于可能会有很多的功能,所以在服务器端设置一个指令分发机制,从而便于执行相应的功能。完整代码如下:

#include<winsock2.h>
#include<windows.h>
#pragma comment(lib, "ws2_32.lib")
//定义开放端口
#define MasterPort 999
//定义帮助信息
#define HELPMSG "help - Show Help Menu \r\n" \
"hack - Show MessageBox \r\n"\
"exit - Quit BdShell"
//显示对话框
void hack()
{
MessageBox(0,"You have been hacked! (by J.Y.)","Warning",0);
return;
}
//指令分发
BOOL Dispatch(SOCKET sock, char *szCmd)
{
BOOL bRet = FALSE; //执行help指令
if ( !strcmp(szCmd, "help") )
{
send(sock, HELPMSG, strlen(HELPMSG) + sizeof(char), 0);
bRet = TRUE;
}
//执行hack指令
else if ( !strcmp(szCmd, "hack") )
{
hack();
bRet = TRUE;
}
return bRet;
} int main(int argc, char argv[])
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData); SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); sockaddr_in sockaddr;
sockaddr.sin_family = PF_INET;
sockaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
sockaddr.sin_port = htons(MasterPort); bind(s, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR)); listen(s, 1); SOCKADDR clientAddr;
int nSize = sizeof(SOCKADDR);
SOCKET clientSock;
clientSock = accept(s, (SOCKADDR*)&clientAddr, &nSize); while(TRUE)
{
//发送一个命令提示
send(clientSock,
"BdShell>",
strlen("BdShell>") + sizeof(char),
0); char buff[MAXBYTE] = { 0 }; //接收客户端发来的命令如果是exit则退出while循环
recv(clientSock, buff, MAXBYTE, 0);
if ( !strcmp(buff, "exit") )
{
break;
} //分发命令并执行
BOOL bRet = Dispatch(clientSock, buff);
//指令输入错误时的处理
if( bRet == FALSE )
{
send(clientSock,
"Command Unsuccessfully!",
strlen("Command Unsuccessfully!") + sizeof(char),
0);
}
}
//关闭套接字
closesocket(clientSock);
closesocket(s); WSACleanup();
return 0;
}

上述代码是一个框架,可以不断完善来丰富功能,功能的修改只涉及服务器端,客户端是无需修改的。不过这仅仅是为了学习,要开发一个专业的木马并不是一件容易的事。最关键的是,我在这里所讲的一切都是为了学习计算机安全知识,而不是为了搞破坏。希望大家铭记于心。

三、客户端的实现

木马客户端的代码就是完成字符串的发送而已,非常简单,代码如下:

#include<stdio.h>
#include<conio.h>
#include<winsock2.h>
#include<windows.h>
#pragma comment(lib, "ws2_32.lib")
//定义开放端口
#define MasterPort 999 int main(int argc, char argv[])
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData); SOCKET ClientSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); sockaddr_in ServerAddr; ServerAddr.sin_family = PF_INET;
//定义服务器端的IP地址
ServerAddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.107");
ServerAddr.sin_port = htons(MasterPort); connect(ClientSock, (SOCKADDR*)&ServerAddr, sizeof(SOCKADDR)); while(TRUE)
{
char Buff[MAXBYTE] = { 0 };
char Cmd[MAXBYTE] = { 0 }; //接收由服务器端传送来的命令提示符或其他信息
recv(ClientSock, Buff, MAXBYTE, 0);
//指令输入错误的处理
if ( !strcmp(Buff, "Command Unsuccessfully!") )
{
printf("%s \r\n", Buff);
recv(ClientSock, Buff, MAXBYTE, 0);
}
printf("%s", Buff); //输入指令
scanf("%s", Cmd);
//发送指令
send(ClientSock, Cmd, MAXBYTE, 0);
//如果输入exit指令则退出
if ( !strcmp(Cmd, "exit") )
{
printf("Login oot ! \r\n");
break;
}
//如果输入help指令则接收帮助信息
else if ( !strcmp(Cmd, "help") )
{
recv(ClientSock, Buff, MAXBYTE, 0);
printf("%s \r\n", Buff);
}
//清零重置缓冲区
memset(Buff, 0, MAXBYTE);
memset(Cmd, 0, MAXBYTE);
} getch();
closesocket(ClientSock);
WSACleanup(); return 0;
}

在我看来,这种基于C/S模式的程序,重要的是要分清楚程序的逻辑,保证在实现不同功能的时候,recv()和send()指令是一一对应的,否则就会接收到不正确的信息。举例来说,当客户端发送help指令的时候,我们希望的是首先接收到由服务器端发送来的帮助信息,紧接着再接收命令提示符,所以需要两个recv()指令用于接收;而如果是hack指令,由于客户端不需要它有返回值,所以接下来只需要一个recv()指令用于接收命令提示符就可以。这个问题在编程中是要特别注意的。

四、实际测试

同上次一样,我准备了两台计算机用于测试。首先需要在一台计算机上运行服务器端程序,之后在另外一台计算机上运行客户端程序,这样客户端就能够直接连接到服务器端。在客户端依次输入help、hack以及exit命令进行测试:


图1 在客户端输入命令

当输入hack命令时,服务器端就会启动用于模拟病毒的对话框程序:


图2 客户端启动对话框

而在客户端输入exit指令,那么无论是客户端还是服务器端都会退出。所以这里所编写的程序是可行的,成功地达到了启动对话框的目的。

五、木马的防范

其实C/S模式的木马的实现原理和网上聊天的原理是基本一致的,都是基于TCP/IP协议的通信,都是在进行消息的传递。所不同的是,木马的客户端向服务器端发送的消息是控制命令,服务器端收到指令后会执行相应的功能,并将执行结果反馈给客户端,这就是远程控制的实现。如果服务器端增加自身隐藏的功能,复制自身到系统目录,然后自动启动……那么服务器端就是一个标准的木马了。可以说,即便是复杂的木马,也是这样的原理,所不同的是高明的木马程序会将自身隐藏得非常完美,还能躲过杀毒软件的查杀,而且难以彻底删除……这些都会在未来进行讨论。

想要进行防范病毒木马,那么首要的是去了解它,了解它的编写方式与运行原理,之后才能更加有效地针对。由于这次所举的木马的例子与上次的类似,那么处理方式也是大同小异的,这里就不再赘述。

六、小结

关于简单木马与病毒结合运用的两篇剖析的文章在此告一段落。结合以前的几篇文章也可以看到,其实黑客编程并不困难,并没有非常复杂的程序与算法,无非是各种API函数的堆砌,重点在于程序编写者对于计算机体系的了解有多少,如果了解得越多,那么其所编写的病毒木马的威力就会越惊人,也就越难以查杀。而从我的这几篇分析文章也可以看到,查杀方法似乎比编写病毒木马还要简单。确实如此,不过由于我所举的这些例子都比较简单,而且我也比较了解这些程序的运行机制,所以处理起来非常快。而在实际的反病毒工作中,为了分析一个非常复杂的病毒,可能需要几天的时间。尽管现在有了自动化的检测工具,但是道高一尺魔高一丈,在攻与防的对立统一中,双方的技术都是在不断进步的,这可以说是一场智力与精力的较量。当然我希望的是,安全领域会最终取得胜利。

反病毒攻防研究第006篇:简单木马分析与防范part2的更多相关文章

  1. 反病毒攻防研究第005篇:简单木马分析与防范part1

    一.前言 病毒与木马技术发展到今天,由于二者总是相辅相成,你中有我,我中有你,所以它们之间的界限往往已经不再那么明显,相互之间往往都会采用对方的一些技术以达到自己的目的,所以现在很多时候也就将二者直接 ...

  2. 反病毒攻防研究第004篇:利用WinRAR与AutoRun.inf实现自启动

    一.前言 由之前的一系列研究可以发现,为了使得"病毒"能够实现自启动,我也是煞费苦心,采取了各种方式,往往需要编写冗长的代码并且还需要掌握系统底层或注册表的很多知识才可以.而这次我 ...

  3. WAF攻防研究之四个层次Bypass WAF

    从架构.资源.协议和规则4个层次研究绕过WAF的技术,助于全方位提升WAF防御能力. 绕过WAF的相关技术研究是WAF攻防研究非常重要的一部分,也是最有趣的部分,所以我在写WAF攻防时先写攻击部分.还 ...

  4. iOS开发网络篇—简单介绍ASI框架的使用

    iOS开发网络篇—简单介绍ASI框架的使用 说明:本文主要介绍网络编程中常用框架ASI的简单使用. 一.ASI简单介绍 ASI:全称是ASIHTTPRequest,外号“HTTP终结者”,功能十分强大 ...

  5. iOS开发UI篇—简单的浏览器查看程序

    iOS开发UI篇—简单的浏览器查看程序 一.程序实现要求 1.要求 2. 界面分析 (1) 需要读取或修改属性的控件需要设置属性 序号标签 图片 图片描述 左边按钮 右边按钮 (2) 需要监听响应事件 ...

  6. iOS开发UI篇—简单介绍静态单元格的使用

    iOS开发UI篇—简单介绍静态单元格的使用 一.实现效果与说明 说明:观察上面的展示效果,可以发现整个界面是由一个tableview来展示的,上面的数据都是固定的,且几乎不会改变. 要完成上面的效果, ...

  7. iOS开发Swift篇—简单介绍

    iOS开发Swift篇—简单介绍 一.简介 Swift是苹果于2014年WWDC(苹果开发者大会)发布的全新编程语言 Swift在天朝译为“雨燕”,是它的LOGO 是一只燕子,跟Objective-C ...

  8. NHibernate 映射基础(第三篇) 简单映射、联合主键

    NHibernate 映射基础(第三篇) 简单映射.联合主键 NHibernate完全靠配置文件获取其所需的一切信息,其中映射文件,是其获取数据库与C#程序关系的所有信息来源. 一.简单映射 下面先来 ...

  9. 鸿蒙内核源码分析(编译过程篇) | 简单案例窥视GCC编译全过程 | 百篇博客分析OpenHarmony源码| v57.01

    百篇博客系列篇.本篇为: v57.xx 鸿蒙内核源码分析(编译过程篇) | 简单案例窥视编译全过程 | 51.c.h.o 编译构建相关篇为: v50.xx 鸿蒙内核源码分析(编译环境篇) | 编译鸿蒙 ...

随机推荐

  1. 只需2分钟!PC端的报表即可转换成手机报表

    转: 只需2分钟!PC端的报表即可转换成手机报表 手机制作报表,这个大家不知有没有尝试过,虽然我们平时都用电脑做,但是电脑要是不在身边了,手机就可以用来应应急.但其实小编并没有在手机上制作报表的实践经 ...

  2. Nginx常用内核参数优化,安装,基本命令

    1.内核参数配置,默认的Linux内核参数考虑的是通用的场景,明显不符合用于支持高并发访问web服务的定义,所以需要修改Linux内核参数,使得Nginx可以拥有更高的性能.可以通过修改 /etc/s ...

  3. 剑指 Offer 53 - I. 在排序数组中查找数字 I + 二分法

    剑指 Offer 53 - I. 在排序数组中查找数字 I Offer_53_1 题目描述 方法一:使用HashMap package com.walegarrett.offer; /** * @Au ...

  4. POJ1458 Common Subsequence

    题目链接:http://poj.org/problem?id=1458 分析:最大公共子序列模板 1 #include<iostream> 2 #include<sstream> ...

  5. Celery:进一步探索

    一.创建Celery专用模块 对于大型项目,一般需要创建一个专用模块,便于管理. 1.1 模块结构 proj/__init__.py /celery.py /tasks.py proj/celery. ...

  6. vue 页面生成图片保存

    需求:将页面中的元素转成图片,支持保存或下载.要求下载的图片包含页面背景,头像,用户名,文本为"我的邀请码"和个人二维码. 实现:将页面绘制到canvas中,生成base64图片链 ...

  7. NET 5.0 Swagger API 自动生成MarkDown文档

    目录 1.SwaggerDoc引用 主要接口 接口实现 2.Startup配置 注册SwaggerDoc服务 注册Swagger服务 引用Swagger中间件 3.生成MarkDown 4.生成示例 ...

  8. flutter资料

    Flutter社区和资源传送门 新: 慕课网<Flutter入门与案例实战>   |   中文网<Flutter实战>电子书 字体图标生成 http://fluttericon ...

  9. python-自定义一个序列

    python的序列可以包含多个元素,开发者只要实现符合序列要求的特殊方法,就可以实现自己的序列 序列最重要的特征就是可以包含多个元素,序列有关的特使方法: __len__(self):该方法的返回值决 ...

  10. python写一个学生信息管理系统

    #coding:utf-8 2 info = []#全局变量 3 def info_print(): 4 print("请选择功能:") 5 print("1:添加学员& ...