2019年12月9日月曜日

SSRF対策としてAmazonから発表されたIMDSv2の効果と限界

サマリ

Capital OneからのSSRF攻撃による大規模な情報漏えい等をうけて、Amazonはインスタンスメタデータに対する保護策としてInstance Metadata Service (IMDSv2) を発表した。本稿では、IMDSv2が生まれた背景、使い方、効果、限界を説明した上で、SSRF対策におけるIMDSv2の位置づけについて説明する。

SSRFとは

SSRFは、下図のように「外部から直接アクセスできないエンドポイント」に対して、公開サーバーなどを踏み台としてアクセスする攻撃方法です。SSRF(Server Side Request Forgery)の詳細については過去記事「SSRF(Server Side Request Forgery)徹底入門」を参照ください。
最終的な攻撃目標は多様ですが、近年問題になっているのが、クラウドサービスのインスタンス・メタデータを取得するAPIのエンドポイントです。有名なものがAmazon EC2の169.254.169.254(IMDS)ですが、類似の機能をクラウドサービス各社が提供しています。
先の記事でも紹介したSSRF脆弱なサンプルを以下に示します。これは、はてなブックマークのようなソーシャルブックマークアプリの「プレビュー機能」を想定しています。
<?php
  require_once('./htmlpurifier/library/HTMLPurifier.includes.php');
  $purifier = new HTMLPurifier();

  $ch = curl_init();
  $url = $_GET['url'];
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $html = curl_exec($ch);
  echo $purifier->purify($html);
このスクリプトをAmazon EC2上においてSSRF攻撃すると、下図のようにIAMのクレデンシャルが表示されます。


 SSRF攻撃が一般の方にも話題になったのはCapital Oneからの1億人超の個人情報流出事件で、詳しくは以下の記事にまとめられています。
 また、SSRF攻撃の標準的な対策は、ネットワーク的な対策で、EC2の場合は以下のようなiptablesによる防御が従来から推奨されていました。
sudo iptables --insert FORWARD 1 --in-interface docker+ --destination 169.254.169.254/32 --jump DROP

Amazon ECS コンテナインスタンスの IAM ロール - Amazon Elastic Container Service より引用
ここまでが長い前置き(前提知識の確認)です。

EC2インスタンスメタデータサービスv2(IMDSv2)とは

この状況に対して、Amazonが批判されたり、Amazonの責任ではないという反論があったりしていましたが、Amazonは今年の11月20日オフィシャルブログにて、Instance Metadata Service v2(IMDSv2) を発表しました。以下は、クラスメソッドの臼田さんのブログ記事から要点の引用です。
  • v2へのアクセスには事前に取得したTokenを必須とする
    • TokenはPUTで取得する必要がある
    • Tokenリクエスト時に有効期限(秒)を設定できる
    • Tokenはヘッダに入れてリクエストする必要がある
  • v1を無効化できる(デフォルトでは併用可能)
  • メタデータサービス自体を無効化できる
IMDSv2によるメタデータ取得は以下のようになります。まずは、トークンの取得
$ curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 60"
AQAAAKunSEcqfWQgz1E-ryJ3fdWDoOkbn8Nn4h2C6qN6nP56npog8Q==$
赤字のBASE64っぽいものがトークンです。TTLを60秒としているので、この値は既に無効です。PUTメソッドとX-aws-ec2-metadata-token-ttl-secondsヘッダを要求することで、攻撃難易度を上げています。
続いて、トークンを利用したメタデータの取得です。X-aws-ec2-metadata-tokenヘッダにより、先程取得したトークンを指定します。
$ curl -H "X-aws-ec2-metadata-token: AQAAAKunSEcqfWQgz1E-ryJ3fdWDoOkbn8Nn4h2C6qN6nP56npog8Q==" http://169.254.169.254/latest/meta-data/iam/info/
{
  "Code" : "Success",
  "LastUpdated" : "2019-12-08T02:32:19Z",
  "InstanceProfileArn" : "arn:aws:iam::999999999999:instance-profile/test-role",
  "InstanceProfileId" : "ZZZZZZZZZZZZZZZZZZZZZ"
}$
これだけだと、IMDSv1が有効になっているのでSSRF攻撃は緩和されません。IMDSv1を無効化するには、AWSCLIから以下のように --http-tokens を required に設定します。
$ aws ec2 modify-instance-metadata-options --instance-id i-FFFFFFFFFFFFFFF --http-tokens required --http-endpoint enabled
{
    "InstanceId": "i-FFFFFFFFFFFFFFFFF",
    "InstanceMetadataOptions": {
        "State": "pending",
        "HttpTokens": "required",
        "HttpPutResponseHopLimit": 1,
        "HttpEndpoint": "enabled"
    }
}
$
この状態で先の攻撃をすると、以下のように攻撃は防御されます。


SSRF攻撃の文脈でPUTメソッドやカスタムHTTPリクエストヘッダを指定することは難しそうなので、「これだけでSSRF対策は十分ではないか」と思う人もいそうですが、実は攻撃は可能です。

Gopherプロトコルとは

以前からSSRF界隈ではGopherプロトコルの活用が話題となっていて、はせがわようすけさんが分かりやすいスライドで紹介されています。
このスライドの12ページからがGopherを用いた攻撃手法についての説明です…が、このスライドは今年の9月18日の講演のものですので、当時存在しなかったIMDSv2についての言及はありません。このため、はせがわさんのスライドを引き継ぐ形で、GopherによるIMDSv2への攻撃を紹介します。

まず、Gopher自体の紹介はこちらの記事などを参照していただくとして、ここではcurlとnetcatによりgopherプロトコルを簡単に試してみます。

まずはcurlコマンドにより以下のURLをアクセスしてみます。
$ curl gopher://localhost:8888/_Hello%0d%0aHiroshi%20Tokumaru%0d%0a
curlコマンド実行前にnetcatで8888ポートを待ち受けていると、以下のような表示になります。
$ nc -l 8888
Hello
Hiroshi Tokumaru

Response           ← この行はResponse 改行 Ctrl-d を手入力したもの
$
この際の呼び出し側は下記となります。
$ curl gopher://localhost:8888/_Hello%0d%0aHiroshi%20Tokumaru%0d%0a
Response
$
このように、Gopherプロトコルを使うと、任意リクエストをURLで指定でき、そのレスポンスを受け取れることから、HTTPやSMTPその他のプロトコルをエミュレートできることになります。

Gopherプロトコルを用いたIMDSv2に対する攻撃

先程のサンプルプログラムをEC2のIMDSv1を無効化した環境に設置した状態で、Gopherプロトコルを用いて攻撃してみましょう。まずはPUTメソッドによるトークン取り出しです。表示が見やすいようにHTMLソースの形で表示しています。アドレスバーには gopher://169.254.169.254:80/_PUT というURLがちらっと見えていますね。


このトークン(有効時間は60秒…もっと長くすることも可能)を用いて、メタデータを表示させた結果が下記です。

このように、IMDSv1を無効化してIMDSv2のみ有効としても、Gopherプロトコルを用いてSSRF攻撃ができました。

リダイレクトを許可している場合

今までの「脆弱なスクリプト」は、与えられたURLに対してスキーム(プロトコル)もホストのIPアドレスもチェックしていなかったので、これらのチェックを追加してみましょう。これだけだと防御できて当然なので、cURLのオプションとしてCURLOPT_FOLLOWLOCATIONをtrueにします。これは、リダイレクトをcURL内部で自動的に追跡するという意味です。
<?php
  require_once('./htmlpurifier/library/HTMLPurifier.includes.php');
  $purifier = new HTMLPurifier();

  $ch = curl_init();
  $url = $_GET['url'];
  $urlinfo = parse_url($url);  // URLのパース
  $scheme = $urlinfo['scheme'];
  $host = $urlinfo['host'];
  $ip = gethostbyname($host);
  if ($ip === "169.254.169.254") {  // IPアドレスのチェック
    die("Invalid host");
  } elseif ($scheme !== 'http' && $scheme !== 'https') { // スキームのチェック
    die("Invalid scheme");
  }
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);  // リダイレクトを自動追跡
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

  $html = curl_exec($ch);
  echo $purifier->purify($html);
このスクリプトに対して、リダイレクトを用いた攻撃をします。具体的には下記のスクリプト(リダイレクタ)のURLをサンプルスクリプトに指定します。
<?php
  header('Location: gopher://169.254.169.254:80/_PUT%20/latest/api/token...以下悪用防止のため略
実行結果は以下となり、トークンを取得できていることがわかります。


同様に、このトークンを使用してEC2インスタンスのメタデータを取得することができます。

※ はせがわさんのスライドでは、この攻撃にはスクリプト側で明示的に任意プロトコルへのリダイレクトが許可されている必要があるように読めます(P23)が、私が実験により確認した範囲では、任意プロトコルの明示的な許可は必要ないようです。

対策

上記攻撃には以下の対策候補が考えられます。
  • curlで扱うプロトコルをHTTPおよびHTTPSに限定(常に指定を推奨)
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
  • リダイレクトの追跡を禁止する(curlのデフォルトに戻す、あるいは以下を設定)
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);  // リダイレクト追跡しない
  • CURLINFO_PRIMARY_IPにより「実際にアクセスしたIPアドレス」を求め、169.254.169.254(等ブラックリストのIPアドレス)であれば表示をやめる
$primary_ip = curl_getinfo($ch, CURLINFO_PRIMARY_IP);
  • URLからホスト名に対応するIPアドレスとスキームを確認する(先のスクリプトでは実施済み)

結局どうすればよいか

IMDSv2はそもそもAmazonからもインスタンスメタデータに対する defense in depth (多層防御)と紹介されており、根本的な解決策ではありません。なので、他の根本的な解決策を実施した上で、予防的な対策(緩和策)として用いるべきです。
では、根本的な解決策はなにかというと、インスタンスメタデータの保護という点では、先に紹介したiptables等を用いたネットワーク的な対策が確実です。あるいは、以下により、HTTPによるインスタンスメタデータ参照そのものを禁止することも有効です。
$aws ec2 modify-instance-metadata-options --instance-id i-FFFFFFFFFFFFFFFF --http-endpoint disabled
{
    "InstanceId": "i-FFFFFFFFFFFFFFFFF",
    "InstanceMetadataOptions": {
        "State": "pending",
        "HttpTokens": "required",
        "HttpPutResponseHopLimit": 1,
        "HttpEndpoint": "disabled"
    }
}
ただし、上記はインスタンスメタデータに対する保護であり、SSRF攻撃全般を防御できるわけではないため、他に守るべきエンドポイントがある場合には他の対策を併用する必要があります。

まとめ

Instance Metadata Service v2 (IMDSv2) について紹介しました。IMDSv2を用いることにより、SSRF攻撃をかなり緩和されることが期待できるものの、根本的な解決策ではなく緩和策の一つとして用いるべきと考えます。これは、Amazon自体がIMDSv2をdefense in depth(多層防御)とうたっていることからも伺えます。
また、SSRF攻撃の対策は難易度が高いため、可能であればSSRF攻撃の影響を受けない仕様(例えば外部から受け取ったURLにアクセスしない)の検討を推奨します。

2019年12月5日木曜日

シェルを経由しないOSコマンド呼び出しがPHP7.4で実装された

この記事はPHP Advent Calendar 2019の5日目の記事です。

はじめに

私は6年前に、PHP Advent Calendar 2013として「PHPだってシェル経由でないコマンド呼び出し機能が欲しい」という記事を書きました。その中で、OSコマンドインジェクション対策の根本的かつ安全な対策は「シェルを経由しないコマンド呼び出し」であることを指摘した上で、末尾に以下のように書きました。
PHPコミッタのみなさま、PHP5.6の新機能として、シェルを経由しないコマンド呼び出しの機能を追加できませんか?
現実には当時からPCNTL関数にてシェルを経由しないコマンド呼び出しはできたのですが、当関数の使用が難しいことと、CLI版あるいはCGI版(FastCGIは可)のPHPでないとサポートされていないなどの制限があり、popenやproc_openなど使いやすいコマンド呼び出し関数において、シェル呼び出しのないコマンド実行機能が欲しいところでした。

この「私の願い」はPHP 5.6では実現しませんでしたが、PHP 7.4においてproc_open関数の拡張として実現しました。実に6年越しの実現ということになります。

proc_openの従来の問題点

proc_openに限りませんが、PHPの従来のコマンド実行機能(PCNTL関数は例外)の問題として、「常にシェル経由でコマンドを呼び出す」ことがあります。これを確認するための簡単なサンプルを示します。以下は、ps -fコマンドをproc_open関数で呼び出しています。
<?php
$cmd = "ps -f";
$process = proc_open($cmd, [], $pipes);
if (is_resource($process)) {
    $return_value = proc_close($process);
    echo "command returned $return_value\n";
}
呼び出し例は下記となります。赤字で示しているように、シェル(/bin/sh)経由でpsコマンドが実行されています。
UID        PID  PPID  C STIME TTY          TIME CMD
ockeghem 16921 16920  0 16:31 pts/0    00:00:00 -bash
ockeghem 18858 16921  0 17:18 pts/0    00:00:00 php-7.4.0 proc_open4.php
ockeghem 18859 18858  0 17:18 pts/0    00:00:00 sh -c ps -f
ockeghem 18860 18859  0 17:18 pts/0    00:00:00 ps -f
command returned 0
このため、コマンドラインにセミコロンなどにより追加のコマンドを実行できる可能性があり、OSコマンドインジェクション脆弱性の原因になっていました。ここで、psのオプションとして、-fの代わりに、「-f; echo Hello」を指定してみましょう。
<?php
$cmd = "ps -f; echo Hello";
$process = proc_open($cmd, [], $pipes);
// 以下省略
呼び出し例は下記となります。sh -c のパラメータとして; echo Helloが追加されていることと、echoコマンドの実行結果としてHelloが表示されていることがわかります。これがOSコマンドインジェクションの原理です。
UID        PID  PPID  C STIME TTY          TIME CMD
ockeghem 16921 16920  0 16:31 pts/0    00:00:00 -bash
ockeghem 18932 16921  0 17:30 pts/0    00:00:00 php-7.4.0 proc_open4.php
ockeghem 18933 18932  0 17:30 pts/0    00:00:00 sh -c ps -f; echo Hello
ockeghem 18934 18933  0 17:30 pts/0    00:00:00 ps -f
Hello
command returned 0
この対策として、コマンドラインのパラメータをエスケープ処理する方法もありますが、エスケープ処理自体が複雑になる可能性があり、実際にPHPのescapeshellcmd関数には脆弱性(こちらを参照)があるため使用を避けるべき状態でした。

proc_openのPHP 7.4での新しい呼び出し方

この状況に対して、PHP 7.4では、proc_openの第1引数を配列として指定することにより、コマンドとパラメータを明確に分離するとともに、シェルを経由しないコマンド実行ができるようになりました(パチパチパチ)。
先のスクリプトをこの形式で書き換えてみましょう。
<?php
$cmd = ["ps", "-f"];
$process = proc_open($cmd, [], $pipes);
if (is_resource($process)) {
    $return_value = proc_close($process);
    echo "command returned $return_value\n";
}
実行例は以下となります。シェルを経由せずに直接コマンドが実行されていることがわかります。
UID        PID  PPID  C STIME TTY          TIME CMD
ockeghem 16921 16920  0 16:31 pts/0    00:00:00 -bash
ockeghem 18895 16921  0 17:27 pts/0    00:00:00 php-7.4.0 proc_open4.php
ockeghem 18896 18895  0 17:27 pts/0    00:00:00 ps -f
command returned 0
続いて、先程同様に、-f オプションの代わりに -f; echo Hello を指定してみましょう。
<?php
$cmd = ["ps", "-f; echo Hello"];
$process = proc_open($cmd, [], $pipes);
// 以下略
実行結果は以下のとおりです。psコマンドにオプションとして「-f; echo Hello」が渡されたため、「unsupported SysV option」というエラーになっていますが、OSコマンドインジェクションにはならないことがわかります。
error: unsupported SysV option

Usage:
 ps [options]

 Try 'ps --help <simple all="" list="" misc="" output="" threads="">'
  or 'ps --help <s a="" l="" m="" o="" t="">'
 for additional help text.

For more details see ps(1).
command returned 1
この呼出方法(proc_openの第一引数を配列で指定)の場合、シェルを経由しないでコマンドを呼び出すことから、原理的にOSコマンドインジェクション脆弱性を避けることができます。今後PHP 7.4以降にて外部コマンドを呼び出す場合は常に、proc_open関数にて第1引数を配列で指定し、かつ配列の先頭要素(コマンド名)は固定とすることで、OSコマンドインジェクションを避けつつ簡便かつ安全な実装が可能になります。

まとめ

PHP 7.4にて新たに追加されたproc_openの新しい呼び出し方を紹介しました。私個人としても、6年越しの要望がかなえられた結果となり、よいクリスマスを迎えられそうです。

2019年7月29日月曜日

PHPサーバーサイドプログラミングパーフェクトマスターのCSRF対策に脆弱性

サマリ

PHPサーバーサイドプログラミングパーフェクトマスターには、PHP入門書としては珍しくクロスサイト・リクエストフォージェリ(CSRF)対策についての説明があるが、その方法には問題がある。アルゴリズムとして問題があることに加えて、実装上の問題があり、そのままコピペして用いると脆弱性となる。

はじめに

古庄親方の以下のツイートを見て驚きました。

CSRFトークンの生成に、password_hash関数を使うですと?
親方に書籍名を教えていただき、購入したのが、この記事で紹介する「PHPサーバーサイドプログラミングパーフェクトマスター」です。同書では、CSRF対策にpassword_hashを2種類の方法で使っています(!)が、本稿では、セクション10.3 (P726~) にて説明されている方法を取り上げます。

当該コード

当該コードを示します。同書では、認証・入力フォーム・登録の3機能が1つのPHPファイルにまとめられていますが、そこから抜き出す形で、以下は入力フォームです。
<?php
function getToken($rand='') {
    $_SESSION['rand'] = $rand;
    $token = password_hash($rand, PASSWORD_DEFAULT);
    return $token;
}
// セッションスタート
session_start();
$rand = mt_rand();
$token = getToken($rand);
print <<<EOD
<form action="" method="post">
<input type="hidden" name="request" value="reg" />
<input type="hidden" name="token" value="$token" />
<input type="submit" value="登録">
</form>
EOD;
トークンの「素(もと)」としてmt_rand()関数が呼ばれ、その値をセッション変数$_SESSION['rand']に保存しています。その乱数値をpassword_hash関数で処理することで、トークンを生成しています。入力フォームの生成例を以下に示します。
<form action="" method="post">
<input type="hidden" name="request" value="reg" />
<input type="hidden" name="token"
  value="$2y$10$alqDLwZSizuBYpwmBR6pj.WzxI7UeW9YutuxHjb.r2qw9QQOBqbw6" />
<input type="submit" value="登録">
</form>
赤字に示した部分($2y$...)がトークンですが、これを見ると、「なんでパスワードのハッシュ値をCSRFトークンにしているわけ?」と勘違いする人が続出しそうですね。
そして、このトークンを受け取り、処理するプログラムが下記の部分です。
<?php
function check ($token = '') {
    return (password_verify($_SESSION['rand'], $token));
}
session_start();
if (isset($_POST['request']) === true && $_POST['request'] === 'reg' && isUser() == true) {
    if(isset($_POST['token']) === false || check($_POST['token']) === false) {
        print '不正なアクセスが行われました。';
    } else {
        print '処理が完了しました!';
        unset($_SESSION['rand']);
        $_SESSION = array();
    }
}
$_POST['token']がNULLでないことを確認した上で、check関数で、セッション変数$_SESSION['rand']をパスワードに見立て、パスワードのハッシュ値に相当する$_POST['token']にてpassword_verify関数で照合する形で、トークンを検証しています。

何が問題か

このプログラムには以下の問題があります。
  1. 設計上の問題
  2. 実装上の問題
以下、順に説明します。

設計上の問題

そもそもpassword_hash関数は、パスワードを安全に保存するための関数なので、CSRFトークンの処理のことはまったく考慮されておらず、一言で言えば「使う場所を間違えている」ことになります。通常トークンの生成には、暗号論的に安全な疑似乱数生成器(CSPRNG)を用います。PHP 7以降ではrandom_bytes関数があるので(*1)、それを素直に使うだけです。さらにハッシュ関数を通すようなことは必要ありません。余計なことをやればやるほど、バグの原因になり、ひいては脆弱性の原因になります。

(追記 2019/7/29 20:36)
*1 当書籍はXAMPP上のPHP5.5を前提としているので、random_bytes関数(PHP 7.0以降)は使えませんが、代わりにopenssl_random_pseudo_bytes関数(PHP 5.3以降)が使えます。当関数はopensslの導入が前提ですが、XAMPPはデフォルトでopenssl関数が使用できます。
(追記終わり)

加えて、mt_rand()の使用も問題です。この関数は、マニュアル(下記引用)にある通り、セキュリティ目的で使うことは適切でありません。
警告 この関数が生成する値は、暗号学的に安全ではありません。そのため、これを暗号として使ってはいけません。暗号学的に安全な値が必要な場合は、random_int() か random_bytes() あるいは openssl_random_pseudo_bytes() を使いましょう。

https://php.net/manual/ja/function.mt-rand.php より引用
また、mt_rand関数を引きなしで呼び出すと、0からmt_getrandmax()の戻り値までの値を返しますが、mt_getrandmax()は64ビット環境でも2147483647なので、31ビットの範囲になります。これはトークンに用いる乱数のエントロピーとしては不足しています。
さらに、password_hash関数はパスワードの保護を強化するためにストレッチング(ハッシュ計算を繰り返すこと)を施していますが、そのために、password_hashおよびpassword_verify関数は非常に低速です。CSRF対策のために、わざわざ処理を遅くする必要はありません。

実装上の問題

紹介したプログラムには実装上の問題もあります。使われているトークンはワンタイムのものであり、使用済みになるとunsetされます。すなわち、トークンがNULLとなる時期が存在します。そのタイミングを狙った攻撃ができるのです。
すなわち、以下の関数呼び出しがtrueになるような$tokenを渡せばよいことになりますが…
password_verify(NULL, $token)
実は、password_verifyの第一引数にNULLを渡すと、空文字列を渡したのと同じ結果になります。なので、空文字列に対するpassword_hash関数の結果を使って、攻撃が可能です。空文字列に対するハッシュ値はソルトにより無数に存在しますが、たとえば以下で攻撃ができます。
$2y$10$V3V9iX2iR6ZqaNuFAyUlPeiIvmQrGKDbrJQWdkXWVECGUodZON0Iu
検証例を示します。
<?php
var_dump(password_verify(null, '$2y$10$V3V9iX2iR6ZqaNuFAyUlPeiIvmQrGKDbrJQWdkXWVECGUodZON0Iu'));

// bool(true) が表示される
これは、前述した「余計なことをやればやるほど、バグの原因になり、ひいては脆弱性の原因にな」った例といえます。

まとめ

PHPサーバーサイドプログラミングパーフェクトマスターにおけるCSRF対策の問題を報告しました。実務上でCSRF対策をする場合は、アプリケーションフレームワークの機能を使うか、よく検証されたライブラリを使うべきですが、特別な事情があって独自実装する場合には、定石的な手法を用い、かつできるだけ簡素な、検証のしやすい実装にすべきと考えます。
また、password_hash関数をトークン生成に用いる例が、同書に限らず散見されますが、これは百害あって一利なしですので、トークン生成には単にCSPRNGを使うと覚えておきましょう。



2019年7月1日月曜日

PHPカンファレンス福岡2019のSST社ブースにてPHPクイズ出題を担当しました

PHPカンファレンス福岡2019のセキュアスカイテクノロジー(SST)社ブースにて、PHPクイズの出題を担当しました。以下は、そのパネルのイメージです。SST社は弊社EGセキュアソリューションズ株式会社のパートナー企業で、私はSST社のEラーラニングコンテンツ(PHP編)の監修を担当しています。


問題はすべて2択で、回答は下の写真のように、赤または青のシールをボードに貼り付ける形になっています。回答がわりとバラけていて、出題者的にはいい感じですね。


以下、出題と解答、解説を記載します。

問題1

以下のPHPスクリプトで、クッキーPHPSESSIDの削除として機能するのはどちら?
PHPのバージョンは7.3.6とする。

A) (正解)31人が選択=正答率 83.8%
<?php
setcookie('PHPSESSID');

B) 6人が選択
<?php
header('Set-Cookie: PHPSESSID=');

解説

setcookie関数の第2引数の省略時の値は '' (空文字列)ですので、A)は setcookie('PHPSESSID', ''); としたのと同じはずです。そして、第2引数が空文字列の場合は、実際にはクッキーの値としてdeletedが指定され、expires属性が過去日時(PHP-7.3.6の場合は、Thu, 01-Jan-1970 00:00:01 GMT)になります。すなわち、setcookie関数の第2引数を省略すると、クッキーの削除として機能します。
B) header関数の方は、クッキーの値が空文字列になりますが、クッキーそのものは削除されません。

参考記事: PHPのsetcookie関数で空文字列を設定しようとするとクッキーが削除される

ところが、出題の確認時にmodphpallで確認したところ、古いPHPでは上記の挙動にはならず、以下のレスポンスヘッダが送信されることがわかりました。この動作は、setcookie関数の第2引数を省略した場合のみで、空文字列またはnullを指定した場合はマニュアルどおりの動作となります。
Set-Cookie: PHPSESSID=
正確に言えば、PHP 4.1.0~PHP 5.6.13までが上記挙動になります。すべてのPHP 4.0と PHP 5.6.14以降、PHP 7以降では、マニュアルどおりの動作となります。この変更は、恐らく以下のバグレポートに対応したものと思われます。

Bug #67131 setcookie() conditional for empty values not met

プログラミング言語のエッジケースの出題をする場合は特に、実環境での動作確認と、処理系の想定バージョンの明記が重要だなとあらためて感じました。

問題2

以下のPHPスクリプトはどちらが表示される? PHPのバージョンは7.3.6とする。
<?php
   $mail = "a@b@example.jp";
   var_dump(filter_var($mail, FILTER_SANITIZE_EMAIL));

A) 31人が選択
bool(false)

B) (正解)6人が選択=正答率 16.2%
string(14) "a@b@example.jp"

解説

この問題は「ひっかけ」でして、実際に多くの方がひっかかりました。
マニュアルにあるように、filter_var関数に FILTER_SANITIZE_EMAIL を指定した場合は、英字、数字および !#$%&'*+-=?^_`{|}~@.[] 以外のすべての文字を取り除きます。出題の場合は、除去対象の文字がないので、入力値がそのまま出力されます。
メールアドレスの形式を検証するためには、FILTER_SANITIZE_EMAIL ではなく、FILTER_VALIDATE_EMAIL を使用します。

率直に言って、FILTER_SANITIZE_EMAILのユースケースは思いつきません。要らんでしょ、こんなもの。

問題3(PHP考古学)

PHP-5.2.17にてregister_globals=onの環境で、あらかじめ以下のようにセッション変数が設定されている。
$_SESSION['user'] = 'yamada';
クエリ文字列 user=tanaka
を指定して以下のスクリプトを実行した場合の表示はどちら?
<?php
   session_start();
   echo $user;
A)yamada  (正解) 23人が選択=正答率 62.2%
B)tanaka 14人が選択

解説

register_globals=on の環境では、session_start()を実行時にセッション変数の値がグローバル変数として初期設定されます。したがって、$_SESSION['user'] = 'yamada'; が設定されている場合、$user の初期値は 'yamada' になります。
仮に、このセッション変数がセットされていない場合、クエリ文字列 user=tanaka の方が使われ、$user の初期値は 'tanaka' になります。セッション変数とクエリ文字列(やPOST変数など)の両方に同じパラメータ名がある場合、セッション変数の方が優先されます。その理由は、セッション変数のグローバル変数へのセットは、起動時ではなく、session_start()の実行時に行われるからです。すなわち、同名のパラメータがあった場合は、セッション変数が上書きします。
したがって、register_globals=on の使用は脆弱性の原因になりやすいことはよく知られていますが、セッション変数をグローバル変数の初期値として用いると、特に脆弱性が混入しやすくなります。

例えば、以下のログインチェックのプログラムについて
session_start();
if (! isset($_SESSION['user']) {
  die('ログインしてください');
}
$user = $_SESSION['user'];

これを register_globals=on を想定して「直訳」すると以下のようになります。
session_start();
if (! isset($user)) {
   die('ログインしてください');
}
// $user = $_SESSION['user'];  // これは不要となる
register_globals=on の場合、session_start()を実行した時点で、セッション変数 $_SESSION['user'] の値はグローバル変数 $user にセットされるため、「これは不要となる」とコメントした行は不要となります。便利ですね!
しかし、$_SESSION['user'] がない場合、$user=nullが実行されるわけではないので、クエリ文字列等にuser=tanakaがあった場合、$userには 'tanaka' がセットされます。すなわち、パスワードを知らなくても誰にでもなりすましできます。これは重大な問題ですね。
register_globals=on を用いて、上記の脆弱性を修正するには以下のように書くべきですが…
$user = null;  // register_globals=onによる初期設定を無効化する
session_start();
// $_SESSION['user'] がある場合、$userにその値がセットされる
if (! isset($user)) {
  die('ログインしてください');
}
上記は著しく直感に反するプログラムですし、それゆえに初期化漏れが盛大に発生しそうです。なので、register_globalsがPHP 5.4で削除されたのは、必然のことと言えましょう。


[PR]
徳丸が代表を務めるEGセキュアソリューションズ株式会社では、ウェブサイトを堅牢にするための各種セキュリティサービスを提供しています。

2019年5月30日木曜日

2019年1月から5月に公表されたウェブサイトからのクレジットカード情報漏えい事件まとめ

株式会社ヤマダ電機の運営するECサイトから、最大37,832件のクレジットカード情報が漏洩したと昨日発表されました。ヤマダ電機のように日本を代表する家電量販店のサイトからクレジットカード情報が漏洩したことに私自身驚きました。

弊社が運営する「ヤマダウエブコム・ヤマダモール」への不正アクセスによる個人情報流出に関するお詫びとお知らせ

漏洩した情報は以下のように発表されています。
  • クレジットカード番号
  • 有効期限
  • セキュリティコード
はてなブックマークやtwitterのコメントを見ていると、「セキュリティコードを保存していたのか」という意見が見えますが、おそらくセキュリティコードは保存されていなかったと推測します。
本稿では、この件を含め、本年の現時点までのウェブサイトからのクレジットカード情報漏えい事件についてまとめました。

事件の一覧

下表に本年(2019年)の現時点までに公表されたウェブサイトからのクレジットカード情報漏洩事件をまとめました。サイト名、漏洩期間、漏洩件数(最大)、セキュリティコードの漏洩有無、漏洩の手口(後述)を記載しています。

サイト名漏洩期間漏洩件数セキュリティコード漏洩手口
バニーファミリー横浜ネットショップ2018年6月28日~同年10月25日241件漏洩Type5
オンライン通販サイト(ハセ・プロ)2018年10月1日~2019年1月24日1,311件漏洩Type5
歯学書ドットコム2012年11月11日~2018年12月28日5,689件漏洩不明
本味主義2017年5月22日~2018年10月14日2,926件漏洩Type4?
子供服サーカス2018年10月1日~2019年1月18日2,200件漏洩Type4
エコレオンラインショップ2018年5月16日~2018年12月11日247件漏洩Type4
ななつ星 Gallery2013年10月5日(サイト開設日)~
2019年3月11日(サイト閉鎖日)
3,086件漏洩不明
「ショコラ ベルアメール」オンラインショップ2018年8月6日~2019年1月21日1,045件漏洩Type5
エーデルワイン オンラインショップ2015年7月8日~2018年8月5日1,140件漏洩不明
小田垣商店オンラインショップ2018年4月3日~2018年5月16日及び
2018年9月3日~2019年2月28日
2,415件漏洩不明
藤い屋オンラインショップ2018年10月15日~2019年1月28日477件Type5
エンターテインメントホビーショップ ジャングル2017年5月2日~2018年11月6日2,507件漏洩Type2
ヤマダウエブコム・ヤマダモール2019年3月18日~2019年4月26日37,832件漏洩Type4

大半の事件でセキュリティコードが漏洩している

上表からわかるように、藤い屋オンラインショップを除いたすべての事件でセキュリティコードが漏洩しています。昨年のまとめも見ていただくとわかりますが、最近のウェブサイトからのクレジットカード情報漏洩では、セキュリティコードが漏洩する方がむしろ普通です。
昨年10月のブログ記事「クレジットカード情報盗み出しの手口をまとめた」では、クレジットカード情報を窃取する手口をType1~Type5にまとめましたが、この中で、Type4とType5はセキュリティコードを容易に盗むことができます。

Type4の手口とは

ここでType4の手口について説明します。下図のように、カード情報入力画面に細工を施すことがType4の特徴です。
下図はサイト利用者がクレジットカード情報を入力している様子です。入力フォームに仕掛けられたJavaScriptにより、カード情報は攻撃者の管理するサーバーに送信されています。
ヤマダ電機のサイトからの情報漏えいがこのパターンと推測する理由は、リリースの以下の記述からです。
(1)原因
第三者によって「ヤマダウエブコム・ヤマダモール」に不正アクセスされ、ペイメントアプリケーションの改ざんが行われたため
弊社が運営する「ヤマダウエブコム・ヤマダモール」への不正アクセスによる個人情報流出に関するお詫びとお知らせより引用
そして、同じくType4と推測されるサイトとしては下記があります。
Q.子供服サーカス、および子供服ミリバールからクレジットカード情報が流出したのですか?
弊社ではカード情報を保有しておりません。今回は、注文情報入力画面 が 不正アクセスにより 改竄され、カード入力画面で入力されたお客様のカード情報が、流出したと思われます。
Q&A】クレジットカード情報流出に関するご質問と回答(株式会社サーカス)より引用
2018 年5 月16 日に攻撃者が、データベースへ不正な仕掛けをページ内に埋め込んだとみられます。
その仕掛けは、ページ内の入力フォームに入力されたカード会員情報を正規の処理とは別に外部サイトへ転送する機能を持っていた為、2018年5月16日以降当該サイトのカード利用者のカード会員情報が搾取されていたと考えられる、との事でした。
エコレ通販サイトにおける不正アクセスによるお客さま情報の流出懸念に関するお知らせ より引用

Type5の手口も依然活発

一方、昨年から使われた始めたType5も依然として活発です。下図は、バニーファミリー横浜のFAQからの引用です。


【重要】カード情報流出についての、ご質問とご回答  バニーファミリー横浜 公式オンラインショップ より引用

そして、下図が攻撃後の画面遷移で、「偽のカード入力画面」が画面遷移に挿入されています。


【重要】カード情報流出についての、ご質問とご回答  バニーファミリー横浜 公式オンラインショップ より引用

この遷移は、「2018年に公表されたウェブサイトからのクレジットカード情報漏えい事件まとめ」で紹介した伊織の事例と酷似しており、偽画面のドメイン名まで同じです。同一犯人、あるいは同一犯行グループではないでしょうか。

また、以下のように、ハセ・プロ、ショコラ ベルアメール、藤い屋についてもこの手口であることがリリースからわかります。

フィッシングサイトによるクレジットカード情報不正取得についてのお詫びと注意喚起のお知らせ (株式会社ハセ・プロ)より引用

「ショコラ ベルアメール」のオンラインショップへの不正アクセスに関するご質問と回答 より引用
2018年10月15日から2019年1月28日までの期間においてシステムが改ざんされた痕跡があり、 クレジットカード決済を選択されたお客様が偽の決済画面へ誘導され、そこで入力されたクレジットカード情報が流出し、 一部のお客様のクレジットカード情報が不正利用された可能性があることを確認いたしました。
弊社が運営する「藤い屋オンラインショップ」への不正アクセスによる個人情報流出に関するお詫びとお知らせより引用

なぜ入力フォームからクレジットカード情報を盗むのか

ブログ記事「ECサイトからクレジットカード情報を盗み出す新たな手口」にて紹介したように、昨年の6月1日に改正割賦販売法が施行され、クレジットカード情報を扱うECサイト事業者にもカード情報保護が求められるようになりました。そして、この保護についてのガイドラインになるのが、『クレジット取引セキュリティ協議会の「実行計画」』であり、中身はクレジットカード情報番号の非保持化が柱になっています。
具体的には、以下に示す「JavaScript(トークン)型」と「リダイレクト(リンク)型」による決済システムが推進されています。
以下は、JavaScript型の決済の様子です。入力フォームは加盟店(ECサイト)側にありますが、カード情報はECサイトのサーバーを通過せず、JavaScriptにより直接決済代行事業者にカード情報を送信する方式です。

実行計画2019 より引用

JavaScript型の場合、先に説明したType4およびType5でカード情報を盗むことができます。
一方下図はリダイレクト型決済の概念図です。カード情報を入力する際には、決済代行事業者の画面に遷移するため、ECサイト側では一切生のカード情報を扱わず、安全性が高い方法と考えられていました。

実行計画2019 より引用

しかし、前記Type5の攻撃ではリダイレクト型決済でもカード情報を盗むことができます。今年のカード情報窃取事件ではType4とType5が使い分けられていますが、これは決済方式に合わせて適した方法が採用されたものと考えられます。

カード情報非保持化で満足せず基本的な対策を

以上で説明してきたように、経産省およびクレジット取引セキュリティ協議会の進める「カード情報非保持化」では十分にカード情報を保護できる状況ではありません。基本に立ち返って、以下の対策を推奨します(2018年末の記事の再掲)。
  • ウェブアプリケーションやソフトウェアライブラリ、プラットフォームの脆弱性対策(パッチ適用など)
  • 管理者等のパスワードを強固にする(可能ならばインターネットからは管理者ログインできないよう設定する)
加えて、以下の対策を推奨します。
  • Web Application Firewall(WAF)の導入
  • ファイルパーミッションとファイルオーナーの適切な設定
  • 改ざん検知システムの導入

[PR]
徳丸が代表を務めるEGセキュアソリューションズ株式会社では、ECサイトを堅牢にするための各種セキュリティサービスを提供しています。


2019年5月7日火曜日

[書評]噂の学園一美少女な先輩がモブの俺に惚れてるって、これなんのバグですか?

瓜生聖(うりゅうせい)の近著「噂の学園一美少女な先輩がモブの俺に惚れてるって、これなんのバグですか? 」を読んだので紹介したい。本書は、JNSA(特定非営利活動法人 日本ネットワークセキュリティ協会)が主催したサイバーセキュリティ小説コンテストにて大賞を受賞した作品「目つきの悪い女が眼鏡をかけたら美少女だった件」を大幅に加筆したのち、角川スニーカー文庫から出版された。

重要事項説明

  • 著者と評者は知人関係にあり公私共に交流がある
  • 評者が読んだ書籍はご恵贈いただいたものである
  • この記事のリンクにはアフィリエイトが含まれる

はじめに

著者の瓜生聖は、twitterのプロフィールには「ITmediaで記事を書いてる兼業ライター」とあるが、本業はITエンジニアである。つまり、現役のITエンジニア兼テクニカルライターである人物が、サイバーセキュリティ小説を書いたのが本書ということになる。瓜生聖はライターとしても一流なので技術面と文章力は申し分ないはずだが、小説となるとどうだろうか。評者の興味は、まずそこにあった。

あらすじ

本書は以下の三部構成となっている。

第一話 試験問題漏洩事件

本書の準ヒロイン格で、主人公鷹野祐(たかのたすく)の幼なじみの西村理乃(にしむらりの)が、数学の試験問題漏洩事件の犯人だという噂が流れ、事件が提示される。祐は、美少女衣川マト(ころもがわまと)の力を借りて事件の真相を解明し、理乃を救う。祐は小学生時代に探偵を志していたが、とある事件がトラウマになり、探偵の夢をあきらめていたが、この事件をきっかけに、自分が進むべき道がおぼろげながら見えてくる。

第二話 夏の嵐

祐は区民プールで子供たちと遊ぶマトを見かけ、そこからの流れでマトが幼少期を過ごした施設を訪問、マトの過去を知ることになる。その後マトの自宅を訪問しドキドキの一時を過ごす。
台風の日、買い物を言いつけられた祐は自宅に帰ることができなくなり、愛帝学園を訪れる。そこで第二の事件を解決する。過程で、サイバーセキュリティに詳しい青年鴻上(こうがみ)が登場する。

第三話 最強の武器

マトが高校に来なくなってしまった。鴻上がマトをスカウトして米国に呼んだらしい。マトが遠くに行ってしまう。しかも、米国でのマトの仕事は…
マトを救うべく、祐は第三の事件を三人の少女の力を借りて解決する。そして、はたして祐とマトは結ばれるのか。

重層的な構造

本書はラブコメラノベという分類になっているが、その実複雑な構成になっている。評者の見るところ、以下の要素を併せ持っている。
  • ラブコメ
  • サイバーセキュリティ小説
  • 成長譚(さまざまな事件を少女たちの力を借りて解決する過程で主人公は成長する)
  • 自分探し(無目的に生きてきた主人公が自分のやりたいことを見出す)
  • 探偵小説(第一話は探偵小説でもある)
  • 家庭内暴力や児童ポルノ問題
まだ他にもあるかもしれない。
これだけの要素を文庫本300ページに突っ込むとごちゃごちゃしてしまいそうだが、どうか。率直なところ、児童ポルノ問題を扱い探偵小説仕立てにもなっている第一話は、話が少し重くなり、また、筋書きを追うのに苦労する箇所がある。著者の初めての小説ということで張り切ってネタをぶち込みすぎたのかもしれない。その反省からか、第二話と第三話では、材料を少し減らして、著者はすっきりとまとめてみせる。全体としては、重層的な構造にも関わらずラノベらしくすらすら楽しく読むことができる。

エピソード紹介

次に、本書の冒頭からいくつかのエピソードを引用で紹介しよう。

物語は、本書の主人公である愛帝学園の1年生の鷹野祐(たかのたすく)が、ヒロイン衣川マト(ころまがわまと)と邂逅するところから始まる。
 教室に入ろうとした瞬間、突然引き戸が勢いよく開いた。
 突然のことに足が絡まり、思わず尻餅をつく。
「いてて……す、すいません」
 見上げた先にいたのは妖精だつた。
 陽の光をまとい、細く艷やかな銀髪がふわりと舞う。シルバーアッシュの柳眉の下はぱっちりとした大きな翠眼(すいがん)で、真っ白な肌は白磁のようにつるつるだ。
 学年の違う俺でも知っている銀髪の美少女ーー衣川先輩だった。
 遠くから見るのとは全然違う美の暴力をまともに受け、俺はただただ、呆然と見つめるだけだった。目を離すこともできない。もしかしたら呼吸も忘れていたかもしれない。
この後、いったんは「氷のように冷たい目で俺を見下ろしていた」マトは、あるきっかけの後主人公を抱きしめるに至る。その後マトは顔を赤らめて走り去るが、主人公は小さなUSBメモリが落ちていることに気づく。

その後、準ヒロイン格でアイドルを目指している西村理乃(にしむらりの)や、主人公が入り浸っているコンピュータ部(主人公は部員ではない)の部員である嵯峨野亜弥(さがのあや)が次々に登場し、わずか10ページほどの間で主要人物が出揃うことになる。スピーディな展開で手際が良い。

主人公は亜弥にUSBメモリの調査を依頼する。亜弥はアーミーナイフを取り出し、慣れた手つきでガワを開くと、USBメモリのチップがPhison2307であり、ファームウェア改造ツールPsychsonにより改造が可能であると指摘する。
「ちょ、ちょっと待ってくれ。つまりその、ファームウェア? ってのを書き換えるとどうなるんだ?」
「デバイスクラスを偽装できるー」
「俺にもわかるように言ってくれ」
「USBデバイスの挙動をエミュレートできるー」
「俺にもわかるように言ってくれ」
 亜弥は話し足りなそうにしながらも、言葉を選ぶように言った。
「PCを乗っ取れるー」
「まじか」
BadUSBが早くも登場である。このやり取りでもわかるように、主人公はコンピュータには詳しくない。本書は主人公の一人称視点で書かれているので、難しい用語が交わる技術的な説明について、主人公に「わからない、もっと易しく説明してくれ」と言わせることによって、わかりやすく解説したり、詳細を省略して要点のみを説明できることになる。これは、著者の工夫だろう。

この後、なぜか主人公と連れ歩いているマトと、アイドルを目指す理乃が、主人公を巡って張り合う場面がある。そう、なんせラブコメなので主人公はモテモテなのだ。理乃は言う。
「好みは人それぞれだと思いますけどね、衣川先輩。幼なじみでずっと昔から知っていて、お互いに祐、理乃と呼び合う関係のあたしから言わせてもらえれば、今の祐はつまんないやつですよ。普通の人に分かる良さなんて、皆無ですからね」
幼なじみの理乃は、祐は昔と違ってつまらないやつになってしまったと言う。祐は、小学生の頃まではシャーロック・ホームズにあこがれ、将来を探偵になることを目指していたが、ある事件に関わったことがきっかけとなり、探偵を志すことをやめ、できるだけ目立たないように過ごしている。

あらすじで紹介したように、この物語は、愛帝学園に起こるさまざまな事件を主人公が周囲の力を解決することにより成長する、いわばロールプレイングゲーム(成長譚)の形態をとっている。主人公は、過去のトラウマから探偵になる夢を放棄してしまったが、友人のトラブルを解決すべく再び探偵として行動する。その過程で、マトからOSINT(オシント)という方法論を教えてもらい、これが自分の進むべき道だと気づく。

問題を抱えているのは主人公だけではない。マトと理乃は、家族に関するトラブルを抱えていたが、それぞれの方法で過去のトラブルを乗り越えようとしている。それが物語に厚みを加えている。

次に、本書の二大要素であるサイバーセキュリティ小説として、およびラブコメラノベとしての側面を紹介する。

サイバーセキュリティ小説として

本書の「事件」に登場するセキリティ要素を紹介しよう。

第一話: BadUSB、MaaS(Malware-as-a-Service)
第二話: ウェブサイト侵入(クレジットカード情報非保持サイト?)
第三話: 暗号通貨

上記のように、イマドキのセキュリティ要素がふんだんに盛り込まれている。しかも、現役のITエンジニアが書いただけあって、セキュリティ部分のクォリティは非常に高い。先に引用したBadUSBもそうだが、ここでは、評者が思わずニヤリとした箇所を引用しよう。以下は、第二話中に出てくる、侵入されたウェブサイトを巡る会話である。
「なるほど…じゃあコレはニセモノってことなんですか?」
 僕は入力途中になっていた通販サイトのページを示す。アドレスバーには緑色で企業名まで表示されている。これがニセモノならどうやって見分ければいいんだろうか。
「ああ、フィッシングという言い方は正確じゃないか。改ざん、と言った方が正しいのかな。通常だと通信が保護されていなかったり、URLが微妙に違ったりすることが多いけど、これは本物のサーバーに何かあったときの予備サーバだから、それ自体は本物よ。ただ、ファイルが書き換えられているだけ」
これはクレジットカード情報窃取の最新の手口である。評者が以前ブログ記事「クレジットカード情報盗み出しの手口をまとめた」に書いたタイプ4かタイプ5に相当する。おそらく「フィッシング」という言葉があることから、タイプ5、すなわち最新の手口であろう。
このように、著者は細かいクラッキングの手口にまで目配りして、最新の手法が紹介されている。まるで、評者がふだん「これをフィッシングと言うな」と言っているのを意識しているかのような会話だw
細かいようだが、セキュリティはディテールが重要であるし、あまりに荒唐無稽な手口だと(荒唐無稽さを突っ込んで楽しむなら別だが)読者は白けてしまう。その点、本書は、セキュリティに精通した読者でも、存分に楽しむことができる。
また、本書のヒロイン衣川マトは、実在の高名なバグハンターがモデルになっている。評者は予めそれを知っていたが、それを知らない読者でも、途中で実在のモデルを暗示する重要なエピソードが出てくるので、セキュリティに関心のある読者なら「ははーん」と分かるだろう。ここは引用したいところではあるが、ネタバレになるので控えておく。

ラブコメとして

ラブコメラノベなのだから、主人公が「冴えないやつ」であるにも関わらずがモテモテなのは、いくら非現実的でも大目に見てあげるのが大人のたしなみというものだ…そんなふうに考えていた時期が私にもありました。
実際冒頭のくだりでは、「おいおい、それはないだろう」と思いながら読んでいたのであるが、読み進めていくうちに、主人公のモテモテぶりが不自然ではなくなってくる。当初は、「主人公がモテモテなのは在原業平や光源氏以来の我が国の伝統だからな」と思っていたが、そうではなかった。鷹野祐は冴えないように見えて実は魅力的な少年なのだ。そのことを、周囲も、当人も、そして読者も気づいていないが、三人の少女は気づいていた。それは、先に引用した「普通の人に分かる良さなんて、皆無ですからね」という理乃の言葉からも伺える。読者は、物語の進展とともに主人公の魅力がわかってくるわけで、それで「モテモテぶりが自然に思えてくる」のだろう。
評者は、主人公の艶福ぶりをうらやんだり、時には「おいおい、昔から『据え膳食わぬは男の恥』と言ってな…なぜ据え膳を食わぬ」と主人公をけしかたり、さらには、「うーん、この調子でいくと祐はマトとくっつくのではなく、理乃とくっついてしまう、なんてどんでん返しもなくないか?」などと要らぬ心配をしたりした。つまり、評者はラブコメとしての本書も存分に堪能した。

おわりに

瓜生聖のサイバーセキュリティ小説「噂の学園一美少女な先輩がモブの俺に惚れてるって、これなんのバグですか? 」を紹介した。本書は、ラブコメ仕立てのサイバーセキュリティ小説であるのみならず、重層的な構造を持つ意欲的な内容であり、それでいて、ラノベとしてすらすらと読める一流のエンタテインメントである。
著者は「あとがき」の末尾で「本書を読んだラノベ好きの方が『サイバーセキュリティって面白そう』と思っていだたければ、サイバーセキュリティ関係者が『ラノベもなかなか面白いな』と思っていただければ著者冥利につきます」と記している。本書は評者が初めて読んだラノベだが、本当に面白かった。可能ならば、本書の続編で、祐とマトが恋人らしくいちゃついているシーンも読んでみたい。


2019年4月29日月曜日

鈴木常彦先生の「共用レンタルサーバにおけるメールの窃盗」の話を聴講した

4月23日(火)に開催された 「#ssmjp 2019/04 ~DNSの話を聞く会~」に「Outputなら任せてください枠」で参加しましたので、講演内容からとくにやばい(?)内容と思われる@tss_ontap(鈴木常彦=浸透言うな先生)の「黒塗りの DNS (萎縮編)」から、「共用レンタルサーバにおけるメールの窃盗」について紹介します。スライドは公開されています

サマリ

レンタルサーバーからメールを送信する場合、悪意の第三者に、特定のドメインに対するメールを横取りされるリスクがある

攻撃手法


  • 攻撃者は、レンタルサーバーを契約(お試しなどでも可能)して、攻撃対象のドメイン名(ここではchukyo-u.ac.jp…中京大学のドメイン名を用いる)を登録する
  • その際に、当該ドメイン名の権利を有している必要はない(権利があれば正当にメールを受信できるので攻撃の必要がない)
  • これだけ

なぜメールが横取りされるか?

一般にメール送信する場合、サーバー内に送信先ドメインがある場合、そちらを優先して配送する。レンタルサーバー内に攻撃対象のドメイン名(ここではchukyo-u.ac.jp)がメール設定されていると、メール配送の際にDNSを参照することなく、無条件に(ローカル内で)当該のメールボックスにメールを配送してしまう。このchukyo-u.ac.jpのメールボックスは、実際には正規のドメイン名登録者ではなく、悪意の第三者が登録したものなので、メールは悪意の第三者が横取りできることになる。

FAQ

Q1: レンタルサーバー契約時にドメイン名の権利は確認されないのか?
A1: 多くの場合権利確認はないそうですし、まぁ難しそうですね

Q2: レンサバ側でDNS権威サーバーやwhoisとか参照しないのか?
A2: 前述の通り、ローカル配送の際にはDNSやwhoisは参照しません

Q3: ドメイン名の権利者ができる対策はあるか?
A3: すべてのレンタルサーバーに契約すれば防げますが現実的ではありせん

Q4: メール送信者(レンタルサーバー利用者)ができる対策はあるか?
A4: メール以外の方法で「メール送ったよ、届いていないときは連絡して!」とメッセージするとか…というのは冗談で、メール送信者側にとれる対策はなさそうです

Q5: DNS関係ないじゃん
A5: はい。DNSとは無関係の問題ですが、近隣のテーマだとは思います

フォロワー

ブログ アーカイブ