【デシリアライズ編】信頼できないデータを蘇らせるな|CTF思考フレームワーク #15
📖 この記事はシリーズの一部です
「CTF思考フレームワーク」 Web脆弱性編 #15 / 公開中 10記事 → シリーズ一覧を見る →
デシリアライズ脆弱性は、「信頼できないデータを蘇らせる」ことで起きるRCEの宝庫。Java、PHP、Python、.NET…どの言語にも独自の地雷があり、Apache Struts2のEquifax事件や PHP のweb shell事案など、世間を騒がせた事件のトリガーになり続けています💀
シリアライズとは「オブジェクトをバイト列に変換」、デシリアライズはその逆。「バイト列を信じてオブジェクトを復元」してしまうと、攻撃者の用意したオブジェクトでサーバが踊らされます。
見た目はただのデータ復元、中身はRCE。OWASP Top10の常連です🧨

デシリアライズは「文字列→オブジェクト」復元時にコードが走る仕組みを悪用する攻撃だよ⚠️
難易度:★★★(中級) / 所要:10〜12分 / 前提:CTF思考フレームワーク #14
👀 観察フェーズ:まず何を見る?

まずCookie/フォーム/APIにBase64っぽい長い文字列がないか観察!それシリアライズ済みデータかも🔍
デシリアライズは「データの形」を覚えると見つけやすい。{O:8:”User”:…} はPHP、aced0005 で始まるBase64はJava、特定のマジックバイトでpickle…と特徴があります。

クライアントに丸ごと預けてるオブジェクトはガジェットチェーンの入り口になっちゃうんだね…😨
🤔 仮説フェーズ:攻撃者は何を考える?

デシリアライズ系の典型は言語別ガジェット。
攻撃者の仮説。
☕ 仮説①:Java(ysoserial)
readObject()を呼び出す経路があれば、CommonsCollections等のガジェットでRCE。古典かつ強力。
🐍 仮説②:Python pickle
pickle.loads()に外部入力を渡すのは即RCE。__reduce__を持つ自作クラスでos.system()を呼ぶ。
🐘 仮説③:PHP unserialize
Magic Method(__wakeup, __destruct)を持つクラスをチェーンしてPOPチェーンを組む。
💎 仮説④:.NET / Ruby Marshal
BinaryFormatterやMarshal.loadも同様の脆弱性パターン。言語問わず同じ発想で攻略。
デシリアライズは「フォーマット特定 → ガジェット選定 → ペイロード生成」の3ステップ。各言語に専用ツールがあります。

すべての言語に共通するのは「外部入力をオブジェクトに戻すな」ってことだね💡
🔬 検証フェーズ:どうやって確かめる?

まずペイロードを差し替えてエラーメッセージを観察。クラス名が出ればガジェット選定の手がかり!
検証ステップ。

ysoserial、Marshalsec、phpggcみたいなペイロード生成ツールが便利なんだね🧪
⚔️ 攻撃フェーズ:実際の手口

デシリアライズ攻撃の本命はこの3つ。
実戦シナリオ。
既存ライブラリのreadObject連鎖でRuntime.exec()に到達。サーバ完全掌握の典型経路。
BillionLaughs風の入れ子データで復元時にメモリ爆発させてサービス停止。
シリアライズされたセッションオブジェクトのisAdminを書き換えて権限昇格。署名なしの実装は壊滅的。
CTF{never_deserialize_untrusted_data_period}
どの言語でも結論は同じ:「信頼できないデータをデシリアライズするな」。これが鉄則です。
🛡️ 防御フェーズ:どう守る?

デシリアライズの守りは「やらない」が最強!🛡️
防御の3原則。
バイナリシリアライズをやめて、JSON / Protocol Buffersのような型固定の形式に。これだけで95%解消。
どうしても使うなら、復元前にクラス名を検査して許可リスト外を弾く(ObjectInputFilter等)。
クライアントに渡すシリアライズ済みデータにはHMAC署名を付け、改ざん検出。Cookieセッションは特に必須。

「外部入力をオブジェクトに復元しない」。これだけで世界が平和になるよ💪
🛡️ 今日からできる対策ツール
パスワードの使い回しや手動管理はどんなに気をつけても限界があります。🔑 パスワード管理ツール「ワンパス」なら、複雑なパスワードを安全に保管して「1つのマスターパスワード」だけ覚えられるので、今日から始める防御策としてしっくりきます。
※ 上記は他社サービスへのリンクです。購入は各自でご判断ください。
⚠️ よくある落とし穴
よくあるミス。
- 「Cookie はBase64で読めないから安全」と勘違い。デコードすればシリアライズデータが現れる。
- unserialize() に allowed_classes を渡さず、全クラス復元可能なまま。
- pickle.loads / yaml.load を「便利だから」と外部入力に対して使う。
- Java ObjectInputFilter を未設定のまま運用。
- .NET の TypeNameHandling.Auto を有効にして任意型復元を許す。
- 署名・暗号化なしのCookieにシリアライズデータを入れる。
🧰 ツール早見表
使う道具。
| ツール | 用途 | ひと言 |
|---|---|---|
| ysoserial | Javaデシリアライズペイロード生成 | ガジェットチェーン豊富 |
| PHPGGC | PHPデシリアライズペイロード集 | フレームワーク別チェーン多数 |
| ysoserial.net | .NETデシリアライズペイロード | TypeNameHandling悪用に |
| Burp Suite + Java Deserialization Scanner | 自動検出 | RCEまで至らなくても痕跡を検出 |
🎓 本気で学びたい人へ
Webセキュリティを「趣味」から「仕事」に変えたい方へ。🎓 ササエルはインフラエンジニアに特化したオンラインスクールで、セキュリティ設計の基礎から体系的に学べます。
📚 もっと深く学びたい人へ
体系的に攻撃と防御の両面を学びたいなら『ホワイトハッカー入門 第2版』が分かりやすい入口です📚
⚖️ 大事なお約束
この記事の手法は、必ず自分の環境か、許可されたCTF・脆弱性報奨金プログラム(HackerOne、Bugcrowd等)で試してください。他人のサービスに無断で攻撃を仕掛けるのは不正アクセス禁止法違反、立派な犯罪です。学んだ知識は守る側で活かしましょう🤝
📚 次に読みたい
- SSTI編|CTF思考フレームワーク #14
- コマンドインジェクション編|CTF思考フレームワーク #16
- ビジネスロジック編|CTF思考フレームワーク #13
- XXE編|CTF思考フレームワーク #17
🧪 自分で検証してみる
「自分でWordPressサイトを立てて、ログイン畫面のセキュリティを実際に試してみたい」なら、まずは安価で高速なConoHa WINGから。初期費用無料で始められます。



