R3CTF-2025 r3note 学习笔记
tag: nginx配置 CSP配置
看目录应该类似xss加bot的组合
先尝试弱口令爆破,没结果,正常流程fuzz也没结果
找到了一份wp
勉强看懂
关键点是利用nginx缓存js文件的配置问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| ./nginx/default.conf
proxy_cache_path /tmp/nginx keys_zone=static_cache:10m;
server { listen 8080;
location = /api/share/report { proxy_pass http://127.0.0.1:3001; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }
location /files/upload/ { deny all; }
location ~ \.(css|js)$ { proxy_cache static_cache; proxy_cache_key $uri$is_args$args; proxy_cache_valid 200 1h; proxy_cache_bypass $cookie_nocache $arg_nocache; proxy_http_version 1.1; proxy_pass http://127.0.0.1:3000; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }
location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
|
这里的正则是css|js,
用.js#后缀名上传,绕过上传文件时的限制,而当有用户访问时,文件名会被nginx正则解析,被缓存为 .js
由于
优先级高于
1 2 3
| location /files/upload/ { deny all; }
|
所以还是能访问,服务器还是会将其缓存
从而成功让服务器上有了一个我们能控制的js文件
此时由于CSP 配置 script-src ‘self’,允许同源脚本执行。
并且在./app/middleware/jwt.go 中并没有配置
1
| c.Writer.Header().Set("X-Content-Type-Options", "nosniff")
|
就会导致浏览器根据文件内容猜测解析方式,只要文件里有html等标签,就会被解析成html文件,从而让客户端浏览器将里面的js代码执行
我们再上传一个伪装成JS的HTML文件并在其中引用前面缓存好的js文件,即可执行js代码。
关键点: 上传时文件名设置为 .js#。这样既能绕过后端黑名单(因为后缀是 .js#),又能利用 Nginx 的正则优先级漏洞(在请求时被视为 .js),从而允许外部访问。假设得到文件 ID 为 html_id。
问题
上传恶意 HTML (伪装成 JS),不能在里面直接写好js代码吗
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| # ./app/middleware/jwt.go func SecureMiddleware() gin.HandlerFunc { return func(c *gin.Context) { c.Writer.Header().Set("Access-Control-Allow-Origin", "*") c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type,Authorization") c.Writer.Header().Set("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS") c.Writer.Header().Set("Content-Security-Policy", "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';") c.Writer.Header().Set("X-Frame-Options", "DENY") if c.Request.Method == "OPTIONS" { c.AbortWithStatus(204) return } c.Next() } }
|
c.Writer.Header().Set(“Content-Security-Policy”, “default-src ‘self’; script-src ‘self’; style-src ‘self’ ‘unsafe-inline’;”)
这里script-src允许引用同源js文件,但是没有’unsafe-inline’,所以不能引用内联的js代码
ai问答:https://gemini.google.com/share/452cce0a5469