Linux权限提升实战:从系统枚举到提权路径
2026/9/9 21:07:05 网站建设 项目流程

说个真实经历。我刚开始练OSCP实验室的时候,拿到一个Linux靶机的普通用户shell,第一反应是查内核版本然后去搜exploit,结果编译了半天,要么目标打了补丁,要么直接跑崩了,白白浪费几个小时。后来老手一句话点醒我:权限提升的大头在枚举,不在exp。你要先知道这台机器上藏了什么能用的东西,再判断走哪条路。哪怕你在考试里不靠内核漏洞,靠配置错误、计划任务、SUID、sudo权限这些路径也完全能拿到root。而这一切的起点,就是系统枚举。

这篇文章是Linux权限提升系列的第一篇,核心讲手动枚举。内容面向正在备考OSCP、或者在实战中拿到shell后不知道从哪下手的同学。枚举不是让你把每个命令都敲一遍就完事,而是要明白每一条输出背后的含义,以及它对你提权有什么帮助。下面我按实际渗透的推进顺序,把系统枚举这件事拆透。

1. 系统枚举在权限提升中的定位

1.1 为什么枚举必须排在第一位

权限提升的本质,是回答三个问题:这台机器是什么系统、上面跑着什么东西、有哪些配置错误可以被我利用。枚举就是在回答前两个问题,同时为第三个问题提供线索。很多人忽略的是,枚举本身风险极低,而直接打内核exp风险极高——一旦失败,轻则提权无效,重则机器崩溃,等于把入口也搞丢了。

在OSCP考试中,我见过太多人栽在“不做枚举就冲exp”上面。考试限时内,刷内核exp的性价比其实很差,因为你要判断内核版本、编译环境、防御机制,还要赌漏洞一定能利用成功。相比之下,通过枚举找到一条配置错误的路径,往往会稳得多。真正高效的提权思路是:先花几分钟把系统的关键信息摸清楚,筛选出3到5条高价值路径,再逐一验证。这样即使某条路径不通,你还有备选方案,不会卡死在一个点上。

1.2 手动枚举和自动化脚本怎么选

自动化工具很诱人,但我的建议是:先手动,后工具。原因很简单,手动命令能让你理解系统结构,自动化脚本只是把结果汇总。你如果不知道自己找什么,工具输出的几百行结果对你来说就是一堆噪音。而且很多自动化脚本在目标机上跑起来动静很大,写入临时文件、占用CPU,在真实场景里容易引起注意。

反过来讲,等到你手动摸了一遍底之后,再用LinPEAS或LinEnum做一次全面扫描,作为查漏补缺,两者结合效果最好。OSCP考试里我一般是先手动敲5分钟关键命令,心里有数了,再挂一个自动脚本慢慢跑,同时去分析已经拿到的信息。这样既不浪费时间,也不会盲信工具的完整性。记住,自动化工具的输出也有遗漏,手动排查才是底线。

2. 系统与内核信息枚举

2.1 内核版本与发行版信息收集

拿到shell第一步,确认你所在的系统环境。基础命令就是这几条:

uname -a cat /etc/os-release cat /etc/issue lsb_release -a 2>/dev/null

uname -a 输出的内核版本,是后续判断内核漏洞可能性的关键依据。比如你看到内核是 4.4.0,发行版是 Ubuntu 16.04,那你心里就要有数:这机器年代比较久,可能存在与内核版本相关的已知漏洞。但注意,知道版本只是起点,还要看补丁打了多少,这是后话。

发行版信息也很重要。Debian/Ubuntu 用 apt,CentOS/RHEL 用 yum,不同包管理器会对后续你能拿到的工具链产生影响。还有系统架构,x86_64和ARM的exp是不同的,如果目标机是ARM架构,很多现成的exp编译都过不了,你得调整策略。真遇到过嵌入式Linux的设备,uname -a能看到armv7l,那你基本可以放弃内核exp路线了,转而排查配置错误更现实。

2.2 防御机制与漏洞可行性判断

知道内核版本后,别急着搜exp,先检查系统的防御机制。现在的Linux内核普遍开启了各种安全特性,比如SMEP、SMAP、KASLR,这些都会直接影响内核exp能否成功。查看方式:

cat /proc/cmdline cat /proc/cpuinfo | grep -E "smep|smap" zcat /proc/config.gz 2>/dev/null | grep -E "CONFIG_RANDOMIZE_BASE|CONFIG_SMEP|CONFIG_SMAP"

如果 /proc/cmdline 里能看到 smep、smap 这些字样,说明内核启用了用户态与内核态的隔离机制,很多老式内核exp直接失效。同样,KASLR开启后,固定的内核地址不再可靠,exp需要额外绕过,复杂度提升一个量级。

我在实际评估中,如果看到一台机器开着SMEP+SMAP+KASLR,基本就不会在内核漏洞上花太多时间了。找到一个能用的POC代价太高,而且不稳定,把精力转向sudo、SUID、计划任务这些配置层面,成功率反而高。OSCP考试说到底不是搞内核研究,你更需要的是找到一条能在合理时间内走通的提权路径。

2.3 环境变量、主机名与系统状态

系统状态里藏着容易被忽略的信息。几条基本命令:

hostname id env uptime date

hostname 输出往往暴露机器角色,比如web01、dc01、backup-server,你拿到主机名就能推断这台机器在目标网络里的定位,后续横向移动的方向也就清楚了。env 看环境变量,有时里面就有数据库连接串、API key之类的敏感信息,虽然不常见,但看到就赚到。

uptime 看系统运行了多久,date 看当前时间。这两个信息结合起来,配合接下来的计划任务枚举,能帮你判断系统是否刚重启过、计划任务是否在执行。如果系统刚重启,说明管理员近期维护过系统,补丁可能比较新,内核漏洞路径的可行性进一步降低,你要有心理准备。

3. 用户、权限与可写文件枚举

3.1 当前用户身份与sudo权限

权限提升的核心,是搞清楚你当前有多少权限、能通过什么方式扩大权限。先看三条:

id whoami sudo -l

id 输出你的uid、gid和所属组,这是判断你权限边界的基础。如果你在docker组里,直接就能走docker组提权路径;如果你在disk组,可以用debugfs读取磁盘文件,包括shadow。whoami 只是快速确认身份,但id信息量更大,养成习惯优先看id。

sudo -l 可以说是OSCP考试里最常考的提权入口。如果输出显示某个用户可以在目标机上以root身份执行某个命令或脚本,那这条路就非常清晰了。比如输出显示你可以在root下运行 /usr/bin/vim,那就用GTFOBins里vim的提权方式,直接进入root shell。如果sudo -l要求输入密码,先试密码复用——很多环境里用户的ssh密码和sudo密码是同一个,尤其是有web后台拿到的shell,配置里的数据库密码也可能被复用为系统密码。

3.2 系统用户、分组与登录用户信息

确认你自己是谁之后,再看看整个系统里都有谁。查看方式:

cat /etc/passwd cat /etc/group ls -la /home/ lastlog w

cat /etc/passwd 的重点不是逐行看所有用户,而是筛选出有shell的用户。如果 /home 下面有多个用户目录,说明系统上有多个真实登录用户,这些用户的密码可能在配置文件或历史记录里存在,是横向移动的潜在目标。有些老系统还会在 /etc/passwd 里直接暴露密码哈希(x表示存储在shadow里,如果字段直接是哈希串就发财了),属于极少数情况,但值得扫一眼。

/etc/group 里的敏感组记得标记:docker组、sudo组、adm组、disk组。docker组提权的方法是挂载宿主机根目录到容器,然后直接读写宿主机的shadow文件,这个必须烂熟于心。adm组成员可以读 /var/log 下的日志,日志里偶尔会有其他用户在终端里输错密码的记录。w 和 lastlog 看当前登录用户和最近登录记录,可以了解这台机器是否活跃,判断管理员什么时候会上线,同时避免在提权过程中撞上管理员。

3.3 可写文件与敏感配置

低权限用户常常拥有对某些系统文件的写权限,这是典型的配置错误。查找可写文件:

find / -writable -type f 2>/dev/null | grep -vE "^/proc|^/sys|^/tmp" find / -writable -type d 2>/dev/null | grep -vE "^/proc|^/sys"

为什么排除 /tmp?因为 /tmp 默认全世界可写,但单纯在 /tmp 里写文件并不能直接提权,除非配合其他漏洞(比如root的计划任务执行 /tmp 下的脚本)。真正有价值的是 /etc 目录下的可写文件,比如 /etc/passwd 或 /etc/shadow 如果可写,你可以直接添加一个新root用户,或者清空root密码。还有 /etc/cron.d/ 下的任务文件如果可写,也能插入自己的计划任务。

另外,重点检查web目录(如 /var/www/html),很多应用会把数据库密码写死在配置文件里。虽然这不直接是系统枚举的内容,但和文件权限检查是同一阶段的工作。检查 /etc/shadow 是否可读、/home/*/.ssh/authorized_keys 是否可写,这些都能快速形成提权或持久化路径。真实案例里,遇到过 /home/user/.ssh/authorized_keys 对当前用户可写的情况,直接写入自己的公钥,后面用ssh登录比反弹shell稳得多。

4. 网络、服务与挂载点枚举

4.1 网络接口、路由与DNS配置

拿到shell后,网络信息决定了你是否需要横向移动。基本命令:

ip addr ip route cat /etc/resolv.conf cat /etc/hosts

ip addr 看网卡数量和IP段。如果发现除了当前网段之外还有另一个内网段,说明这台机器是双网卡,它在目标内网里可能承担着更重要的角色,后续横向移动就要从这里展开。ip route 看默认路由,判断这台机器是不是网关角色。DNS配置如果指向一个内网IP,说明网络里可能有域控,这台机器很可能是域内成员,后续的枚举方向要朝着域环境调整。

/etc/hosts 也值得看,有时候管理员会把常见主机名和IP手动写进去,等于给你提供了一份内网主机清单。OSCP考试里的环境多以独立靶机为主,但同样会存在双网卡的情况,认真看网络配置能帮你找到通往下一台机器的路径。

4.2 监听端口与服务分析

知道网络拓扑后,看看这台机器自己对外开放了什么服务。命令:

ss -tlnp 2>/dev/null || netstat -tlnp ps aux | grep -vE "\[.*\]" | head -50

监听端口的重点是发现非标准端口和未知服务。如果看到某个高端口在监听,而且这个服务是root权限启动的,这就可能是突破口。特别是老旧服务、自带Web管理界面的服务,经常存在未授权访问或已知漏洞。举个例子,发现8080端口跑的是一个老版本Jenkins,而Jenkins是以root身份运行的,那你就可以先拿到Jenkins执行命令的权限,再用root权限做后续操作。

ps aux 看进程列表,能帮你把端口和服务对应起来。注意看进程是以什么用户身份运行的,如果MySQL、Nginx这些服务是root启动,一旦服务本身存在代码执行漏洞,你拿到的就是root权限。这个过程里,目标机上存在哪些不常见的进程(比如备份脚本、自定义daemon),往往比标准服务更有价值。

4.3 挂载点与NFS共享检查

文件系统挂载和网络共享也可能指向提权路径。查看方式:

mount -l cat /etc/fstab showmount -e 2>/dev/null

mount -l 看当前挂载的文件系统,重点看有没有带 noexec、nosuid、nodev 之外的异常挂载,以及有没有临时挂载的目录。特别是 /tmp、/dev/shm 如果被单独挂载且没有 noexec,你之后传脚本上去执行就没有障碍。如果 /tmp 是noexec,但 /dev/shm 可执行,那你在目标机上跑自动化工具时就要把脚本放到 /dev/shm。

/etc/fstab 看开机自动挂载,里面有时会出现包含credentials文件的CIFS挂载,credential文件里保存的是共享访问凭据。如果这个文件对当前用户可读,你就能拿到一个内网账号。showmount 看NFS共享,如果共享目录配置了no_root_squash,你在攻击机上mount过去,创建一个setuid root二进制,再回到目标机上执行,直接获得root权限。这条路径在OSCP考试里也出现过,值得每次枚举时都顺手查一下。

5. 计划任务、SUID与特权文件枚举

5.1 计划任务逐一排查

计划任务是Linux提权的高频路径,因为管理员经常写脚本来自动化备份、清理日志,而这些脚本常常存在可写或路径可劫持的问题。排查命令:

crontab -l crontab -u root -l 2>/dev/null cat /etc/crontab ls -la /etc/cron.d/ ls -la /etc/cron.hourly/ /etc/cron.daily/ /etc/cron.weekly/ /etc/cron.monthly/ systemctl list-timers 2>/dev/null

看到计划任务列表后,先判断哪些是以root身份运行的,然后去看对应脚本的权限。如果脚本是root运行,但普通用户能修改脚本内容,那就直接改写脚本,加入反弹shell命令,等待root执行即可。整个过程要快,因为计划任务可能只在特定时间执行,你要么等,要么用篡改脚本的方式让命令在下次执行时生效。

还有一个容易忽略的点是PATH劫持。有些计划任务脚本内部调用了外部命令,比如 tar、python,但脚本里写的是相对路径,而管理员没有设置安全的PATH环境变量,那你有机会在可写的目录里放置一个同名恶意文件,让计划任务执行你的脚本。实际排查时要看脚本内容,而不仅仅是脚本是否存在。

5.2 SUID/SGID文件搜索与利用

SUID是Linux里最经典的提权漏洞点。目标程序以文件所有者的权限运行,如果所有者是root,而程序本身可被利用来执行命令,那你就能以root权限执行任意命令。查找命令:

find / -perm -4000 -type f 2>/dev/null find / -perm -2000 -type f 2>/dev/null

拿到SUID文件列表后,先排除常规的passwd、su、mount等,这些虽然带SUID但本身没有提供提权功能。真正危险的是python、perl、ruby、env、find、vim、bash、nmap这些带SUID的程序,它们具备执行外部命令或读取文件的能力。逐项对照GTFOBins,比如 /usr/bin/find 带SUID,直接执行 find / -exec whoami ; 验证是不是root,是的话用 find / -exec sh -p ; 进入root shell。

注意bash的-p参数是保留真实uid的关键。普通用户执行sh不会保留SUID权限,但带-p参数时,sh会以真实uid运行,这样SUID才能生效。这个细节很多人会忽略,直接在GTFOBins里抄命令,结果发现弹出的是普通用户shell,其实就是少了-p参数。

5.3 capabilities特权和特殊权限

除了SUID,现代Linux系统越来越多地用capabilities来分配特权,这也是枚举时不能漏掉的一环。查找命令:

getcap -r / 2>/dev/null

重点关注cap_setuid和cap_setgid。比如 /usr/bin/python3 带有 cap_setuid,你就可以用一行脚本把进程的uid设置为0:

python3 -c "import os; os.setuid(0); os.system('/bin/bash')"

capabilities的存在是因为有些管理员觉得给程序加SUID权限太粗暴,改用setcap来精确分配能力,但配置不当造成的提权路径和SUID一模一样。我在靶机上遇到过 /usr/bin/tar 带cap_dac_read_search的情况,这意味着可以绕过文件读权限检查,直接读 /etc/shadow。如果你的SUID列表里没找到突破口,一定要看看capabilities。

6. 日志、历史与隐藏信息

6.1 bash历史记录与vim信息

用户的历史记录里藏着大量敏感信息,是低权限枚举里最容易捡漏的地方。查看命令:

cat ~/.bash_history 2>/dev/null cat /home/*/.bash_history 2>/dev/null cat /root/.bash_history 2>/dev/null ls -la /home/*/.viminfo 2>/dev/null

管理员在配置服务器时,经常直接在命令行里输密码,比如 mysql -u root -p'password'、su - 之后跟密码、sshpass -p 'xxx'。如果你能读到root的bash历史,基本等于拿到了账户密码。即使读不到root的历史,普通用户的历史里也可能包含数据库口令,可以通过密码复用尝试sudo。

.viminfo记录了vim的编辑历史和搜索历史,能看到曾打开过的文件路径和搜索过的字符串,这些路径能指引你去看哪些敏感文件。如果用户用vim打开过某个配置文件,里面很可能有密码,那这个文件就值得深入检查。

6.2 配置文件中的硬编码密码

系统里到处是配置文件,密码硬编码的情况非常普遍。常用搜索命令:

grep -rniE "password|passwd|pwd|secret|token" /etc/ 2>/dev/null grep -rniE "password|passwd|pwd|secret|token" /var/www/ 2>/dev/null find / -name "*.conf" -o -name "*.config" -o -name "*.env" 2>/dev/null | xargs grep -niE "password" 2>/dev/null

注意覆盖面要广,包括web目录下的wp-config.php、config.php、.env、settings.py这些文件。拿到数据库密码后,优先尝试复用:root用户密码、其他系统用户密码、数据库密码,有很大概率是同一个。SSL证书的私钥、SSH的id_rsa私钥也属于高价值文件,找到后可以直接用来ssh登录。

隐藏文件也值得扫一眼,用 ls -la 就能看到。有些管理员会把备份文件放在当前目录,比如config.php.bak、db.sql,文件名不起眼但内容非常敏感。这类备份文件经常是老的配置,里面可能有不同的密码,甚至没有修改过的默认密码。

6.3 临时目录、备份文件与敏感数据

/tmp、/var/tmp、/var/backups 这几个目录值得仔细翻。查看命令:

ls -la /tmp/ /var/tmp/ /var/backups/ /var/log/ find /var/backups -type f 2>/dev/null find / -name "*.bak" -o -name "*.old" -o -name "*backup*" 2>/dev/null | grep -v "^/proc"

/var/backups 下面经常有系统的备份文件,比如shadow.bak、passwd.bak。如果这些文件可读,直接看是否包含密码哈希。有些系统还会做passwd和shadow的定期备份,权限配置不当导致普通用户可读,这就是一条直达root的路径。

日志文件也值得检查。/var/log/auth.log 里能看到ssh登录记录,可能存在密码尝试记录。/var/log/mysql/ 或其他应用日志里可能记录了SQL查询,包含敏感数据。如果管理员配置了应用日志级别为debug,那里面可能记录了大量环境变量、请求参数,甚至明文密码。日志看完了,结合历史记录,已经把这台机器上最有价值的信息挖得差不多了。

7. 自动化枚举工具与手动命令的组合

7.1 三款主流脚本实测对比

手动枚举掌握之后,自动化工具是提升效率的利器。我常用的三款是LinEnum、LinPEAS和Linux Smart Enumeration,各有优劣:

工具输出风格运行依赖适用场景
LinEnum结构清晰,按段输出bash,依赖较少快速摸底,结果便于人工阅读
LinPEAS彩色高亮,按风险等级标记bash + 可选python/perl全面扫描,高亮风险项,最适合OSCP阶段
Linux Smart Enumeration (LSE)分级别,从低危到高危逐级运行bash老旧系统、精简系统、资源受限环境

LinPEAS虽然输出冗长,但它把提权相关的条目用颜色标了出来,适合查漏补缺。不过它的输出越多,越容易让人迷失,你必须有手动枚举的基础,才能从一堆结果中筛选出真正有价值的信息。LSE的好处是它按级别执行,连bash版本太老的情况都考虑到了,适合目标机是一些精简的嵌入式系统。

7.2 手动编辑枚举脚本的思路

推荐的做法是把常用命令串成一个脚本,每次拿shell后先跑一遍,这样既能保证不漏项,也方便快速记录。脚本不一定要写得复杂,把上面提到的命令按类别组织好,输出重定向到文件,再逐段分析。我自己整理的脚本大概分四段:系统信息、用户权限、网络服务、文件搜索。每段之间加分隔符,后续分析时定位更快。

自动化工具跑完后的关键动作,是去验证而不是盲信。比如LinPEAS标红了某个用户的计划任务,你还要去手动确认这个计划任务是否存在、脚本是否真的可写、执行时间是什么时候。工具只是帮你把候选清单拉出来,最终的利用还是要靠手动验证。这个习惯能避免你在考试中走弯路,因为工具高亮的内容不一定都能利用,而工具没标红的东西也可能被忽略。

8. 常见问题与排查技巧实录

8.1 常见问题速查表

症状可能原因排查方向
find 输出大量Permission denied普通用户权限不足加 2>/dev/null 过滤,或用 -readable 选项只显示可读文件
ss 或 netstat 命令不存在目标系统精简或使用busybox用 cat /proc/net/tcp 查看端口,或检查 /bin/busybox
sudo -l 要求输入密码且不知道密码当前用户无免密sudo权限尝试密码复用,或从配置文件/历史记录找突破口
LinPEAS/LinEnum 运行失败/tmp 挂载为noexec,或缺少依赖先看挂载选项,改用 /dev/shm 或 /var/tmp 执行脚本
SUID文件列表里程序无法利用程序本身不含可执行命令功能对照GTFOBins逐项验证,不要凭文件名臆断
内核exp编译失败缺少gcc/make,或版本不匹配检查编译环境,考虑换静态编译版本,或者放弃内核路径
计划任务脚本内容无法修改文件属主是root且无写权限检查脚本调用的命令是否在可写目录中,尝试PATH劫持
找不到任何可写文件当前用户权限极低扩大搜索范围到/tmp、/var/tmp,检查是否可写登录用户的.ssh目录

8.2 实测踩坑记录

第一个坑是/bin/sh 和 /bin/bash 的行为差异。用SUID的sh提权时,如果不小心用成 /bin/sh 而没有加-p参数,只会得到一个普通shell,白忙一场。Ubuntu的 /bin/sh 是dash,表现得和bash不一样,用GTFOBins的命令时要看清楚目标系统默认的shell。

第二个坑是find命令的括号语法。执行 find / -perm -4000 -type f,后面的2>/dev/null不能省,不然输出会被一堆权限报错淹没。还有一个细节是 -perm -4000 和 -perm 4000 的区别,前者表示权限位中包含setuid即可,后者要求精确匹配。搜索SUID时用 -perm -4000 更合适,因为二进制文件可能同时还有其他权限位。

第三个坑是计划任务实际执行时间不确定。检查到可写脚本后,脚本可能每小时、每天才执行一次,等待的时间容易被忽略。我遇到过写好了payload但迟迟不触发的情况,后来发现目标机在特定时间才执行任务,中间隔了几个小时。为了避免干等,可以同时准备其他提权路径,不要把所有希望寄托在计划任务上。

最后提醒一下,枚举输出一定要记录下来。用脚本跑完后把结果保存到本地,或者自己复制粘贴到笔记里,方便后续反复查看。提权卡住的时候,回头看枚举输出的细节,往往能找到之前没发现的线索。这一点在考试里非常重要——时间不是用来反复跑同样命令的,而是用来深度分析已有信息的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询