我正在考虑可能的拒绝服务攻击场景,其中脚本通过递归调用自身作为解释器而导致系统资源中断。
原理如下:
该脚本在其第一行以 shabang 的形式指定#!
其自身的绝对路径,作为其自己的解释器。
系统内核将根据其支持在execve
系统调用期间自动调用解释器,并将解释器前置到参数向量中。
{ARG_MAX}
此类调用将耗尽系统中设置的程序参数 () 的大小限制,从而导致(可能是孤立的)故障。
实验
我创建了两组不同的攻击向量,
第一个,调用自身
#!/usr/local/bin/recurse
第二个,互相呼唤。
#!/usr/local/bin/recurse-1
#!/usr/local/bin/recurse-2
我已在 macOS Big Sur 11.5.2 上测试了这 2 个攻击向量。当我使用 检查退出状态时echo $?
,它显示 0,这意味着进程成功完成。
问题。
现代操作系统是否已针对此类攻击进行了修补?有这方面的研究论文吗?
答案1
在 Linux 上,我得到以下信息:
在 hashbang 行上有一个不存在的解释器的脚本(execve()
给出ENOEXEC
):
$ cat brokenhashbang.sh
#!/bin/nonexisting
echo hello
$ ./brokenhashbang.sh
bash: ./brokenhashbang.sh: /bin/nonexisting: bad interpreter: No such file or directory
带有递归 hashbang ( ) 的脚本ELOOP
:
$ cat /tmp/recursivehashbang.sh
#!/tmp/recursivehashbang.sh
echo hello
$ /tmp/recursivehashbang.sh
bash: /tmp/recursivehashbang.sh: /tmp/recursivehashbang.sh: bad interpreter: Too many levels of symbolic links
具有现有但不可执行的解释器的脚本 ( EACCESS
):
$ cat noexechashbang.sh
#!/etc/passwd
echo "hello?"
$ ./noexechashbang.sh
bash: ./noexechashbang.sh: /etc/passwd: bad interpreter: Permission denied
不仅仅是 Bash:Dash、ksh 和 zsh 也会给出类似的错误。
如果脚本没有 hashbang,或者 hashbang 指向其他不可执行的文件(需要有+x
,您会得到ENOEXEC
),则行为会略有不同。 Bash 将文件本身作为 shell 脚本运行,而 zsh 似乎会查看内部是否有 hashbang 行,然后尝试启动该解释器,或者使用/bin/sh
.通过 ENOEXEC 上的 shell 运行脚本是shell 的 POSIX 指定行为和对于execlp()
/execvp()
功能。
(对于不存在解释器的情况,Dash 只是给出令人困惑的dash: 1: ./brokenhashbang.sh: not found
,就好像脚本本身不存在一样。但我认为这是来自底层系统调用的相同错误,并且 Dash 太简单了,无法检查哪个文件丢失。 )
无论如何,我看不出这里的攻击是什么,因为如果他们运行你选择的命令,你已经可以做任何你喜欢的事情了。不是通过一个不存在的脚本解释器,而是一个可以工作的解释器。
答案2
笔记以下是在 macOS Big Sur 11.5.2 上测试的。
根据标准(以及现有实践),贝壳exec
如果函数调用失败返回,将尝试解释该文件并执行其中的命令。
这是第三个攻击向量:
#!/usr/local/bin/recurse
eval 'printf "%s\n" xxx'
将该文件命名为/usr/local/bin/recurse
并执行它后,该字符串xxx
被打印在标准输出上,尽管解释器循环应该阻止该命令被评估。
如果使用 C 程序通过函数调用脚本execv
,则errno
函数调用设置的值为ENOEXEC
。