bash ã®èå¼±æ§ "Shell Shock" ã®ãã£ã¡ãç´°ãã話 (CVE-2014-6271)
â»(2014/10/1 追è¨) èå¼±æ§ã®çªå·ã誤ã£ã¦ CVE-2014-6721 ã¨è¡¨è¨ãã¦ãã¾ã£ã¦ãã¾ãã
æ£ãã㯠"CVE-2014-6271" ã§ã 失礼è´ãã¾ãã
â»(2014/10/7 追è¨) 2014/10/7 14:00æç¹ã§ Shell Shock ã¸ã®ä¿®æ£ãããã¯6å å
¬éããã¦ãã¾ã
æ¢ã«å¯¾å¿æ¸ã¿ã®ã·ã¹ãã ã§ããããã®æ¼ãããªãã注æãã¦ãã ãã
ã·ã§ã«ã«èå¼±æ§ãè¦ã¤ãã£ããããã§ã
ãã®ã³ãã³ããå®è¡ããã¨èå¼±æ§ããããã¼ã¸ã§ã³ãã®ãã§ãã¯ãã§ããããã§ã
$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
以ä¸ã®ããã«è¡¨ç¤ºããããã¢ã¦ãã§ã
vulnerable
this is a test
ã©ãããããã®ã³ãã³ããæ£å¸¸ã«å®è¡ã§ããã¨ããã®ããã®èå¼±æ§ã®æ£ä½ãããã
echo vulnerable
ã®é¨åã«ã¯ä»»æã®ã³ãã³ããå ¥ãããã¨ãã§ãã¾ã
ã©ãã¾ã§ã®ã³ãã³ããå®è¡å¯è½ãã©ãã㯠å®è¡ã¦ã¼ã¶ã¼ã®æ¨©éã«ããã¾ããã
å ´åã«ãã£ã¦ã¯å®å
¨ã«ãµã¼ãã¼ãä¹ã£åãããå¯è½æ§ãããã¾ã
èå¼±æ§ã«ã¤ãã¦ã®å±éºæ§ã対å¦æ¹æ³ã¯æ¢ã«ããããã®è¨äºãæ¸ããã¦ããããã
詳ããã¯ä»¥ä¸ã®ãµã¤ããã確èªãã ãã
èå¼±æ§ãå ¬éãããæ¬å®¶ã®ãµã¤ã
oss-sec: Re: CVE-2014-6271: remote code execution through bash
æ¥æ¬èªã§ã®æç¨ãªæ å ±ãã¾ã¨ãã¦ããã¦ãã¾ã
bashの脆弱性(CVE-2014-6271) #ShellShock の関連リンクをまとめてみた - piyolog
ä»åã®è¨äºã§ã¯ bash ãã©ããªå®è£
ã«ãªã£ã¦ããã®ãåé¡ã§ã
ã©ããã£ãä¿®æ£ããããã®ããç´è§£ãã¦ããã¾ã
ã·ã§ã«èªä½ã®ã½ã¼ã¹ãè¦ãæ©ä¼ãªãã¦ã¾ããªãã®ã§ãããæ©ä¼ã ã¨æã£ã¦ä¸ç·ã«åå¼·ãã¾ããã
èªå® ã® Mac ã® bash ãè¦ã㨠version 3.2 ã ã£ãã®ã§ãbash 3.2 ã®ã½ã¼ã¹ãå ã«èª¿æ»ãã¾ã
ãã®è¨äºã§ã¯
1. SehllShock (CVE-2014-6271) ã®æ¦è¦
2. ã½ã¼ã¹ã³ã¼ãã®å
¥æã¨ãããã®é©ç¨
3. ä¿®æ£ç®æã«ã¤ãã¦
4. ã³ã¼ããå®è¡ãããã¾ã§ã®è©³ç´°ã«ã¤ãã¦
5. ã¾ã¨ã
ã«ã¤ãã¦èª¬æãã¾ã
1. SehllShock (CVE-2014-6271) ã®æ¦è¦
ç°å¢å¤æ°ã«ããç¹æ®ãªæ§æã® bash ã³ã¼ããã»ããããã¦ããã¨ãbash ã®èµ·åæã«ãã®ã³ã¼ããåæã«å®è¡ãã¦ãã¾ããã¨ãããã®ã§ã
ãã®ãããå¤é¨ããä½ã§ãããã®ã§ã©ããã®ç°å¢å¤æ°ã«æ¸ãè¾¼ããã¨ãã§ããããã«ãªã£ã¦ããã¨ãShellShock ã®èå¼±æ§ãã¤ããæ»æãå¯è½ã«ãªã£ã¦ãã¾ãã¾ã
ããã«ãã OSã³ãã³ãã¤ã³ã¸ã§ã¯ã·ã§ã³ã¨ãã種é¡ã®æ»æãå¯è½ã«ãªãã¾ã
bash ã¯èµ·åæã« ãã®æè¨å®ããã¦ããç°å¢å¤æ°ãèªã¿è¾¼ãã§ããå¦çãéå§ãã¾ã
é常ã¯ç°å¢å¤æ°ã®å¤ã«ã³ã¼ããå ¥ã£ã¦ãã¦ããæ示çã«å®è¡ããªãéãã¯æååã¨ãã¦æ±ãããä»æ§ã«ãªã£ã¦ãã¾ã
ã§ããããã®é¨åã®å¦çã«ãã°ããããbash èµ·åæã®ç°å¢å¤æ°ãèªã¿è¾¼ãã¿ã¤ãã³ã°ã§ãã®æååãã³ã¼ãã¨ãã¦å®è¡ããã¦ãã¾ããã¨ããã®ãä»åæããã«ãªã£ãåé¡ç¹ã§ã
ã½ã¼ã¹ã調æ»ããçµæãèå¼±æ§ãå«ãã bash ã®ãã¼ã¸ã§ã³ã§ã¯ä»¥ä¸ã®ãããªå¦çã«ãªã£ã¦ãããã¨ãåããã¾ãã
ããããã¯èª¿æ»ããã½ã¼ã¹ã®è§£èª¬ããã¦ããã¾ã
2. ã½ã¼ã¹ã³ã¼ãã®å ¥æã¨ãããã®é©ç¨
ãããã®é©ç¨åå¾ã®ã½ã¼ã¹ã確èªãããã®ã§ bash ã®ã½ã¼ã¹ã³ã¼ããå ¥æãã¾ã
以ä¸ã®è¨äºãåèã«ããã¦ããã ãã
ã½ã¼ã¹ã®ãã¦ã³ãã¼ãã¨æåã§ã®ãããé©ç¨ãè¡ãã¾ãã
CVE-2014-6271のbashの脆弱性に対応する方法
ä»åã®èå¼±æ§ã¸ã®ä¿®æ£ãããã®ãã¼ã¸ã§ã³ã¯ 3.2.52 ã¨ã®ãã¨ãªã®ã§ã
bash-3.2.51 㨠bash-3.2.52 ã®ã½ã¼ã¹ãç¨æãã¾ã
$ curl https://opensource.apple.com/tarballs/bash/bash-92.tar.gz | tar zxf - $ mv bash-92 bash-3.2.51 $ cp -pr bash-3.2.51 bash-3.2.52 $ cd bash-3.2.52/bash-3.2 $ curl https://ftp.gnu.org/pub/gnu/bash/bash-3.2-patches/bash32-052 | patch -p0
ä»åã¯ããã¾ã§ã½ã¼ã¹ã®ç¢ºèªãç®çãªã®ã§ãæ¬å®¶ã® GNU ãããã¦ã³ãã¼ããã¦ãã¦ãããã§ã
Index of /pub/gnu/bash
opensource.apple.com ãªãã¦ãã®ãåãã¦ç¥ã£ãã®ã§ãããapple ããªã¼ãã³ã½ã¼ã¹ã®ã½ããã¦ã§ã¢ãå
¬éãã¦ãããµã¤ããããã§ã
Open Source - Releases
3. ä¿®æ£ç®æã«ã¤ãã¦
GNU ãå
¬éãã¦ããããããã¡ã¤ã«ã¨ã
å
ã»ã©ãã¦ã³ãã¼ããã¦ããã½ã¼ã¹ã®å·®åããããã確èªãã¾ã
GNU ã§å ¬éããã¦ããããããã¡ã¤ã«
å ã»ã©å ¥æããã½ã¼ã¹ã®å·®å
$ diff -rq bash-3.2.52 bash-3.2.51
Files bash-3.2.52/bash-3.2/builtins/common.h and bash-3.2.51/bash-3.2/builtins/common.h differ
Files bash-3.2.52/bash-3.2/builtins/evalstring.c and bash-3.2.51/bash-3.2/builtins/evalstring.c differ
Files bash-3.2.52/bash-3.2/patchlevel.h and bash-3.2.51/bash-3.2/patchlevel.h differ
Files bash-3.2.52/bash-3.2/variables.c and bash-3.2.51/bash-3.2/variables.c differ
å·®åã確èªããã¨ã以ä¸ã®4ãã¡ã¤ã«ã«ä¿®æ£ãå
¥ã£ã¦ããããã§ã
- bash-3.2/builtins/evalstring.c
- bash-3.2/builtins/common.h
- bash-3.2/patchlevel.h
- bash-3.2/variables.c
1ã¤ã¥ã¤å
容ãè¦ã¦è¡ãã¾ããã
bash-3.2/builtins/evalstring.c parse_and_execute ()
ã¨ã©ã¼ãåãã¦å¦çãåæ¢ãããæãã®ã³ã¼ãã追å ããã¦ãã¾ã
æããä»åã®èå¼±æ§ã«å¯¾å¿ããã³ã¢ãªé¨åã§ããã
$ diff bash-3.2.52/bash-3.2/builtins/evalstring.c bash-3.2.51/bash-3.2/builtins/evalstring.c 237,244d236 < if ((flags & SEVAL_FUNCDEF) && command->type != cm_function_def) < { < internal_warning ("%s: ignoring function definition attempt", from_file); < should_jump_to_top_level = 0; < last_result = last_command_exit_value = EX_BADUSAGE; < break; < } < 302,304d293 < < if (flags & SEVAL_ONECMD) < break;
bash-3.2/variables.c initialize_shell_variables ()
parse_and_execute () ãå¼ã³åºãéã®å¼æ°ãå¤æ´ããã¦ãã¾ã
ã¾ããåé¤ããã¦ããç®æãããã¾ããããã½ã¼ã¹ä¸ã®ã³ã¡ã³ããã㯠ä¸ä½äºææ§ãä¿ã¤ããã®ã³ã¼ãã®ããã§ã
$ diff bash-3.2.52/bash-3.2/variables.c bash-3.2.51/bash-3.2/variables.c 321,324c321,326 < /* Don't import function names that are invalid identifiers from the < environment. */ < if (legal_identifier (name)) < parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD); --- > 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'; 332a335,338 > > /* ( */ > if (name[char_index - 1] == ')' && name[char_index - 2] == '\0') > name[char_index - 2] = '('; /* ) */
bash-3.2/builtins/common.h
SEVAL_FUNCDEFãSEVAL_ONECMD ã®2ã¤ã®å®æ°ã追å ããã¦ãã¾ã
ãã®å®æ°ã¯ä¸ã®2ã¤ã§è¿½å ãããå¦çå
ã§å©ç¨ããã¦ãããã®ã§ã
$ diff bash-3.2.52/bash-3.2/builtins/common.h bash-3.2.51/bash-3.2/builtins/common.h 36,37d35 < #define SEVAL_FUNCDEF 0x080 /* only allow function definitions */ < #define SEVAL_ONECMD 0x100 /* only allow a single command */
bash-3.2/patchlevel.h
ããã¯ãããçªå·ã表ãå®æ°ã£ã½ãã§ãã
$ diff bash-3.2.52/bash-3.2/patchlevel.h bash-3.2.51/bash-3.2/patchlevel.h 28c28 < #define PATCHLEVEL 52 --- > #define PATCHLEVEL 51
4. ã³ã¼ããå®è¡ãããã¾ã§ã®è©³ç´°ã«ã¤ãã¦
bash ãèµ·åããã¦ããã®å¦çã追ãã¨ã以ä¸ã®é çªã§å¦çãå®è¡ããã¦ãã¾ãã
1.bash-3.2/shell.c main ()
â
2.bash-3.2/shell.c shell_initialize ()
â
3.bash-3.2/variables.c initialize_shell_variables ()
â
4.bash-3.2/builtinsevalstring.c parse_and_execute ()
â
5.bash-3.2/builtinsevalstring.c execute_command_internal ()
ããããé©ç¨ããåã® initialize_shell_variables () ãç´°ããè¦ã¦ã¿ã¾ããã
å¼æ°ã§æ¸¡ããã env ã«ã¯ç°å¢å¤æ°ã®ä¸è¦§ãæ ¼ç´ããã¦ãã¾ã
variables.c initialize_shell_variables ()
/* 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; {
env ã§æ¸¡ãããå
容ã1ã¤1ã¤ãã§ãã¯ããã¾ã
"() {" ããå§ã¾ã£ã¦ããæååã¯å¦çãåå²ãããä»åã®èå¼±æ§ã§åé¡ã¨ãªã£ã parse_and_execute () ã«ç°å¢å¤æ°ã®å¤ã渡ãã¦å
¥ã£ã¦è¡ãã¾ã
variables.c initialize_shell_variables ()
/* 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);
parse_and_execute () ã¨ããé¢æ°ã®ååããã¯ã渡ãããæååã®ã³ãã³ãããã¼ã¹ãã¦å®è¡ããå¦çã ã¨ãããã¨ãæ³åã§ãã¾ã
ãããæªããããªæãããã¾ã
evalstring.c parse_and_execute ()
int parse_and_execute (string, from_file, flags) char *string; const char *from_file; int flags; {
ãã®å¾ã® parse_command () å
ã®å¦çã«ã¦æ¸¡ãããæååããã¼ã¹ããã¾ã
æ§æã¨ã©ã¼ãç¡ãã£ãå ´åã«ã¯ parse_command () ããæ»ãå¤ 0 ãè¿ããã¾ã
evalstring.c parse_and_execute ()
if (parse_command () == 0) { if (interactive_shell == 0 && read_but_dont_execute) { last_result = EXECUTION_SUCCESS; dispose_command (global_command); global_command = (COMMAND *)NULL; } else if (command = global_command) { // -------- çç¥ -------- } else last_result = execute_command_internal (command, 0, NO_PIPE, NO_PIPE, bitmap);
parse_command () ã®å¦çã§ã¯ ä¸ããããæååãã©ããªæ§æã®ã³ãã³ããªã®ãããã§ãã¯ããå¤å®ãããã³ãã³ãã®ç¨®é¡ã command->type ã«ã»ããããã¾ã
ã¾ãããã¼ã¹ããçµææ§æã¨ã©ã¼ãç¡ããã°ãglobal_command ã«ã¯ç°å¢å¤æ°ã®æååãã»ããããã¾ã
ããã¦ãexecute_command_internal () å ã§æ§æãã§ãã¯ãçµããã³ãã³ãã«é¢ãã¦ã®å¦çãå®è¡ããã¾ã
execute_command_internal ã¨ããååãããã¦ã
ããã«å
¥ãã¨ã©ããªå¦çã§ãå®è¡ããã¦ãã¾ãããã«è¦ãã¾ã
execute_command_internal () ã®å é¨ã§ã¯ãã¼ã¹ã§å¤å®ããã command->type ã®å¤ã«ãã£ã¦å¦çãåå²ããã¾ã
æååã®å 容ãé¢æ°ã®å®ç¾©ã¨ãã¦èªèãããå ´åã«ã¯ command->type ã« cm_function_defãã»ããããããããexecute_command_internal () å ã§ã¯ä»¥ä¸ã®å¦çãå®è¡ããã¾ã
execute_cmd.c execute_command_internal ()
case cm_function_def: exec_result = execute_intern_function (command->value.Function_def->name, command->value.Function_def->command); break;
ãã®æå®è¡ããã¦ãã execute_intern_function () ã¯ã³ãã³ãã®æååãé¢æ°ã¨ãã¦ãã¤ã³ãããã ãã®å¦çã§ãé¢æ°ãå®è¡ããå¦çã«ã¯ãªã£ã¦ãã¾ããã§ãã
ãªã®ã§æ£ããï¼æ§æã§é¢æ°å®ç¾©ãæå®ããã¦ããå ´åã«ã¯ãç°å¢å¤æ°ã«é¢æ°ã¨ãã¦ãã¤ã³ããããã ãã§é¢æ°ãã®ãã®ã®å¦çãå®è¡ããããã¨ã¯ãªããã¨ãåããã¾ãã
ãã¦ãåé¡ã¯
x='() { :;}; echo vulnerable'
ã¨ããæååããªãç°å¢å¤æ°ã®èªã¿è¾¼ã¿æã«å®è¡ããã¦ãã¾ããã§ã
ç´°ããæãè¦ã¦è¡ãã¨ãä¸è¨ã®æååããã¼ã¹ããçµæ㯠cm_function_def ã¨ãã¦å¤å®ããã¦ãããã以ä¸ã®ãããªæ§é ã® cm_connection ã¨ãã種é¡ã«å¤å®ããã¦ãã¾ãã
cm_function_def ; cm_simple
cm_connection 㯠"&" ã";"ã"|" ãªã©ã§ã³ãã³ããé£çµããã¦ããæ§é ã示ããã®ã§ã
x=() { :;} ã®é¨åã cm_function_def ã¨ãã¦è§£éããã
echo vulnerable ã®é¨åã cm_simple ã¨ãã¦è§£éããã¦ãã¾ãã
cm_connection ã®å ´åã® execute_intern_function () ã®å¦çã¯ä»¥ä¸ã«ãªã£ã¦ããã; ã§ç¹ããã2ã¤ã®ã³ãã³ãã¯å·¦å´ãã1ã¤ã¥ã¤ execute_intern_function () ãå®è¡ããã¾ã
ããã¯ã¯ã³ã©ã¤ãã¼ã®ããã«ãã³ãã³ãã ; ã§åºåã£ã¦è¨è¿°ããå ´åã®å¦çãªã®ã§ãç¹å¥ãªãã®ã§ã¯ããã¾ãã
å½ç¶ããã®å¦çèªä½ããã°ãå«ãã§ããããã§ã¯ããã¾ãã
å¦çã®è©³ç´°ãè¦ã¦ã¿ã¾ããã
ã¾ããcm_connection ã®ã³ãã³ã㯠execute_connection () ãå®è¡ããã¾ã
execute_cmd.c execute_intern_function ()
case cm_connection: exec_result = execute_connection (command, asynchronous, pipe_in, pipe_out, fds_to_close); break;
execute_connection () ã®ä¸èº«ã§ã
é£çµãã¦ããæåã ";" ã®å ´åã¯å·¦å´ãã1ã¤ã¥ã¤å®è¡ããã¦ãããã¨ãåããã¾ã
å³å´ã®ã³ãã³ãã¯ããã« é£çµããããã®ã§ããå¯è½æ§ãããã®ã§ execute_command_internal () ã§å®è¡ããã¦ããããã§ã
execute_cmd.c execute_connection ()
/* Just call execute command on both sides. */ case ';': if (ignore_return) { if (command->value.Connection->first) command->value.Connection->first->flags |= CMD_IGNORE_RETURN; if (command->value.Connection->second) command->value.Connection->second->flags |= CMD_IGNORE_RETURN; } QUIT; execute_command (command->value.Connection->first); QUIT; exec_result = execute_command_internal (command->value.Connection->second, asynchronous, pipe_in, pipe_out, fds_to_close); break;
cm_simple ã®å ´åã¯åç´ã«ã³ãã³ããå®è¡ãããå¦çã«ãªã£ã¦ãã¾ãã
5. ã¾ã¨ã
ä»ã¾ã§ã®è©±ãã¾ã¨ããã¨ãç°å¢å¤æ°ã®ã»ããã¢ãããè¡ãå¦çã®ä¸ã§é¢æ°ã®ãã¤ã³ããè¡ãã ãã ã¨æã£ã¦ããå¦çããå®ã¯é¢æ°å®ç¾©ã®å¾ã«ç¶ãã³ãã³ããåæã«å®è¡ããã¦ãã¾ãå®è£ ã«ãªã£ã¦ããããã§ã
ããã«å¯¾ãã¦ã®ä¿®æ£å
容ã¯ãbash èµ·åæã®ç°å¢å¤æ°ã»ããã®æã ããã§ãã¯å¦çã追å ãã¦ãã¾ã
ç°å¢å¤æ°ã® "() {" ããå§ã¾ã£ã¦ããæååãcm_function_def ã¨å¤å®ãããã°é常ã®ãã¤ã³ãå¦çãå®è¡ãã
ãã以å¤ã®å ´åã¯ã¨ã©ã¼ã¨ãªãããã«ä¿®æ£ããã¦ãã¾ãã
ãã®å·®åãã¾ãã«ãã®ãã§ãã¯å¦çã®é¨åã§ã
bash èµ·åæã®ç°å¢å¤æ°ã»ããã®æã ããflags ã« SEVAL_FUNCDEFãSEVAL_ONECMD ã®ããããã»ãããããããã«ãªã£ã¦ãã¾ã
$ diff bash-3.2.52/bash-3.2/builtins/evalstring.c bash-3.2.51/bash-3.2/builtins/evalstring.c 237,244d236 < if ((flags & SEVAL_FUNCDEF) && command->type != cm_function_def) < { < internal_warning ("%s: ignoring function definition attempt", from_file); < should_jump_to_top_level = 0; < last_result = last_command_exit_value = EX_BADUSAGE; < break; < } < 302,304d293 < < if (flags & SEVAL_ONECMD) < break;
ãªãã ãããã³ãã«ãã®ä¿®æ£ã§å¤§ä¸å¤«ãªã®ï¼ã¨ããæããã¨ã¦ããã¾ãããè¶
ç·æ¥ã®æ«å®å¯¾å¿ã¨ããã¨ãããªãã§ãããã
é¢æ°ã®ãã¤ã³ãã¨ã³ãã³ãã®å®è¡ã¨ããå
¨ãå¥ã®æ§è³ªãæã¤å¦çã parse_and_execute () ã¨ããé¢æ°ã«ã¾ã¨ãããã¦ãã¾ã£ã¦ãããã¨ããæ··ä¹±ãæãåå ã«ãªã£ã¦ãã¾ã£ã¦ããããã«æãã¾ã
ãã ããããæ¹ä¿®ããã®ã¯ç¸å½å¤§å¤ãããªã®ãåããã®ã§ãã¨ããããã®å¯¾å¿ã¨ãã¦ãããã£ãä¿®æ£ã«ãªã£ã¦ãããã§ããã
å®éããã®ä¿®æ£ãé©ç¨ããå¾ãã¾ã å®è¡ã§ããã³ã¼ãããããï¼ã¨ããå ±åããããCVE-2014-7169 ã¨ãã¦å¯¾å¿ããã¦ãã¾ã
ããªãããªããã¼ãªãã¨ããã¦ãã¦èå³æ·±ãã£ãã®ã§ãããã«ã¤ãã¦ã¯ã¾ãå¥éè¨äºãæ¸ããã¨æãã¾ã
â»CVE-2014-7169 ã«ã¤ãã¦ã®è¨äºãæ¸ãã¾ãã
bash の脆弱性 "Shell Shock" のめっちゃ細かい話 その2 (CVE-2014-7169) - もろず blog