1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| want_to_write_len = snprintf( print_temp_rule, 0x10000, (unsigned int)"{\"issuer\": \"https://%.*s\", \"authorization_endpoint\": \"https://%.*s/oauth/id" "p/login\", \"token_endpoint\": \"https://%.*s/oauth/idp/token\", \"jwks_uri\": \"h" "ttps://%.*s/oauth/idp/certs\", \"response_types_supported\": [\"code\", \"token\"," " \"id_token\"], \"id_token_signing_alg_values_supported\": [\"RS256\"], \"end_sess" "ion_endpoint\": \"https://%.*s/oauth/idp/logout\", \"frontchannel_logout_supported" "\": true, \"scopes_supported\": [\"openid\", \"ctxs_cc\"], \"claims_supported\": [" "\"sub\", \"iss\", \"aud\", \"exp\", \"iat\", \"auth_time\", \"acr\", \"amr\", \"em" "ail\", \"given_name\", \"family_name\", \"nickname\"], \"userinfo_endpoint\": \"ht" "tps://%.*s/oauth/idp/userinfo\"}", ...... hostname); authv2_json_resp = 1; if ( (unsigned int)ns_vpn_send_response(a1, 0x100040LL, print_temp_rule, want_to_write_len) ) {
|
这里可以看到,snprintf函数被用于将hostname参数拼接到print_temp_rule变量中,并根据返回的长度,通过ns_vpn_send_response函数返回HTTP请求的结果。这种对snprintf的使用方法是一个常见的错误。这里的hostname参数是由 HTTP 请求中的 Host 头决定的,因此这个参数的长度我们是完全可以控制的。这让我想到一个长亭之前发布的一篇经典文章 实战栈溢出:三个漏洞搞定一台路由器。也是使用snprintf 从缓冲区泄漏内存。
总结一下就是, snprintf 这个函数应该返回的是 ”想要写入buffer 的字符串长度“ , 而不是实际写入buffer的字符长长度。可以从一个 DEMO 看出这个效果:
具体一样长度能不能泄漏出 token , 看起来和版本还是有关系的,至少我这个版本在 CVE-2023-4966这个利用中是打不出来的。应该和不同缓冲区的大小不一样?猜测的,具体我就不进一步调试了。
文章来源: https://bestwing.me/CVE-2023-4966-Citrix-memory-leak.html
如有侵权请联系:admin#unsafe.sh