颠覆Linux系统上的execute标志。为什么会这样呢?


23

在阅读本文的同时,我发现了以下漏洞:

% cp /usr/bin/id ~
% chmod -x ~/id
% ls -al ~/id
-rw-r--r-- 1 edd edd 22020 2012-08-01 15:06 /home/edd/id
% ~/id
zsh: permission denied: /home/edd/id
% /lib/ld-linux.so.2 ~/id
uid=1001(edd) gid=1001(edd) groups=1001(edd),1002(wheel)

此代码片段表明,我们可以像普通的非特权用户一样轻易地避开文件系统的执行权限。我在Ubuntu 12.04上运行它。

虽然Linux加载器是file(1)的共享对象,但它也具有允许直接执行的入口点。当以这种方式执行时,Linux加载程序将充当ELF二进制文件的解释器。

但是,在我的OpenBSD机器上,此利用无效,因为您可能未将加载程序作为程序执行。OpenBSD手册页显示:“ ld.so本身是一个共享对象,最初由内核加载。”

在Solaris 9上尝试此操作,您将遇到段错误。我不确定其他地方会发生什么。

因此,我的问题是:

  • 为什么Linux加载器(直接执行时)在解释ELF二进制文件之前检查文件系统属性?
  • 为什么要实施一种机制,该机制被设计成不允许执行文件(如果它被轻易地绕开了)?我错过了什么吗?

1
没有充分的理由,但是,如果您曾经设法删除系统的系统libc(我曾经做过一次,升级了Arch框),那么您会对这个小怪癖表示感谢。
2012年

1
@ new123456哦,上帝,那升级后的IRC频道是痛苦的是英寸
罗布

它是加载程序,而不是链接程序。
停止Harming Monica 2012年

Answers:


33

该目标execute的权限是阻止执行一般。指定setuid位(等)时,是(1)告诉程序要执行哪些文件,(2)防止以特权用户身份执行。

链接器骇客似乎没有什么利用能力。您可以执行任何具有读取权限的非可执行文件:

$ cp unexecutable_file ~/runme
$ chmod +x ~/runme
$ ~/runme

请参阅Arch Linux论坛上的讨论

综上所述:

标记应执行的文件

编写Shell脚本时,可以使用将其标记为可执行文件chmod +x。这向您的Shell暗示您希望它是可执行的(否则,对于所有Shell来说,它只是另一个纯文本文件)。然后,当您键入时,shell可以在制表符补全中显示它./Tab

同样:something.d目录(例如init.d)包含启动或控制外壳程序脚本,这些脚本通常由守护程序自动执行。您可能希望将注释或自述文件作为纯文本文件放在目录中。或者,您可能想暂时禁用其中一个脚本。您可以通过清除该特定文件的执行位来实现。这告诉守护程序跳过它。

防止特权执行

setuid位表示执行文件时,将以指定用户(例如root)的身份执行文件。

论坛帖子对此进行了很好的解释:

您希望某个用户的可执行文件被设置为setuid,但是您只希望特定组中的人能够以setuid的身份执行该可执行文件。他们仍然可以通过复制来执行它,但是setuid标志丢失了,因此他们将自己执行它,而不是拥有原始文件的用户。


2
谢谢-我忽略了用户可以复制他可以读取的任何文件并因此选择任意权限的事实。
爱德·巴雷特

具有执行权限但没有读取权限的文件怎么样?
Lie Ryan

@LieRyan他们呢?
恢复莫妮卡

@BrendanLong:您显然无法复制这些文件,因此您无法更改其权限。(但是,为什么不能,我不能说-无论如何,您唯一可以做的事情就是放弃执行权限)
MSalters 2012年

9

如果您具有文件的读取权限,则始终可以对其进行复制。

如果可以制作个人副本,则始终可以将该副本标记为可执行文件。

这并不能解释ld-linux的行为,但确实表明它可能不是一个非常有用的安全漏洞。

如果您想要更严格的安全性,请考虑使用SELinux


这是真的。
爱德·巴雷特

这只是一个概念上的问题。我想您也可以在文件系统上设置nonexec。
艾德·巴雷特

2

以不同的方式看待这个问题:正如Mechanical Snail所说,对文件的执行许可并不是为了阻止执行。但是,文件系统选项“ noexec”确实阻止了执行,并且不那么容易被规避(并非所有文件系统都支持,但最流行的linux系统也不支持)。如果管理员希望阻止用户运行自己的程序,则可以在主目录和tmp目录以及用户可以在其中创建文件的任何其他目录上指定noexec选项。

$ mount -o noexec /dev/sdd1 /test
$ cd /test
$ cp /usr/bin/id .
$ ./id
-bash: ./id: Permission denied

显然,使用问题中提到的加载器技巧可以绕过noexec选项,但是在内核中已经解决了几个版本。

http://linux.die.net/man/8/mount

Noexec

不允许在已挂载的文件系统上直接执行任何二进制文件。(直到最近,仍可以使用/lib/ld*.so / mnt / binary这样的命令来运行二进制文件。此技巧自Linux 2.4.25 / 2.6.0起失败。)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.