アカウント名:
パスワード:
$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
ここに echo vulnerable 書き足せるシチュエーションだと関数 () { :;} の中も好き放題出来そうな気がするんだけどそれは気のせいなの?
「(){~}」の部分は関数の定義の部分で、その関数定義を環境変数にセットされるところまでは良くて、環境変数にセットされただけだと、誰かがその環境変数に入っている関数を叩かないと実際の処理は発生しない。
ところが、その直後の「;」の後ろ、関数定義の外側のにある部分を bash が勝手に実行してしまう、というのが今回の脆弱性。
...と理解しているけど合ってるかな?
env echo='() { ls; }' bash -c 'echo hoge'とかできる時点で、環境変数で関数定義を渡せるという機能自体が、今回の問題と大差ない脆弱性のような気がする
env echo='() { ls; }' bash -c 'echo hoge'のような攻撃はスクリプト側(or bash経由で起動されるプロセス)で対処できます.例えば echo という変数を再定義するなり/bin/echo を使うようフルパスを記述するだけです.ですので,これはスクリプト側の脆弱性と捉えるべきだと思います.つまりスクリプト側を修正すべきです.
しかしenv x='() { :;}; echo vulnerable' bash -c "echo this is a test"この攻撃は スクリプト側では対処できません.スクリプト側で対処できないので,これは bashの脆弱性で,bash側で対処すべき問題だと思います.
>のような攻撃はスクリプト側(or bash経由で起動されるプロセス)で対処できます.
export unset='() { ls; }'とされてしまったら、環境変数経由で渡ってくる関数を消そうにもできないわけだが。unset 以外にも回避手段はあるかもしれないが、unset 同様に関数で上書きされてしまったら手も足も出ない。cd のように外部コマンドではなくシェルのビルトインでないと実現できない機能はフルパスで指定することもできないし。なので、これをスクリプトの脆弱性とするのは無理がある。
Bourne sh にはなかった機能であって、bsh では気にする必要のなかったことでもあるし、bash の脆弱性以外の何ものでもない。
cd のように外部コマンドではなくシェルのビルトインでないと実現できない機能はフルパスで指定することもできないし。
えっ
[foo@bar ~]$ which cd/usr/bin/cd
/usr/bin/cd の中身はシェルスクリプトで、 "builtin cd" を実行。
自己レスだけど、 /usr/bin/cd は builtin の cd の代替にはならないのか。
[foo@bar ~]$ pwd/home/foo[foo@bar ~]$ /usr/bin/cd /[foo@bar ~]$ pwd/home/foo[foo@bar ~]$ cd /[foo@bar /]$ pwd/
/usr/bin/cd はサブシェルで実行されるので、呼出元のシェルでは cd されないということで合っているかな?じゃあなんで /usr/bin/cd が用意されているのだろう…?
フルパス記述では回避できないっぽいですね
これでも上書きされてしまうようですenv /bin/echo='() { ls; }' bash -c '/bin/echo hoge'
env echo='() { ls; }' bash -c 'echo hoge'
他の方のコメントでも書かれていますが、これだと「bash -c」に渡している「echo hoge」の部分を攻撃者が挿入できるか、もしくは、事前に bash 経由で echo を実行する事が分かっている場合になります。前者だと、この問題が無くても外部から任意の実行できることになるので、この脆弱性以前の話だし、後者だと狙った動きをするためには、事前に bash が実行する内容を知っている事が必要、という事になると思います。
少なくとも、今回の脆弱性があれば、bash が本来実行しようとしている内容にかかわらず、環境変数さえ設定できれば任意のコマンドが実行できます。「-c 'echo hoge'」の部分すら必要ありません。
ただ、確かに、bash が本来、実行しようとしているコマンドを置き換える事が可能、という点は、条件がそろうと現実的な問題になりうると思います。通常、関数の方が PATH で見つかるコマンドや内部コマンドよりも優先順位が高いですが、環境変数経由で渡ってくる関数も、同様の優先順位で良いのか、という気がします。環境変数経由の関数が通常のコマンドよりも低い優先順位であれば、コマンドの置き換えは避けられるのでは、と思いました。
bash が本来、実行しようとしているコマンドを置き換える事が可能、という点
builtin [nikkeibp.co.jp]とかcommand [nikkeibp.co.jp]とかで対処できそうな気がする。
>builtinとかcommandとかで対処できそうな気がする。
ダメです。export builtin='() { rm -rf /;}'export command='() { rm -rf /;}'とされると、こいつらも置き換えられちゃうので。
その方法で攻撃するためには、攻撃対象が任意の環境変数を渡せるサービスでないとならない。
攻撃対象が HTTP なら渡せる環境変数は HTTP_USER_AGENT 等に限られるし (多分) 、他のサービスでもさすがに任意の環境変数を渡せるようなものは無いのでは。(断言はできないけど。)
user agentみたいなどうでもいい変数をいじるだけでアタックできてしまうのがこの問題の怖さだろう。
個人で借りてるvpsサーバ(centos 5)のログを
grep '()' /var/log/httpd/access_log /var/log/httpd/ssl_access_log (←しょぼすぎるので、もっとましなの誰か作ってください、、、)
とかして、ざっと調べてみたけど、すでにアタックの形跡があった。
ひとつはrefererだか何かが"() { :; }; ping -c 11 209.126.230.74"となってるアクセスで、pingが帰れば脆弱性ありと判定できる仕組みであるらしい。ただこれは、http://blog.erratasec.com/2014/09/bash-shellshock-scan-of-internet.html でバグの影響を調査しているらしく、悪質なものではないようだ。だた、もうひとつ別のアクセス(同じくpingの実行を狙ったもの)があって、それは本当にアタックしてきたものらしい。
うちの場合は404やら403のエラーになっていたので問題なかったけど、ちょっとぞっとした。速攻でbashをアップデートしたことは言うまでもない。
perlで作ったcgiなら、
$a=`echo hello`;
みたいなのがあったら、sh呼び出されてアウトになるわけで、それくらいのことなら私(=趣味でプログラムをいじる程度の人)は余裕でやっちゃってます。怖いよ。このバグ。
ここでの話って、UserAgent等による危険性は重大だけど、そもそも関数定義を渡せること自体も問題にならないかという話では?
"echo"等を再定義されちゃったりするとマズイよね?でも、そういう変数はhttp経由だといじれないか...という話になっていると理解しているんだけど。
curl とか rsync とかで 他サーバにデータ渡せないの?
"echo vulnerable" は bash が起動された時点で実行されるけど、関数 () { :; } の中は起動した bash の中でさらに x を実行しないと実行されない。
渡された環境変数名を関数として実行しているとか、任意の環境変数を渡せる(=本来実行すべきコマンドが環境変数で上書きされる)とかいうことが無ければ関数の中が実行されることは無いと思う。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
192.168.0.1は、私が使っている IPアドレスですので勝手に使わないでください --- ある通りすがり
イマイチ理解できないんだけど (スコア:0)
$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
ここに echo vulnerable 書き足せるシチュエーションだと
関数 () { :;} の中も好き放題出来そうな気がするんだけどそれは気のせいなの?
Re:イマイチ理解できないんだけど (スコア:3, 興味深い)
「(){~}」の部分は関数の定義の部分で、その関数定義を環境変数にセットされるところまでは良くて、環境変数にセットされただけだと、誰かがその環境変数に入っている関数を叩かないと実際の処理は発生しない。
ところが、その直後の「;」の後ろ、関数定義の外側のにある部分を bash が勝手に実行してしまう、というのが今回の脆弱性。
...と理解しているけど合ってるかな?
Re: (スコア:0)
env echo='() { ls; }' bash -c 'echo hoge'
とかできる時点で、
環境変数で関数定義を渡せるという機能自体が、
今回の問題と大差ない脆弱性のような気がする
Re:イマイチ理解できないんだけど (スコア:2)
env echo='() { ls; }' bash -c 'echo hoge'
のような攻撃はスクリプト側(or bash経由で起動されるプロセス)で対処できます.
例えば echo という変数を再定義するなり
/bin/echo を使うようフルパスを記述するだけです.
ですので,これはスクリプト側の脆弱性と捉えるべきだと思います.つまりスクリプト側を修正すべきです.
しかし
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
この攻撃は スクリプト側では対処できません.
スクリプト側で対処できないので,これは bashの脆弱性で,bash側で対処すべき問題だと思います.
Re: (スコア:0)
>のような攻撃はスクリプト側(or bash経由で起動されるプロセス)で対処できます.
export unset='() { ls; }'
とされてしまったら、環境変数経由で渡ってくる関数を消そうにもできないわけだが。
unset 以外にも回避手段はあるかもしれないが、unset 同様に関数で上書きされてしまったら手も足も出ない。
cd のように外部コマンドではなくシェルのビルトインでないと実現できない機能は
フルパスで指定することもできないし。
なので、これをスクリプトの脆弱性とするのは無理がある。
Bourne sh にはなかった機能であって、bsh では気にする必要のなかったことでもあるし、
bash の脆弱性以外の何ものでもない。
Re: (スコア:0)
えっ
/usr/bin/cd の中身はシェルスクリプトで、 "builtin cd" を実行。
Re: (スコア:0)
自己レスだけど、 /usr/bin/cd は builtin の cd の代替にはならないのか。
/usr/bin/cd はサブシェルで実行されるので、呼出元のシェルでは cd されないということで合っているかな?
じゃあなんで /usr/bin/cd が用意されているのだろう…?
Re: (スコア:0)
# といった使い道が cd(1) に記述されていました。
Re: (スコア:0)
フルパス記述では回避できないっぽいですね
これでも上書きされてしまうようです
env /bin/echo='() { ls; }' bash -c '/bin/echo hoge'
Re:イマイチ理解できないんだけど (スコア:1)
env echo='() { ls; }' bash -c 'echo hoge'
他の方のコメントでも書かれていますが、これだと「bash -c」に渡している「echo hoge」の部分を攻撃者が挿入できるか、もしくは、事前に bash 経由で echo を実行する事が分かっている場合になります。前者だと、この問題が無くても外部から任意の実行できることになるので、この脆弱性以前の話だし、後者だと狙った動きをするためには、事前に bash が実行する内容を知っている事が必要、という事になると思います。
少なくとも、今回の脆弱性があれば、bash が本来実行しようとしている内容にかかわらず、環境変数さえ設定できれば任意のコマンドが実行できます。「-c 'echo hoge'」の部分すら必要ありません。
ただ、確かに、bash が本来、実行しようとしているコマンドを置き換える事が可能、という点は、条件がそろうと現実的な問題になりうると思います。通常、関数の方が PATH で見つかるコマンドや内部コマンドよりも優先順位が高いですが、環境変数経由で渡ってくる関数も、同様の優先順位で良いのか、という気がします。環境変数経由の関数が通常のコマンドよりも低い優先順位であれば、コマンドの置き換えは避けられるのでは、と思いました。
Re: (スコア:0)
builtin [nikkeibp.co.jp]とかcommand [nikkeibp.co.jp]とかで対処できそうな気がする。
Re: (スコア:0)
>builtinとかcommandとかで対処できそうな気がする。
ダメです。
export builtin='() { rm -rf /;}'
export command='() { rm -rf /;}'
とされると、こいつらも置き換えられちゃうので。
Re: (スコア:0)
その方法で攻撃するためには、攻撃対象が任意の環境変数を渡せるサービスでないとならない。
攻撃対象が HTTP なら渡せる環境変数は HTTP_USER_AGENT 等に限られるし (多分) 、
他のサービスでもさすがに任意の環境変数を渡せるようなものは無いのでは。
(断言はできないけど。)
Re:イマイチ理解できないんだけど (スコア:1)
user agentみたいなどうでもいい変数をいじるだけでアタックできてしまうのがこの問題の怖さだろう。
個人で借りてるvpsサーバ(centos 5)のログを
grep '()' /var/log/httpd/access_log /var/log/httpd/ssl_access_log (←しょぼすぎるので、もっとましなの誰か作ってください、、、)
とかして、ざっと調べてみたけど、すでにアタックの形跡があった。
ひとつはrefererだか何かが"() { :; }; ping -c 11 209.126.230.74"となってるアクセスで、pingが帰れば脆弱性ありと判定できる仕組みであるらしい。ただこれは、http://blog.erratasec.com/2014/09/bash-shellshock-scan-of-internet.html でバグの影響を調査しているらしく、悪質なものではないようだ。だた、もうひとつ別のアクセス(同じくpingの実行を狙ったもの)があって、それは本当にアタックしてきたものらしい。
うちの場合は404やら403のエラーになっていたので問題なかったけど、ちょっとぞっとした。速攻でbashをアップデートしたことは言うまでもない。
perlで作ったcgiなら、
$a=`echo hello`;
みたいなのがあったら、sh呼び出されてアウトになるわけで、それくらいのことなら私(=趣味でプログラムをいじる程度の人)は余裕でやっちゃってます。怖いよ。このバグ。
Re: (スコア:0)
ここでの話って、UserAgent等による危険性は重大だけど、そもそも関数定義を渡せること自体も問題にならないかという話では?
"echo"等を再定義されちゃったりするとマズイよね?でも、そういう変数はhttp経由だといじれないか...
という話になっていると理解しているんだけど。
Re: (スコア:0)
curl とか rsync とかで 他サーバにデータ渡せないの?
Re: (スコア:0)
"echo vulnerable" は bash が起動された時点で実行されるけど、
関数 () { :; } の中は起動した bash の中でさらに x を実行しないと実行されない。
渡された環境変数名を関数として実行しているとか、任意の環境変数を渡せる
(=本来実行すべきコマンドが環境変数で上書きされる)とかいうことが無ければ
関数の中が実行されることは無いと思う。