Hatena::ブログ(Diary)

葉っぱ日記 このページをアンテナに追加

2006-02-08

[] 第1回: Unicode から Shift_JIS への変換(その1) 15:49  第1回: Unicode から Shift_JIS への変換(その1)を含むブックマーク

Windows 上で Unicode を扱う場合に発生するセキュリティ上の問題点などについて不定期に書いていくことにします。以前の内容と重なる部分も多いですし、時間的にもどこまで書けるかわかりませんけれど…。

さて第1回目は、 Windows 上で Unicode を扱う際のもっとも基本とも言える WideCharToMultiByte を使用した Unicode から Shift_JIS (コードページ932)への変換についてです。

WideCharToMultiByte を使用する際に発生しやすい問題点は以下の2点です。

  • バッファサイズの指定ミスによるバッファオーバーフロー
  • Unicode から Shift_JIS への変換における多対一のマッピング

バッファサイズの指定ミスによるバッファオーバーフロー

変換前の Unicode の文字列は「文字数」で指定するのに対し(cchWideChar)、変換結果を受け取るバッファのサイズ(cbMultiByte)は「バイト単位」で指定しなければいけません。cchWideChar、cbMultiByte のどちらも終端のヌル文字を含めたサイズを指定します。

cbMultiByte にゼロを指定した場合には、関数の戻り値としてバッファに必要な大きさが返されますので、それを利用して動的にメモリを確保するのもよいでしょう。

Unicode から Shift_JIS への変換における多対一のマッピング

WideCharToMultiByte の呼び出しにて、フラグ(dwFlags) に WC_NO_BEST_FIT_CHARS を指定していない場合、Unicode から Shift_JIS に変換する場合に複数の Unicode 文字が同じ文字に変換されることがあります。WC_NO_BEST_FIT_CHARS フラグは Windows 2000 および Windows 98 以降で有効となりますが、残念なことに WideCharToMultiByte に関する世の中の例題の多くではあまり指定されていないようです。

このフラグを指定した場合には、Unicode 文字に直接対応する Shift_JIS の文字がない場合には、既定の文字(デフォルトでは '?' )に変換されます。このフラグを指定している場合、Unicode と Shift_JIS は一対一に対応しますので、Shift_JIS をもう一度 Unicode に直した場合には(対応する文字がなく '?' に変換された場合を除き)同じ文字に戻すことができます。

フラグが指定されていない場合には、「よく似た文字」に変換されてしまい、そのような Shift_JIS の文字を再び Unicode に変換した場合には元の文字とは異なった文字に変換されてしまいます。例えば、U+00C0(À)は、Shift_JIS に変換すると 0x41(A) に置き換わります。もちろん、U+0041(A)も Shift_JIS への変換で 0x41(A) になります。逆に、Shift_JIS の 0x41 を Unicode に変換した場合には、U+0041(A) になります。このように、WC_NO_BEST_FIT_CHARS を設定しない変換においては、Unicode と Shift_JIS の間では多対一の変換が行われてしまいます。

具体的に、Shift_JIS に変換した場合に「似たような文字」として変換される文字は以下の通りです。次回はこれらの「似た文字の変換」によって引き起こされる問題について説明したいと思います。

UnicodeShift_JIS
¡U+00A1!0x21
¢U+00A2¢0x81 0x91
£U+00A3£0x81 0x92
¥U+00A5\0x5C
¦U+00A6|0x7C
©U+00A9c0x63
ªU+00AAa0x61
«U+00AB0x81 0xE1
¬U+00AC¬0x81 0xCA
­U+00AD-0x2D
®U+00AER0x52
¯U+00AF0x81 0x50
²U+00B220x32
³U+00B330x33
µU+00B5μ0x83 0xCA
·U+00B70x81 0x45
¸U+00B8 0x81
¹U+00B910x31
ºU+00BAo0x6F
»U+00BB0x81 0xE2
ÀU+00C0A0x41
ÁU+00C1A0x41
ÂU+00C2A0x41
ÃU+00C3A0x41
ÄU+00C4A0x41
ÅU+00C5A0x41
ÆU+00C6A0x41
ÇU+00C7C0x43
ÈU+00C8E0x45
ÉU+00C9E0x45
ÊU+00CAE0x45
ËU+00CBE0x45
ÌU+00CCI0x49
ÍU+00CDI0x49
ÎU+00CEI0x49
ÏU+00CFI0x49
ÐU+00D0D0x44
ÑU+00D1N0x4E
ÒU+00D2O0x4F
ÓU+00D3O0x4F
ÔU+00D4O0x4F
ÕU+00D5O0x4F
ÖU+00D6O0x4F
ØU+00D8O0x4F
ÙU+00D9U0x55
ÚU+00DAU0x55
ÛU+00DBU0x55
ÜU+00DCU0x55
ÝU+00DDY0x59
ÞU+00DET0x54
ßU+00DFs0x73
àU+00E0a0x61
áU+00E1a0x61
âU+00E2a0x61
ãU+00E3a0x61
äU+00E4a0x61
åU+00E5a0x61
æU+00E6a0x61
çU+00E7c0x63
èU+00E8e0x65
éU+00E9e0x65
êU+00EAe0x65
ëU+00EBe0x65
ìU+00ECi0x69
íU+00EDi0x69
îU+00EEi0x69
ïU+00EFi0x69
ðU+00F0d0x64
ñU+00F1n0x6E
òU+00F2o0x6F
óU+00F3o0x6F
ôU+00F4o0x6F
õU+00F5o0x6F
öU+00F6o0x6F
øU+00F8o0x6F
ùU+00F9u0x75
úU+00FAu0x75
ûU+00FBu0x75
üU+00FCu0x75
ýU+00FDy0x79
þU+00FEt0x74
ÿU+00FFy0x79
U+30940x83 0x94

[] XSS の脅威 14:07  XSS の脅威を含むブックマーク

今さらな感もあるけど、備忘録ついでにメモ。

CSRF対策をちゃんとしていて、なおかつセッションCookieが取れない状況でも、スクリプトが動けばブログの更新とか勝手にできちゃうこともあるわけで。

[] 〜 JVN オンラインアンケートご協力のお願い 〜 − JVN 10:44  〜 JVN オンラインアンケートご協力のお願い 〜 − JVNを含むブックマーク

より分かり易く充実した情報提供のため、JVN をご利用される皆様のご意見・ご要望を伺いたく、アンケートを実施いたします。

だそうです。

[][] Microsoft Security Advisory (914457) Possible Vulnerability in Windows Service ACLs 09:34  Microsoft Security Advisory (914457) Possible Vulnerability in Windows Service ACLsを含むブックマーク

サードパーティのアプリケーションサービスにて Windows XP SP1 および Windows Server 2003 にて特権の上昇が可能とのこと。

RIPRIP 2006/02/08 16:35 文字コード話キターー(゜∀゜)ーー!

hasegawayosukehasegawayosuke 2006/02/08 16:42 (* ̄ー ̄)y−~~

rlyehrlyeh 2006/02/08 16:47 ひそかに100回予定ですよねと言ってみるテスト(w<どこまで書けるかわかりませんけれど…。

hasegawayosukehasegawayosuke 2006/02/08 16:48 (゜д゜;)

Ghetto(ゲットー)Ghetto(ゲットー) 2006/02/08 17:05 えっ?100テラ回予定ですよね?
とか言ってみたり・・・

hasegawayosukehasegawayosuke 2006/02/08 17:06 (;`Д´)

comikencomiken 2006/02/08 17:20 さすがに 100テラ回は辛そうですし、ここは間を取って…(100テラ+100)/2回ってことで (笑

hasegawayosukehasegawayosuke 2006/02/08 17:25 ヽ(`д´)ノ

こじまこじま 2006/02/09 11:30 ひゃくてらですか……
http://shop.kodansha.jp/bc/books/junrei/

ripjyrripjyr 2006/02/09 11:49 ひゃくてら、わらたwwwww

hasegawayosukehasegawayosuke 2006/02/09 11:51 ∩(´∀`)∩

通りすがり通りすがり 2006/02/10 15:08 > Unicode 文字に直接対応する Shift_JIS の文字がない場合には、既定の文字(デフォルトでは ’?’ )に変換されます。その場合、Shift_JIS をもう一度 Unicode に直した場合には同じ文字に戻すことができます。
? に変換された文字は、逆変換では元に戻らないと思うのですが。

hasegawayosukehasegawayosuke 2006/02/10 15:28 修正しました m(_ _)m

通りすがり2通りすがり2 2006/03/28 10:17 u+00b8 の所がtypoですね。81ではなくて 81 43に変換されます。
(81に変換されたら ¥ の無効化に使える別のセキュリティホールになりますね)

hasegawayosukehasegawayosuke 2006/03/28 10:21 おぉ。ありがとうございます<通りすがり2さん。
最初、Unicodeから2バイト文字に変換されるのを考慮してないプログラムで機械的に変換かけて後から手作業で修正したのでその漏れですね orz