ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

SpringBoot微服务黑盒渗透实战:从文件上传到Redis接管完整攻击链与防御落地

2026/9/3 1:52:30 拓冰建站 浏览量
SpringBoot微服务黑盒渗透实战:从文件上传到Redis接管完整攻击链与防御落地 摘要很多团队做安全建设习惯单独修复单个高危漏洞忽略漏洞串联后的杀伤链。本次测试目标是一套对外提供业务服务的Spring Boot微服务集群公网仅暴露业务域名与文件上传子域名。测试人员没有拿到源码、没有内网接入权限纯黑盒状态下依靠前端校验绕过、LibreOffice文档解析漏洞拿下应用服务器权限读取SpringBoot明文配置拿到数据库、Redis凭证伪造JWT管理员身份越权导出全量业务数据。整套环境没有出现传统意义上的RCE高危漏洞全部由中危、低风险漏洞拼接形成完整入侵路径。很多线上业务系统都存在同类配置缺陷组件版本老旧、上传校验只做前端、缓存权限管控缺失任意单点缺陷单独看风险可控组合之后直接造成业务全量数据泄露。本文完整还原攻击链路给出可直接复制的检测脚本、mermaid架构与攻击流程图、生产加固配置同时站在对抗式审查视角拆解开发自测、安全审计时容易漏掉的盲点。1 目标业务架构与资产测绘业务对外架构公网用户请求经过Nginx反向代理转发至SpringBoot应用网关网关路由分发到各个微服务实例业务存储层使用MySQL存储业务数据Redis承担会话缓存、用户权限、JWT会话存储对外单独拆分一个子域名专门处理用户文档上传、文档在线预览转换功能。1.1 业务架构图flowchart LR Internet[公网用户] -- Nginx[Nginx反向代理] Nginx -- Gateway[SpringBoot网关服务] Nginx -- UploadSubDomain[文件上传子域名br/文档转换服务] Gateway -- MicroA[业务微服务A] Gateway -- MicroB[业务微服务B] MicroA -- Mysql[(MySQL业务库)] MicroB -- Redis[(Redis缓存br/会话、角色、JWT缓存)] UploadSubDomain -- LibreOffice[LibreOffice文档转换组件] UploadSubDomain -- Disk[服务器本地磁盘br/上传文件存储]测试阶段公网端口扫描只开放80、443端口没有开放数据库、Redis对外端口。从外部看端口层面防护做得很到位数据库缓存组件无法从公网直接访问。测试人员资产探测发现独立子域名提供文件上传接口业务允许普通用户上传docx、pdf等文档用于在线预览。业务逻辑用户上传文档后端调用LibreOffice把docx转换为pdf返回预览链接给到前端。很多开发的安全认知停留在Redis、Mysql不对外暴露公网就不会被外部攻击者访问。但攻击者拿到应用服务器权限之后就处于内网信任域所有内部组件不再有网络隔离保护。1.2 攻击链路流程图flowchart TD A[资产探测发现上传子域名] -- B[抓包绕过前端文件校验] B -- C[上传恶意docx文档] C -- D[LibreOffice XXE解析漏洞执行命令br/获取应用服务器shell权限] D -- E[读取application‑prod.yml生产配置] E -- F[拿到MySQL账号密码、Redis连接凭证、JWT签名密钥] F -- G[本地连接Redis读取管理员会话缓存] G -- H[利用密钥伪造超级管理员JWT Token] H -- I[登录后台管理接口触发越权数据导出接口] I -- J[全量业务用户数据泄露]2 漏洞入口文件上传前端校验绕过2.1 业务原始上传逻辑前端页面做文件后缀名校验只允许.docx、.pdf、.xlsx文件JS脚本在浏览器端校验文件扩展名不满足格式直接拦截不会发送HTTP请求到后端。第一性原理视角浏览器JS校验全部属于客户端可控逻辑攻击者完全可以绕过。对抗式审查要点所有前端实现的安全校验都不能当作安全屏障只能作为普通用户的体验优化。安全校验逻辑必须下沉服务端。普通用户正常上传数据包POST /upload/file HTTP/1.1 Host: shturl.cc Content‑Type: multipart/form‑data; boundary----WebKitFormBoundaryxxxx ------WebKitFormBoundaryxxxx Content‑Disposition: form‑data; namefile; filenamebusiness.docx Content‑Type: application/vnd.openxmlformats‑officedocument.wordprocessingml.document [docx文件二进制内容] ------WebKitFormBoundaryxxxx‑测试人员关闭浏览器JS校验使用BurpSuite抓包篡改数据包。前端的校验逻辑已经在浏览器被跳过直接构造恶意文件数据包向后端提交。后端没有校验文件真实文件头、没有校验文件内容仅仅简单读取http请求头内的filename文件名后缀。只要文件名后缀是docx就放行处理完全不校验文件内部内容。2.2 可复现的绕过请求示例POST /upload/file HTTP/1.1 Host: shturl.cc User‑Agent: Mozilla/5.0 Content‑Type: multipart/form‑data; boundaryboundary123 --boundary123 Content‑Disposition: form‑data; namefile; filenameevil.docx Content‑Type: application/vnd.openxmlformats‑officedocument.wordprocessingml.document [嵌入恶意XXE载荷的docx二进制数据] --boundary123--上传成功之后HTTP响应头会暴露后端调用LibreOffice做文档转换。从响应头字段可以判断组件版本存在已知XXE解析漏洞。对抗式审查自查点是否只依赖前端JS校验文件上传后端是否只判断文件名后缀不校验文件真实内容业务引入第三方文档解析、Office转换组件是否跟踪组件安全公告。很多业务开发只关注文件上传能不能拿到webshell忽略文档解析类组件的风险。就算不能上传可执行脚本恶意文档交给第三方组件解析同样可以实现服务器文件读取、命令执行。3 LibreOffice XXE解析漏洞拿到服务器权限LibreOffice在处理docx内部XML子文件时没有禁用外部实体引用。docx本质是zip压缩包内部包含大量xml格式描述文件。攻击者构造恶意docx解压修改内部xml植入XXE外部实体载荷再重新压缩为docx后缀文件。当业务后端调用LibreOffice转换这份恶意docx解析内部XML时触发外部实体注入读取服务器本地文件进一步可以构造载荷执行系统命令。第一性原理思考业务引入第三方组件组件的安全风险等于业务自身风险。很多开发认为只是调用工具做文档转pdf工具本身的漏洞不在自己业务代码范围内不去做版本维护。3.1 恶意docx构造思路将正常docx文件修改后缀为zip解压全部文件修改内部word/document.xml插入XXE实体载荷将所有文件重新打包zip改回.docx后缀。示例document.xml内恶意载荷片段?xml version1.0 encodingUTF‑8? !DOCTYPE root [ !ENTITY xxe SYSTEM file:///etc/passwd ] w:document xmlns:whttp://schemas.openxmlformats.org/wordprocessingml/2006/main w:body w:p w:r w:txxe;/w:t /w:r /w:p /w:body /w:document上传该docxLibreOffice解析文档读取/etc/passwd内容渲染到转换后的PDF预览文件中。攻击者下载转换完成pdf就能拿到服务器本地文件输出。在真实测试场景攻击者不再读取passwd直接读取项目配置文件路径application‑prod.yml。对抗式审查提醒业务如果有文档预览、文档在线转换功能必须锁定LibreOffice版本关闭外部实体解析做文档沙箱隔离禁止直接在业务应用服务器执行文档转换任务。不要直接在业务容器内部调用libreoffice二进制程序。4 读取SpringBoot生产配置文件批量泄露敏感凭据拿到服务器文件读取能力之后攻击者首要目标就是SpringBoot生产配置文件。SpringBoot项目默认加载application‑prod.yml数据库账号密码、Redis连接地址密码、JWT签名密钥、中间件凭证全部明文写在配置文件中。典型被泄露的配置片段脱敏模拟spring: datasource: url: jdbc:mysql://127.0.0.1:3306/biz_db username: biz_user password: BizPass123456 redis: host: 127.0.0.1 port: 6379 password: Redis2026 jwt: secret: SUPER_JWT_SECRET_KEY_XXXXXX expire: 7200这个配置文件泄露之后整个微服务体系信任链直接崩塌。虽然MySQL、Redis没有对公网开放端口但是攻击者已经站在应用服务器本地访问127.0.0.1即可访问全部中间件。不需要爆破直接拿到明文账号密码。很多项目开发、运维习惯生产配置直接明文写在yml依赖服务器权限做保护。一旦文件读取漏洞出现全部凭据直接泄露。第一性原理配置文件明文存储密钥等于把钥匙和大门放在同一个房间。只要攻击者拥有任意文件读取密钥直接交付对手。对抗式审查自查清单生产环境配置是否明文存放数据库密码、JWT密钥、中间件密码配置文件文件系统权限是否最小化是否其他用户可读是否使用配置中心、密钥管理服务替代本地yml硬编码密钥。5 Redis会话劫持 JWT伪造完成权限提升Redis内部存储两类关键数据用户登录会话Session保存用户ID、角色权限业务JWT相关缓存部分登录逻辑会把管理员角色、权限存入Redis。攻击者拿到Redis密码在应用服务器执行redis‑cli直接连接本地Redisdump全量key。找到管理员登录会话key读取管理员UID、角色标识。同时拿到JWT secret签名密钥。攻击者本地即可伪造任意JWT令牌直接构造超级管理员身份token。不需要劫持真实用户cookie直接生成合法后台凭证。5.1 Python检测脚本JWT密钥伪造测试脚本仅用于企业内部授权安全检测禁止未授权使用。完整可复制代码块。import jwt import datetime def forge_admin_jwt(jwt_secret:str): payload { sub: admin‑001, user_id: 1, username: super_admin, roles: [SUPER_ADMIN], exp: datetime.datetime.utcnow() datetime.timedelta(hours24) } token jwt.encode(payload, jwt_secret, algorithmHS256) print(f伪造管理员JWT:\n{token}) return token if __name__ __main__: # 填入从配置文件泄露拿到的jwt.secret SECRET_KEY SUPER_JWT_SECRET_KEY_XXXXXX forge_admin_jwt(SECRET_KEY)拿到伪造JWT之后请求后台接口带上Authorization请求头GET /api/admin/user/export HTTP/1.1 Host: api.bizdomain.com Authorization: Bearer 【伪造出来的JWT字符串】后台接口没有做二次权限校验只校验JWT签名合法性。签名密钥被泄露攻击者可以无限生成任意权限身份。更进一步业务后台存在越权漏洞导出接口没有数据范围限制管理员接口可以导出全部用户业务数据表。攻击者直接调用导出接口批量下载全量业务数据。至此整套业务被完整攻陷。5.2 Redis侧风险点拆解Redis没有网络边界防护应用服务器本地可以无限制访问没有针对业务应用做账号最小权限业务账号拥有keys * 全量查询权限会话数据明文存储没有加密大量业务把权限、角色信息放在Redis一旦被读取直接权限泄露。对抗式审查很多开发认为Redis只对内网开放就足够安全。内网不是安全隔离带应用服务器被攻陷内网中间件等于裸奔。6 完整攻击链复盘没有高危漏洞一样可以拿下业务整条攻击链路没有出现传统意义上直接高危的远程代码执行漏洞。文件上传仅绕过前端校验本身不能直接上传webshell属于中危LibreOffice XXE需要业务主动调用组件解析恶意文档属于中危配置文件明文存放密钥配置缺陷很多安全扫描器只会报低危Redis会话明文存储、JWT密钥硬编码配置类风险后台越权导出接口业务逻辑漏洞。每一个单点拿出来风险评级都不是致命。但是攻击者把链路串联直接实现从公网入口到全量数据泄露。第一性原理安全观点安全不能单点打分要看漏洞串联之后的杀伤链。安全扫描工具单漏洞评级不能代表系统整体风险。很多企业安全建设误区只盯着高危漏洞修复中低风险漏洞拖延不处理认为内网是安全域内网中间件不需要权限隔离把安全校验交给前端密钥明文放在本地配置文件第三方业务组件只追求功能不维护版本安全更新。7 生产环境完整加固落地清单下面给出可直接落地的加固方案分为上传模块、文档转换组件、SpringBoot配置、Redis防护、JWT设计、业务接口权限、网络隔离7个部分。7.1 文件上传模块加固全部校验逻辑迁移后端直接废弃前端JS作为安全校验校验文件真实文件头不能只判断文件名后缀上传文件存储目录禁止执行权限上传文件重命名使用随机文件名禁止用户可控文件名业务文档转换功能拆分独立隔离服务不和业务应用共用同一台服务器/容器。文档转换服务做沙箱转换服务禁止访问业务Redis、MySQL。7.2 LibreOffice文档转换组件加固升级到安全修复后的LibreOffice版本关闭XML外部实体解析文档转换服务最小权限运行禁止读取项目配置文件转换服务与业务应用做网络隔离转换服务不能访问业务数据库缓存。7.3 SpringBoot配置加固禁止yml明文存放密钥密码。推荐使用配置中心Nacos/Apollo或者密钥管理服务生产环境密钥不落地本地配置文件。示例application‑prod.yml安全改造参考spring: datasource: url: jdbc:mysql://127.0.0.1:3306/biz_db username: ${MYSQL_USER} password: ${MYSQL_PASS} redis: host: 127.0.0.1 port: 6379 password: ${REDIS_PASS} jwt: secret: ${JWT_SECRET}密码从环境变量注入不在yml写死明文。生产服务器配置文件权限设置600仅应用进程用户可读。7.4 Redis加固业务Redis账号做最小权限禁用keys *、flushall等高风险命令Redis和业务应用之间开启密码认证会话敏感数据尽量加密存储不要明文存放用户角色权限容器环境Redis做网络策略只有指定业务Pod可以访问同服务器其他进程禁止访问。7.5 JWT安全加固JWT密钥定期轮换密钥泄露之后可以快速重置不要把全部权限依赖JWT签名接口服务端做二次权限校验敏感后台接口增加二次校验即使JWT合法也要校验当前会话状态。7.6 业务接口权限加固所有后台管理接口严格校验数据权限导出接口做数据范围限制管理接口增加操作日志记录导出、查询行为管理后台接口增加访问频率限制异常大量导出行为直接告警。7.7 检测脚本本地审计脚本扫描yml明文密钥可复制shell脚本扫描项目目录下yml、properties查找明文密码密钥用于运维自查。#!/bin/bash # scan_plain_key.sh 扫描配置文件明文密钥仅用于内部审计 grep -rE password|secret|passwd --include*.yml --include*.properties ./ 2/dev/null运行输出会把配置文件中疑似密码密钥行全部打印出来快速定位硬编码明文凭据。8 对抗式审查自测方法开发自测时可以直接套用开发上线前站在攻击者视角自问几个问题如果攻击者拿到当前应用服务器读取文件权限能读到哪些敏感文件会不会拿到数据库密钥、JWT密钥如果攻击者绕过前端校验传入恶意文件后端组件会发生什么行为中间件只对内网开放一旦应用服务器被攻破中间件是否可以被直接访问JWT仅仅校验签名如果密钥泄露系统是否还有其他防护手段很多团队做安全测试只找漏洞不做杀伤链推演。对抗式审查核心就是模拟攻击者拿到其中一个漏洞之后还能往哪些方向继续推进。9 总结这套攻击链在真实互联网业务中出现频率很高。很多系统没有一眼看上去高危的漏洞但是多重中低风险缺陷叠加形成完整入侵路径。微服务架构下组件数量变多各个组件之间的信任关系往往是安全短板。安全防护不能依赖单点漏洞修复要做链路层面防御。就算某一处被突破也要在后续链路设置障碍阻止攻击者一路横向移动拿到全量数据。互动问题你们线上业务是否还在yml配置文件硬编码数据库与JWT密钥实际生产中采用什么方案做密钥管理做文档预览转换业务你们团队是直接在业务容器调用LibreOffice还是独立部署隔离转换服务欢迎评论区交流。