地址:https://tryhackme.com/room/guidedpentestweb
通过从漏洞探测到服务器被完全攻破的整个过程,来学习 Web 应用渗透测试的技巧。
引言
假设你被聘为一名渗透测试员。你的客户运营着一个名为 RecruitX 的小型网络应用程序,这其实是一个内部招聘平台。在该平台上,招聘经理可以发布职位信息,求职者可以提交申请,而管理员则负责管理整个招聘流程。客户怀疑该应用程序存在安全问题,但不知道具体出在哪儿。你的任务就是找出这些问题。
这个模拟环境会全程指导你完成一次真实的 Web 应用程序渗透测试。你不会被丢进某个测试环境中,然后被要求“找出其中的漏洞”。相反,每个任务都会详细指导你完成测试的各个步骤,解释该做什么、为什么要这么做,以及需要注意什么。最终,你将从对目标系统一无所知的状态,逐步实现在该服务器上执行远程代码的目标。
学习目标
该合作过程遵循以下路径:
- 侦察与枚举——发现应用程序暴露的内容
- 不安全的直接对象引用IDOR——查看属于其他用户的数据
- 弱密码重置机制——利用有缺陷的重置流程来窃取账户控制权
- 管理面板访问权限——从普通用户升级为管理员
- 远程代码执行——利用管理权限在服务器上执行命令
每一个漏洞都是在前一步所收集的信息基础上产生的。这就是现实世界中的渗透测试方式:很少会有某个单一的、极其严重的漏洞存在。相反,各种较小的弱点会相互叠加,最终形成严重的安全问题。
先决条件
侦查与枚举
在开始使用该应用程序之前,我们先来了解一下自己所要处理的内容。在任何渗透测试中,第一步都是情报收集:在不做任何假设的前提下,尽可能多地收集关于目标系统的信息。如果你受雇去评估某栋建筑,你肯定不会不先查看建筑外观、检查门的情况、阅读指示牌就直接进入吧。同样的原则也适用于这里。
端口扫描
首先,让我们先了解一下目标系统上正在运行的服务有哪些。打开终端,然后运行 Nmap 扫描:
1 | ┌──(root㉿kali)-[~] |
我们可以看到四个开放的端口。端口 22 用于 SSH 连接,如果我们需要获取某些凭证的话,这个端口会非常有用。端口 80 上运行着基于 Apache 的 Web 应用程序。端口 3306 则用于连接 MySQL 数据库,这说明该应用程序在后台使用了 MySQL 数据库。端口 8080 则显示的是 Apache 的默认页面。这些信息非常重要:这意味着该应用程序很可能会使用 SQL 语句来处理数据,而任何输入处理上的漏洞都可能导致与 SQL 相关的问题。
探索其应用场景
打开浏览器,然后访问 http://10.48.188.32 。你应该会看到 RecruitX 的首页。在点击任何链接之前,请先仔细看看页面上的内容。你会看到一个导航栏,上面有“首页”、“职位招聘”、“登录”和“注册”等链接。页面底部还写着“RecruitX v2.4”。

让我们也来看看 HTTP 响应头信息吧:
1 | ┌──(root㉿kali)-[~] |
这些信息表明:该服务器运行的是 Apache 服务器,其版本为 2.4.58 。 PHPSESSID Cookie 则说明该服务器使用了 PHP 会话管理功能。由此可知,该服务器所使用的技术架构为:Apache + PHP + MySQL——典型的 LAMP 架构。
目录枚举
现在,让我们来看看在导航栏所显示的内容之外,还有哪些目录和文件存在。我们将使用 Gobuster 与常见的词汇列表来辅助查找。
1 | root@ip-10-48-169-6:~# gobuster dir -u http://10.48.188.32 -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -x php |
这一结果告诉我们很多信息。让我们来详细分析一下这些重要的发现:
/admin—— 虽然有管理面板,但点击后会跳转至登录页面。需要输入用户名和密码才能使用该管理面板。/api—— API 通常会以前端无法处理的方式来展示数据。/reset.php—— 密码重置页面。目前的密码重置机制往往存在安全漏洞。/uploads—— 用于上传文件的目录。如果我们能够将文件上传到这里,那么这里就有可能成为代码执行的路径。/profile.php和/dashboard.php——这些内容需要身份验证才能查看,因此我们必须先登录才能使用它们。
注册账户
有好几页内容需要身份验证。让我们使用账户登录,这样才能体验该应用的各种功能。请访问 http://10.48.188.32/login.php ,并使用以下信息进行登录:
- 电子邮件:[email protected]
- 密码:Password123
注意:您可以在 http://10.48.188.32/register.php 进行注册,从而使用其他任何账户。
登录后,该应用程序会将您重定向到 /dashboard.php 。现在,您会看到一个仪表板,上面显示着诸如 Open Positions 、 Total Applications 之类的信息,或者有 Browse Jobs 等选项。在浏览页面时,请务必记下 URL 地址,尤其是在查看自己的个人资料时。

探索API功能
早些时候,Gobuster 发现了一个 /api 端点。让我们来看看它提供了哪些功能/信息:
1 | root@ip-10-48-169-6:~# curl http://10.48.188.32/api/ |
该 API 详细列出了所有的接口端点。在正式应用中,这显然属于信息泄露的问题——未经授权的用户不应能够知晓这些内部 API 的路径。在继续下一步操作时,我们必须牢记这一点。

IDOR
既然我们已经建立了有效的会话连接,并且了解了该应用程序的结构,那我们就开始寻找其中的漏洞吧。在 Web 应用程序中,最常见却又最容易被忽视的漏洞之一,就是不安全的直接对象引用漏洞。
打个比方吧:你住在酒店里,而你的房间钥匙其实就是房间号 104。没有电子锁,也不需要任何验证手续,只要知道房间号就行了。那有什么能阻止你走到 105 号房间并打开门呢?什么都没有。这其实就是 IDOR 漏洞的实质:应用程序使用容易预测的标识符来标识各种对象(如用户资料、文档、订单等),却不去验证请求访问该对象的用户是否具有相应的权限。
寻找IDOR
以测试用户的身份登录后,点击仪表板右上角显示您用户名的按钮,进入您的个人资料页面。请仔细查看浏览器地址栏中的 URL 地址:
1 | http://10.48.188.32/profile.php?id=6 |
测试漏洞情况
让我们把 id 参数改为 1 ,看看会发生什么。你可以在浏览器中直接进行操作,或者使用 curl 来操作。在浏览器中,输入 URL http://10.48.188.32/profile.php?id=1 后,会得到如下结果:

提取 Cookie 信息:
在这个练习中,你需要使用会话 Cookie。你可以通过右键点击页面上的任意位置,然后选择“检查”来获取该 Cookie,操作方式如下所示:

转到 Storage 标签页,然后展开 Cookies 并选择 http://10.48.188.32 。你会看到所有 Cookie 的列表,找到 PHPSESSID Cookie 并复制其值。

我们也可以使用 curl ,这样就能清楚地知道返回了什么内容。请务必在 PHPSESSID= 后面的命令中包含您的会话 Cookie。
1 | root@ip-10-48-169-6:~# curl -s -b "PHPSESSID=pv9lg9d9g1pp422hssahr6gh11" "http://10.48.188.32/profile.php?id=1" | grep "fw-semibold" |
我们刚刚查看了用户 ID 为 1 的用户资料,该用户是管理员 Sarah Mitchell。该应用程序并未验证我们是否有权查看该用户的资料。它只是获取了 id 这个值,然后查询了数据库,最后返回了查询结果。
我们还要检查一下,之前发现的那个 API 端点是否也存在同样的问题。另外,也要看看是否根本不需要会话 Cookie 即可使用该 API 端点。
1 | root@ip-10-48-169-6:~# curl -s "http://10.48.188.32/api/user?id=1" |
该 API 提供的信息比网页上显示的还要详细。它返回包含用户姓名、电子邮件、角色以及账户创建日期的 JSON 数据。通过将 id 参数的值从 1 逐步增加到 5,我们可以列出系统中的所有用户。
为什么这很重要
IDOR 漏洞始终属于最常见的 Web 应用程序缺陷之一。出现这种漏洞的原因是,开发人员假设用户只会访问属于自己的资源。但一旦有人更改了 URL 参数,这一假设就不成立了。解决这个问题的方法很简单:服务器必须确认当前已认证的用户确实有权访问所请求的资源。但实际上,这种验证往往被忽视了。

弱密码重置
我们现在知道了该管理员的电子邮件地址: [email protected] 。我们的下一个目标就是接管她的账户。与其试图猜测她的密码(这可能需要很长时间,而且还可能导致账户被锁定),不如直接利用密码重置功能来解决问题。在网页应用中,密码重置功能往往是容易出问题的部分,因为其实现起来相当复杂,而开发者们往往选择走捷径来处理这个问题。
了解重置流程
请导航至 http://10.48.188.32/reset.php 。你会看到一个简单的表单,需要输入电子邮件地址。我们先用自己的账号来测试一下,以便了解其运作方式。请输入 [email protected] ,然后提交表单。

这是我们的第一个重要发现。在设计合理的应用程序中,重置令牌会被发送到用户的邮箱中,而不会显示在屏幕上。但这款应用程序却直接在响应结果中显示了该令牌。虽然仅凭这一点我们就可以重置自己的密码,但真正的问题是:该令牌究竟是如何被传递给用户的呢?
分析该令牌
让我们再生成一些令牌,然后试着找出其中的规律。请多次提交重置表格来获取属于自己的令牌,并把它们记录下来:
- 尝试1:878916
- 尝试2:461127
- 尝试3:178606
这些令牌都是六位数的数字。虽然它们看起来像是随机生成的,但实际上其取值范围是有限的:总共有 100 万种可能的数值(从 000000 到 999999)。可以说,这是一个“弱令牌空间”。不过,试图逐一尝试这 100 万种数值来破解令牌的密码,过程会相当缓慢。让我们再仔细看看,试着用管理员的电子邮件地址 [email protected] 来重置令牌吧。这样就能得到以下结果:

重置管理员密码
我们现在拥有所需要的一切了。让我们使用该令牌来重置 Sarah Mitchell 的密码吧。请访问重置密码的网址,系统会要求你输入新密码。

让我们用新密码登录来验证一下吧。

我们现在以管理员身份登录了系统。让我们先来梳理一下到目前为止所发生的流程:我们利用了 IDOR 漏洞来获取管理员的电子邮件地址,然后又利用了密码重置机制中的漏洞——该机制会导致令牌信息直接暴露在响应数据中。单独来看,这两种漏洞都无法让我们获得管理员权限。但当它们结合在一起时,就造成了严重的后果。
出了什么问题?
密码重置机制存在三个明显的缺陷:
- 作为响应而显示的令牌——该令牌应仅发送到账户所有者的邮箱中,绝不能在屏幕上显示。
- 令牌生成强度不足——六位数的数字令牌其可用密钥空间很小,因此很容易受到暴力攻击。
- 没有速率限制——该应用程序没有对重置请求的次数或令牌尝试的次数进行限制。

管理面板访问权限
我们现在以该应用程序的管理员 Sarah Mitchell 的身份登录了系统。在之前的检测过程中,Gobuster 发现了一个 /admin 路径,该路径会将未经身份验证的用户重定向到登录页面。既然我们现在拥有管理员权限,那就让我们来看看那扇“门”后面究竟有什么吧。
探索管理控制面板
请使用您以 Sarah Mitchell 身份登录的浏览器,访问 http://10.48.188.32/admin 。管理面板上有多个管理页面。其中大部分都是常规的管理功能,但有一个功能格外引人注目: /admin/upload.php 。对于管理员来说,文件上传功能是非常强大的工具;而从渗透测试人员的角度来看,这可能被利用来实现远程代码执行。

探究上传功能
让我们来看看上传页面。右键点击 Upload 按钮,然后选择 Inspect ,这样就可以查看客户端代码了:

我们可以注意到几个重要的细节。该表单表明它接受 PDF、DOCX 和图片文件作为上传格式。文件输入框上的 accept 属性虽然限制了可上传的文件类型,但这只是客户端层面的限制而已。实际上,浏览器会执行这一限制,但通过直接的 HTTP 请求,可以上传任何类型的文件。该页面还显示了文件的上传目的地: /uploads/documents/ 。
测试上传限制功能
让我们来测试一下服务器是否执行了文件类型限制。首先,我们会尝试上传一个无害的文本文件,看看应用程序会有怎样的反应。在 AttackBox 中,输入以下命令来创建一个文本文件:
1 | ┌──(root㉿kali)-[~] |
文件创建完成后,将其上传到管理面板中。进入上传页面后,右键点击文件输入框,然后选择“检查”。在 HTML 代码中,删除“accept”属性,这样浏览器就不再会限制文件类型了。接下来,直接选择并上传您的文件,从而绕过客户端的限制。

服务器拒绝了 .txt 文件。

所以,服务器端确实会进行一些验证。但这种验证的彻底性如何呢?我们来测试一下:服务器是只检查文件扩展名,还是同时检查文件内容。我们将使用以下命令来创建一个 PHP 文件:
1 | ┌──(root㉿kali)-[~] |
创建完成后,再尝试上传一次。结果还是被拒绝了。看来,该应用程序在检查文件的扩展名是否正确。
让我们再试一种常见的绕过方式,即使用 .phtml 扩展名。Apache 通常会将这种请求当作 PHP 请求来处理。
1 | ┌──(root㉿kali)-[~] |
.phtml 扩展已被接受。该应用程序的文件类型过滤器会阻止 .php 扩展的运行,但却没有考虑到其他 PHP 扩展。这是个常见的疏忽:开发人员会列出那些“危险”的扩展来阻止其运行,却忽略了那些不太常见的扩展,而服务器仍然会将其作为 PHP 扩展来处理。

让我们通过访问页面 http://10.48.188.32/uploads/documents/test.phtml 来确认我们上传的文件是否能够正常执行。

服务器执行了 PHP 代码并返回了输出结果。我们已经确认,可以在该服务器上上传和执行 PHP 文件。在接下来的步骤中,我们将利用这一功能来实现远程代码执行。

远程代码执行
我们已经确认,可以将 PHP 文件上传到服务器上,而且服务器也会执行这些文件。在渗透测试中,这一阶段是所有前期工作的最终成果。我们一开始什么都没有:没有登录凭证,也不了解该应用程序的运作方式。通过各种手段,比如枚举、利用 IDOR 漏洞、滥用密码重置功能以及获取管理员权限,我们终于能够在这台服务器上执行任意代码了。
创建一个webshell
webshell是一种小型脚本,它通过HTTP参数接收命令,并在服务器上执行这些命令。让我们来创建一个简单的webshell,将其保存为 shell.phtml 吧:
1 |
|
该脚本会检查 URL 中是否存在 cmd 参数。如果存在,该参数的值会被传递给 shell_exec() 。 shell_exec() 会在操作系统中执行相应的命令,并返回执行结果。请将文件上传到管理面板上的 http://10.48.188.32/admin/upload.php 位置。
执行命令
让我们通过运行一个简单的命令来确认代码确实能够被执行:
1 | ──(root㉿kali)-[~] |
我们遇到了远程代码执行的问题。这些命令是以 www-data 的权限来运行的,而 www-data 正是 Ubuntu 系统中 Apache Web 服务器的默认用户。让我们进一步了解有关该系统的更多信息吧:
1 | ┌──(root㉿kali)-[~] |
我们现在可以看到主机名、内核版本,还可以在系统上执行任何命令。
读取敏感文件
既然我们可以在服务器上读取文件,那么第一步就是检查那些记录了用户信息的系统文件。在 Linux 系统中, /etc/passwd 文件中包含了用户的各项基本信息。
1 | ┌──(root㉿kali)-[~] |
通过利用我们的网络 shell,我们成功进入了 /etc/passwd 系统,并获取了该系统的用户信息。在现实环境中,这样的访问权限足以让我们进一步获取配置文件中的信息,从而窃取数据库凭证,进而完全控制该应用程序的后端数据。
获取反向 shell
webshell虽然可以使用,但存在诸多限制:每个命令都需要通过单独的 HTTP 请求来发送,无法实现交互式操作。此外,包含特殊字符的复杂命令也很难通过 URL 参数来传递。让我们升级到更可靠的反向shell吧。
首先,在你的 AttackBox 上设置一个监听器:
1 | ┌──(root㉿kali)-[~] |
在另一个终端中,通过 webshell来触发反向 shell 程序。为了避免特殊字符带来的问题,我们需要对有效载荷进行 URL 编码处理:
1 | ┌──(root㉿kali)-[~] |
回到您的监听终端:
1 | ┌──(root㉿kali)-[~] |
现在,目标服务器上已经有了交互式 shell。通常情况下,渗透测试人员会利用这个 shell 来对系统进行进一步的检测和权限提升操作,不过这些内容超出了本次讨论的范围。
读取flag
为确认您已完成该任务,请阅读系统中的标记文件:
1 | www-data@recruitx-prod:/var/www/recruitx/uploads/documents$ cat /var/www/flag.txt |

攻击链
让我们退一步,回顾一下我们所经历的整个过程。在渗透测试报告中,需要详细记录所有的漏洞环节,向客户说明每个漏洞是如何共同导致整体安全问题的。以下就是我们的漏洞链条:
- 枚举:我们了解了该应用程序所使用的技术架构。Apache,PHP,MySQL,以及其目录结构,api端点、密码重置页面、一个上传目录和管理面板。
- IDOR:
/profile.php?id=参数和/api/user?id=端点让我们能够获取所有用户的详细信息,包括管理员的姓名和电子邮件地址。 - 弱密码重置功能:该重置机制会直接在 HTTP 响应中返回令牌,这样我们就可以为管理员生成新的令牌,并更改其密码。
- 管理面板访问权限的获取:利用被攻破的管理员账户,我们成功进入了管理面板。在那里,我们发现了一个用于上传文件的功能,但该功能的扩展名过滤列表并不完整。
- 远程代码执行:我们使用了
.phtml扩展名上传了一个 PHP 网络壳程序,从而绕过了过滤机制。这样一来,我们就能在服务器上执行命令了,同时也能获得建立完整反向 shell 的途径。
在这整个攻击链中,没有任何一个漏洞本身就能导致服务器被完全控制。IDOR 漏洞虽然泄露了用户信息,但并未提供直接访问服务器的权限。密码重置功能虽然可以被利用,但由于我们已经知道管理员的邮箱地址,这一漏洞也就无足轻重了。上传过滤功能也有被绕过的风险,但我们需要管理员的凭证才能利用这一漏洞。正是这些漏洞的结合,才导致了服务器被完全控制。
补救措施总结
如果您要为这项工作撰写报告,那么对于每一项发现,您都应该提出相应的改进措施:


结论
在这个房间里,我们完整地体验了一次网络应用程序渗透测试的整个过程:从最初的 Nmap 扫描,到在目标服务器上实现远程代码执行。在整个过程中,你学会了区分优秀渗透测试员与普通测试员的必备素质:耐心、观察力,以及将应用程序各部分之间的信息联系起来的能力。
让我们总结一下这次互动中的关键要点:
- 枚举是关键所在。我们能够发现那些漏洞,是因为在尝试利用这些漏洞之前,我们先花了时间来了解该应用程序的结构、请求头信息、端点以及其行为模式。
- 小的缺陷会累积成严重的问题。这里没有任何一个问题是特别复杂或难以解决的。IDOR、弱密码重置、上传绕过等漏洞都是众所周知的安全隐患。这些漏洞的威胁性在于它们之间的相互关联方式。
- 客户端的限制措施并不能真正起到安全作用。在文件上传表单中,
accept属性被用来限制浏览器可以上传的文件类型。而在服务器端,虽然使用了阻止列表来限制文件类型,但却遗漏了某些其他类型的文件。 - 密码重置机制需要格外重视。要确保其安全性,实现起来相当复杂。哪怕只有一个设计上的缺陷,比如在响应中泄露了令牌信息,都可能导致账户被窃取。
- 要像攻击者那样思考,像顾问那样汇报。找出漏洞只是工作的一半而已。真正能让这项工作对客户有价值的是:以清晰的格式记录这些漏洞,同时标明其严重程度,并给出可行的修复建议。
您已经完成了指导式的渗透测试。现在是时候将所学的知识应用到即将面临的挑战中了。