本当は怖い文字コードの話

第7回 Unicodeからの多対一の変換[前編]

この記事を読むのに必要な時間:およそ 8 分

Windows上でのUnicodeからISO-8859-1への変換

ISO-8859-1(Windows-1252)は,英語環境などで使われているエンコーディングです。これも実際にWC_NO_BEST_FIT_CHARSを指定せずにWideCharToMultiByte関数を使ってUnicodeからISO-8859-1へ変換した結果を表2に示しておきます。

表2 WC_NO_BEST_FIT_CHARSを指定しない場合のWideCharToMultiByte関数によるUnicode→ISO-8859-1への変換

UnicodeISO-8859-1
ĀU+0100A 0x41
āU+0101a 0x61
ĂU+0102A 0x41
ăU+0103a 0x61
ĄU+0104A 0x41
ąU+0105a 0x61
ĆU+0106C 0x43
ćU+0107c 0x63
ĈU+0108C 0x43
ĉU+0109c 0x63
ĊU+010aC 0x43
ċU+010bc 0x63
ČU+010cC 0x43
čU+010dc 0x63
ĎU+010eD 0x44
ďU+010fd 0x64
ĐU+0110D 0xD0
đU+0111d 0x64
ĒU+0112E 0x45
ēU+0113e 0x65
ĔU+0114E 0x45
ĕU+0115e 0x65
ĖU+0116E 0x45
ėU+0117e 0x65
ĘU+0118E 0x45
ęU+0119e 0x65
ĚU+011aE 0x45
ěU+011be 0x65
ĜU+011cG 0x47
ĝU+011dg 0x67
ĞU+011eG 0x47
ğU+011fg 0x67
ĠU+0120G 0x47
ġU+0121g 0x67
ĢU+0122G 0x47
ģU+0123g 0x67
ĤU+0124H 0x48
ĥU+0125h 0x68
ĦU+0126H 0x48
ħU+0127h 0x68
ĨU+0128I 0x49
ĩU+0129i 0x69
ĪU+012aI 0x49
īU+012bi 0x69
ĬU+012cI 0x49
ĭU+012di 0x69
ĮU+012eI 0x49
įU+012fi 0x69
İU+0130I 0x49
ıU+0131i 0x69
ĴU+0134J 0x4A
ĵU+0135j 0x6A
ĶU+0136K 0x4B
ķU+0137k 0x6B
ĹU+0139L 0x4C
ĺU+013al 0x6C
ĻU+013bL 0x4C
ļU+013cl 0x6C
ĽU+013dL 0x4C
ľU+013el 0x6C
ŁU+0141L 0x4C
łU+0142l 0x6C
ŃU+0143N 0x4E
ńU+0144n 0x6E
ŅU+0145N 0x4E
ņU+0146n 0x6E
ŇU+0147N 0x4E
ňU+0148n 0x6E
ŌU+014cO 0x4F
ōU+014do 0x6F
ŎU+014eO 0x4F
ŏU+014fo 0x6F
ŐU+0150O 0x4F
őU+0151o 0x6F
ŔU+0154R 0x52
ŕU+0155r 0x72
ŖU+0156R 0x52
ŗU+0157r 0x72
ŘU+0158R 0x52
řU+0159r 0x72
ŚU+015aS 0x53
śU+015bs 0x73
ŜU+015cS 0x53
ŝU+015ds 0x73
ŞU+015eS 0x53
şU+015fs 0x73
ŢU+0162T 0x54
ţU+0163t 0x74
ŤU+0164T 0x54
ťU+0165t 0x74
ŦU+0166T 0x54
ŧU+0167t 0x74
ŨU+0168U 0x55
ũU+0169u 0x75
ŪU+016aU 0x55
ūU+016bu 0x75
ŬU+016cU 0x55
ŭU+016du 0x75
ŮU+016eU 0x55
ůU+016fu 0x75
ŰU+0170U 0x55
űU+0171u 0x75
ŲU+0172U 0x55
ųU+0173u 0x75
ŴU+0174W 0x57
ŵU+0175w 0x77
ŶU+0176Y 0x59
ŷU+0177y 0x79
ŹU+0179Z 0x5A
źU+017az 0x7A
ŻU+017bZ 0x5A
żU+017cz 0x7A
ƀU+0180b 0x62
ƉU+0189D 0xD0
ƑU+0191ニ・ 0x83
ƗU+0197I 0x49
ƚU+019al 0x6C
ƟU+019fO 0x4F
ƠU+01a0O 0x4F
ơU+01a1o 0x6F
ƫU+01abt 0x74
ƮU+01aeT 0x54
ƯU+01afU 0x55
ưU+01b0u 0x75
ƶU+01b6z 0x7A
ǀU+01c0| 0x7C
ǃU+01c3! 0x21
ǍU+01cdA 0x41
ǎU+01cea 0x61
ǏU+01cfI 0x49
ǐU+01d0i 0x69
ǑU+01d1O 0x4F
ǒU+01d2o 0x6F
ǓU+01d3U 0x55
ǔU+01d4u 0x75
ǕU+01d5U 0x55
ǖU+01d6u 0x75
ǗU+01d7U 0x55
ǘU+01d8u 0x75
ǙU+01d9U 0x55
ǚU+01dau 0x75
ǛU+01dbU 0x55
ǜU+01dcu 0x75
ǞU+01deA 0x41
ǟU+01dfa 0x61
ǤU+01e4G 0x47
ǥU+01e5g 0x67
ǦU+01e6G 0x47
ǧU+01e7g 0x67
ǨU+01e8K 0x4B
ǩU+01e9k 0x6B
ǪU+01eaO 0x4F
ǫU+01ebo 0x6F
ǬU+01ecO 0x4F
ǭU+01edo 0x6F
ǰU+01f0j 0x6A
ɡU+0261g 0x67
ʹU+02b9' 0x27
ʺU+02ba" 0x22
ʼU+02bc' 0x27
˄U+02c4^ 0x5E
ˈU+02c8' 0x27
ˉU+02c9 0xAF
ˊU+02ca´ 0xB4
ˋU+02cb` 0x60
ˍU+02cd_ 0x5F
˚U+02da° 0xB0
̀U+0300` 0x60
́U+0301´ 0xB4
̂U+0302^ 0x5E
̃U+0303~ 0x7E
̄U+0304 0xAF
̅U+0305 0xAF
̈U+0308¨ 0xA8
̊U+030a° 0xB0
̎U+030e" 0x22
̧U+0327 0xB8
̱U+0331_ 0x5F
̲U+0332_ 0x5F
;U+037e; 0x3B
ΓU+0393G 0x47
ΘU+0398T 0x54
ΣU+03a3S 0x53
ΦU+03a6F 0x46
ΩU+03a9O 0x4F
αU+03b1a 0x61
βU+03b2s 0xDF
δU+03b4d 0x64
εU+03b5e 0x65
μU+03bcμ 0xB5
πU+03c0p 0x70
σU+03c3s 0x73
τU+03c4t 0x74
φU+03c6f 0x66
һU+04bbh 0x68
։U+0589: 0x3A
٪U+066a% 0x25
 U+2000  0x20
U+2001  0x20
U+2002  0x20
U+2003  0x20
U+2004  0x20
U+2005  0x20
U+2006  0x20
U+2010- 0x2D
U+2011- 0x2D
U+2017= 0x3D
U+2024 0xB7
U+2032' 0x27
U+2035` 0x60
U+2044/ 0x2F
U+2070° 0xB0
U+20744 0x34
U+20755 0x35
U+20766 0x36
U+20777 0x37
U+20788 0x38
U+207fn 0x6E
U+20800 0x30
U+20811 0x31
U+20822 0x32
U+20833 0x33
U+20844 0x34
U+20855 0x35
U+20866 0x36
U+20877 0x37
U+20888 0x38
U+20899 0x39
U+20a1 0xA2
U+20a4 0xA3
U+20a7P 0x50
U+2102C 0x43
U+2107E 0x45
U+210ag 0x67
U+210bH 0x48
U+210cH 0x48
U+210dH 0x48
U+210eh 0x68
U+2110I 0x49
U+2111I 0x49
U+2112L 0x4C
U+2113l 0x6C
U+2115N 0x4E
U+2118P 0x50
U+2119P 0x50
U+211aQ 0x51
U+211bR 0x52
U+211cR 0x52
U+211dR 0x52
U+2124Z 0x5A
U+2128Z 0x5A
U+212aK 0x4B
U+212bA 0xC5
U+212cB 0x42
U+212dC 0x43
U+212ee 0x65
U+212fe 0x65
U+2130E 0x45
U+2131F 0x46
U+2133M 0x4D
U+2134o 0x6F
U+2205O 0xD8
U+2212- 0x2D
U+2213± 0xB1
U+2215/ 0x2F
U+2216\ 0x5C
U+2217* 0x2A
U+2218° 0xB0
U+2219 0xB7
U+221av 0x76
U+221e8 0x38
U+2223| 0x7C
U+2229n 0x6E
U+2236: 0x3A
U+223c~ 0x7E
U+2248ヒ・ 0x98
U+2261= 0x3D
U+2264= 0x3D
U+2265= 0x3D
U+226a 0xAB
U+226b 0xBB
U+22c5 0xB7
U+2302| 0xA6
U+2303^ 0x5E
U+2310 0xAC
U+2320( 0x28
U+2321) 0x29
U+2329< 0x3C
U+232a> 0x3E
U+2500- 0x2D
U+2502| 0xA6
U+250c+ 0x2B
U+2510+ 0x2B
U+2514+ 0x2B
U+2518+ 0x2B
U+251c+ 0x2B
U+2524| 0xA6
U+252c- 0x2D
U+2534- 0x2D
U+253c+ 0x2B
U+2550- 0x2D
U+2551| 0xA6
U+2552+ 0x2B
U+2553+ 0x2B
U+2554+ 0x2B
U+2555+ 0x2B
U+2556+ 0x2B
U+2557+ 0x2B
U+2558+ 0x2B
U+2559+ 0x2B
U+255a+ 0x2B
U+255b+ 0x2B
U+255c+ 0x2B
U+255d+ 0x2B
U+255e| 0xA6
U+255f| 0xA6
U+2560| 0xA6
U+2561| 0xA6
U+2562| 0xA6
U+2563| 0xA6
U+2564- 0x2D
U+2565- 0x2D
U+2566- 0x2D
U+2567- 0x2D
U+2568- 0x2D
U+2569- 0x2D
U+256a+ 0x2B
U+256b+ 0x2B
U+256c+ 0x2B
U+2580 0xAF
U+2584_ 0x5F
U+2588| 0xA6
U+258c| 0xA6
U+2590| 0xA6
U+2591| 0xA6
U+2592| 0xA6
U+2593| 0xA6
U+25a0| 0xA6
U+263cツ、 0xA4
U+2758| 0x7C
 U+3000  0x20
U+3008< 0x3C
U+3009> 0x3E
U+300a 0xAB
U+300b 0xBB
U+301a[ 0x5B
U+301b] 0x5D
U+30fb 0xB7
U+ff01! 0x21
U+ff02" 0x22
U+ff03# 0x23
U+ff04$ 0x24
U+ff05% 0x25
U+ff06& 0x26
U+ff07' 0x27
U+ff08( 0x28
U+ff09) 0x29
U+ff0a* 0x2A
U+ff0b+ 0x2B
U+ff0c, 0x2C
U+ff0d- 0x2D
U+ff0e. 0x2E
U+ff0f/ 0x2F
U+ff100 0x30
U+ff111 0x31
U+ff122 0x32
U+ff133 0x33
U+ff144 0x34
U+ff155 0x35
U+ff166 0x36
U+ff177 0x37
U+ff188 0x38
U+ff199 0x39
U+ff1a: 0x3A
U+ff1b; 0x3B
U+ff1c< 0x3C
U+ff1d= 0x3D
U+ff1e> 0x3E
U+ff20@ 0x40
U+ff21A 0x41
U+ff22B 0x42
U+ff23C 0x43
U+ff24D 0x44
U+ff25E 0x45
U+ff26F 0x46
U+ff27G 0x47
U+ff28H 0x48
U+ff29I 0x49
U+ff2aJ 0x4A
U+ff2bK 0x4B
U+ff2cL 0x4C
U+ff2dM 0x4D
U+ff2eN 0x4E
U+ff2fO 0x4F
U+ff30P 0x50
U+ff31Q 0x51
U+ff32R 0x52
U+ff33S 0x53
U+ff34T 0x54
U+ff35U 0x55
U+ff36V 0x56
U+ff37W 0x57
U+ff38X 0x58
U+ff39Y 0x59
U+ff3aZ 0x5A
U+ff3b[ 0x5B
U+ff3c\ 0x5C
U+ff3d] 0x5D
U+ff3e^ 0x5E
_U+ff3f_ 0x5F
U+ff40` 0x60
U+ff41a 0x61
U+ff42b 0x62
U+ff43c 0x63
U+ff44d 0x64
U+ff45e 0x65
U+ff46f 0x66
U+ff47g 0x67
U+ff48h 0x68
U+ff49i 0x69
U+ff4aj 0x6A
U+ff4bk 0x6B
U+ff4cl 0x6C
U+ff4dm 0x6D
U+ff4en 0x6E
U+ff4fo 0x6F
U+ff50p 0x70
U+ff51q 0x71
U+ff52r 0x72
U+ff53s 0x73
U+ff54t 0x74
U+ff55u 0x75
U+ff56v 0x76
U+ff57w 0x77
U+ff58x 0x78
U+ff59y 0x79
U+ff5az 0x7A
U+ff5b{ 0x7B
U+ff5c| 0x7C
U+ff5d} 0x7D
U+ff5e~ 0x7E

UnicodeからISO-8859-1への変換の場合には,Shift_JISのときより非常に多くの文字が多対一で変換されていることが見て取れます。

たとえば,全角文字「A」⁠U+FF21)は0x41(A)に,添え字用の数字である「₀」⁠U+2080)「0」⁠0x30)に変換されています。

問題を引き起こす「似た文字への変換」

このような多対一での文字の変換によって引き起こされるセキュリティ上の問題の一例としては,以下のようなものが考えられます。

パストラバーサル

UnicodeからShift_JISへの変換では,U+00A5の円記号「¥」が0x5Cのバックスラッシュ「\」に変換されます(日本語環境では表示する字体として円記号が当てられていますが⁠⁠。

また,UnicodeからISO-8859-1への変換では,U+2216「∖」とU+FF3Cの全角のバックスラッシュ「\」が ともに0x5Cのバックスラッシュ「\」に,U+2044「⁄⁠⁠,U+2215「∕⁠⁠,U+FF0F「/」が0x2Fのスラッシュ「/」に変換されます。

0x5Cや0x2FはWindowsにおけるディレクトリの区切りとして使用する文字ですので,Unicodeにて文字列の検証を行ったあとにShift_JISやISO-8859-1へ変換される場合,変換後の文字列に0x5Cが混入し,パストラバーサルが発生する可能性があります。

クロスサイトスクリプティング

UnicodeからISO-8859-1への変換では,U+2329「〈⁠⁠,U+3008「〈⁠⁠,U+FF1C「<」といった文字が0x3C「<」に,また,U+02BA「ʺ⁠⁠,U+030E「̎⁠⁠,U+FF02「"」が0x22「"」に変換されます。

前述のパストラバーサル同様,Unicode にて文字列の検証を行ったあとにShift_JISやISO-8859-1へ変換される場合,変換後の文字列に0x3Cや0x22といったメタキャラクタが含まれることになりますので,クロスサイトスクリプティングを引き起こす可能性があります。

このように,

  1. Unicodeで文字列の検査を行う
  2. Unicodeから他のエンコーディングに変換
  3. 変換された文字列を使用する

といった順序のときに,本来であれば1.でフィルタリングされるべき文字が含まれてしまい,セキュリティ上の問題点を引き起こすというのが「多対一の変換」による攻撃の一般的なシナリオとなります。

次回は,この多対一の変換が引き起こしたソフトウェアの脆弱性の具体例を挙げながら,対策方法などについても説明したいと思います。

著者プロフィール

はせがわようすけ

ネットエージェント株式会社 研究開発部。
Unicodeなどの文字コードが引き起こすセキュリティ上の問題点について調査・研究を行っている。Internet Explorer,Mozilla Firefox をはじめソフトウェア製品およびWebアプリケーションに関する脆弱性を多数発見。

URLhttp://utf-8.jp/