I'm having difficulty understanding the Shells

2019-02-24 20:17发布

问题:

This question already has an answer here:

  • Is the behavior behind the Shellshock vulnerability in Bash documented or at all intentional? 4 answers

I got this while I was checking for the Shellshock vulnerability:

host1:~$ env x='(){ :;}; echo vulnerable' bash -c "echo hello"
hello
host1:~$ env x='() { :;}; echo vulnerable' bash -c "echo hello"
vulnerable
hello
host1:~$

Weird huh?

回答1:

Bash recognizes an environment variable as a function if it starts with precisely the four characters () {, including the space. So env x='(){ :;}; echo vulnerable' doesn't count.

This doesn't quite conform to the syntax you use to define a function in bash; internally, bash will store the string representation of a function in a normalized form. If the function is exported (with export -f function_name), then the normalized form is added to the environment, and child bash processes will recognize it as a function definition.

The "shellshock" bug comes from the way bash handles recognized functions; the buggy versions of bash (which go back a long way) simply evaluate the string from the environment as a function definition (by prepending the name of the variable as the function name), which is subject to an injection attack as demonstrated in the vulnerability test.

Manually creating strings which look like bash function definitions in order to define functions in child bash processes is a known technique. Exporting functions and reimporting them is very common, and often is not even noticed by the user. (For example, this technique is used to pass bash functions into subshells started by xargs bash -c and find ... -exec bash -c.)



回答2:

bash is a little picky about what it considers an embedded function definition in the environment. In the first

env x='(){ :;}; echo vulnerable' bash -c "echo hello"}

the lack of a space between () and { is enough to prevent bash from recognizing this as an exported function, so it remains a simple shell variable; to see, try running

env x='(){ :;}; echo vulnerable' bash -c 'echo $x'

In the second example, the value of x, with the space, is crafted correctly to mimic an exported function, and so the child bash evaluates the entire value of x to "import" the function, but executing the code following the function definition as well.