首页 网络安全 正文

FreeRDP绕过堆缓冲区溢出CVE-2026-44421

摘要

栋科技漏洞库关注到FreeRDP RDPGFX CacheToSurface 通过固定矩形验证绕过堆缓冲区溢出漏洞,漏洞现追踪为CVE-2026-44421。

FreeRDP 是 Apache 协议开源、完整实现微软 RDP(远程桌面协议)工具库,支持Linux、macOS、Windows、Android、iOS全平台。

一、基本情况

FreeRDP 轻量化无闭源依赖,私有云桌面搭建大量运维、云桌面软件基于它二次开发,是Linux环境管理 Windows 服务器的标准方案。

FreeRDP 原生支持 NLA 网络级身份验证、多显示器,它是各类图形化远程桌面工具(Remmina、GNOME 连接)底层依赖核心组件。

FreeRDP绕过堆缓冲区溢出CVE-2026-44421

FreeRDP 支持双向剪贴板、本地磁盘映射、打印机/音频/麦克风/USB设备透传,能单独拉起Windows RemoteApp无缝融合本地桌面。

栋科技漏洞库关注到FreeRDP RDPGFX CacheToSurface 通过固定矩形验证绕过堆缓冲区溢出漏洞,漏洞现追踪为CVE-2026-44421。

二、漏洞分析

CVE-2026-44421导致恶意 RDP 服务器可通过发送特制的 RDPGFX 协议数据单元,在 FreeRDP 客户端触发堆缓冲区溢出写入漏洞。

该漏洞存在于剪贴板静态虚拟通道中,位于 gdi_CacheToSurface 函数:该函数会对目标矩形做校验并限制数值上限为 UINT16_MAX。

但是,后续的拷贝操作仍使用缓存项原始的宽高参数,恶意服务器可诱使客户端连接并传输文件,从而在客户端设备上执行任意代码。

这会造成大范围堆内存越界写入,引发客户端崩溃或任意代码执行,恶意RDP服务器可触发该漏洞,前提是客户端开启RDPGFX功能。

该漏洞的核心问题在于FreeRDP Windows客户端(wfreerdp组件)的剪贴板静态虚拟通道中,存在堆缓冲区溢出。

(一)详细分析

恶意RDP服务器可发送特制RDPGFX协议数据单元,在FreeRDP客户端触发堆缓冲区溢出写入漏洞。

漏洞存在于gdi_CacheToSurface函数:

函数对目标矩形做校验时会将边界值限制在UINT16_MAX范围内,但后续内存拷贝操作仍使用缓存条目原始的宽、高数值。

该行为会造成大范围堆内存越界写入,可能导致客户端崩溃或任意代码执行。

恶意RDP服务器能够触发此漏洞,但前提是客户端开启了RDPGFX功能。

C语言漏洞验证程序仅为本地测试工具,它会调用与服务端下发RDPGFX报文所触发的完全相同的FreeRDP处理函数。

FreeRDP提交记录23b36cd00ebf0ccd97750fcdbc9aa2f362352da7中相关逻辑:

gdi_CreateSurface函数会将画布尺寸向上对齐至16像素,对应代码如下:

surface->width = gfx_align_scanline(createSurface->width, 16)、surface->height = gfx_align_scanline(createSurface->height, 16)。

因此若服务端传入创建画布参数宽65535、高1,程序实际会分配一块65536×16像素的画布。

gdi_CacheToSurface函数会基于经过数值截断的右下边界构造RECTANGLE_16矩形。

由于矩形右边界被限制为UINT16_MAX,即便实际拷贝的宽高会超出画布范围,矩形校验逻辑依旧会判定校验通过。

可稳定触发崩溃的参数(攻击者可通过标准RDPGFX报文控制):

创建画布参数宽65535、高1;创建缓存条目参数宽65535、高1;下发CacheToSurface指令,目标坐标为x=65534,y=15。

(二)攻击流程:

首先,客户端向恶意服务器请求文件内容;

随后,服务器响应一个远大于请求大小的数据负载。

协议解析器在计算复制大小时未进行任何上限验证,导致系统使用服务器控制的大小执行复制操作,

将数据写入超出分配目标边界的内存区域,从而触发堆缓冲区溢出。

通过覆盖相邻的堆对象,攻击者能够劫持控制流,最终实现远程代码执行。

三、POC概念验证

(一)该复现程序无需运行真实RDP服务器

它会模拟gdi_CacheToSurface中完全一致的边界校验逻辑,再传入和该函数相同的参数调用freerdp_image_copy_no_overlap。

已在Linux系统下基于FreeRDP提交记录23b36cd00ebf0ccd97750fcdbc9aa2f362352da7完成测试。

1、使用地址消毒器/未定义行为消毒器编译FreeRDP(关闭该漏洞验证程序无需的可选依赖库): 

git clone https://github.com/FreeRDP/FreeRDP.git /tmp/freerdp-src
cd /tmp/freerdp-src
git checkout 23b36cd00ebf0ccd97750fcdbc9aa2f362352da7

mkdir build-asan && cd build-asan
cmake .. \
  -DCMAKE_BUILD_TYPE=Debug \
  -DCMAKE_C_FLAGS='-g -O1 -fno-omit-frame-pointer -fsanitize=address,undefined' \
  -DCMAKE_EXE_LINKER_FLAGS='-fsanitize=address,undefined' \
  -DCMAKE_SHARED_LINKER_FLAGS='-fsanitize=address,undefined' \
  -DWITH_FFMPEG=OFF -DWITH_SWSCALE=OFF -DWITH_FUSE=OFF \
  -DWITH_SERVER=OFF -DWITH_SAMPLE=OFF -DWITH_SHADOW=OFF -DWITH_PROXY=OFF \
  -DWITH_CLIENT_SDL=OFF -DWITH_WAYLAND=OFF -DCHANNEL_URBDRC=OFF -DBUILD_TESTING=OFF
make -j"$(nproc)"

2、将代码保存为 poc_505.c(例如路径 /tmp/poc_505.c):

管理员已设置登录后刷新可查看

3、编译并运行:

cd /tmp/freerdp-src/build-asan

gcc -g -O1 -fsanitize=address,undefined \
  -I../include -I./include -I../winpr/include -I./winpr/include \
  /tmp/poc_505.c \
  -L./libfreerdp -L./winpr/libwinpr -lfreerdp3 -lwinpr3 \
  -Wl,-rpath,./libfreerdp:./winpr/libwinpr -o /tmp/poc_505

ASAN_OPTIONS='detect_leaks=0:abort_on_error=1:halt_on_error=1:print_stacktrace=1' \
  LD_LIpARY_PATH=./libfreerdp:./winpr/libwinpr \
  /tmp/poc_505

预期结果:地址消毒器(ASAN)会报出堆缓冲区溢出,写入数据长度为 262140 字节。

(二)修复建议

在调用 freerdp_image_copy_no_overlap 函数前,基于未经截断的真实拷贝尺寸增加边界校验逻辑。

diff --git a/libfreerdp/gdi/gfx.c b/libfreerdp/gdi/gfx.c
index feec35967..aaad7b349 100644
--- a/libfreerdp/gdi/gfx.c
+++ b/libfreerdp/gdi/gfx.c
@@ -1659,6 +1659,11 @@ static UINT gdi_CacheToSurface(RdpgfxClientContext* context,
                if (!is_rect_valid(&rect, surface->width, surface->height))
                        goto fail;
+
+               if ((UINT32)destPt->x + cacheEntry->width > surface->width)
+                       goto fail;
+               if ((UINT32)destPt->y + cacheEntry->height > surface->height)
+                       goto fail;

                if (!freerdp_image_copy_no_overlap(surface->data, surface->format, surface->scanline,
                                                   destPt->x, destPt->y, cacheEntry->width,
                                                   cacheEntry->height, cacheEntry->data, cacheEntry->format,

(三)危害影响

该漏洞属于 FreeRDP 客户端堆缓冲区溢出写入漏洞。

所有使用FreeRDP用户与应用程序(如 xfreerdp),若连接攻击者管控、协商启用 RDPGFX 功能的 RDP 服务器,都会受到漏洞影响。

最低危害后果是攻击者远程造成 FreeRDP 客户端程序崩溃(拒绝服务攻击,该场景下风险等级中等);

同时存在客户端进程内任意代码执行的可能性。

原因是攻击者能够发起大规模堆内存越界写入操作,写入尺寸与内容均由服务端可控的缓存像素数据决定。

RDP 服务端可完全控制触发 gdi_CacheToSurface 函数的各项参数,且漏洞位于服务端向客户端传输报文的真实数据链路中。

(四)漏洞发现背景

该漏洞由 Anthropic 团队在开展开源软件自动化漏洞挖掘大模型相关研究时发现。

随后 Anthropic 委托 Trail of Bits 团队独立对该漏洞进行分类研判与有效性验证。

四、影响范围

FreeRDP Windows ≤ 3.28.0

五、修复建议

FreeRDP Windows ≥ 3.29.0

六、参考链接

管理员已设置登录后刷新可查看



扫描二维码,在手机上阅读
评论
更换验证码
友情链接