[漏洞分析] CVE-2024-6387 OpenSSH核弹核的并不是很弹

文章目录

    • 漏洞简介
    • 漏洞原理
      • 补丁分析
      • 漏洞原理
    • 漏洞利用
      • 漏洞利用1: SSH-2.0-OpenSSH_3.4p1 Debian 1:3.4p1-1.woody.3 (Debian 3.0r6, from 2005) [无ASLR无NX]
        • 漏洞利用原理
        • 漏洞利用关键点
      • 漏洞利用2: SSH-2.0-OpenSSH_4.2p1 Debian-7ubuntu3 (Ubuntu 6.06.1, from 2006) [无ASLR无NX]
      • 漏洞利用3: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2 (Debian 12.5.0, from 2024) [有ASLR无NX 32位]
    • 盖棺定论
    • poc分析

先说结论,在当前已经披露的漏洞利用方法而言,利用非常困难,也不能说完全利用不了吧,只能在特定场景成功,作者给了三个案例。但总的来说,核的并不是很弹,省流直接看下面盖棺定论

漏洞简介

漏洞编号: CVE-2024-6387

漏洞产品: OpenSSH - sshd

影响范围: 8.5p1 <= OpenSSH < 9.8p1

利用条件: 见最后"盖棺定论"章节

利用效果: 远程代码执行(RCE)(理论环境,单纯以博客中展示的漏洞利用方法而言,现网中几乎不可能完成利用

漏洞作者的博客如下:

https://www.qualys.com/2024/07/01/cve-2024-6387/regresshion.txt

由于作者没公开利用代码,并且利用实在太麻烦,本文纯纯基于该漏洞作者博客中的描述进行理论分析,不涉及实际调试。所有结论均为我YY的,不作为处置建议

漏洞原理

补丁分析

漏洞是在commit 752250c中引入的,关键点在于,该修改重命名了sigdie函数,并且去掉了#ifdef DO_LOG_SAFE_IN_SIGHAND

在这里插入图片描述

在这里插入图片描述

根据该宏定义的名字不难看出,该宏定义的意思是,在信号安全需求场景,不会执行中间的log部分代码,而是直接exit。现在去掉了该宏,则无条件执行这段log的代码。

漏洞原理

我们先来看看sshsigdie会在哪里使用:

log.h:

#define sigdie(...)		sshsigdie(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_ERROR, NULL, __VA_ARGS__)

这里将sshsigdie 定义为sigdie。

sshd.c:

/** Signal handler for the alarm after the login grace period has expired.*/
/*ARGSUSED*/
static void
grace_alarm_handler(int sig)
{if (use_privsep && pmonitor != NULL && pmonitor->m_pid > 0)kill(pmonitor->m_pid, SIGALRM);/** Try to kill any processes that we have spawned, E.g. authorized* keys command helpers.*/if (getpgid(0) == getpid()) {ssh_signal(SIGTERM, SIG_IGN);kill(0, SIGTERM);}/* XXX pre-format ipaddr/port so we don't need to access active_state *//* Log error and exit. */sigdie("Timeout before authentication for %s port %d",ssh_remote_ipaddr(the_active_state),ssh_remote_port(the_active_state));
}

在grace_alarm_handler 函数中调用了sigdie打印log,看名字就知道grace_alarm_handler 是一个时钟信号的处理函数。在main函数中注册为SIGALRM信号的处理函数:

sshd.c:

    /** We don't want to listen forever unless the other side* successfully authenticates itself.  So we set up an alarm which is* cleared after successful authentication.  A limit of zero* indicates no limit. Note that we don't set the alarm in debugging* mode; it is just annoying to have the server exit just when you* are about to discover the bug.*/ssh_signal(SIGALRM, grace_alarm_handler);if (!debug_flag)alarm(options.login_grace_time);

在options.login_grace_time 秒之后如果没有登录完成,则抛出超时信号SIGALRM。该参数默认为120,可以通过-g参数设置:

在这里插入图片描述
在这里插入图片描述

接下来看一下sshsigdie 函数中的逻辑,为什么这个函数在信号不安全场景会出问题:

void
sshsigdie(const char *file, const char *func, int line, int showfunc,LogLevel level, const char *suffix, const char *fmt, ...)
{va_list args;va_start(args, fmt);sshlogv(file, func, line, showfunc, SYSLOG_LEVEL_FATAL,suffix, fmt, args);va_end(args);_exit(1);
}

调用了sshlogv:

void
sshlogv(const char *file, const char *func, int line, int showfunc,LogLevel level, const char *suffix, const char *fmt, va_list args)
{char tag[128], fmt2[MSGBUFSIZ + 128];int forced = 0;const char *cp;size_t i;snprintf(tag, sizeof(tag), "%.48s:%.48s():%d",(cp = strrchr(file, '/')) == NULL ? file : cp + 1, func, line);for (i = 0; i < nlog_verbose; i++) {if (match_pattern_list(tag, log_verbose[i], 0) == 1) {forced = 1;break;}}if (log_handler == NULL && forced)snprintf(fmt2, sizeof(fmt2), "%s: %s", tag, fmt);else if (showfunc)snprintf(fmt2, sizeof(fmt2), "%s: %s", func, fmt);elsestrlcpy(fmt2, fmt, sizeof(fmt2));do_log(file, func, line, level, forced, suffix, fmt2, args);
}

最后调用了do_log:

static void
do_log(const char *file, const char *func, int line, LogLevel level,int force, const char *suffix, const char *fmt, va_list args)
{··· ···if (log_handler != NULL) {··· ···} else {
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);syslog_r(pri, &sdata, "%.500s", fmtbuf);closelog_r(&sdata);
#elseopenlog(argv0 ? argv0 : __progname, LOG_PID, log_facility);syslog(pri, "%.500s", fmtbuf);closelog();
#endif}errno = saved_errno;
}

可以看到这个函数中调用了syslog(),而syslog是信号不安全的函数,这其中也会使用大量的如malloc、free等信号不安全的libc函数。所以漏洞的根因是:在信号处理函数中使用信号不安全函数。

漏洞利用

指的一提的是,该漏洞并不是第一次出现,实际上这个漏洞就是CVE-2006-5051 漏洞的再现,上面提到的被删除的关键代码#ifdef DO_LOG_SAFE_IN_SIGHAND正式为了修复CVE-2006-5051 增加的,但是在上述commit中被错误删除,导致CVE-2006-5051 又重现。但不得不说CVE-2006-5051 漏洞从来没有被利用成功过。

除此之外,不可忽略的博客中的关于他们所尝试成功的漏洞利用的前提是:

  • 漏洞利用只针对虚拟机,而不是裸机服务器,控制网络的数据包抖动在0~10ms 之间;

漏洞利用1: SSH-2.0-OpenSSH_3.4p1 Debian 1:3.4p1-1.woody.3 (Debian 3.0r6, from 2005) [无ASLR无NX]

漏洞利用原理

该漏洞利用的环境没有ASLR与NX。

这个漏洞利用基本就是上古版本的ubuntu,来自2005年,其实这个漏洞利用尝试主要是尝试利用CVE-2006-5051。而且很容易就成功了,我们可以通过这个漏洞来理解一下他是如何利用的这个漏洞,并且理解一下该漏洞想要利用成功需要满足的前提条件。

首先,20年前的代码和现在有很大不同,我自然也懒得去找20年前的代码了反正思路是相同的,这个漏洞的原理还是相当简单的,直接看博客即可,根据博客中的描述,20年前的漏洞中大概使用的信号不安全函数不是syslog,而是packet_close,并且packet_close中调用了free:

------------------------------------------------------------------------302 grace_alarm_handler(int sig)303 {...307         packet_close();
------------------------------------------------------------------------329 packet_close(void)330 {...341         buffer_free(&input);342         buffer_free(&output);343         buffer_free(&outgoing_packet);344         buffer_free(&incoming_packet);
------------------------------------------------------------------------35 buffer_free(Buffer *buffer)36 {37         memset(buffer->buf, 0, buffer->alloc);38         xfree(buffer->buf);39 }
------------------------------------------------------------------------51 xfree(void *ptr)52 {53         if (ptr == NULL)54                 fatal("xfree: NULL pointer given as argument");55         free(ptr);56 }
------------------------------------------------------------------------

free函数是一个经典的信号不安全函数。在上古版本的glibc中,gree流程有如下关键代码:

------------------------------------------------------------------------
1028 struct malloc_chunk   这一部分是堆块结构,跟现在一样
1029 {
1030   INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
1031   INTERNAL_SIZE_T size;      /* Size in bytes, including overhead. */
1032   struct malloc_chunk* fd;   /* double links -- used only if free. */
1033   struct malloc_chunk* bk;
1034 };
------------------------------------------------------------------------
2516 #define unlink(P, BK, FD)                                           \
2517 {                                                                   \
2518   BK = P->bk;                                                       \
2519   FD = P->fd;                                                       \
2520   FD->bk = BK;                                                      \
2521   BK->fd = FD;                                                      \
2522 }                                                                   \
------------------------------------------------------------------------
3160 chunk_free(arena *ar_ptr, mchunkptr p)
....
3164 {
3165   INTERNAL_SIZE_T hd = p->size; /* its head field */
....
3177   sz = hd & ~PREV_INUSE;
3178   next = chunk_at_offset(p, sz);
3179   nextsz = chunksize(next);
....
3230   if (!(inuse_bit_at_offset(next, nextsz)))  这个分支的意思是,下一个堆块如果是释放状态,则将其unlink出来,然后跟当前要释放的堆块合并,在重新加入链表
3231   {
....
3241       unlink(next, bck, fwd);
....
3244   }
3245   else
3246     set_head(next, nextsz);                  /* clear inuse bit */
....
3251     frontlink(ar_ptr, p, sz, idx, bck, fwd);
------------------------------------------------------------------------

我们需要做的大概是构造如下堆布局,关于glibc的堆结构,经常打CTF的同学应该都很熟悉,不在这里解释了,直接看漏洞利用:

-----|---+---------------|---+---------------|---+---------------|-----... |p|s|f|b|  chunk_X  |p|s|f|b|  chunk_Y  |p|s|f|b|  chunk_Z  | ...
-----|---+---------------|---+---------------|---+---------------|-----|<------------->|user data

p,s,f,b分别是prev_size,size,fd 和 bk 字段。构造三个连续的堆块,chunk_X, chunk_Y, chunk_Z,其中chunk_Y是我们内容可控的堆块。当一个堆块在被使用状态的时候,fd和bk字段是没用的,这连个字段的位置是用户数据,也就是我们可控的数据。那么我们需要让他在free chunk_Y的过程中触发SIGARLM信号中断,并且中断的位置必须在上述代码的3246到3251之间,这样已经执行完set_head(next, nextsz);也就是已经修改chunk_Z的prev_inused位,已经将chunk_Y标记为释放,但还没将其正式添加到free_list中,这时触发中断。

进入到中断逻辑中,中断逻辑中还有free函数,这时需要再中断逻辑中free chunk_X堆块,这样在3230行,检测下一个堆块是否释放的时候,它会发现chunk_Y是释放的状态, 但他并不值得chunk_Y并不在free_list中,而是继续执行unlink函数,而参与unlink函数的两个指针fd和bk此时还是我们可控的用户数据。直接经典的unlink任意地址写,由于在该漏洞利用中没有ASLR与NX,则直接修改free_hook 到堆上,并在堆上部署shellcode完成利用。

漏洞利用关键点

有一个关键点被我一笔带过了,那就是,我们需要在正好free chunk_Y的时候的free的3246到3251之间触发超时中断。我不知道如何评价这个动作有多难,我只是说达成原理大家自行判断:

超时中断是在我们发起ssh链接的时候开始计时,默认状态120秒后触发。如果我们想要在正好free 的时候触发,那么我们得在发起ssh之后精确的等待120秒多一点触发free的操作。

但事实也并不是这么苛刻,漏洞作者采用的方法是通过DSA 公钥解析逻辑来触发free,因为该逻辑中有四次free我们可控内容的堆块的机会,并且sshd允许尝试6次认证,总共24次free机会。只要任意一次完成了,就是成功。

但即便如此代码的执行是非常快的,单条指令的执行时间是微妙级别,即便我们有24次机会,但触发从120秒之前设置的信号,还是很难,就好像赌博默示录中伊藤开司挑战柏青哥机器时需要连续进入123层3个小孔一样。

漏洞作者给出的一些优化方案是:

  • 再一次测试中如果我们收到对我们的 DSA 公钥数据包的响应(SSH2_MSG_USERAUTH_FAILURE),则说明我们发送得太早了
  • 如果我们甚至无法发送我们的 DSA 数据包的最后一个字节,那么我们发的太晚了(sshd 已经收到了 SIGALRM 并关闭了我们的连接);
  • 如果我们可以发送我们的 DSA 数据包的最后一个字节,并且在 sshd 关闭我们的连接之前没有收到任何响应,则我们的时间安排是相当准确的。

这三条基本可以让你对自己等待时间是否过长或过短有个判断,但即便如此能打到的效果大概就是,我能将等待时间缩短到一个比较小的范围内,但众所周知,这个时间每次都是不一样的,毕竟你要发送网络报文过去,该漏洞利用的环境是虚拟机,每次网络报文的延迟还算稳定,但如果换成远程网络,我都不敢想。

在虚拟机环境中,作者说平均10000次可以成功,没600秒处理10个连接,需要一周才能成功一次。

漏洞利用2: SSH-2.0-OpenSSH_4.2p1 Debian-7ubuntu3 (Ubuntu 6.06.1, from 2006) [无ASLR无NX]

同样是上古版本,但和上面的利用不同的是,不再使用packet_close函数,而是使用的pam系列的函数,原理大同小异,找到一个对全局资源的关键访问函数,并且在其还没完成完整的修改之前中断,然后在中断处理中再次访问该全局资源。

除了漏洞利用的目标函数有区别外,在时间优化方面没有进一步优化,还是需要上述漏洞利用的苛刻条件。除此之外,还是需要非NX环境,还是需要shellcode。

漏洞利用3: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2 (Debian 12.5.0, from 2024) [有ASLR无NX 32位]

该漏洞利用环境开启了ASLR,但该环境的ASLR 有问题,随的并不是很机,参考:

https://zolutal.github.io/aslrnt/

https://grsecurity.net/toolchain_necromancy_past_mistakes_haunting_aslr

然后呢漏洞利用原理大差不差,关于时间,在该版本中时间更加难以确定,但作者依旧采用了一个很好的区间法能够尽量确认正确等待时间的范围:

------------------------------------------------------------------------88 userauth_pubkey(struct ssh *ssh, const char *method)89 {
...
138         if (pktype == KEY_UNSPEC) {
139                 /* this is perfectly legal */
140                 verbose_f("unsupported public key algorithm: %s", pkalg);
141                 goto done;
142         }
143         if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
144                 error_fr(r, "parse key");
145                 goto done;
146         }
...
151         if (key->type != pktype) {
152                 error_f("type mismatch for decoded key "
153                     "(received %d, expected %d)", key->type, pktype);
154                 goto done;
155         }
------------------------------------------------------------------------

通过发送错误的数据包频繁触发138-142的错误和151-155的错误可以确认正确的数据包处理时间大概是多久。根据作者描述,120秒接受100个连接的情况下(注意远大于前两次的频率)大概3-4小时能成功竞争时间窗,6-8小时能成功爆破地址,根据他提供的数据,可以看出ASLR的问题还是很大的,只有两种可能这随机了个寂寞,况且最后漏洞利用还是shellcode,还是得在没有NX的环境才可以漏洞利用成功

盖棺定论

整体来说,我觉得漏洞的实际威胁程度不大,首先该利用在2024年的ubuntu环境之所以能成功,有如下几个先决条件:

  1. ASLR开了,但约等于没开,那个ASLR漏洞让ASLR随机几乎完全失效,只有两种地址可能。
  2. 不能开NX,还是依赖shellcode
  3. 在虚拟机中,网络的波动在可控范围内
  4. 120秒发起100个连接
  5. 32位环境

这上面的条件还只是硬性条件,满足了之后才能开始时间窗的竞争尝试,可见有多难,在虚拟机场景下3-4小时才能竞争成功一次时间窗也就是获得一次猜地址的机会,但凡ASLR正常也是利用不成的,除非欧皇一发入魂。

更别说64位环境了。

关于这个竞争时间窗,多说一嘴,想在网络环境中发起请求之后120秒出发超时中断的时候,还正好在我们目标的被中断的代码之间的难度,我理解大概就是一列火车正在全速行驶,你站在铁轨旁边向火车扔石头,石头正好从车厢之间穿过的概率吧。

poc分析

尽早来发现github上有poc了,链接如下:

https://github.com/zgzhang/cve-2024-6387-poc

其实大概原理都知道,主要是验证一下上面分析的结论是否正确:

  1. ASLR确实只有两种可能:

    在这里插入图片描述

  2. 最后用shellcode完成利用,所以还需要关闭NX

    在这里插入图片描述

这么看来当前确实很难利用,期待有人发现更强的理由方式。

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

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

相关文章

PD/PPS适配器/充电器高频快速AC-DC充电器芯片

概述 PC1067 是一款集成 GaN 功率器件的高频准谐振反激控制器&#xff0c;适合设计在离线式 USB-PD和USB Type-C 等快速充电器和电源供应器方案&#xff0c;待机功耗小于 75mW。 PC1067 集成全面的保护功能&#xff0c;包括逐周期过流保护&#xff08;OCP&#xff09;&#x…

library source does not match the bytecode for class SpringApplication

library source does not match the bytecode for class SpringApplication 问题描述&#xff1a;springboot源码点进去然后download source后提示标题内容。spring版本5.2.8.RELEASE&#xff0c;springboot版本2.7.18 解决方法&#xff1a;把spring版本改为与boot版本对应的6.…

一键搞定长图处理:高效精准,轻松实现按固定高度像素切割

在数字时代&#xff0c;图像已经成为我们日常生活中不可或缺的一部分。无论是网页设计、广告海报&#xff0c;还是社交媒体分享&#xff0c;图像都在扮演着至关重要的角色。但是&#xff0c;当你面临一张长长的图片&#xff0c;需要按照特定的尺寸进行切割时&#xff0c;你是否…

物流行业:智能物流跟踪

在现代物流中&#xff0c;RFID技术的应用已经成为提高运输效率和安全性的重要手段。RFID标签可以被轻松地附加到货物上&#xff0c;并能够实时记录物品的位置和状态。通过这些标签&#xff0c;物流公司可以实时追踪货物的运输路径&#xff0c;监控货物的运输状况&#xff0c;确…

Docker 部署 Minio 对象存储服务器

文章目录 Github官网文档简介dockerdocker-compose.ymlmc 客户端mc 基础命令Golang 示例创建 test 账号密钥文件上传示例 Github https://github.com/minio/minio 官网 https://min.io/https://www.minio.org.cn/ 文档 https://www.minio.org.cn/docs/minio/kubernetes/up…

hamibot 学习

1.参考文档&#xff1a; https://blog.csdn.net/zxl0428/article/details/1285318731.参考官网 快速入手步骤&#xff1a;注册&#xff0c;安装客户端&#xff0c;添加设备&#xff0c;开发脚本&#xff0c;运行脚本 https://hamibot.com/guide1.安装客户端 2.添加设备 …

如何为董事会会议做准备?【会前会后】

召开一场富有成效的董事会会议需要花费大量的时间&#xff0c;可能要进行数周的沟通和拉扯&#xff0c;这些对董事做好充分准备至关重要。真实情况下的董事会会议往往需要大量的时间来准备&#xff0c;使用董事会会议工具能有效节省董事会会议准备时间、提高效率&#xff0c;保…

MySQL5.7安装初始化错误解决方案

问题背景 今天在给公司配数据库环境时,第一次报initializing database 数据库初始化错误? 起初没管以为是安装软件原因,然后就出现以下错误:如下图 点开log,我们观察日志会发现 无法识别的参数 ‘mysqlx_port=0.0’,???,官方的安装程序还能出这问题?

LabVIEW风机跑合监控系统

开发了一种基于LabVIEW的风机跑合监控系统&#xff0c;提高风机测试的效率和安全性。系统通过自动控制风机的启停、实时监控电流和功率数据&#xff0c;并具有过流保护功能&#xff0c;有效减少了人工操作和安全隐患&#xff0c;提升了工业设备测试的自动化和智能化水平。 项目…

仓库管理系统25--数据导出

原创不易&#xff0c;打字不易&#xff0c;截图不易&#xff0c;多多点赞&#xff0c;送人玫瑰&#xff0c;留有余香&#xff0c;财务自由明日实现 1、添加用户控件 <UserControl x:Class"West.StoreMgr.View.DataExportView"xmlns"http://schemas.microsof…

全年免费!环信发布出海创新版,助力泛娱乐创业者扬帆起航

目前&#xff0c;以陌生人社交、直播、语聊、电商等热门场景为代表的社交泛娱乐出海正发展得如火如荼&#xff0c;成为企业新的增长曲线。但随着出海企业增多&#xff0c;海外市场争夺、资源竞争与技术博弈也愈加激烈。 为了让更多创业者与创新者获得支持&#xff0c;快速高效…

onCreateOptionsMenu()和onOptionsItemSelected()的使用

书籍 《第一行代码 Android》第三版 开发 环境 Android Studio Jellyfish | 2023.3.1 创建Menu资源 在《第一行代码 Android》中的3.2.5 在Activity中使用Menu章节中,根据书中指引,在res/目录下创建menu目录,然后在menu目录下创建main.xml的布局资源. menu&#xff1a;必选…

PPT文件中,母版视图与修改权限的区别

在PPT&#xff08;PowerPoint&#xff09;制作过程中&#xff0c;母版视图和修改权限是两个重要的概念&#xff0c;它们各自在演示文稿的编辑、管理和分发中扮演着不同的角色。本文将从定义、功能、使用场景及区别等方面详细探讨PPT母版视图与修改权限的异同。 PPT母版视图 定…

六西格玛培训:不只是理论,更是实战中的利器——张驰咨询

六西格玛作为一种强大的流程改进和质量管理工具&#xff0c;其应用范围已经远远超出了传统制造业的界限&#xff0c;逐步渗透到金融业、互联网以及新能源等前沿领域。以下张驰咨询将结合之前的分析&#xff0c;展示六西格玛培训在这些行业中的成功案例及其带来的深远影响。 制造…

Keysight 是德 EXR604A 实时示波器

Keysight 是德 EXR604A 实时示波器 EXR604A Infiniium EXR 系列示波器&#xff1a;6 GHz&#xff0c;4 通道 全部 4 个通道均可提供 6 GHz 带宽&#xff0c;强大的 8 合 1 仪器&#xff0c;出色的硬件加速绘图功能&#xff0c;并且支持全面升级&#xff0c;可升级到 8 个通道…

ERP系统中有哪些模块?有哪些具体实现方案呢?

对于许多初次接触ERP系统的企业来说&#xff0c;可能会对系统中包含的模块和功能感到困惑。本文将详细介绍ERP系统中的主要模块&#xff0c;需要明确的是&#xff0c;ERP系统是一个庞大的系统&#xff0c;包含了多个模块&#xff0c;每个模块都有其独特的功能和作用。这些模块涵…

如何用python语言从json数据中获取自己想过的值?

&#x1f3c6;本文收录于《CSDN问答解答》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&…

要不要从单片机转Linux?进来看看大神怎么说

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「单片机的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;究竟要不要从单片机转Linu…

二维正态结论

关于二维正态分布&#xff0c;需掌握如下结论&#xff1a; &#xff08;1&#xff09;二维正态分布的两个边缘分布均为一维正态分布。 即由&#xff08;X&#xff0c;Y&#xff09;~N&#xff08;μ1&#xff0c;μ2&#xff0c;σ1&#xff0c;σ2&#xff0c;ρ&#xff09…

互联网下的扭蛋机小程序开发:探索其独特优势

随着互联网技术的飞速发展&#xff0c;小程序作为一种新兴的轻量级应用形式&#xff0c;已经在各个领域展现出强大的生命力和广泛的应用前景。在娱乐和零售行业&#xff0c;扭蛋机作为一种经典的随机性消费体验方式&#xff0c;结合小程序进行开发&#xff0c;带来了诸多独特优…