Apache Guacamole多个漏洞分析( 二 )


Apache Guacamole多个漏洞分析

文章插图
 
图2. 缺少输入过滤导致出现越界读取
恶意RDP服务器可以发送一个恶意的rdpsnd信道消息 , 导致客户端认为数据包中包含大量字节 , 而这些字节实际上为客户端内存中的字节 。这样一来 , 客户端就会向服务端返回包含这些字节的响应包 , 导致RDP服务端最终得到了大量数据 , 实现类似心脏滴血的信息泄露原因 。
CPR-ID-2142:信息泄露漏洞
CVE编号: CVE-2020-9497文件: protocolsrdpchannelsrdpsndrdpsnd.c函数: guac_rdpsnd_process_receive()
在这个RDP通道中 , 有另一个消息还存在类似的漏洞 。这次越界(Out-of-Bounds)数据会发送给客户端 , 而不是发送回RDP服务端 。
Apache Guacamole多个漏洞分析

文章插图
 
图3. 类似的越界读取漏洞 , 向客户端泄露信息
这个漏洞会将信息泄露给客户端 , 我们希望能够在客户端不知道网关已被攻击的情况下 , 开发出可用的利用代码 。
CPR-ID-2143:信息泄露漏洞
CVE编号: CVE-2020-9497文件: protocolsrdppluginsguacaiguacai-messages.c函数: guac_rdp_ai_read_format()
我们找到了另一个通道:guacai , 该通道负责声音消息(“音频输入”) , 因此名为guacai 。尽管该漏洞存在前面类似的漏洞 , 但默认情况下处于被禁用状态 。
Apache Guacamole多个漏洞分析

文章插图
 
图4. 与第一个漏洞类似的越界读取漏洞
此时我们已经找到了3个主要的信息泄露漏洞 , 应该足以绕过ASLR(地址空间布局随机化) , 然而我们仍需要一个内存破坏漏洞来构造完整的利用链 。由于研究进入瓶颈期 , 我们开始重新分析FreeRDP , 希望能找到之前可能被遗漏的漏洞 。
 
0x04 熟悉的FreeRDP与上一次相比 , RDP客户端中并没有太多改动 , 打上补丁的版本仍然为当时最新的版本 。我们先来理解该客户端涉及到的wStream类型中关键要素 , 该结构的相关字段如图5所示:
Apache Guacamole多个漏洞分析

文章插图
 
图5. 用来封装传入/传出数据包的wStream对象
这是一个典型的流封装结构 , 包括:
  • buffer:指向传入数据包头的指针 。
  • pointer:指向传入数据包内头部的指针 。
  • length:传入数据包的字节数 。
在解析传入流的指定字段之前 , 代码应该先检查数据流大小是否足以容纳相应数据 。检查逻辑如图6所示:
Apache Guacamole多个漏洞分析

文章插图
 
图6. 使用Stream_GetRemainingLength()检查可用的输入
这个输入检查非常重要 , 每次解析或跳过某个字段时 , 指针字段都会相应地往前挪动 。在执行下一次检查时对应的代码逻辑如下:
Apache Guacamole多个漏洞分析

文章插图
 
图7. 使用当前流的头部来计算剩余长度
当指针字段越过传入数据包的末尾时 , 这个计算逻辑将会向下溢出 , 从而返回一个巨大的无符号值 , 代表剩余字节为负数 。简而言之 , 只要有溢出检查失效 , 剩余的检查过程将毫无意义 。这种设计思路导致FreeRDP很容易受到越界读取漏洞所影响 , 下文我们将分析这一点 。
在提供这类越界读取漏洞之前 , 我们先了解一下这些漏洞的重要性 。通常情况下 , 读取操作只有在以某种方式向攻击者返回读取的字节时才有能够利用 。否则读取操作只能用来访问内存中未映射的页面 , 使程序崩溃 。Apache Guacamole攻击场景比较特殊 , 这里我们能够接触连接的两端节点 。比如 , 如果内存字节对应的是屏幕的图形更新数据 , 那么这些更新数据也会被发送给连接的客户端 。
在这种场景下 , 每个越界读取漏洞都有可能变成微小却有用的信息泄露漏洞 。
CPR-ID-2145 & CPR-ID-2146:FreeRDP越界读取漏洞由于wStream对象设计中存在缺陷 , 我们只需要寻找没有被过滤的读取操作即可 。这个思路很准确 , 我们找到了两个漏洞:CPR-ID-2145以及CPR-ID-2146 。


推荐阅读