# Nginx

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS红队专家）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>

<figure><img src="/files/LVZ3PLDyldGi3gva0h7n" alt=""><figcaption></figcaption></figure>

**即时提供的漏洞评估和渗透测试设置**。从任何地方运行完整的渗透测试，拥有20多种工具和功能，从侦察到报告。我们不取代渗透测试人员 - 我们开发定制工具、检测和利用模块，让他们有更多时间深入挖掘、弹出shell并享受乐趣。

{% embed url="<https://pentest-tools.com/>" %}

## 缺少根位置 <a href="#missing-root-location" id="missing-root-location"></a>

在配置Nginx服务器时，**root指令**起着关键作用，定义了文件提供服务的基本目录。请考虑下面的示例：

```bash
server {
root /etc/nginx;

location /hello.txt {
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8080/;
}
}
```

在这个配置中，`/etc/nginx` 被指定为根目录。这种设置允许访问指定根目录内的文件，比如 `/hello.txt`。然而，需要注意的是只定义了一个特定位置 (`/hello.txt`)，并没有为根位置 (`location / {...}`) 进行配置。这个遗漏意味着根指令适用于全局，使得对根路径 `/` 的请求可以访问 `/etc/nginx` 下的文件。

这个配置带来了一个关键的安全考虑。一个简单的 `GET` 请求，比如 `GET /nginx.conf`，可能通过提供位于 `/etc/nginx/nginx.conf` 的 Nginx 配置文件来暴露敏感信息。将根目录设置为一个不太敏感的目录，比如 `/etc`，可以减轻这个风险，但仍可能允许意外访问其他关键文件，包括其他配置文件、访问日志，甚至用于 HTTP 基本认证的加密凭据。

## 别名 LFI 配置错误 <a href="#alias-lfi-misconfiguration" id="alias-lfi-misconfiguration"></a>

在 Nginx 的配置文件中，需要仔细检查 "location" 指令。一个称为本地文件包含 (LFI) 的漏洞可能会通过类似以下配置而被无意中引入：

```
location /imgs {
alias /path/images/;
}
```

这种配置容易受到LFI攻击的影响，因为服务器会将诸如`/imgs../flag.txt`这样的请求解释为试图访问目标目录之外的文件，最终解析为`/path/images/../flag.txt`。这个漏洞允许攻击者从服务器的文件系统中检索文件，这些文件本不应通过网络访问。

为了减轻这种漏洞，应调整配置为：

```
location /imgs/ {
alias /path/images/;
}
```

更多信息: <https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misconfigured-nginx-alias/>

Accunetix 测试:

```
alias../ => HTTP status code 403
alias.../ => HTTP status code 404
alias../../ => HTTP status code 403
alias../../../../../../../../../../../ => HTTP status code 400
alias../ => HTTP status code 403
```

## 不安全的路径限制 <a href="#unsafe-variable-use" id="unsafe-variable-use"></a>

查看以下页面以了解如何绕过诸如以下指令：

```plaintext
location = /admin {
deny all;
}

location = /admin/ {
deny all;
}
```

## 不安全的变量使用 / HTTP请求拆分 <a href="#unsafe-variable-use" id="unsafe-variable-use"></a>

{% hint style="danger" %}
易受攻击的变量 `$uri` 和 `$document_uri`，可以通过将它们替换为 `$request_uri` 来修复。

正则表达式也可能存在漏洞，例如：

`location ~ /docs/([^/])? { … $1 … }` - 易受攻击

`location ~ /docs/([^/\s])? { … $1 … }` - 不易受攻击（检查空格）

`location ~ /docs/(.*)? { … $1 … }` - 不易受攻击
{% endhint %}

以下示例演示了Nginx配置中的一个漏洞：

```
location / {
return 302 https://example.com$uri;
}
```

字符 \r (回车) 和 \n (换行) 表示 HTTP 请求中的换行字符，它们的 URL 编码形式表示为 `%0d%0a`。在请求中包含这些字符 (例如，`http://localhost/%0d%0aDetectify:%20clrf`) 发送到配置错误的服务器会导致服务器发出一个名为 `Detectify` 的新标头。这是因为 $uri 变量解码 URL 编码的换行字符，导致响应中出现意外的标头：

```
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.19.3
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: https://example.com/
Detectify: clrf
```

了解更多关于CRLF注入和响应拆分的风险，请访问<https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/>.

此技术也在[**这个讲座中得到解释**](https://www.youtube.com/watch?v=gWQyWdZbdoY\&list=PL0xCSYnG_iTtJe2V6PQqamBF73n7-f1Nr\&index=77)，其中提供了一些易受攻击的示例和检测机制。例如，为了从黑盒角度检测此错误配置，您可以使用以下请求：

* `https://example.com/%20X` - 任何HTTP代码
* `https://example.com/%20H` - 400 Bad Request

如果存在漏洞，第一个请求将返回为"X"，因为"X"是任何HTTP方法，而第二个请求将返回错误，因为"H"不是有效的方法。因此，服务器将接收类似于：`GET / H HTTP/1.1`，从而触发错误。

其他检测示例包括：

* `http://company.tld/%20HTTP/1.1%0D%0AXXXX:%20x` - 任何HTTP代码
* `http://company.tld/%20HTTP/1.1%0D%0AHost:%20x` - 400 Bad Request

在该讲座中发现的一些易受攻击的配置包括：

* 请注意\*\*`$uri`\*\*是如何设置为最终URL中的内容。

```
location ^~ /lite/api/ {
proxy_pass http://lite-backend$uri$is_args$args;
}
```

* 请注意再次在 URL 中 **`$uri`** 出现（这次是作为参数的一部分）

```
location ~ ^/dna/payment {
rewrite ^/dna/([^/]+) /registered/main.pl?cmd=unifiedPayment&context=$1&native_uri=$uri break;
proxy_pass http://$back;
```

* 现在在 AWS S3

```
location /s3/ {
proxy_pass https://company-bucket.s3.amazonaws.com$uri;
}
```

### 任意变量

发现在某些情况下，**用户提供的数据**可能被视为**Nginx变量**。这种行为的原因仍然有些难以捉摸，但并不罕见，也不容易验证。这一异常在HackerOne的一份安全报告中得到了突出，可以在[这里](https://hackerone.com/reports/370094)查看。对错误消息的进一步调查导致在[Nginx代码库的SSI过滤模块](https://github.com/nginx/nginx/blob/2187586207e1465d289ae64cedc829719a048a39/src/http/modules/ngx_http_ssi_filter_module.c#L365)中确定了其发生，将服务器端包含（SSI）识别为根本原因。

为了**检测这种错误配置**，可以执行以下命令，其中涉及设置一个referer头来测试变量打印：

```bash
$ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’
```

系统中对此错误配置的扫描显示，有多个实例允许用户打印Nginx变量。然而，易受攻击实例数量的减少表明修补此问题的努力在某种程度上取得了成功。

## 后端原始响应读取

Nginx通过`proxy_pass`提供了一个功能，允许拦截后端产生的错误和HTTP标头，旨在隐藏内部错误消息和标头。这是通过Nginx在响应后端错误时提供自定义错误页面来实现的。然而，当Nginx遇到无效的HTTP请求时就会出现挑战。这样的请求会像接收到的那样转发到后端，然后后端的原始响应将直接发送给客户端，而不经过Nginx的干预。

考虑涉及uWSGI应用程序的示例场景：

```python
def application(environ, start_response):
start_response('500 Error', [('Content-Type', 'text/html'), ('Secret-Header', 'secret-info')])
return [b"Secret info, should not be visible!"]
```

为了管理这个，Nginx 配置中使用特定指令：

```
http {
error_page 500 /html/error.html;
proxy_intercept_errors on;
proxy_hide_header Secret-Header;
}
```

* [**proxy\_intercept\_errors**](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors): 该指令使Nginx能够为后端响应的状态码大于300的情况提供自定义响应。它确保对于我们的示例uWSGI应用程序，`500错误`响应会被Nginx拦截并处理。
* [**proxy\_hide\_header**](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_hide_header): 正如其名称所示，该指令会从客户端隐藏指定的HTTP头，增强隐私和安全性。

当发出有效的`GET`请求时，Nginx会正常处理它，返回标准错误响应而不会透露任何秘密头信息。然而，无效的HTTP请求会绕过此机制，导致原始后端响应的暴露，包括秘密头信息和错误消息。

## merge\_slashes设置为off

默认情况下，Nginx的\*\*`merge_slashes`指令**被设置为**`on`**，它会将URL中的多个斜杠压缩为单个斜杠。这个特性虽然简化了URL处理，但可能会意外地掩盖Nginx后面的应用程序中的漏洞，特别是那些容易受到本地文件包含（LFI）攻击的应用程序。安全专家**Danny Robinson和Rotem Bar\*\*已经强调了与这种默认行为相关的潜在风险，特别是当Nginx充当反向代理时。

为了减轻这种风险，建议**关闭`merge_slashes`指令**，以保护容易受到这些漏洞影响的应用程序。这样可以确保Nginx将请求转发给应用程序而不会改变URL结构，从而不掩盖任何潜在的安全问题。

有关更多信息，请查看[Danny Robinson和Rotem Bar](https://medium.com/appsflyer/nginx-may-be-protecting-your-applications-from-traversal-attacks-without-you-even-knowing-b08f882fd43d)。

### **恶意响应头**

如[**此文**](https://mizu.re/post/cors-playground)所示，如果Web服务器的响应中存在某些头信息，它们将改变Nginx代理的行为。您可以在[**文档**](https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/)中查看它们：

* `X-Accel-Redirect`：指示Nginx内部重定向到指定位置。
* `X-Accel-Buffering`：控制Nginx是否应该缓冲响应。
* `X-Accel-Charset`：在使用X-Accel-Redirect时设置响应的字符集。
* `X-Accel-Expires`：在使用X-Accel-Redirect时设置响应的过期时间。
* `X-Accel-Limit-Rate`：在使用X-Accel-Redirect时限制响应的传输速率。

例如，头部\*\*`X-Accel-Redirect`**会在Nginx中引起内部**重定向\*\*。因此，如果nginx配置中有类似\*\*`root /`**的内容，而来自Web服务器的响应中包含**`X-Accel-Redirect: .env`**，将导致nginx发送**`/.env`\*\*的内容（路径遍历）。

### **Map指令中的默认值**

在**Nginx配置**中，`map`指令通常在**授权控制**中发挥作用。一个常见的错误是没有指定**默认**值，这可能导致未经授权的访问。例如：

```yaml
http {
map $uri $mappocallow {
/map-poc/private 0;
/map-poc/secret 0;
/map-poc/public 1;
}
}
```

```yaml
server {
location /map-poc {
if ($mappocallow = 0) {return 403;}
return 200 "Hello. It is private area: $mappocallow";
}
}
```

在`/map-poc`中未定义`default`的情况下，**恶意用户**可以通过访问未定义的URI绕过安全性。[Nginx手册](https://nginx.org/en/docs/http/ngx_http_map_module.html)建议设置**默认值**以避免此类问题。

### **DNS欺骗漏洞**

在某些条件下，对Nginx进行DNS欺骗是可行的。如果攻击者知道Nginx使用的**DNS服务器**并能拦截其DNS查询，则可以欺骗DNS记录。然而，如果Nginx配置为使用\*\*localhost (127.0.0.1)\*\*进行DNS解析，则此方法无效。Nginx允许按以下方式指定DNS服务器：

```yaml
resolver 8.8.8.8;
```

### **`proxy_pass`和`internal`指令**

\*\*`proxy_pass`**指令用于将请求重定向到其他服务器，无论是在内部还是在外部。**`internal`\*\*指令确保某些位置仅在Nginx内部可访问。虽然这些指令本身并非漏洞，但它们的配置需要仔细检查，以防止安全漏洞。

## proxy\_set\_header Upgrade & Connection

如果nginx服务器配置为传递Upgrade和Connection标头，则可以执行[h2c Smuggling攻击](/pentesting-web/h2c-smuggling.md)以访问受保护/内部端点。

{% hint style="danger" %}
此漏洞将允许攻击者与`proxy_pass`端点（在本例中为`http://backend:9999`）建立直接连接，nginx不会检查其内容。
{% endhint %}

以下是一个易受攻击配置的示例，用于从[此处](https://bishopfox.com/blog/h2c-smuggling-request)窃取`/flag`：

```
server {
listen       443 ssl;
server_name  localhost;

ssl_certificate       /usr/local/nginx/conf/cert.pem;
ssl_certificate_key   /usr/local/nginx/conf/privkey.pem;

location / {
proxy_pass http://backend:9999;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
}

location /flag {
deny all;
}
```

{% hint style="warning" %}
请注意，即使 `proxy_pass` 指向特定的 **路径**，比如 `http://backend:9999/socket.io`，连接也将建立在 `http://backend:9999`，因此您可以**访问内部端点中的任何其他路径。因此，在 proxy\_pass 的 URL 中指定路径并不重要。**
{% endhint %}

## 请自行尝试

Detectify 创建了一个 GitHub 存储库，您可以使用 Docker 设置自己的易受攻击的 Nginx 测试服务器，并尝试找到本文中讨论的一些错误配置！

<https://github.com/detectify/vulnerable-nginx>

## 静态分析工具

### [GIXY](https://github.com/yandex/gixy)

Gixy 是一个用于分析 Nginx 配置的工具。Gixy 的主要目标是防止安全配置错误并自动化缺陷检测。

### [Nginxpwner](https://github.com/stark0de/nginxpwner)

Nginxpwner 是一个简单的工具，用于查找常见的 Nginx 配置错误和漏洞。

## 参考资料

* [**https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/**](https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/)
* [**http://blog.zorinaq.com/nginx-resolver-vulns/**](http://blog.zorinaq.com/nginx-resolver-vulns/)
* [**https://github.com/yandex/gixy/issues/115**](https://github.com/yandex/gixy/issues/115)

<figure><img src="/files/LVZ3PLDyldGi3gva0h7n" alt=""><figcaption></figcaption></figure>

**即时可用的漏洞评估和渗透测试设置**。从任何地方运行完整的渗透测试，使用 20 多种工具和功能，从侦察到报告。我们不取代渗透测试人员 - 我们开发定制工具、检测和利用模块，让他们有更多时间深入挖掘、弹出 shell 并享受乐趣。

{% embed url="<https://pentest-tools.com/>" %}

<details>

<summary><strong>从零开始学习 AWS 黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS 红队专家）</strong></a><strong>！</strong></summary>

支持 HackTricks 的其他方式：

* 如果您想看到您的 **公司在 HackTricks 中做广告** 或 **下载 PDF 版本的 HackTricks**，请查看 [**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取 [**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
* 探索 [**PEASS 家族**](https://opensea.io/collection/the-peass-family)，我们独家的 [**NFT**](https://opensea.io/collection/the-peass-family) 收藏品
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或 **关注** 我们的 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* 通过向 [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 存储库提交 PR 来分享您的黑客技巧。

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hacktricks.xsx.tw/network-services-pentesting/pentesting-web/nginx.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
