Linux利用动态链接共享对象库提权
RPATH和弱文件权限会导致系统的损害。Linux应用程序可以利用动态链接的共享对象库(我们从现在开始称它们为共享库)来提供应用程序功能,而不必重复编写相同的代码-有点像Windows应用程序中的DLL文件。就像在Windows上的DLL植入攻击一样,Linux共享库与弱文件权限相结合,可以用来执行任意代码并危害Linux系统。
操作系统如何查找共享库?
运行使用共享库的应用程序时,操作系统按以下顺序搜索库(来自https://linux.die.net/man/1/ld):
- 任何由rpath-link选项指定的目录(由rpath-link选项指定的目录仅在链接时有效)
- 任何由rpath选项指定的目录(rpath选项指定的目录都包含在可执行文件中,并在运行时使用)
- LD_RUN_PATH
- LD_LIBRARY_PATH
- DT_RUNPATH或DT_RPATH中的目录。(如果存在DT_RUNPATH条目,则忽略DT_RPATH条目)
- /lib和/usr/lib目录
- /etc/ld.so.conf中的目录
我们怎么能得到root权限?
如果攻击者可以用一个恶意代码替换一个共享库,那么当应用程序运行时,它将加载恶意代码并以所有者的权限执行。如果应用程序以root身份运行,则会导致主机完全损害。
攻击者可能需要耐心等待应用程序由用户运行,或者使用社会工程学的元素诱骗系统管理员运行藏有恶意代码的程序并执行恶意代码。如果在系统启动时调用应用程序,由cron调用作业或进程,则利用可能会更快。
为了识别共享库使用的二进制文件,可以使用ldd工具:
可以跟踪下列攻击路径,以确定使用共享库的二进制文件是否容易受到攻击:
示例:
我将演示一个示例,其中使用RPATH编译的二进制文件结合弱文件权限可以导致获得root权限。
运行ldd识别二进制文件查看它使用的共享库:
当objdump运行时,你可以看到它已经被编译成一个静态的RPATH指向/tmp/program/main:
默认情况下,/ tmp分区是可写的,如果没有NOEXEC标志创建,那么分区将允许攻击者编写恶意共享库,当“contextBinary”运行时将执行该库。在服务器上,有一个root用户的cronjob恰好执行脆弱的二进制文件:
在这个例子中,我们将使用metasploit框架来创建一个我们可以在系统上植入的共享库。 首先在攻击者的主机上设置一个处理程序:
然后创建恶意库。由于我们正在利用第一个位置,操作系统将寻找一个共享库,我们可以模仿应用程序使用的任何库:
我已经使用msfvenom创建了一个共享库,其有效载荷与我的处理程序相同:
在易受攻击的主机上,创建了目录结构,并使库成为可写的:
一旦cronjob运行,恶意库就会被执行,在我们的metasploit控制台中,我们成功得到一个以root身份运行的shell会话:
我该如何防范呢?
作为系统管理员:
这种攻击归结为薄弱的文件权限,所以要确保低权限用户无法写入:
- 在RPATH或RUNPATH中指定的位置
- 在LD_RUN_PATH和LD_LIBRARY_PATH环境变量中指定的位置
- /lib或/usr/lib
- 在/etc/ld.so.conf中指定的位置
作为一名开发人员:
如果必须用RPATH或RUNPATH编译一个库,那么请指定该目录只有二进制所有者或root才能写入。或者指定$ORIGIN变量,该变量将在运行时解析到二进制文件的任何位置。
或者,可以将库移动到/lib或/ur/lib,然后使用chrpath工具从编译的二进制文件中删除RPATH或RUNPATH。
其他需要注意的事项:
- 用最小的权限执行应用程序。由Root调用的恶意二进制文件将导致对主机的完全损害。
- 考虑在/tmp分区上设置NOEXEC选项
本人英语水平不是很高,有误之处,还请指正。