[分享开源]SooRDP-好用的Windows远程桌面RDP隧道工具

开发背景

ssh -D 1080 user@192.168.1.1

如果常用SSH端口转发的技术人员应该很熟悉-D或-L参数的功能了,-D参数可以让ssh客户端本地监听的TCP端口是一个socks5代理服务,然后把接入的流量基于ssh的TCP通道从远程连接出去。-L参数就是纯端口转发,不支持代理协议。-D参数应该更常用。

由于Windows服务器的主要远程管理方式是3389端口的RDP协议,但RDP协议相比Linux系统的SSH协议却没有自带这个功能,然而,RDP协议通道预留了开发接口,可以让开发者在RDP的会话通道中嵌入自己的传输频道。

接下来我将分享如何开发插件实现Socks Over RDP隧道,我在开发这个之前有了解到一款叫SocksOverRDP的开源工具,经过试用,个人觉得易用性稳定性和兼容性都不如我意,本文分享的SooRDP这个插件可以更方便的为Windows的远程桌面客户端增加类似SSH的-D或-L参数的功能。项目源码github链接见底部。

SooRDP功能介绍

基本操作

下面是工具的文件列表,例如本地操作系统64位的就运行SooRDPClientApp64.exe,
在这里插入图片描述

然后软件界面如下,同类工具没提供这么方便自动注册和配置参数的界面呢。先配置端口和转发模式,还可以配置mstsc的参数,例如浏览个rdp文件,或者直接点打开启动远程桌面客户端,工具会先自动注册SooRDP-Plugin64.dll,不需要你去执行regsvr32,然后点打开按钮启动远程桌面客户端。

在这里插入图片描述

接下来把SooRDPServerApp复制粘贴到远程后运行,界面如下图,并点“启动”按钮。这时隧道就准备就绪了。这时远程桌面要保留住不能断开,最小化它就可以使用这个RDP通道了。

在这里插入图片描述

功能特点

  • SooRDP为了方便用户使用,提供了界面操作配置RDP隧道参数,从客户端程序打开远程桌面时会自动注册DLL插件,关闭退出时自动卸载插件的注册表注册的信息。
  • SooRDP支持Windows 2003至今,在全网似乎找不到能支持Server 2008之前的此类工具,SooRDP会根据系统自适应Static或Dynamic Virtual Channel接口,因为Server 2008之前远程桌面只有Static接口(用该接口针对实现端口转发功能难度较大)。

RDP的虚拟通道API接口编程

下面代码是我从MSDN修改而来,这个在远程模块的代码,我们可以通过API打开一个VirtualChannel的文件句柄,然后就可以像文件一样读写数据流和客户端插件通信了。

DWORD OpenVirtualChannel(
    BOOL bDynamic,
    LPCSTR szChannelName,
    HANDLE* phWTSHandle,
    HANDLE* phFile)
{
    HANDLE hWTSHandle = NULL;
    HANDLE hWTSFileHandle;
    PVOID vcFileHandlePtr = NULL;
    DWORD len;
    DWORD rc = ERROR_SUCCESS;
    BOOL fSucc;

    if (bDynamic) {
        if (gpWTSVirtualChannelOpenEx == NULL)
        {
            rc = ERROR_PROC_NOT_FOUND;
            goto exitpt;
        }
        hWTSHandle = gpWTSVirtualChannelOpenEx(
            WTS_CURRENT_SESSION,
            (LPSTR)szChannelName,
            WTS_CHANNEL_OPTION_DYNAMIC | WTS_CHANNEL_OPTION_DYNAMIC_PRI_HIGH);
    }
    else {
        hWTSHandle = WTSVirtualChannelOpen(
            WTS_CURRENT_SERVER_HANDLE,
            WTS_CURRENT_SESSION,
            (LPSTR)szChannelName);
    }
    if (NULL == hWTSHandle)
    {
        rc = GetLastError();
        goto exitpt;
    }

    fSucc = WTSVirtualChannelQuery(
        hWTSHandle,
        WTSVirtualFileHandle,
        &vcFileHandlePtr,
        &len);
    if (!fSucc)
    {
        rc = GetLastError();
        goto exitpt;
    }
    if (len != sizeof(HANDLE))
    {
        rc = ERROR_INVALID_PARAMETER;
        goto exitpt;
    }

    hWTSFileHandle = *(HANDLE*)vcFileHandlePtr;

    fSucc = DuplicateHandle(
        GetCurrentProcess(),
        hWTSFileHandle,
        GetCurrentProcess(),
        phFile,
        0,
        FALSE,
        DUPLICATE_SAME_ACCESS);
    if (!fSucc)
    {
        rc = GetLastError();
        goto exitpt;
    }

    rc = ERROR_SUCCESS;
    if (phWTSHandle) {
        *phWTSHandle = hWTSHandle;
        hWTSHandle = NULL;
    }

exitpt:
    if (vcFileHandlePtr)
    {
        WTSFreeMemory(vcFileHandlePtr);
    }
    if (hWTSHandle)
    {
        WTSVirtualChannelClose(hWTSHandle);
    }

    return rc;
}

目前有两个版本的API接口,从Vista开始有WTSVirtualChannelOpenEx,早期是WTSVirtualChannelOpen。他们的主要区别是:

  • 新版的支持动态,支持按需创建多个Channel,也就是RDP会话中,可以有多个子Channel,每个Channel就像TCP一样,插件可以感知每个Channel的建立和断开的状态。这种很方便就能实现把socks5的每个进来的TCP和Channel关联起来,实现流量转发。哪个TCP断了就把对应Channel关闭,远程就能自动感知Channel关闭。
  • 旧版的只有静态模式,也就是只有一个Channel。静态Channel的建立和断开是随着RDP会话的建立和断开同步的。这种要实现socks5通道,相对比较麻烦,需要自己把所有socks5的连接封装到一个Channel。

Socks5封装编程

为了能同时兼容新版和旧版的Channel,我选择只用一个Channel,并把多个socks5的连接封装到其中,为此我实现了一个叫SoTunnel的协议,它是基于异步socket实现的,可以参见源码中的SoTunnel.h,它支持在一个数据流中,封装多个子数据流,为了能管理好每个子数据流,我简单实现了几个协议指令。

#define stb_cmd_newconn 0  //建立新的子通道
#define stb_cmd_data    1  //子通道的数据
#define stb_cmd_close   2  //关闭一个子通道
#define stb_cmd_config  3  //发送配置信息,是否启动socks5协议
#define stb_cmd_reset   4  //重置通道
#define stb_cmd_ready   5  //通道状态
#define stb_cmd_ruready 6  //询问通道状态
#define stb_cmd_ping    7  //测试子通道
#define stb_cmd_pong    8  //测试子通道

接着我还需要在SoTunnel的对端子数据流的代码中实现socks5代理服务器的代码,详见SoTunnel.cpp。值得一提,为了解决域名解析阻塞问题,异步socket我不用CAsyncSocket,而是重写了一个类似的,域名解析时创建线程来解析。

void CEndPointSocket::OnSocksTalk()
{
    int ret;
    if (s5_stage == 0) {
        if (!s5data_read(2)) {
            return;
        }
        if (s5buf[0] != 0x05) {
            Close();
            return;
        }
        s5_nmethod = s5buf[1];
        s5buf.erase(0, 2);
        s5_stage++;
    }
    if (s5_stage == 1) {
        if (!s5data_read(s5_nmethod))
            return;
        s5buf.erase(0, s5_nmethod);
        s5_stage++;
    }
    if (s5_stage == 2) {
        if (!channel_write("\x05\x00", 2)) {
            return;
        }
        s5_stage++;
    }
    if (s5_stage == 3) {
        if (!s5data_read(4)) {
            return;
        }
        unsigned char ver = s5buf[0];
        unsigned char cmd = s5buf[1];
        unsigned char rsv = s5buf[2];
        unsigned char address_type = s5buf[3];
        if (cmd != 1) { // tcp connect
            Close();
            return;
        }
        s5_stage++;
    }
    省略

由于我们能到的VirtualChannel是一个文件句柄,而SoTunnel是基于socket实现的,那么还需要实现将文件句柄的输入输出和SoTunnel的socket进行转发就可以了。总体实现原理大概就是如此,其他代码实现细节就不一一列举了。最后可以吐槽下,经过测试RDP通道的传输速度最快约12M/s,我开始怀疑是SoTunnel的实现问题,经过在复制粘贴文件测试,显示拷贝文件传输速度也是差不多速度。我推测是RDP内部为了图像数据优先级,其他VirtualChannel的数据优先级较低的原因。

链接

项目地址: https://github.com/threatexpert/SooRDP

RDP(Remote Desktop Protocol)终端用户权限的管理和设置工具,用于管理和设置Windows远程桌面连接中的用户权限,有效防止RDP远程连接过程中的用户权限漏洞。 具体功能如下: 1、禁止关机、注销、禁用命令行、任务管理器、控制面板等。 2、设置用户帐号的登录时间限制,过期时间限制。例如只允许周一至周五的9:00~18:00登录。 3、隐藏或禁用磁盘内容,只允许运行特定的应用程序或禁止运行指定的应用程序。 该软件需要 Microsoft .NET Framework 2.0 运行环境。 Windows再爆超高危漏洞 黑客一个指令看光用户隐私 3月13日晚间,微软发布了今年3月份的安全公告,共更新了6个漏洞。其中一个名为MS12-020的漏洞为超高危漏洞,黑客可利用该漏洞特别构造RDP协议包来远程控制用户电脑或服务器,该漏洞影响Windows XP、Vista、2003、win7和2008等主流操作系统。考虑到远程桌面服务在系统中默认打开,大量用户正在使用此服务,瑞星特此发布紧急提示,告知用户尽快安装此漏洞补丁。目前,瑞星安全助手(http://tool.ikaka.com/)已经对此次微软更新的漏洞列表提供了自动安装修复功能据介绍,MS12-020漏洞存在于Windows远程桌面协议中,如果攻击者向开启远程桌面的计算机发送一个特别构造的RDP协议包请求,那么就能对其进行远程代码执行,也就是通常上说的可对电脑进行远程控制。 瑞星安全专家表示,与以往黑客通过病毒来实现对用户电脑控制的方式不同,此次漏洞导致黑客只需要发送一个协议数据包,便可以获得未安装此漏洞补丁电脑的本地最高权限,进而获取用户电脑上存储的所有资料。用户虽然可以通过关闭远程桌面服务来暂时避免受攻击,但最彻底的解决办法仍是第一时间安装微软的相关漏洞补丁。 附: 微软2012年3月份安全公告地址:http://technet.microsoft.com/en-us/security/bulletin/ms12-mar MS12-020漏洞说明:http://technet.microsoft.com/en-us/security/bulletin/ms12-020 解决方案,可以通过RDP终端安全设置工具 搞定安全问题!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值