乐趣区

关于安全:shellshock漏洞分析

这是 tr0ll2 靶机波及到的货色,先看一下在这个靶机上的过程。
咱们获取了 noob 用户的 ssh 密钥,之后登录却失败了:

之后咱们输出如下命令:

ssh  noob@192.168.16.141 -i noob -t '() { :;}; /bin/bash'

再次登录,竟然胜利了:

以上就是 shellshock 攻打,其利用的是 bash 在导入环境变量函数时候的破绽,启动 bash 的时候,它不仅会导入这个函数,也会把函数定义前面的命令执行,在有些 CGI 脚本的设计中,数据是通过环境变量来传递的,这样就给了数据提供者利用 Shellshock 破绽的机会。

这个破绽刚开始接触还会感觉有些奇怪,因为命令自身就是 bash 执行的,不感觉有什么危害。理论环境中在近程拜访时,有些 CGI 会把 post 包中的变量导入成用户变量,并起一个子 bash 来运行。

此利用形式,须要以下条件:

  1. 近程服务会调用 bash。(创立 bash 子过程)
  2. 近程服务容许用户定义环境变量。
  3. 近程服务调用子 bash 时加载了用户定义的环境变量。

成因剖析如下,参考了一位博主的文章,结尾贴链接:
在 bash 中能够自定义 Shell 变量 , 如下所示

但此时该变量仅是以后 Shell 的一个局部变量 , 只有在以后 Shell 过程中能够调用 . 即便是以后 Shell Fork 出的子过程 , 也是不能拜访该变量的 .

为此 , 咱们能够通过 export 命令 , 将该变量转变为一个环境变量 , 这样以后 Shell 的子过程就能够拜访它了

不仅如此 , 在 Bash 中还能够定义 Shell 函数并将其导出为环境函数 , 只须要指明 -f 参数即可

上图这种函数的定义方法是十分广泛的 , 很容易了解 . 但在 Bash 中还有一种独有的办法来定义函数 , 即 : 通过环境变量来定义函数

当某个环境变量的值以字符串 ” () { ” 的格局作为结尾 (留神大括号与小括号间的空格不能少) , 那么该变量就会被以后 Bash 当作一个导出函数(export function ) , 该函数仅会在以后 Bash 的子过程中失效 . 在很多文章中会把它称为 Bash 的 “` 主动导入机制(主动导入函数到以后 Bash

因为这种独特的函数定义形式仅会在以后 bash 的子过程中失效 , 所以网络上很多帖子给出的 POC 都是上面这样 .

POC : env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
通过 bash -c 开启以后 Bash 的子过程 , 在子过程载入时会初始化用户环境变量 , 在初始化时发现了蕴含 “() {” 格局的字符串 , 所以将该字符串作为一个主动导入函数 . 但因为没有判断函数定义的完结 , 所以谬误的将该函数定义后的语句也初始化并当作命令执行了 . 所以子 Bash 会执行该语句并输入 vulnerable , 而后再输入 this is a test .

简略的说 , 就是将歹意命令增加到非法的 Bash 函数定义后 , 在启动子过程时 , Bash 会先执行歹意命令 , 而后再执行失常的指令 .

Shellshock 破绽回顾与分析测试 中有一副图做的十分棒 , 非常容易了解 , 这里贴出来 .


之后看一下源代码:
因为 ShellShock 触发于 Bash 子过程初始化环境变量的时候 . 所以咱们进入 variables.c 文件 , 找到 initialize_shell_variables() 函数 .



这里先定义了一些参数 , 而后循环遍历所有环境变量 , 通过 ” = ” 来宰割变量名与变量值。之后判断方才获取到的环境变量中是否有不非法的(比方 “=xxx” 或者没有等号的 ) . 如果发现不非法的变量 , 就跳过它们,并赋值。再之后先判断是否存在主动导出函数(通过 “() {” 来判断 ) , 若存在就将其定义为一个函数 . 同时判断以后是否处于 privileged mode , 若不处于该模式就将之前导出的函数导入到新的环境变量中 .

留神这里 , string(获取到的环境变量值) 没有进行任何过滤 , 就被放入到 parse_and_execute 函数中 . 这是典型的注入破绽。

参考链接:https://www.guildhab.top/?p=1805

退出移动版