← 返回首页

Nginx 缓存投毒:一个 Set-Cookie 引发的越权

2025-11-14

L3HCTF2025 nginx缓存攻击

Nginx配置分析

从配置片段可以看出,Nginx对静态资源设置了缓存:

location ~.*\.(gif|jpg|jpeg|png|bmp|swf)$ {
    proxy_ignore_headers Cache-Control Expires Vary Set-Cookie;
    proxy_pass http://127.0.0.1:5000;
    proxy_cache static;
    proxy_cache_valid 200 302 30d;
}

这几个配置选项的致命组合是:

  1. proxy_ignore_headers ... Set-Cookie:这是最关键的一条。它指示Nginx在缓存时忽略后端返回的Set-Cookie头。通常,一个需要登录的页面会包含Set-Cookie,而Nginx默认不会缓存带有Set-Cookie的响应。忽略它之后,Nginx就敢缓存这些本该私有的页面了。
  2. proxy_cache_valid 200 302 30d:告诉Nginx对于200和302状态码的响应缓存长达30天。
  3. location ~.\*\.(png)$:任何以.png结尾的URL请求都会匹配到这个规则。

攻击逻辑:如果一个需要认证才能访问的页面(如 /get_last_ip/z3r4y.png)的URL看起来像静态资源,那么第一个访问它的已认证用户的请求内容和响应,会被Nginx缓存下来。后续所有用户(包括未登录用户)再次访问这个完全相同的URL时,Nginx会直接返回缓存的副本,而不会再向后端Flask应用请求,从而绕过了Flask的登录检查。


🚀 完整做题流程

假设目标网站是 http://target.com

第一步:注册特殊用户名

第二步:污染 last_ip 字段

X-Forwarded-For: {{ 7*7 }}

第三步:触发Nginx缓存

第四步:通过缓存绕过认证并执行SSTI

第五步:利用SSTI获取权限

X-Forwarded-For: {{lipsum.__globals__['os'].popen('id').read()}}

总结

这道题的流程精髓在于:利用Nginx对“伪静态”资源的缓存机制,将动态、需认证的页面“冻结”成一个公开可访问的静态文件,从而绕过认证,并利用其中被污染的数据触发SSTI漏洞。