作者: 1u0m@WoodSec
本文为作者投稿,Seebug Paper 期待你的分享,凡经采用即有礼品相送!
投稿邮箱:paper@seebug.org

0x00 起因

在一次项目过程中遇到了一个需要通过服务器攻击pc管理员的情况,在抛开tsclient的传统攻击方法下我发现了checkpoint团队关于rdp客户端的研究文章,文章描述了rdesktop,FreeRDP以及mstsc的研究结果,由于项目有了其他突破便没研究,直到前两天看见有牛人已经实现了,于是乎仔细分析了一下

0x01 分析

在高版本的mstsc和rdp服务里面微软已经实现了粘贴板的功能,从text到文件都可以以复制粘贴的方法在服务器和PC机之间传输。一个文件的传输过程有如下流程

  1. 在服务器上,"复制"操作会创建格式为"CF_HDROP"的剪贴板数据
  2. 在客户端计算机中执行"粘贴"时,将触发一系列事件
  3. 要求服务器上的rdpclip.exe进程提供剪贴板的内容,并将其转换为FileGroupDescriptor(Fgd)剪贴板格式
  4. 使用HdropToFgdConverter::AddItemToFgd()函数,将文件的元数据添加到描述符中
  5. 完成后,将Fgd Blob发送到服务器上的RDP服务
  6. 服务器只是将其包装并将其发送给客户端
  7. 客户端将其解包并将其存储在自己的剪贴板中
  8. "粘贴"事件将发送到当前窗口(例如,explorer.exe)
  9. 处理事件并从剪贴板读取数据
  10. 通过RDP连接接收文件的内容

使用ClipSpy观察服务器和PC上的剪贴板变化

当复制一个文件的时候,剪贴板的CF_HDROP是以Unicode编码储存的文件的路径

而此时PC上的剪贴板的FileGroupDescriptorW以Unicode编码储存的文件的名称

在IDA中通过查找几个剪贴板的API(OpenClipboard,CloseClipboard)定位到一处可疑的函数:CClipBase::OnFormatDataRequest

这里具体的操作就是打开剪贴板,获取剪贴板数据,如果存在CF_HDROP的格式就进入CHdropToFgdConverter::DoConversion进行处理不然就去CFormatDataPacker::EncodeFormatData里面处理

可以看出DoConversion就是我们要找的文件处理的函数,继续跟进

DoConversion 只是做了检查HDrop格式和堆的分配等准备工作,然后进入了CHdropToFgdConverter::DoConversionWorker 跟进DoConversionWorker发现终于开始干正事了

首先是获取Hdrop里面文件是数量,以及是否是unicode编码和编码转换

然后遍历Hdrop里面的文件,通过wcsrchr()在路径里面获取文件名,最后把文件路径和文件名一起传给CHdropToFgdConverter::AddItemToFgd

根据checkpoint的描述,这里将文件逐个通过AddItemToFgd打包成Fgd格式然后发送给PC端,这里应该就是发送文件前最后的文件打包检查操作了。

在这里面我发现对传入进来的文件名没有任何检查之类的,直接打包

通过传入的文件全路径获取文件的一些基本信息和属性然后打包

接下来就是发送给RDP服务然后发给PC端,这里不再跟进

回顾上面的关键点就是如下几条

  1. 通过GetClipboardData函数在剪贴板中获取Hdrop数据
  2. 遍历Hdrop数据获取文件路径信息,并且使用wcsrchr()获取文件名
  3. 使用文件路径获取文件的基本信息和属性
  4. 将文件名和文件基本信息和属性打包

0x02 Poc

那我们的攻击点就在文件名,修改文件名实现跨目录

文件名是通过wcsrchr(&szFile, '\\')获取到的,看来微软忘了他自己的文件API还支持"/"访问

wcsrchr返回的是一个指针,意味着修改了文件名之后路径也会变,路径变化之后后面的CreateFileW函数会出错返回失败,这里我想到的Hook大法好,当然可能还有其它办法

A.定义两个文件路径

B.首先我Hook GetClipboardData函数,在正常的Hdrop数据里面加入我们的文件

C.然后Hook DragQueryFileW函数,在枚举文件路径的时候修改成跨目录的路径

D.最后Hook GetFileAttributesWCreateFileW函数,在打开文件的时候不要用我们跨目录的路径,而使用之前的正常路径

总结流程如下

  1. 在获取剪贴板的Hdrop数据的时候插入我们的正常路径
  2. 在枚举文件路径的时候返回跨目录的路径
  3. 在执行GetFileAttributesWCreateFileW的时候给他正常路径

运行poc之后我们再来看看ClipSpy的变化

服务器上和之前没有变化(GetClipboardData是在PC端粘贴的时候触发的)

PC端以及有了两条数据,其中包括我们的跨目录

演示视频

0x03 最后

  1. 由于mstsc可以多窗口复制粘贴,所以这种方法在多窗口一样生效
  2. 在测试的时候发现,跨目录的同时还可以创建不存在的目录
  3. 由于建立了RDP连接,两边的系统就会同步剪贴板,可以实现通过服务器监控PC的剪贴板
  4. 感谢checkpoint的文章

Paper 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/1074/