次のコードを想像してください:
ATTACKERDATA="$(cat attackerControlledFile.txt)"
echo "${ATTACKERDATA}"
攻撃者は、任意のプロセスを介して、attackerControlledFile.txt
の内容を好きなように変更できます。コンテンツは、ASCII、UTF-8、バイナリなどにすることができます。何でもかまいません。マシンはまた、それが無限に高速であることを前提としているため、数テラバイトの非常に大きなファイルであっても、即座に読み取られて印刷されます。
攻撃者は、可能性は低いものの、attackerControlledFile.txt
の内容を変更することによって、何らかの方法でこれを悪用することは可能ですか? 「どういうわけか」は次のようなものを指します:
bash
でのみ機能します他のすべては、合理的に健全なシステムを想定しています。つまり、「echo
が攻撃者が制御するバイナリであり、実際にマルウェアである場合」などの回答はカウントされません。マルウェアの存在は厳密には「常識的」ではないためです。特定のソフトウェアまたはそのソフトウェアのバージョンが存在することを必要とする回答doは、そのソフトウェアが悪用の目的で作成されていない限りカウントされます。
同様の質問が Linuxの "echo"コマンドを悪意を持って使用することは可能ですか? ですが、受け入れられた答えは、実際にはWebアプリケーションの設計の欠陥に関するものです。さらに、攻撃者はリダイレクトを実行できる必要がありますが、私の知る限り、この構成ではできません。
攻撃者が、可能性は低いが、attackerControlledFile.txtの内容を変更することにより、何らかの方法でこれを悪用することは可能ですか? 「どういうわけか」は次のようなものを指します:
このコードでは、特定の端末エミュレータに出力を印刷する必要があります
実際、そうです。 vt100のような古い端末には、ANSIエスケープシーケンスを使用して、コマンドの実行などの特別なことを行う機能があります。以下のサイトでは、説明したように、単純なエコーを使用してこの機能を説明しています。
https://www.proteansec.com/linux/blast-past-executing-code-terminal-emulators-via-escape-sequences/
この記事は特定のエクスプロイト手順について詳しく説明していますが、サイトからのこの抜粋から一般的な考え方を要約できます。
危険なエスケープシーケンスターミナルエミュレーターは、以下で説明するように複数の機能をサポートします[8]。
画面ダンプ:画面ダンプエスケープシーケンスは、任意のファイルを開き、端末の現在の内容をファイルに書き込みます。一部の端末エミュレータは既存のファイルに書き込まず、新しいファイルにのみ書き込みますが、他の端末エミュレータは単にファイルを新しい内容で上書きします。攻撃者はこの機能を使用して、WebサーバーのDocumentRootに新しいバックドアPHP=ファイルを作成し、後で任意のコマンドを実行するために使用できます。
ウィンドウタイトル:ウィンドウタイトルを設定するためのエスケープシーケンスがあり、ウィンドウタイトル文字列を変更します。この機能は、現在のウィンドウタイトルを読み取って現在のコマンドラインに出力する別のエスケープシーケンスと一緒に使用できます。ウィンドウタイトルではキャリッジリターン文字が禁止されているため、攻撃者はコマンドをウィンドウタイトルに保存して現在のコマンドラインに出力できますが、実行するにはユーザーがEnterキーを押す必要があります。テキストの色を背景と同じ色に設定するなど、コマンドを非表示にする方法があります。これにより、Enterキーを押すユーザーの変化が大きくなります。
コマンドの実行:一部の端末エミュレータでは、エスケープシーケンスを使用してコマンドを直接実行することもできます。
コメントで指摘されているように、この特定のエクスプロイトは数十年前に最新のターミナルエミュレータで修正されました。これはたまたま単純な例であり、30秒のGoogle検索で、ファイルを表示するだけの単純なものでも悪用できるソフトウェアがまだ機能しているという概念をうまく示していることがわかりました。
理論的には、最近の端末エミュレーター(バッファーオーバーフロー?)に他の問題があり、悪用される可能性があります。
出力が端末に送られる場合、他の回答と同様に、(特殊文字を削除しない限り、印刷方法に関係なく)潜在的に多くの問題があります。
ファイルが巨大になる可能性がある場合、攻撃者はbash
に大量のRAMを使用させることができます。 100kBの上限を設定するには、cat
ではなく_head -c 100000
_を検討してください。または_head -c 10000 | cat -v
_(印刷されない文字を_^M
_などとして表示します。UTF-8マルチバイト文字が壊れる可能性があります)。
データを巨大にする可能性がある場合は、cat
の出力をstdoutに直接接続して、そのコマンドを直接(var=$()
キャプチャ内ではなく)実行することを検討してください。
シェル変数にデータがあり、二重引用符内でeval
edされていないため、いくつかの点から安全です。
例えばコマンド置換は機能しません。
_peter@volta:/tmp$ foo='$(touch bar)'
peter@volta:/tmp$ echo "${foo}"
$(touch bar)
_
攻撃者は文字列_-n
_を使用して出力をわずかに変更できます。これはecho
がリテラルの代わりにオプションとして解釈しますデータ。
_$ echo "-n" # notice that this doesn't print a newline.
$ echo "" # unlike a normal echo "" or echo with no args
$
_
ただし、bashの組み込みecho
は_"-n foo"
_をオプションとして扱いません。それは文字通り印刷されます:
_$ echo "-nabcd"
-nabcd
_
シェル変数を二重引用符で囲んで展開しているため、_echo "-n" "leave the cursor at the end of this string"
_のように、エコーのmultiple引数になる方法はありません。
同様に、_-e
_は不可能であり、ファイルに任意のバイナリデータが既に含まれている可能性があるため、いずれにしても危険ではありません。
_/bin/echo
_ from GNU Coreutilsは_--version
_オプションをサポートしているため、Shellビルトインエコーを使用していない場合、攻撃者がプログラムにソフトウェアのバージョン情報を出力させる可能性があります。その出力が攻撃者に見えるものになる場合、ターゲットシステムに関する情報が開示されます。
これらの理由により、portably任意のデータを印刷するための推奨事項は、次のとおりです
_printf "%s\n" "${ATTACKERDATA}"
_
echo
のシステム固有のバリエーションの影響を受けない、すべてのPOSIXシェルで動作します。
https://unix.stackexchange.com/questions/65803/why-is-printf-better-than-echo/65819
https://unix.stackexchange.com/questions/58310/difference-between-printf-and-echo-in-bash
しかし、これは端末の脆弱性については何もしないことに注意してください。これは、echo
を変更せずに文字どおりにデータを書き込む安全な方法です。
また、bashは内部的にC文字列を使用するため、バイナリデータは、ほとんどのシェルで_\0
_(ゼロバイト)をターミネータとして扱います。 OSのexecve
インターフェイスもC文字列を使用しますが、Shellビルトインは、シェルがecho
/printf
のバイパスを許可するため、です例えばzsh
は、0バイトを含むバイナリデータをプリント/エコーします。
ところで、bashでは実際にファイルを読み取るためにcat
は必要ありません。リダイレクトによるコマンド置換は、bashに自分自身を読む。
_ATTACKERDATA="$(< attackerControlledFile.txt)"
_
ただし、_head -c
_や_cat -v
_などの処理が必要な場合は、実際のコマンドを使用する必要があります。
一部の端末では、入力したとおりに画面のコンテンツをエコーバックできます。
したがって、「タイピング」を強制することができるため、正しい端末コマンドでコマンドを実行できます。物理的なDEC VT62-t
sでこれを行いました。 X-termのVT-52モードでそれをやろうとしなかった
このエクスプロイトはよく知られており、おそらくfinger -l username
が~username/.plan
などからすべての制御文字(改行とタブを除く)を削除する理由です
はい、それは危険です。安全なパイプにするために、lessまたはcolなどにパイプします。
いいえ、上の例で使用されているエコーは問題ありません
Echoは単純に文字列をパイプstdoutに出力します(デフォルト)
あたり: https://superuser.com/a/699500/527937
パイプはオーバーフローできません。パイプは、プロデューサーとコンシューマーの間の単なるバッファー(特定の量のメモリー、現在のシステムではおそらく64KB)です。プロデューサーがコンシューマーが消費するよりも速くプロデュースする場合、コンシューマーがバッファーから読み取ることによってバッファーに再びスペースを確保するまで、プロデューサーはブロックされます(つまり、プログラムはスリープします)。
余談ですが、1x行に大量のデータがあると... cat
がハングしたり、システムメモリを大量に消費したりする可能性があります。
攻撃者は content-injection attack を実行する可能性があります。特に、シェルプロンプトがどのように見えるかを知っている場合はなおさらです。
システムの他の一部からの出力のように見えるファイルに何かを含めることにより、ユーザーを欺いて、何らかのアクションを実行させることができる場合があります。