TP可能用到的函数

news2024/10/4 17:30:06

说明

该文章来源于同事lu2ker转载至此处,更多文章可参考:https://github.com/lu2ker/

文章目录

  • 说明
    • in_array()
    • filter_var()
    • class_exists()
    • strpos()
    • escapeshellarg()
    • escapeshellcmd()
    • preg_replace()
    • parse_str()
    • 无字母数字下划线的webshell
    • str_replace()
    • extract()
    • htmlentities()
    • CURL传输选项CURLOPT_POSTFIELDS
    • file_exists的bug?or机制?

in_array()

功能: 检查数组中是否存在某个值。

定义: in_array ( mixed $needle , array $haystack , bool $strict = false ) : bool

解释:大海捞针,在大海(haystack)中搜索针( needle),如果没有设置 strict 则使用宽松的比较。

当in_array()函数的第三个参数未设置为true时(默认为false),会进行弱比较。例如:

$exp = '2shell';
$whitelist = array(0,1,2,3,4,5);
# 此时如果调用 in_array($exp,$whitelist);  是会判定为true的。

image
当第三个参数设置为true时,就会进行强比较,会比较类型的。
image

filter_var()

函数定义如下:

功能:使用特定的过滤器过滤一个变量。

定义:filter_var( mixed $value, int $filter = FILTER_DEFAULT, array|int $options = 0) : mixed

该函数可调用指定的PHP内置的过滤器来过滤一个变量,如果符合过滤器的要求就返回原$value。比如,如果指定的是FILTER_VALIDATE_URL过滤器的话。FILTER_VALIDATE_URL 过滤器把$value作为 URL 来验证,验证其是否是URL格式的字符串,但是有一个很大的问题是 这个过滤器的”宽容性很高“,类似于qwe://这种形式的URL都可以通过它的过滤。

在这里插入图片描述

经过一些测试发现,形如xxx://xxx即可验证通过该过滤器。但是如果前半部分是http://的话,正斜杠后边不允许有特殊字符了。比如http://><"";''是不行的但是qwe://><"";''确实可以通过过滤的。

这里有一篇该函数相关的技术文

class_exists()

功能:检查类是否已定义。

定义:class_exists ( string $class , bool $autoload = true ) : bool

解释:检查指定的类是否已定义。$autoload是是否默认调用__autoload函数。

一个可以造成任意文件包含漏洞的例子。

<?php 
	function __autoload($classname){
    	echo 'I\'m working...';
		include $classname;
	}
	$classname = $_GET['c'];
	if (class_exists($classname)) {
		echo 'balbala';
	} else {
		echo 'There is no page';
	}
?>

这段代码的本意作用是:参数c获取一个classname ,class_exists()判断其值是否是被定义好的类,如果程序中没有定义该类,就会默认调用__autoload()将其包含到程序代码中。

这里就有一个任意文件包含漏洞,可以使用../路径穿越来实现任意文件包含。但是,只有在PHP5~5.3(含)中才可以在class_exists()中传入../达到目的,高版本php中向class_exists中传入../不会调用__autoload()的。

strpos()

功能:查找字符串首次出现的位置

定义:strpos ( string $haystack , mixed $needle , int $offset = 0 ) : int

解释:返回 needlehaystack 中首次出现的数字位置。如果提供了$offset,搜索会从字符串该字符数的起始位置开始统计。如果是负数,搜索会从字符串结尾指定字符数开始。

这个函数可能会被利用的点在于,例如下面这段代码:

<?php
$a = $_GET['a'];
$b = $_GET['b'];
if (!strpos($a, '<') && !strpos($b, '>')) {
    if (strstr($a, '<') && strstr($b, '>')) {
    	echo 'That\'s ok.';
    } else {
        echo 'No No No.';
    }
} else {
    echo 'No No No.';
}
?>

这段代码的本意是:如果参数a中不含有<且参数b中不含有>,又 如果参数a中含有<且参数b中含有>,就输出That's ok. 。其余情况都输出No No NO. 。听起来确实是自相矛盾,但是是为了更好的理解这个函数。在这段代码中传入?a=<&b=>即可通过所有的判断。

在PHP手册中查询strstr()函数的用法,会看到这样一句话:

在这里插入图片描述

但是,strpos()函数并不能像上述案例代码那样使用。有一种特殊的情况即:<是在$a的首位置时,strpos()会返回0,因为本身strpos()函数的功能就是查找字符串首次出现的位置。而!0true。所以除了$a中不存在<这种办法可以使第一个if判定为真外,将<写在$a的第一个字符位置也是可以的。

escapeshellarg()

escapeshellcmd()

功能:escapeshellarg()把字符串转码为可以在 shell 命令里使用的参数。

功能:escapeshellcmd()对字符串中可能会欺骗shell命令执行任意命令的字符进行转义。此函数保证用户输入的数据在传送到exec()system()函数,或者执行操作符之前进行转义

原理很简单,就是escapeshellarg()为了转义字符而加上的\又被escapeshellcmd()转义了。具体原理和漏洞案例看这里。

但是我在Windows环境下做测试,PHP5.2.17中,原字符串中有没有单引号都“不影响”最后的结果。而大于5.2的版本,无论如何都达不到逃逸的目的。

PHP5.2.17 字符串中无单引号:

在这里插入图片描述

PHP5.2.17 字符串中有单引号:

在这里插入图片描述

PHP>5.2.17 字符串中有单引号(^是windows中的转义字符):

在这里插入图片描述

preg_replace()

功能:执行一个正则表达式的搜索和替换

定义:preg_replace ( string|array $pattern , string|array $replacement , string|array $subject , int $limit = -1 , int &$count = null ) : string|array|null

解释:搜索 subject 中匹配 pattern 的部分,以 replacement 进行替换。

其中以前最大的问题是 $pattern/e修饰符带来的代码执行问题。但只在PHP<5.5.0有效了。

经典案例:

preg_replace('/(.*)/ei', 'strtolower("\1")', {${phpinfo()}});

PS:可以看看这个

补充一个名词:反向引用

反向引用

对一个正则表达式模式或部分模式 两边添加圆括号 将导致相关 匹配存储到一个临时缓冲区 中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。每个缓冲区都可以使用 ‘\n’ 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。

新学到了另一个问题,首先看看官方对第二个参数的部分描述:

replacement 中可以包含后向引用 \\n$n,语法上首选后者。 每个这样的引用将被匹配到的第 n 个捕获子组捕获到的文本替换。 n 可以是0-99,\\0$0 代表完整的模式匹配文本。捕获子组的序号计数方式为:代表捕获子组的左括号从左到右, 从1开始数。如果要在 replacement 中使用反斜线,必须使用 4 个("\\\\",译注:因为这首先是 PHP 的字符串,经过转义后,是两个,再经过正则表达式引擎后才被认为是一个原文反斜线)。

**preg_replace()函数在处理字符串的时候,会自动对第二个参数的 ‘ \ ’这个字符进行转义。**那么如果在第二个参数中传入\'就很有可能造成单引号逃逸问题了。

例如P师傅给过的这个经典的配置文件写入案例:

#index.php
<?php
if(!isset($_GET['option'])) die();
$str = addslashes($_GET['option']);
$file = file_get_contents('./config.php');
$file = preg_replace('|\$option=\'.*\';|', "\$option='$str';", $file);
file_put_contents('./config.php', $file);

#config.php
<?php
$option='test';

构造payload?option=a\';phpinfo();//即可。

另外该题还有一个有意思的解法 也是利用了第二个参数的问题,即$n当n为0时代表完整的模式匹配文本(什么xx意思看不懂啊=-=)好像是因为捕获子组是从1开始计数的,语法表示为$1那么$0就代表满足匹配的第三个参数的值了(被匹配的本身)。所以存在如下解法:

第一次:?option=;phpinfo();
结果:$option=';phpinfo();';
第二次:?option=%00 或者 ?option=$0
结果:$option='$option=';phpinfo();';';	//刚好能闭合单引号。
对比:$option='---第一次执行后的结果---';

parse_str()

功能:将字符串解析成多个变量

定义:parse_str ( string $string , array &$result ) : void

解释:如果 string 是 URL 传递入的查询字符串(query string),则将它解析为变量并设置(or覆盖)到当前作用域(如果提供了 result 则会设置到该数组里 )。

**变量覆盖问题。**这个函数的行为非常类似于注册全局变量,且它在注册变量之前不会验证变量是否已经存在。不安全的使用该函数也就是使用时没有用另外的代码判断它将要注册的变量是否已经存在。

demo案例:

在这里插入图片描述

同样的如果是从外部获取到的参数:

在这里插入图片描述

2022/6/2补充:对parse_str()规则的绕过,from PbootCMS<=3.1.2前台注⼊

由于 PHP 的变量名不能带「点」和「空格」,所以它们会被转化成下划线。用本函数带 result 参数,也会应用同样规则到数组的键名。
但是由于parse_str()底层C代码的设计问题,可能造成点或空格的绕过,在PbootCMS案例中就利用这个绕过造成了sqli漏洞,绕过demo如下:
正常处理结果:
image
利用’[‘字符进行绕过:
image
可以看到空格没有被替换为下划线了。
原因:在底层C代码的实现中,如果检测到’[‘字符会跳出 将「点」和「空格」替换为下划线的这个循环,还会将’[‘替换为下划线是因为
如果之后没有检测到’]‘字符的话,php就认为是误输入,会将当前指针指向(是’[‘后的第一个字符,因为这个时候还会考虑’[]'中包
裹字符的情况)的前一位赋值为下划线:

image

如果’[]'中包裹字符的最终效果:
image

无字母数字下划线的webshell

原理明白,不造轮子(懒)

str_replace()

功能:子字符串替换

定义:str_replace ( mixed $search , mixed $replace , mixed $subject , int &$count = ? ) : mixed

解释:该函数返回一个字符串或者数组。该字符串或数组是将 subject 中全部的 search 都被 replace 替换之后的结果。 $count如果被指定,它的值将被设置为替换发生的次数。

这个函数可能被利用的点在于替换,我见过有两种利用形式:①替换过滤函数插入的\。②单次替换,双写绕过。

着重记录一下第一种利用:

function replace_bad_word($str){
    global $black_list;
    foreach ($black_list as $old => $new) {
        strlen($old) > 2 && $str = str_replace($old,trim($new),$str);
    }
    return $str;
}
...
...
if(isset($_POST['msg']) && $_POST['msg'] !==''){
    $msg = addslashes($_POST['msg']);
    $msg = replace_bad_word(convert($msg));
    $sql = "INSERT INTO users VALUES($id,'".$msg."')";
    echo $sql;
    $result = $conn->query($sql);
    if($conn->error) die($conn->error);
}
...

以上是部分代码,为了不占篇幅就没有多贴,不过已经足够解释清楚利用方式了。

大概能明白这段代码的本意是:POST获取参数msg,第一步addslashes函数转义单引号、双引号、反斜线和NUL(null字符),第二步接着调用replace_bad_word函数替换黑名单字符,比如一些敏感词之类的东西。最后再执行SQL语句。

这段代码是没毛病的。但是第二步替换的时候,**如果能够把addslashes函数添加的\给替换为空,不就能造成引号逃逸了吗?**现在加上一段注册全局变量的代码,这也是一段经典的变量覆盖漏洞代码:

foreach (array('_GET','_POST') as $method) {
    foreach ($$method as $key => $value) {
        $$key = $value;
    }
}

可以使用这段代码的功能,构造任意的$black_list,甚至构造成$black_list[\\\]=''也是合法的。

例如msg传入1\' and xxxx,在addslashes转义后变成了1\\\' and xxx即单引号和反斜线一起被转义了,但如果我们利用注册全局变量功能同时再传入一个参数$black_list[\\\]=''当执行replace_bad_word函数的时候,就会把1\\\' and xxx中的\\\给替换为空!造成单引号逃逸!

在这里插入图片描述

这种利用还有几个有同样效果的paylaod,如:

//传入参数
msg=1%00' and xxxxx
//被addslashes处理后为
msg=1\0\' and xxxxx
//做替换处理时的黑名单构造为
limit_words[\0\]=''
同样是能达到替换效果的

extract()

功能:从数组中将变量导入到当前的符号表

定义:extract ( array &$array , int $flags = EXTR_OVERWRITE , string $prefix = “” ) : int

解释:就是把一个数组注册成变量。其中$flags很重要:默认EXTR_OVERWRITE:如果有冲突,覆盖已有的变量; 但是可以选择EXTR_SKIP:如果有冲突,不覆盖已有的变量。 而prefix仅在 flags 的值是 EXTR_PREFIX_SAMEEXTR_PREFIX_ALLEXTR_PREFIX_INVALIDEXTR_PREFIX_IF_EXISTS 时需要。如果附加了前缀后的结果不是合法的变量名,将不会导入到符号表中。前缀和数组键名之间会自动加上一个下划线。

与parse_str()的区别:

​ extract是将数组中元素分解,执行后数组的key值作为变量名,数组的value赋值给对应Key的变量,这样可以直接通过Key变量去访问,不用数组加key去访问。parse_str是根据"="来分解字符串,主要用于对url参数的解析。extract 是从数组创建变量parse_str 是将url参数串转换成数组。功能不一样,使用对象也不一样。

手册里面也有对开发者的提示:

在这里插入图片描述

htmlentities()

功能:将字符转换为 HTML 转义字符

定义:htmlentities ( string $string , int $flags = ENT_COMPAT | ENT_HTML401 , string $encoding = ini_get(“default_charset”) , bool $double_encode = true ) : string

解释:关键的是$flags,ENT_COMPAT 会转换双引号,不转换单引号。 ENT_QUOTES 既转换双引号也转换单引号。 ENT_NOQUOTES 单/双引号都不转换

审计的时候注意flags的值。

CURL传输选项CURLOPT_POSTFIELDS

根据文档介绍:

image-20220610121027365

存在这样一种情况,示例代码如下:

$url = $_GET['url'];
$username = $_GET['username'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_SAFE_UPLOAD,0);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
$res = curl_exec($ch);

利用示例:
image-20220610121724898

算是一种SSRF任意文件读取的效果。如果目标做了一些过滤,比如过滤了常用到的伪协议file://,还可以通过这种外部监听的方式,把文件内容发送到自己的vps上。利用条件就是

  • 设置CURLOPT_POSTFIELDS
  • 设置CURLOPT_SAFE_UPLOAD为false

而CURLOPT_SAFE_UPLOAD是PHP 5.5.0 中添加,默认值 FALSE。 PHP 5.6.0 改默认值为 TRUE。. PHP 7 删除了此选项, 必须使用 CURLFile interface 来上传文件

注:curl_setopt( resource $ch, int $option, mixed $value) : bool 第二个参数是int型,这意味着所有的选项实际上都是PHP内部定义的一个整型值,比如CURLOPT_URL实际上是
10002,所有选项对应的数字是多少:这里有一个网站可以查

file_exists的bug?or机制?

2022-08-19

$path2 = "C:\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\a\\..\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\aaa.txt";
if(file_exists($path2)){
	echo "yes";
}else{
	echo "No";
}
$path = "C:\a\b\c\d/e/f/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\..\\..\\..\\..\\..\\..\\..\\aaa.txt";

if(file_exists($path)){
	echo "yes";
}

如上两段代码,当你再增加反斜杠的话,file_exists就会返回false了。貌似和整体路径中的穿越\a\b\..\c\有关系,构造不同的目录穿越,使得file_exists返回true的反斜杠的最大数量(一个偶数)也不一样,但一定有一个最大数量。具体原理未知,可能得看内核 C源码。

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

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

相关文章

GNN algorithm(4): HAN, Heterogeneous Graph Attention Network

目录 background (1) heterogeneity of graph (2) semantic-level attention (3) Node-level attention (4) HAN contributions 2. Related Work 2.1 GNN 2.2 Network Embedding 3. Preliminary background 4. Proposed Model 4.1 Node-level attention ideas: …

Unity脚本(四)

视频教程&#xff1a;https://www.bilibili.com/video/BV12s411g7gU?p149 目录 键盘输入 InputManager 键盘输入 当通过名称指定的按键被用户按住时返回true&#xff1a; bool resultInput.GetKey(KeyCode.A); 当用户按下指定名称按键时的那一帧返回true&#xff1a;…

Python学习笔记——变量和简单数据类型

编码默认情况下&#xff0c;Python 3 源码文件以 UTF-8 编码&#xff0c;所有字符串都是 unicode 字符串。 当然你也可以为源码文件指定不同的编码。标识符第一个字符必须是字母表中字母或下划线 _ 。标识符的其他的部分由字母、数字和下划线组成。标识符对大小写敏感。在 Pyth…

【深度学习】机器学习\深度学习常见相关公开数据集汇总(图像处理相关数据集、自然语言处理相关数据集、语音处理相关数据集)

一、前言 1. 介绍 常来说&#xff0c;深度学习的关键在于实践。从图像处理到语音识别&#xff0c;每一个细分领域都有着独特的细微差别和解决方法。 然而&#xff0c;你可以从哪里获得这些数据呢&#xff1f;现在大家所看到的大部分研究论文都用的是专有数据集&#xff0c;这…

超声波测距传感器认知

目录 一、超声波测距传感器认知 二、从零编程实现超声波测距 三、项目——感应开关盖垃圾桶 1、开发步骤 2、感应开关盖垃圾桶代码测试 一、超声波测距传感器认知 超声波测距模块是用来测量距离的一种产品&#xff0c;通过发送和接收超声波&#xff0c;利用时间差和声音…

【网络】udp_socket编程

目录 1.认识端口号 1.1 理解端口号和进程ID 1.2 理解源端口号和目的端口号 2.认识TCP协议 3.认识UDP协议 4.网络字节序 5.socket编程接口 5.1socket常见API 5.2sockaddr结构 sockaddr结构 sockaddr_in 结构 in_addr结构 6.简单的UDP网络程序 6.1创建套接字 6.2 …

【Docker】三 镜像容器常用命令

这里写目录标题1 配置镜像加速器2 Docker镜像常用命令2.1 搜索镜像2.2 下载镜像[重要]2.3 列出镜像[重要]2.3 删除本地镜像[重要]2.4 保存镜像2.5 加载镜像2.6 构建镜像[重要]3 容器常用命令3.1 新建并启动容器[重要]3.2 列出容器[重要]3.3 停止容器[重要]3.4 强制停止容器[重要…

你可以不用Git,但不能不会Git(三)基础(下)

目录 一.将文件添加至忽略列 二.日志记录操作 三.比较文件差异 四.还原文件 一.将文件添加至忽略列 一般我们总会有些文件无需纳入Git的管理&#xff0c;也不希望它们总出现在未跟踪文件列表。通常都是些自动生成的文件&#xff0c;比如日志文件&#xff0c;或者编译过程中…

重学 Java 设计模式-结构型模式-适配器模式

重学 Java 设计模式-结构型模式-适配器模式 内容摘自&#xff1a;添加链接描述 适配器模式介绍 图片来自&#xff1a;https://refactoringguru.cn/design-patterns/adapter(opens new window) 适配器模式的主要作用就是把原本不兼容的接口&#xff0c;通过适配修改做到统一。…

canva绘制(二次、三次)贝塞尔曲线并且图片在曲线上运动

下图为实现效果&#xff08;图片在三次贝塞尔曲线中运动&#xff09; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…

Spring之注解开发

目录 一&#xff1a;Bean基本注解开发 二&#xff1a;Bean依赖注入注解开发 三&#xff1a;非自定义Bean注解开发 四&#xff1a;Bean配置类的注解开发 五&#xff1a;Spring配置其他注解 六&#xff1a;Spring注解的解析原理 一&#xff1a;Bean基本注解开发 Spring除了…

【区块链】区块链技术学习总结

文章目录一、区块链技术简介1.1 区块链概念1.2 区块链应用1.2.1 区块链1.0技术&#xff1a;比特币1.2.2 区块链2.0技术&#xff1a;以太坊1.2.3 区块链3.0技术&#xff1a;价值互联网二、区块链1.0技术比特币2.1 比特币2.1.1 比特币概念2.1.2 比特币性质2.1.3 比特币解决的问题…

Springboot扩展点之BeanDefinitionRegistryPostProcessor

前言通过这篇文章来大家分享一下&#xff0c;另外一个Springboot的扩展点BeanDefinitionRegistryPostProcessor&#xff0c;一般称这类扩展点为容器级后置处理器&#xff0c;另外一类是Bean级的后置处理器&#xff1b;容器级的后置处理器会在Spring容器初始化后、刷新前这个时间…

第二章 chrony服务器

文章目录第二章 chrony服务器1.1安装与配置1.2同步网络时间服务器1.3 配置时间服务器1.4 chronyc 命令1.5常见时区课后练习第一题&#xff1a;第一台机器从阿里云同步时间&#xff0c;第二台机器从第一台机器同步时间第二题&#xff1a;第一台服务器使用系统时间作为第二台服务…

jetson nano GPIO控制说明

文章目录一.GPIO介绍二.安装GPIO库python库C库三.几种常用的通信协议UARTPWMI2CI2SSPI四.控制函数说明python&#xff08;[参考](https://pypi.org/project/Jetson.GPIO/)&#xff09;C五.例程一.GPIO介绍 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输…

干货 | Web自动化测试中显式等待与隐式等待该怎么用?

在实际工作中等待机制可以保证代码的稳定性&#xff0c;保证代码不会受网速、电脑性能等条件的约束。等待就是当运行代码时&#xff0c;如果页面的渲染速度跟不上代码的运行速度&#xff0c;就需要人为的去限制代码执行的速度。在做 Web 自动化时&#xff0c;一般要等待页面元素…

高压放大器在电子束增材制造聚焦消像散控制技术研究的应用

实验名称&#xff1a;高压放大器在电子束增材制造聚焦消像散控制技术研究的应用 研究方向&#xff1a;增材制造 实验目的&#xff1a; 电子束选区熔化技术&#xff0c;即电子束3D打印技术&#xff0c;属于金属增材制造的分支。该技术以电子束为热源&#xff0c;在计算机控制下以…

华为防火墙配置笔记

防火墙&#xff08;Firewall&#xff09;也称防护墙&#xff0c;是由Check Point创立者Gil Shwed于1993年发明并引入国际互联网&#xff08;US5606668&#xff08;A&#xff09;1993-12-15&#xff09;防火墙是位于内部网和外部网之间的屏障&#xff0c;它按照系统管理员预先定…

实战工作十年的Code Review方法论与实践总结

作为卓越工程文化的一部分&#xff0c;Code Review其实一直在进行中&#xff0c;只是各团队根据自身情况张驰有度&#xff0c;松紧可能也不一&#xff0c;这里简单梳理一下CR的方法和团队实践。 一、为什么要CR 提前发现缺陷 在CodeReview阶段发现的逻辑错误、业务理解偏差、…

CleanMyMac2023Mac下载排行最好的清理工具

CleanMyMac是Mac清理工具&#xff0c;具有很多功能。例如‬&#xff0c;删除大量不可见的缓存文件&#xff0c;可以批量删除未使用的DMG、不完整的下载以及其余的旧包。不过由于MAC系统不像windows那样会产生缓存或系统垃圾&#xff0c; 使用Win电脑很多人会下载各类系统优化软…