程序代码如下
#include <stdio.h>
int main(){setresuid(getegid(), getegid(), getegid());setresgid(getegid(), getegid(), getegid());system("/home/shellshock/bash -c 'echo shock_me'");return 0;
}
拿到这道题,我一看到那熟悉的system函数,就觉得问题一定出在它身上,于是我想着删除bash文件后自己手动创建一个bash软连接到flag上,发现由于我对bash文件没有w权限,所以我无法删除
之后我又想了一个办法,就是给bash添加一个软连接,让它指向一个我写好的运行flag程序的二进制文件,但是,同样的道理,我没有W权限,所以会报错
emm。于是我上网查了一下,发现说这是一个著名的bash破壳漏洞。。。what?看来我还是做题太少,竟然没有听说过。。。
漏洞原理
目前的Bash使用的环境变量是通过函数名称来调用的,导致漏洞出问题是以“(){”开头定义的环境变量在命令env
中解析成函数后,Bash执行并未退出,而是继续解析并执行shell命令。而其核心的原因在于在输入的过滤中没有严格限制边界,也没有做出合法化的参数判断。
漏洞范围:
GNU Bash 版本小于等于4.3
关于shellshock可以看这里
这篇文章将shellshock漏洞也讲的很好
我们既然已经知道是shellshock漏洞了,于是我们可以查看一下bash的版本
可以发现我们当前的bash是已经修补漏洞的,但是bash可执行文件确是有漏洞的bash
所以我们就来利用这个神奇的字符串(){ :;};
即,得到了我们的flag,虽然这次没有小笑脸啦~
附shellshock漏洞利用:
1)Linux WEB Server一般可以提供CGI接口,允许远程执行Bash命令;
2)对于HTTP头部,CGI脚本解析器会将其当作环境变量,调用bash的env相关函数设置到临时环境变量中;
3)HTTP协议允许发送任意客户端自定义的HTTP头部;
4)这样就产生了一个完整的可供Bash命令注入的场景,客户端故意发送构造好的带攻击命令的HTTP头部到服务端,服务端调用设置环境变量的函数,直接执行了客户端指定的头部里面的命令。并且还会将结果一并返回给客户端。