I’ve been working through finding new ways to solve some of the Impossible Challenges Labs that Portswigger posts. During my exploration, I discovered a sibling to the well-known Relative Path Overwrite (RPO) technique, which I have named Relative Path File Injection (RPFI). It is my hope that this new technique opens up new possibilities and sheds light on previously unexplored avenues for exploitation.
我一直在努力寻找新的方法来解决 Portswigger 发布的一些不可能的挑战实验室。在我的探索过程中,我发现了著名的相对路径覆盖 (RPO) 技术的兄弟姐妹,我将其命名为相对路径文件注入 (RPFI)。我希望这项新技术开辟了新的可能性,并揭示了以前未开发的开发途径。
Background: 背景:
I have been investigating a category of vulnerabilities where it is possible to inject text into a webpage, but there are no known methods to execute JavaScript directly. One such scenario involves injecting content within a <frameset> tag when the equals sign (=) is filtered.
我一直在研究一类漏洞,在这些漏洞中,可以将文本注入网页,但没有已知的方法可以直接执行 JavaScript。其中一种方案涉及<frameset>在过滤等号 (=) 时在标记中注入内容。
In this context, injecting JavaScript code within a <frameset> tag proves ineffective because the <frameset> tag was originally designed to be used as an alternative to the <body> tag. It was intended to contain only <frame> tags or <noframes> tags. Traditionally, web developers would either use a <body> tag or a <frameset> tag that encapsulated individual <frame> tags, each with its own <body>.
在这种情况下,在标记中注入 JavaScript 代码<frameset>被证明是无效的,因为<frameset>标记最初被设计为用作标记的<body>替代方法。它旨在仅包含<frame>标记或<noframes>标记。传统上,Web 开发人员会使用<body>标签或<frameset>封装单个标签的标签<frame>,每个标签都有自己的 <body>.
The <noframes> tag was commonly used to define a fallback <body> for browsers that did not support frames. However, in modern browsers, any content injected within a <noframes> tag is simply rendered as plain text, similar to how content within <noscript> tags is treated.
该<noframes>标记通常用于定义不支持帧的浏览器的回<body>退。但是,在现代浏览器中,标签中注入的任何内容<noframes>都只是呈现为纯文本,类似于标签中内容的<noscript>处理方式。
Here’s an example that demonstrates the limitation of injecting HTML into a <noframes> tag:
下面是一个示例,演示了将 HTML 注入<noframes>到标记中的限制:
Inject payload into noframes tag
将有效负载注入 noframes 标签
Portswigger Research lists a few similar scenarios in their Impossible Challenges Lab:
Portswigger Research 在他们的 Impossible Challenges Lab 中列出了一些类似的场景:
“innerHTML context but no equals allowed
“innerHTML 上下文,但不允许等于
You have a site that processes the query string and URL decodes the parameters but splits on the equals then assigns to innerHTML. In this context <script> doesn’t work and we can’t use = to create an event.”
您有一个网站,该站点处理查询字符串和 URL 解码参数,但在等于时拆分,然后分配给 innerHTML。在这种情况下,这是<script>行不通的,我们不能使用 = 来创建事件。
View lab 查看实验室
“Injection occurs inside a frameset but before the body
“注射发生在框架内,但在身体之前
We received a request from twitter about this next lab. It occurs within a frameset but before a body tag with equals filtered. You would think you could inject a closing frameset followed by a script block but that would be too easy.”
我们收到了来自 twitter 的关于下一个实验室的请求。它发生在框架集中,但在过滤后等于的正文标记之前。你可能会认为你可以注入一个结束框架集,然后是一个脚本块,但这太容易了。
View lab 查看实验室
My first insight here was that these types of problems are easily solvable if Angularjs is available on the page because the Angularjs parser doesn’t care where in the page the Angularjs template string occurs. For example, you can inject a <noframes> tag with ng-app on it to instantiate Angularjs and execute Javascript.
我在这里的第一个见解是,如果页面上有 Angularjs,这些类型的问题很容易解决,因为 Angularjs 解析器不关心 Angularjs 模板字符串在页面中的位置。例如,您可以注入<noframes>带有 ng-app 的标签来实例化 Angularjs 并执行 Javascript。
<frameset> <noframes ng-app> {{1+1}} </noframes> </frameset> |
This works because Angularjs parser doesn’t care that HTML doesn’t want us executing JavaScript here. The same could be done with Gareth Heyes Relative Path Overwrite (RPO) with CSS injection.
这之所以有效,是因为 Angularjs 解析器不在乎 HTML 不希望我们在这里执行 JavaScript。Gareth Heyes 使用 CSS 注入的相对路径覆盖 (RPO) 也可以完成相同的操作。
<frameset> <noframes> *{ xss:expression(alert(1));
xss:表达式(alert(1)); } </noframes> </frameset> |
The CSS parser operates independently of the HTML parser and focuses solely on identifying and parsing CSS code within a webpage. It (with some conditions) does not concern itself with the location or context of the CSS code. This behavior allows techniques like Relative Path Overwrite (RPO) to inject and execute JavaScript in unconventional locations.
CSS 解析器独立于 HTML 解析器运行,仅专注于识别和解析网页中的 CSS 代码。它(在某些条件下)不关心CSS代码的位置或上下文。此行为允许相对路径覆盖 (RPO) 等技术在非常规位置注入和执行 JavaScript。
Similarly, the AngularJS parser can execute JavaScript expressions embedded within AngularJS-specific attributes or bindings, regardless of their placement within the HTML structure. Both RPO and AngularJS injection techniques leverage parsers that are separate from the standard HTML parser. These parsers are more lenient and can interpret and execute code even when it is surrounded by arbitrary HTML content.
同样,AngularJS 解析器可以执行嵌入在特定于 AngularJS 的属性或绑定中的 JavaScript 表达式,无论它们在 HTML 结构中的位置如何。RPO 和 AngularJS 注入技术都利用了独立于标准 HTML 解析器的解析器。这些解析器更宽松,即使代码被任意 HTML 内容包围,也可以解释和执行代码。
However, it’s worth noting that these techniques have certain limitations and are somewhat outdated. AngularJS has reached its end-of-life, and the expression() function in CSS, which was used for RPO, has been deprecated in Internet Explorer 8 and later versions. While these techniques can still be applicable in specific scenarios, their effectiveness may be limited in modern web environments. Given these limitations, it would be beneficial to explore alternative parsers that can be used to achieve similar results.
然而,值得注意的是,这些技术有一定的局限性,并且有些过时。AngularJS 已达到其生命周期的尽头,CSS 中用于 RPO 的 expression() 函数在 Internet Explorer 8 及更高版本中已被弃用。虽然这些技术仍适用于特定方案,但它们在现代 Web 环境中的有效性可能有限。鉴于这些限制,探索可用于实现类似结果的替代解析器将是有益的。
PDF Parser PDF 解析器
There are many other parsers on the web: SVG, XML, Emoji, PDF, Rich Text, Markdown, to name a few. PDF is another lenient parser. It can also be hand coded and doesn’t need to include equals and can execute Javascript. A PDF file starts and ends with %PDF / %%EOF that indicates the PDF boundary and many PDF implementations ignore anything before or after that. Even HTML.
网络上还有许多其他解析器:SVG、XML、表情符号、PDF、富文本、Markdown 等等。PDF 是另一个宽松的解析器。它也可以手动编码,不需要包含等号,并且可以执行 Javascript。PDF 文件以 %PDF / %%EOF 开头和结尾,表示 PDF 边界,许多 PDF 实现会忽略在此之前或之后的任何内容。甚至 HTML。
Consider this HTML page that has PDF injected into it via persistent XSS for example:
例如,考虑这个通过持久 XSS 注入了 PDF 的 HTML 页面:
<html>
<body>
<div>
%PDF-1.3
1 0 obj
<<
% /Type /Catalog
/Pages 2 0 R
>>
endobj
2 0 obj
<<
/Type /Pages
/Count 1
/Kids [ 3 0 R ]
>>
endobj
3 0 obj
<<
/Type /Page
/Contents 4 0 R
/Parent 2 0 R
/Resources <<
/Font <<
/F1 <<
/Type /Font
/Subtype /Type1
/BaseFont /Arial
>>
>>
>>
>>
endobj
4 0 obj
<< /Length 47>>
stream
BT
/F1 100
Tf 1 1 1 1 1 0
Tr(Hello World!)Tj
ET
endstream
endobj
xref
0 1
0000000000 65535 f
0000000010 00000 n
trailer
<<
/Root 1 0 R
>>
%%EOF
</div>
</body>
</html>
* Special thanks to Ange Albertini for crafting a PDF that works on Chrome, Safari and Firefox.
This PDF will display Hello World! and pop an alert using JavaScript.
此 PDF 将显示 Hello World!并使用 JavaScript 弹出警报。
The catch is that the browser needs to be told somehow that its displaying PDF instead of HTML. The easiest way is to simply save the HTML and rename the extension as PDF. This file will happily render in all of the Chrome browsers (Chrome, Edge, Opera, etc) as well as Firefox and other versions can be crafted that work in non-browser PDF readers. Here is an example of a HTML page being rendered as a PDF.
问题是浏览器需要以某种方式被告知它显示的是 PDF 而不是 HTML。最简单的方法是简单地保存 HTML 并将扩展名重命名为 PDF。此文件将愉快地在所有 Chrome 浏览器(Chrome、Edge、Opera 等)以及 Firefox 中呈现,并且可以制作其他版本,可以在非浏览器 PDF 阅读器中工作。下面是呈现为 PDF 的 HTML 页面的示例。
This is a valid HTML page, and it’s a valid PDF, and will display ‘Hello World!’ in many browser and non-browser based PDF renderers. Javascript can easily be included in the PDF.
这是一个有效的 HTML 页面,它是一个有效的 PDF,并且将在许多基于浏览器和非浏览器的 PDF 渲染器中显示“Hello World!”。Javascript 可以很容易地包含在 PDF 中。
If you save that HTML page as a PDF (pretty much regardless of where it is included in the page, it should execute when opened in a browser. This is how I found the third example of a parser we can use to solve this family of problems. The problem we next need to solve is how to get this HTML page that contains PDF saved as a PDF file type.
如果您将该 HTML 页面另存为 PDF(几乎无论它包含在页面中的哪个位置,它都应该在浏览器中打开时执行。这就是我如何找到我们可以用来解决这一系列问题的解析器的第三个示例。我们接下来需要解决的问题是如何将包含 PDF 的 HTML 页面保存为 PDF 文件类型。
Relative Path Overwrite
Gareth Heyes discovered RPO which, given some specific conditions, will cause a CSS payload injected into the current HTML page to be imported as a stylesheet.
Read this brief reminder about how Relative Path Overwrite works if you need a refresher.
What I have found is that there is another version of it that we can use to inject arbitrary file data into the user’s download via a simple relative anchor tag. I’ve named it Relative Path File Injection.
我发现它还有另一个版本,我们可以使用它通过简单的相对锚标记将任意文件数据注入用户的下载中。我将其命名为相对路径文件注入。
Relative Path Overwrite vs. Relative Path File Injection:
相对路径覆盖与相对路径文件注入:
RPO and RPFI are similar. RPO requires you to inject CSS on the page and that there is a preexisting link tag that uses a relative import for that stylesheet:
RPO 和 RPFI 是相似的。RPO 要求您在页面上注入 CSS,并且有一个预先存在的链接标记使用该样式表的相对导入:
<link rel="stylesheet" href="css/style.css">
RPFI requires you to inject PDF on the page and there is a preexisting anchor tag link to download a PDF that also uses a relative path:
RPFI 要求您在页面上注入 PDF,并且有一个预先存在的锚标记链接来下载同样使用相对路径的 PDF:
<a href="pdf/sample.pdf" download="sample.pdf">Safe PDF Download</a>
In RPO, when you have no forward slash at the end of a URL, the page renders normally. When you add that forward slash at the end, the browser attempts to import the current page as a CSS stylesheet.
在 RPO 中,当 URL 末尾没有正斜杠时,页面将正常呈现。在末尾添加正斜杠时,浏览器会尝试将当前页面导入为 CSS 样式表。
RPFI acts in a similar way. When a relative anchor tag is used, and a user clicks on it, if there is no forward slash at the end, the normal file is downloaded but if there is a forward slash at the end of the URL, the current HTML page is downloaded as the PDF instead of the actual PDF.
RPFI以类似的方式行事。当使用相对锚标记时,用户单击它,如果末尾没有正斜杠,则下载普通文件,但如果 URL 末尾有正斜杠,则当前 HTML 页面将下载为 PDF 而不是实际的 PDF。
And because we have injected PDF content on the page, we have injected a new file for the user to download instead of the intended file. A user downloading a file from a trusted source and following instructions from a trusted source, will most likely open the file they just downloaded.
而且由于我们在页面上注入了 PDF 内容,因此我们注入了一个新文件供用户下载,而不是预期的文件。用户从受信任的来源下载文件并按照受信任来源的说明进行操作,很可能会打开他们刚刚下载的文件。
RPFI Requirements: RPFI要求:
- The site should have the same basic properties that RPO requires (path confusion vulnerability when forward slash is appended to the URL).
- You need a Download link already on the page that has the download attribute fully defined. <a href=”pdf/sample.pdf” download=”sample.pdf”>Safe PDF Download</a> The download attribute is important because the file needs the correct extension when downloaded. There are exceptions to this rule discussed later.
您需要页面上已有一个已完全定义下载属性的下载链接。<a href=“pdf/sample.pdf” download=“sample.pdf”>安全 PDF 下载</a>download 属性很重要,因为文件在下载时需要正确的扩展名。此规则也有例外,稍后将讨论。
- That anchor tag must use relative paths
该锚标记必须使用相对路径
- You must be able to inject the PDF content into the page via a persistent XSS, or, XSS via Cache poisoning. This is important – the injected payload needs to be returned with the HTML from the server or cache provider if it will be part of the download.
您必须能够通过持久性 XSS 或通过缓存中毒将 XSS 注入页面的 PDF 内容。这很重要 – 注入的有效负载需要与服务器或缓存提供程序的 HTML 一起返回,如果它将成为下载的一部分。
Putting it all together:
把它们放在一起:
Using the outlined criteria, you locate a vulnerable site. This site would contain some links to download PDFs. You would inject a PDF into the page in any of the normal ways (persistent XSS, cache poisoning) and you would craft a URL with the trailing forward slash. You would get the user to click that link. From the user perspective, they are going to a valid site that provides links to download valid PDFs. If the user hovers a link, it is a normal link which shows the file to be downloaded with a correct extension tax-document-5150.pdf for example. But if the user clicks the link, the current page with the injected PDF is downloaded with the correct name and file extension. The user who intended to download this file opens the malicious PDF.
使用概述的条件,您可以找到一个易受攻击的站点。该网站将包含一些下载PDF的链接。您将以任何正常方式(持久性 XSS、缓存中毒)将 PDF 注入页面,并使用尾部正斜杠制作一个 URL。您将让用户单击该链接。从用户的角度来看,他们将访问一个有效的网站,该网站提供下载有效 PDF 的链接。如果用户将鼠标悬停在链接上,则该链接是一个普通链接,它显示要下载的文件,例如扩展名tax-document-5150.pdf正确。但是,如果用户单击该链接,则将下载具有注入的 PDF 的当前页面,并具有正确的名称和文件扩展名。打算下载此文件的用户打开恶意 PDF。
All that changed was the forward slash in the URL and the payload included on the page, the user has a completely different PDF downloaded when they click the same link as when there is no slash in the URL. To a user, there is pretty much no difference if the server itself was simply serving the malicious PDF.
所有改变的只是 URL 中的正斜杠和页面上包含的有效负载,当用户单击同一链接时,他们下载的 PDF 与 URL 中没有斜杠时完全不同。对于用户来说,如果服务器本身只是提供恶意 PDF,几乎没有区别。
Observations about this technique:
关于此技术的观察:
- The PDF will render and execute cross browser.
PDF 将跨浏览器呈现和执行。
- The vulnerable page can have a modern doc type (though it’s not always preferable for a reason I’ll mention in a minute).
易受攻击的页面可以具有现代文档类型(尽管由于我稍后会提到的原因,它并不总是可取的)。
- The PDF could be crafted as any form of malicious PDF. It could submit to an attacker controller server, or use a launch action to open a shell.
- Not limited to JavaScript code execution as discussed later.
- The JavaScript execution is within the context of a PDF opened locally instead of on the original site. This limits its effectiveness but if a launch action can be used, perhaps a shell can be accessed.
- This will be harder to find than RPO because while CSS links are on practically every site in the world, relative download links are not.
这将比RPO更难找到,因为虽然世界上几乎每个站点都有CSS链接,但相对下载链接却没有。
One last note on PDF injection:
关于PDF注入的最后一点说明:
Astute readers will have realized by now that when you add that forward slash to the URL, the style on the page breaks. This will make it less likely for a user to convince themselves that nothing is wrong and continue to download a file. If the page is susceptible to RPO, you could potentially use a CSS payload with an @import command to import the original page styles from the non-forward slash URL and get the style back. The CSS could be injected before or after the PDF, without affecting how either render.
精明的读者现在已经意识到,当您将正斜杠添加到 URL 时,页面上的样式会中断。这将使用户不太可能说服自己没有任何问题并继续下载文件。如果页面容易受到 RPO 的影响,则可以使用带有 @import 命令的 CSS 有效负载从非正斜杠 URL 导入原始页面样式并取回样式。CSS 可以在 PDF 之前或之后注入,而不会影响任何一个的呈现方式。
This example so far uses PDF but it works for any file type being downloaded. The interpreter executing that file will also need to be lenient in its execution, and disregard the surrounding HTML. What file types can we find that fit this description?
到目前为止,此示例使用 PDF,但它适用于正在下载的任何文件类型。执行该文件的解释器在执行时也需要宽松,并忽略周围的 HTML。我们可以找到哪些符合此描述的文件类型?
Shell Script Injection: Shell 脚本注入:
Do other file types work similarly? The answer is yes! I was emailing back and forth with Ange Albertini, and he suggested looking into archive file types which often allow arbitrary text to begin with. I found .zip would be hard to inject (binary injection would open a lot of possibilities here if anyone has any idea), but I thought I may be able to get .tar working.
其他文件类型的工作方式是否类似?答案是肯定的!我和 Ange Albertini 来回发电子邮件,他建议研究通常允许任意文本开头的存档文件类型。我发现.zip很难注入(如果有人有任何想法,二进制注入会在这里打开很多可能性),但我认为我可能能够让.tar工作。
While exploring that, I realized that tars often contain shell scripts and shell scripts may be a better candidate. Shell scripts often have some exact property that we need. It’s called ‘non-strict-mode’. In this mode, they execute line by line, and each line can error, but it will carry on until it finds code that works. The below webpage can be executed as a shell script using WSL-2 Ubuntu on Windows.
在探索这个问题时,我意识到 tar 通常包含 shell 脚本,而 shell 脚本可能是更好的候选者。Shell 脚本通常具有我们需要的一些确切属性。它被称为“非严格模式”。在这种模式下,它们逐行执行,每行都可能出错,但它会继续执行,直到找到有效的代码。以下网页可以在 Windows 上使用 WSL-2 Ubuntu 作为 shell 脚本执行。
This HTML page that is vulnerable to RPFI when downloaded as a .sh file, will execute when run in WSL-2 (Ubuntu 22.04.2 LTS (GNU/Linux 5.15.146.1-microsoft-standard-WSL2 x86_64) bash shell.
<!DOCTYPE html> <!DOCTYPE html> <html lang=”en”> <html lang=“en”> <head> <link rel=”stylesheet” href=”css/style.css”>
<link rel=“stylesheet” href=“css/style.css”> </head> <body>
<a href=”pdf/sample.sh” download=”sample-link.sh”>Safe Script Download</a>
<a href=“pdf/sample.sh” download=“sample-link.sh”>安全脚本下载</a> echo “Hello World” exit(0) 退出(0)
</body> </html> |
When a user clicks the safe download link, this HTML is downloaded as a file named sample-link.sh.
当用户单击安全下载链接时,此 HTML 将下载为名为 sample-link.sh 的文件。
When the user executes this script, they receive the following output on WSL-2 (Ubuntu 22.04.2 LTS (GNU/Linux 5.15.146.1-microsoft-standard-WSL2 x86_64):
当用户执行此脚本时,他们会在 WSL-2 (Ubuntu 22.04.2 LTS (GNU/Linux 5.15.146.1-microsoft-standard-WSL2 x86_64) 上收到以下输出:
It errors on each line leading up to the Hello World echo command, but then executes the command and exits.
它在导致 Hello World echo 命令的每一行上都出错,但随后执行该命令并退出。
And out of curiosity, I tried the same with Windows Powershell files (.ps1), and found it has this same behavior:
出于好奇,我对 Windows Powershell 文件 (.ps1) 进行了相同的尝试,发现它具有相同的行为:
<!DOCTYPE html> <!DOCTYPE html> <html lang=”en”> <html lang=“en”> <head> <link rel=”stylesheet” href=”css/style.css”>
<link rel=“stylesheet” href=“css/style.css”> </head> <body>
Write-Host “Hello, World!”
写主持人“你好,世界!
<a href=”pdf/sample.ps1″ download=”sample.ps1″>Safe .PS1 Download</a>
<a href=“pdf/sample.ps1” download=“sample.ps1”>Safe .PS1 下载</a>
</body> </html> |
Again, it errors on each line but when it gets to the Hello World, it is executed.
同样,它在每一行上都出错,但当它到达 Hello World 时,它就会被执行。
And lastly, I did find some limited circumstances that you can get .sh scripts working in Linux shells. If you can inject either double quotes or opening parenthesis right after the HTML element, you may get it to execute each line without stopping. I suspect there are other ways to do this and will follow up in the future.
最后,我确实发现了一些有限的情况,你可以让.sh脚本在Linux shell中工作。如果可以在 HTML 元素之后注入双引号或左括号,则可以让它不停止地执行每一行。我怀疑还有其他方法可以做到这一点,并将在未来跟进。
<html>”” <html>“” # line with an error
# 行有错误 ls /path/to/nonexistent/directory
ls /path/to/nonexistent/目录
# Valid shell code # 有效的 shell 代码 echo “This line will still execute”
echo “此行仍将执行” ls ./sample-link.sh <a href=”pdf/sample.sh” download=”sample-link.sh”>Safe Script Download</a>
<a href=“pdf/sample.sh” download=“sample-link.sh”>安全脚本下载</a> </html> |
*Note the above example is run on Linux 5.4.0-167-generic #184-Ubuntu SMP Tue Oct 31 09:21:49 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux Description: Ubuntu 20.04.6 LTS
*注意:以上示例运行在 Linux 5.4.0-167-generic #184-Ubuntu SMP Tue Oct 31 09:21:49 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux 描述: Ubuntu 20.04.6 LTS
So RPFI works with not only PDF, but also shell scripts on Windows WSL-2, Windows Powershell, and to a lesser degree, Linux shells. Any site letting you download shell scripts probably gives you instructions to run them that start by using ‘sudo’ to elevate privileges.
因此,RPFI 不仅适用于 PDF,还适用于 Windows WSL-2、Windows Powershell 上的 shell 脚本,以及较小程度的 Linux shell。任何允许您下载 shell 脚本的网站都可能为您提供运行它们的说明,这些脚本首先使用“sudo”来提升权限。
Note that Windows Defender flagged the .sh file download as a virus for me and didn’t let me open it (not the .ps1 file though). I had to turn off Windows Defender.
请注意,Windows Defender将.sh文件下载标记为病毒,并且不让我打开它(但不是.ps1文件)。我不得不关闭 Windows Defender。
Also, Note that if you can use a PDF launch action to run a shell command on Windows, Linux, or macOS when the PDF is opened, you could also write a shell command that executes only the shell commands in that same PDF.
另外,请注意,如果可以在打开 PDF 时使用 PDF 启动操作在 Windows、Linux 或 macOS 上运行 shell 命令,则还可以编写一个 shell 命令,该命令仅执行同一 PDF 中的 shell 命令。
Server Template Page Injection:
服务器模板页面注入:
The more types of files we can find that RPFI works with, the more useful this exploit will be.
我们可以找到RPFI使用的文件类型越多,此漏洞就越有用。
So far we have .PDF, .SH, .PS1 What else can we use? It turns out that many server side template scripts will also work. These have the added benefit that they already expect the server side code to be mixed with HTML. Meaning, if a user downloads a PHP or ASP or Coldfusion file and drops it into a server to view the result in the browser, you can execute server code. Server-side code executes before client-side code is rendered and so again, these interpreters are all lenient and ignore the standard HTML rules.
到目前为止,我们已经.PDF,.SH, .PS1 我们还能用什么?事实证明,许多服务器端模板脚本也可以使用。这些代码还有一个额外的好处,即他们已经期望服务器端代码与 HTML 混合。这意味着,如果用户下载了 PHP 或 ASP 或 Coldfusion 文件并将其拖放到服务器中以在浏览器中查看结果,则可以执行服务器代码。服务器端代码在呈现客户端代码之前执行,因此,这些解释器都非常宽松,忽略了标准 HTML 规则。
This is not an exhaustive list. I’ll leave it up to others to expand on it. Injecting any of these into an HTML page, that gets downloaded and rendered on a server should execute server side:
这不是一个详尽的清单。我会把它留给其他人来扩展它。将其中任何一个注入到HTML页面中,在服务器上下载和呈现应该执行服务器端:
- ASP (.asp) <% Response.Write(1+1) %>
ASP (.asp) <% 响应.写入 (1+1) %>
- Python Flask (.html) {{1+1}}
Python 烧瓶 (.html) {{1+1}}
- Coldfusion (.cfm) #1+1# Coldfusion (.cfm) #1+1#
- PHP(.php) <?php echo 1+1; ?>
PHP(.php) <?php echo 1+1; ?>
- Embedded Ruby (.erb) <%= 1+1 %>
嵌入式 Ruby (.erb) <%= 1+1 %>
- Perl (.pl, .cgi) <% print 1+1; %>
Perl (.pl, .cgi) <% 打印 1+1; %>
- Server Side JavaScript (.js,.ejs,.pug,.hbs) <%= 1+1 %>
服务器端 JavaScript (.js,.ejs,.pug,.hbs) <%= 1+1%>
I will only demo one of these and allow the user to extrapolate the same for all the various server pages.
我将只演示其中之一,并允许用户对所有不同的服务器页面进行推断。
If you can get persistent XSS for a PHP string <?php echo 1+1; ?> And that page has a php download, the resulting download will run as a PHP page should the user drop it into a PHP server to check it out.
如果你能得到一个PHP字符串的持久XSS <?php echo 1+1; ?> 并且该页面有一个 php 下载,如果用户将其放入 PHP 服务器进行检查,则生成的下载将作为 PHP 页面运行。
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<a href="pdf/sample.php" download>Safe PHP Download</a>
<div>
<?php
$name = "<?php echo 1+1; ?>"; // some value you can control from the database
if (!empty($name)) {
echo "Welcome, $name";
}
?>
</div>
</body>
</html>
Becomes sample.php on download
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<a href="pdf/sample.php" download>Safe PHP Download</a>
<div>
Welcome, <?php echo 1+1; ?></div>
</body>
</html>
With 1000’s of file types out there, I’m sure many more will be found in the future. Binary would open many file types for exploration.
有 1000 种文件类型,我相信将来会发现更多。二进制文件将打开许多文件类型进行探索。
Conclusion: 结论:
All in all, I found a new parser to use when we are trying to execute JavaScript from an injection point that doesn’t allow it and a novel version of RPO for file downloads, I’ve dubbed RPFI. Along the way I learned that HTML pages can be executed as shell scripts, PDF’s, and server pages.
总而言之,当我们尝试从不允许 JavaScript 的注入点执行 JavaScript 时,我找到了一个新的解析器,以及用于文件下载的新版本 RPO,我称之为 RPFI。在此过程中,我了解到 HTML 页面可以作为 shell 脚本、PDF 和服务器页面执行。
To mitigate this vulnerability on your own website, use a base tag to make all relative paths use a common base URL, or use relative paths that begin with a forward slash making them root relative, and use modern doc types.
要在您自己的网站上缓解此漏洞,请使用基本标记使所有相对路径使用通用基本 URL,或者使用以正斜杠开头的相对路径,使其成为根相对路径,并使用现代文档类型。
Special thanks to Gareth Heyes and Ange Albertini for feedback and suggestions!
特别感谢 Gareth Heyes 和 Ange Albertini 的反馈和建议!