2019-01-29

SK远程控制软件制作实现思路

作者:administrator 所属分类 - 干货

在进行大批量集群的管理的时候,我们会用到集群远程控制管理软件,对于一些特殊目的的远程管理需求可能需要免杀。而大灰狼、gh0st等远程控制软件由于架构老旧,需要升级架构和更换协议才能满足需求。

这篇文章并不是要修改大灰狼或者gh0st,而是意图自行实现一个远程控制软件。我们实现远程控制软件有数种思路,且让我慢慢道来。

上图是SK远程控制软件第10版,现在已经全面升级到第15版了。

实现远程控制软件,我们可以用下面几种思路:

1、实现一个由协议回调执行内容的软件,通过协议的连接、关闭连接、数据流等回调客户端和服务端的函数(重载对象的函数,如以下实现方式[C++])
#define extends :public
class NetworkProtocol
{
public:
virtual VOID OnGetConn();
virtual BOOL OnCloseSock();
private:
BOOL GetConn();
};
// 上层内容,协议层和上层隔离
class uApp extends NetworkProtocol
{
VOID OnGetConn()
{
/* 自己的内容 */
NetworkProtocol::OnGetConn();
}
};

如上我们实现的是协议回调的用户函数,只需要把工作重心放在业务层的构建即可。这种实现包括HP-Socket套件的应用在内,优点是容易专注于业务层,缺点是耦合性差,调试不方便,有时候协议的问题会影响用户层。适合反向或者正向连接。

2、由执行内容更改协议,改变传输的数据

这种方法大多是rawsocket构建的应用,而且比较适合C语言。优点是可以发送不定长数据以及随时灵活变更、杀死、创建连接。并且和协议耦合比较好,一般协议是在业务里面,没有分离的。
优点是调试方便,且协议可控,容易修复BUG。缺点是协议更改以后客户端和服务端都要重构,应该在设计的时候就考虑模型。如SK远程控制系列都用了这种思路,适合反向连接。

3、由现成组件组合

这个例子就很多了,类似托管,实现依赖平台特性以及平台安装的组件,例如Windows远程桌面查看组件,优点是代码量少,实现轻松,缺点是几乎不可控。适合正向连接。

4、动态加载,只有底层协议软件,动态下载要加载的插件,可以和主程序分离

例子挺多,大多数MBR木马病毒采用这种方式,即加载器-插件的形式。优点是程序体积可以非常小,且可以用非编译语言和托管代码实现。缺点是网络环境差的时候,该类实现方式的体验不好。

那么我们来实现基于第二种思路的软件。这个也是新手最适合的思路。简单粗暴实现一个远程控制软件。

首先实现一个C/S通讯的最基础模型,如果是面向对象,那应该在类里面实现底层连接。我们实现到connect的时候,就可以把SOCKET对象交归逻辑处理函数。

逻辑处理函数接收SOCKET对象(Linux是int),交给判断合法函数以及接收/发送控制指令函数,例如以下的内容:

  • // 服务端
  • class ServerDlg
  • {
  • public: //......
  • BOOL SendTask()
  • {
  • // ..........
  • send(m_sock,(char*)&dwReserve,sizeof(dwReserve),0);
  • //............
  • }
  • };
  • // 客户端

  • class ServerDlg
    {
    public: //......
    BOOL RecvTask()
    {
    // ..........
    recv(m_sock,(char*)&dwReserve,sizeof(dwReserve),MSG_WAITALL);
    //............
    }
    } ;

可以看出来协议是紧密结合的,一个发送对应一个接收。这个时候,我们尝试实现最简单的命令行接收发送。

注意,为了防止粘包,建议采用一收一发,定长方式处理数据。即响应包的方式,并且将较大的数据做封包处理,例如下面的数据包格式[C++]:

// 我们采用的是VS2017 IDE,MSVC14.2编译器
#pragma pack(1)
struct DataPkg

{
typedef uint64_t UXLONG;
typedef int32_t BOOL;
BOOL bis_Verify = 1;
char lpData[PKG_LEN] = {0}; // #define PKG_LEN 1000ULL
UXLONG qwVeriFlag = 0ULL; // 校验数值,校验数据是否出错
UXLONG qwFlag = 0ULL; // 顺序或者别的,可以自定义很多信息
UXLONG qwReserve = 0ULL; // 保留扩展
};

#pragma pop

这个时候我们尝试发送一个CMD命令行包到客户端,试试是否成功执行。命令行可以只用一个数据包发送,或者设置分段发送。分段发送的时候,当qwFlag为0的时候就结束接收,并且舍弃那个数据包,拼接前面的数据包即可(TCP保证顺序,UDP也可以将保留扩展作为别的功能位使用。)。

这样我们的一个简单的远程控制软件就实现了,我们可以在这个基础之上扩展更多的功能出来。

可以参考我的远程控制软件:(GitHub开源)

https://github.com/lianglixin/RemoteControl-X3

这个远程控制软件就是这样实现的,拥有屏幕查看、键盘记录、文件管理以及自启动等多种功能。欢迎大家一起交流经验。

麦科技原创,转载请说明出处。

隐藏