当前位置: 首页 > article >正文

拓展知识六:MetInfo6.0.0目录遍历漏洞原理分析

所需进行代码审计的文件路径:

C:\phpStudy\WWW\MetInfo6.0.0\include\thumb.php

C:\phpStudy\WWW\MetInfo6.0.0\app\system\entrance.php

C:\phpStudy\WWW\MetInfo6.0.0\app\system\include\class\load.class.php 

C:\phpStudy\WWW\MetInfo6.0.0\app\system\include\moduleold_thumb.class.php

文件间的关联与作用

thumb.php:

<?php
# MetInfo Enterprise Content Management System
# Copyright (C) MetInfo Co.,Ltd (http://www.metinfo.cn). All rights reserved.
define('M_NAME', 'include');
define('M_MODULE', 'include');
define('M_CLASS', 'old_thumb');
define('M_ACTION', 'doshow');
require_once '../app/system/entrance.php';
# This program is an open source system, commercial use, please consciously to purchase commercial license.
# Copyright (C) MetInfo Co., Ltd. (http://www.metinfo.cn). All rights reserved.
?>

 此文件定义了 4 个常量。M_NAMEM_MODULE被设为include,虽在此漏洞利用过程中未直接起关键作用,但它们是系统模块标识的一部分。重点是M_CLASS被定义为old_thumbM_ACTION被定义为doshow ,这两个常量为系统后续确定执行的类和方法提供了核心标识。同时,通过require_once '../app/system/entrance.php';引入系统入口文件 entrance.php,启动整个系统执行流程。

重点代码:
<?php
define('M_CLASS', 'old_thumb');
define('M_ACTION', 'doshow');
require_once '../app/system/entrance.php';
?>
  1. define 函数
    • define('M_CLASS', 'old_thumb');:这行代码使用 define 函数定义了一个名为 M_CLASS 的常量,并将其值设置为 old_thumb。常量在整个脚本执行过程中值是固定不变的,不能被重新赋值。
    • define('M_ACTION', 'doshow');:同样使用 define 函数定义了名为 M_ACTION 的常量,值为 doshow。这些常量后续会被用来确定系统要执行的类和类中的方法。
  2. require_once 语句
    • require_once '../app/system/entrance.php';require_once 是 PHP 中用于引入外部文件的语句。它会尝试引入 ../app/system/entrance.php 文件。如果该文件已经被引入过,require_once 不会再次引入,以避免重复引入导致的问题。在这里,它的作用是启动系统的执行流程,进入 entrance.php 文件继续执行。

entrance.php

//当前访问的主机名
define ('HTTP_HOST', isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']);
//来源页面
define('HTTP_REFERER', $_SERVER['HTTP_REFERER']);
//来源页面
define('REQUEST_URI', $_SERVER['REQUEST_URI']);//脚本路径
$phpfile = basename(__FILE__);
$_SERVER['PHP_SELF']=htmlentities($_SERVER['PHP_SELF']);
define ('PHP_SELF', $_SERVER['PHP_SELF']=="" ? $_SERVER['SCRIPT_NAME'] : $_SERVER['PHP_SELF']);if (!preg_match('/^[A-Za-z0-9_]+$/', M_TYPE.M_NAME.M_MODULE.M_CLASS.M_ACTION)) {echo 'Constants must be numbers or letters or underlined';die();
}require_once PATH_SYS_CLASS.'load.class.php';load::module();# This program is an open source system, commercial use, please consciously to purchase commercial license.
# Copyright (C) MetInfo Co., Ltd. (http://www.metinfo.cn). All rights reserved.

        该文件首先定义了与 HTTP 请求和服务器相关的常量,如HTTP_HOST用于获取当前访问的主机名,HTTP_REFERER记录来源页面,REQUEST_URI表示当前请求的 URI 等。这些常量主要用于系统对请求环境的识别和记录,但与本次路径穿越漏洞利用无直接关联。接着,它对M_TYPE.M_NAME.M_MODULE.M_CLASS.M_ACTION进行正则匹配检查,确保其由数字、字母或下划线组成,目的是保证系统常量的规范性。关键在于require_once PATH_SYS_CLASS.'load.class.php';引入了load.class.php文件,并调用load::module();方法。在调用load::module()方法时,默认会依据 thumb.php 中定义的M_CLASSM_ACTION常量来确定要加载的类和执行的动作,由此建立起与 thumb.php 和load.class.php的紧密联系。

重点代码:
require_once PATH_SYS_CLASS.'load.class.php';
load::module();
  1. require_once 语句
    • require_once PATH_SYS_CLASS.'load.class.php';:这行代码引入了 load.class.php 文件,PATH_SYS_CLASS 是一个预定义的路径常量(在提供的代码中虽然没有看到它的定义,但从代码逻辑推测应该是存在的),它和 'load.class.php' 拼接成完整的文件路径。引入这个文件是为了使用其中定义的 load 类及其相关方法。
  2. load::module() 方法调用
    • load::module();:这里调用了 load 类的静态方法 moduleload 类定义在 load.class.php 文件中,module 方法的作用是根据传入的参数(如果没有传入参数则使用默认值)来加载相应的类并执行类中的方法。在这个调用中,由于没有传入参数,它会使用默认的参数值,而默认值就与 thumb.php 中定义的 M_CLASS 和 M_ACTION 常量相关。

load.class.php:

class load {// ...public static function module($path = '', $modulename = '', $action = '') {if (!$path) {if (!$path) $path = PATH_OWN_FILE;if (!$modulename) $modulename = M_CLASS;if (!$action) $action = M_ACTION;if (!$action) $action = 'doindex';}return self::_load_class($path, $modulename, $action);}// ...private static function _load_class($path, $classname, $action = '') {$classname=str_replace('.class.php', '', $classname);$is_myclass = 0;if(!self::$mclass[$classname]){if(file_exists($path.$classname.'.class.php')){require_once $path.$classname.'.class.php';} else {echo str_replace(PATH_WEB, '', $path).$classname.'.class.php is not exists';exit;}$myclass = "my_{$classname}";if (file_exists($path.'myclass/'.$myclass.'.class.php')) {$is_myclass = 1;require_once $path.'myclass/'.$myclass.'.class.php';}}if ($action) {if (!class_exists($classname)) {die($classname . ' ' . $action . ' class\'s file is not exists!!!');}if(self::$mclass[$classname]){$newclass = self::$mclass[$classname];}else{if($is_myclass){$newclass = new $myclass;}else{$newclass = new $classname;}self::$mclass[$classname] = $newclass;}if ($action!='new') {if(substr($action, 0, 2) != 'do'){die($action.' function no permission load!!!');}if(method_exists($newclass, $action)){call_user_func(array($newclass, $action));}else{die($action.' function is not exists!!!');}}return $newclass;}return  true;}// ...
}

该文件提供了一系列加载类、函数库、模块等的方法。其中load::module方法至关重要,在没有传入特定参数时,它会使用默认值。这里if (!$modulename) $modulename = M_CLASS;if (!$action) $action = M_ACTION;,意味着会使用 thumb.php 中定义的M_CLASS(即old_thumb)和M_ACTION(即doshow)。然后调用self::_load_class方法。_load_class方法会先检查要加载的类文件是否存在,若存在则引入。当$action存在且符合条件(以do开头)时,会实例化类并调用类中的对应方法。由于load::module方法在 entrance.php 中被调用,且根据 thumb.php 的常量设置,最终会调用old_thumb类的doshow方法。

重点代码:
class load {public static function module($path = '', $modulename = '', $action = '') {if (!$modulename) $modulename = M_CLASS;if (!$action) $action = M_ACTION;return self::_load_class($path, $modulename, $action);}private static function _load_class($path, $classname, $action = '') {if ($action) {if (!class_exists($classname)) {die($classname . ' ' . $action . ' class\'s file is not exists!!!');}$newclass = new $classname;if ($action!='new') {if(substr($action, 0, 2) == 'do' && method_exists($newclass, $action)) {call_user_func(array($newclass, $action));}}return $newclass;}return  true;}
}
  1. module 方法
    • public static function module($path = '', $modulename = '', $action = ''):这是 load 类的一个公共静态方法,接受三个参数 $path(文件路径)、$modulename(类名)和 $action(要执行的方法名)。
    • if (!$modulename) $modulename = M_CLASS;:如果没有传入 $modulename 参数,就使用 M_CLASS 常量的值作为类名。
    • if (!$action) $action = M_ACTION;:同理,如果没有传入 $action 参数,就使用 M_ACTION 常量的值作为要执行的方法名。
    • return self::_load_class($path, $modulename, $action);:调用 _load_class 方法,并将当前的参数传递过去,_load_class 方法会负责加载类并执行相应的方法。
  2. _load_class 方法
    • private static function _load_class($path, $classname, $action = ''):这是一个私有静态方法,用于实际加载类和执行方法。
    • if ($action):检查是否传入了 $action 参数,如果有传入才会继续执行后续逻辑。
    • if (!class_exists($classname)):检查指定的类名 $classname 是否存在,如果不存在就输出错误信息并终止脚本执行。
    • $newclass = new $classname;:如果类存在,就实例化这个类。
    • if ($action!='new'):如果 $action 不是 new,则继续检查。
    • if(substr($action, 0, 2) == 'do' && method_exists($newclass, $action)):检查 $action 是否以 do 开头,并且类中是否存在这个方法,如果满足条件,就使用 call_user_func 函数调用类中的方法。

old_thumb.class.php:

<?php
# MetInfo Enterprise Content Management System
# Copyright (C) MetInfo Co.,Ltd (http://www.metinfo.cn). All rights reserved.defined('IN_MET') or exit('No permission');load::sys_class('web');class old_thumb extends web{public function doshow(){global $_M;$dir = str_replace(array('../','./'), '', $_GET['dir']);if(substr(str_replace($_M['url']['site'], '', $dir),0,4) == 'http' && strpos($dir, './') === false){header("Content-type: image/jpeg");ob_start();readfile($dir);ob_flush();flush();die;}if($_M['form']['pageset']){$path = $dir."&met-table={$_M['form']['met-table']}&met-field={$_M['form']['met-field']}";}else{$path = $dir;}$image =  thumb($path,$_M['form']['x'],$_M['form']['y']);if($_M['form']['pageset']){$img = explode('?', $image);$img = $img[0];}else{$img = $image;}if($img){header("Content-type: image/jpeg");ob_start();readfile(PATH_WEB.str_replace($_M['url']['site'], '', $img));ob_flush();flush();}}
}
# This program is an open source system, commercial use, please consciously to purchase commercial license.
# Copyright (C) MetInfo Co., Ltd. (http://www.metinfo.cn). All rights reserved.

此文件定义了old_thumb类,其中doshow方法存在路径穿越漏洞。在doshow方法中,$dir = str_replace(array('../','./'), '', $_GET['dir']);$_GET中获取dir参数,并尝试通过str_replace函数移除.././来进行简单过滤。但这种过滤方式存在严重缺陷,攻击者可构造特殊输入如....//绕过过滤。随后,若满足一定条件,会使用readfile($dir);函数读取文件。若攻击者成功绕过过滤,就能利用该函数读取服务器上的任意文件,例如敏感文件/etc/passwd,从而导致敏感信息泄露。

重点代码:
class old_thumb {public function doshow() {$dir = str_replace(array('../','./'), '', $_GET['dir']);if(substr(str_replace($_M['url']['site'], '', $dir),0,4) == 'http' && strpos($dir, './') === false){readfile($dir);}// ... 其他逻辑if ($img) {readfile(PATH_WEB.str_replace($_M['url']['site'], '', $img));}}
}
  1. old_thumb 类
    • class old_thumb:定义了一个名为 old_thumb 的类。
  2. doshow 方法
    • public function doshow():这是 old_thumb 类的一个公共方法。
    • $dir = str_replace(array('../','./'), '', $_GET['dir']);:从 $_GET 超全局变量中获取名为 dir 的参数值,然后使用 str_replace 函数尝试移除字符串中的 ../ 和 ./。这里的意图是对用户输入的路径进行简单过滤,防止目录穿越。
    • if(substr(str_replace($_M['url']['site'], '', $dir),0,4) == 'http' && strpos($dir, './') === false):进一步检查处理后的 $dir 参数,如果它以 http 开头并且不包含 ./,则执行 readfile($dir);readfile 函数会读取指定路径的文件内容并输出。
    • if ($img):在后续逻辑中,如果 $img 存在,也会使用 readfile 函数读取经过处理的路径对应的文件内容。这里的问题在于,str_replace 函数的过滤方式不够严格,攻击者可以通过构造特殊的输入(比如 ....//)绕过过滤,从而实现路径穿越,读取服务器上的任意文件。

利用过程及方式

  • 攻击者构造请求:攻击者精心构造一个包含恶意dir参数的 HTTP 请求,假设系统访问入口为http://example.com/thumb.php,攻击者构造的请求可能是http://example.com/thumb.php?dir=../../../etc/passwd。这里使用../../../等目录穿越字符,试图突破正常的文件访问限制,访问到服务器上的敏感文件/etc/passwd。这是利用了old_thumb.class.phpdoshow方法对dir参数过滤不严格的漏洞。
  • 系统执行流程:当攻击者的请求发送到服务器并到达 thumb.php 文件后,thumb.php 引入 entrance.php 文件,启动系统流程。entrance.php 文件在执行过程中,引入load.class.php并调用load::module()方法。由于 thumb.php 中定义的M_CLASSold_thumbM_ACTIONdoshowload::module方法在执行时,会根据这些默认常量设置,通过_load_class方法实例化old_thumb类并调用其doshow方法。具体来说,load::module方法中if (!$modulename) $modulename = M_CLASS;if (!$action) $action = M_ACTION;语句使得old_thumb类和doshow方法被选中,然后_load_class方法负责完成类的实例化和方法调用准备工作。
  • 漏洞触发:在old_thumb.class.phpdoshow方法被调用后,获取到攻击者传入的恶意dir参数。尽管进行了简单的str_replace过滤,但攻击者构造的特殊输入可能绕过该过滤。例如,若攻击者输入....//,经过str_replace后可能仍然包含有效的目录穿越字符。随后,readfile函数会尝试读取经过处理后的dir对应的文件路径。如果攻击者成功绕过过滤,readfile函数就会读取服务器上的敏感文件,如/etc/passwd,将文件内容返回给攻击者,导致敏感信息泄露。

代码分析和理解

  • 常量定义的影响:thumb.php 中的常量定义在整个系统执行流程中起着关键的引导作用。M_CLASSM_ACTION常量如同系统执行的 “导航标”,虽然它们本身只是简单的字符串定义,但却决定了系统后续执行的具体类和方法。攻击者正是利用了这一机制,通过控制与这些常量相关的请求参数,间接地影响到存在漏洞的old_thumb.class.php中的doshow方法。这种常量定义方式在实现系统功能模块化和灵活性的同时,也为潜在的安全攻击留下了隐患,因为常量的全局有效性使得攻击者可以在系统的执行流程中找到切入点。
  • 文件加载和方法调用:entrance.php 引入load.class.php并调用相关方法,体现了系统模块化设计的思路,将不同功能的代码分离到不同文件中,便于管理和维护。然而,这种设计也为攻击者利用模块间的关联创造了条件。load.class.php中的方法负责加载各类资源和调用相应的功能,其逻辑较为复杂。例如,load::module_load_class方法之间的协作,通过层层传递参数和执行逻辑,最终实现类的加载和方法的调用。攻击者通过分析系统的这种执行逻辑,利用 thumb.php 中的常量设置,精准地控制load::module方法的参数,从而调用到存在漏洞的doshow方法。这表明在系统设计中,虽然模块化提高了开发效率,但也需要更加严格地把控模块间交互的安全性,避免因复杂的调用关系而引入安全风险。
  • 输入验证和过滤不足old_thumb.class.phpdoshow方法对dir参数的验证和过滤过于简单。仅使用str_replace函数移除.././,这种方式无法有效抵御目录穿越攻击。从安全编程的角度来看,对用户输入的验证应该采用更加严格和全面的方式,例如使用白名单过滤,只允许合法的字符和路径格式。攻击者通过构造特殊输入,如....//,可以轻易绕过这种简单的过滤机制。一旦绕过成功,readfile函数就会被攻击者利用来读取任意文件,这充分暴露了代码在安全防护方面的不足。在开发过程中,对于涉及文件操作的用户输入,必须进行严格的安全检查,以防止类似的路径穿越漏洞导致的安全问题。

相关文章:

拓展知识六:MetInfo6.0.0目录遍历漏洞原理分析

所需进行代码审计的文件路径&#xff1a; C:\phpStudy\WWW\MetInfo6.0.0\include\thumb.php C:\phpStudy\WWW\MetInfo6.0.0\app\system\entrance.php C:\phpStudy\WWW\MetInfo6.0.0\app\system\include\class\load.class.php C:\phpStudy\WWW\MetInfo6.0.0\app\system\include…...

tar包部署rabbitMQ

部署erlang&#xff1a; 有网使用&#xff1a; sudo apt-get update sudo apt-get install libncurses5-dev libncursesw5-dev sudo yum install ncurses-devel 无网使用 tar zxvf ncurses.tar.gz mkdir ncurses cd ncurses-6.3/ ./configure --with-shared --without-debu…...

天锐蓝盾终端安全防护——企业终端设备安全管控

从办公室的台式电脑到员工手中的移动终端&#xff0c;这些设备不仅是工作的得力助手&#xff0c;更是企业数据的重要载体。然而&#xff0c;随着终端设备的广泛使用&#xff0c;安全风险也如影随形。硬件设备使用不当、数据随意传输等问题频发&#xff0c;使得企业数据面临着泄…...

MySQL高级特性与大数据应用

事务与锁机制 1.1 事务控制 START TRANSACTION; UPDATE account SET balance balance - 500 WHERE user_id 1001; UPDATE account SET balance balance 500 WHERE user_id 2002; COMMIT; -- 显式提交事务 ROLLBACK; -- 异常时回滚 1.2 锁机制 ​锁类型&#xff1a;共…...

小智机器人关键函数解析,Application::OutputAudio()处理音频数据的输出的函数

以下是对 Application::OutputAudio() 函数的详细解释&#xff1a; 源码&#xff1a; void Application::OutputAudio() { // 扬声器的输出auto now std::chrono::steady_clock::now();auto codec Board::GetInstance().GetAudioCodec();const int max_silence_seconds 10;…...

玛卡巴卡的k8s知识点问答题(五)

17. Init 类型容器有什么特点&#xff0c;主要用途&#xff1f; 特点&#xff1a; 启动顺序&#xff1a;Init 容器在普通容器启动之前运行&#xff0c;必须先完成所有 Init 容器后&#xff0c;Pod 的主容器才会启动。 顺序执行&#xff1a;如果定义了多个 Init 容器&#xff…...

3.27学习总结 爬虫+二维数组+Object类常用方法

高精度&#xff1a; 一个很大的整数&#xff0c;以字符串的形式进行接收&#xff0c;并将每一位数存储在数组内&#xff0c;例如100&#xff0c;即存储为[1][0][0]。 p2437蜜蜂路线 每一个的路线数前两个数的路线数相加。 #include <stdio.h> int a[1005][1005]; int …...

kafka零拷贝技术的底层实现

什么是 Sendfile&#xff1f; sendfile 是一种操作系统提供的系统调用&#xff08;system call&#xff09;&#xff0c;用于在两个文件描述符&#xff08;file descriptor&#xff09;之间高效传输数据。它最初由 Linux 内核引入&#xff08;从 2.1 版本开始&#xff09;&…...

MFC中CMap类的用法和原理

1、CMap 的原理 CMap 是一个基于哈希表的映射类&#xff0c;它将唯一键映射到对应的值。其内部实现依赖于哈希算法&#xff0c;通过哈希函数将键转换为哈希值&#xff0c;然后将哈希值映射到哈希表中的某个位置。如果多个键的哈希值相同&#xff08;即哈希冲突&#xff09;&am…...

elementplus的el-tabs路由式

在使用 Element Plus 的 el-tabs 组件&#xff0c;实现路由式的切换&#xff08;即点击标签页来切换不同的路由页面&#xff09;。下面是一个基于 Vue 3 和 Element Plus 实现路由式 el-tabs 的基本步骤和示例。 步骤 1: 安装必要的库 在vue3项目安装 Vue Router 和 Element …...

数据结构初阶:单链表

序言&#xff1a; 本篇博客主要介绍单链表的基本概念&#xff0c;包括如何定义和初始化单链表&#xff0c;以及如何进行数据的插入&#xff0c;删除和销毁等操作。 1.单链表 1.1 概念与结构 概念&#xff1a;链表是一种非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过…...

北斗导航 | 改进伪距残差矢量的接收机自主完好性监测算法原理,公式,应用,RAIM算法研究综述,matlab代码

改进伪距残差矢量的接收机自主完好性监测算法研究 摘要 接收机自主完好性监测(RAIM)是保障全球卫星导航系统(GNSS)可靠性的核心技术。本文针对传统伪距残差矢量法在微小故障检测和多故障隔离中的不足,提出一种融合加权奇偶空间与动态阈值调整的改进算法。通过理论推导验证…...

RabbitMQ高级特性--TTL和死信队列

目录 1.TTL 1.1设置消息的TTL 1.1.1配置交换机&队列 1.1.2发送消息 1.1.3运行程序观察结果 1.2设置队列的TTL 1.2.1配置队列和交换机的绑定关系 1.2.2发送消息 1.2.3运行程序观察结果 1.3两者区别 2.死信队列 2.1 声名队列和交换机 2.2正常队列绑定死信交换机 …...

Java后端开发: 如何安装搭建Java开发环境《安装JDK》和 检测JDK版本

文章目录 一、JDK的安装1、 打开 Oracle 官方网址2、点击产品 二、检测JDK是否安装成功以及JDK版本的查看1. 打开命令行窗口检测是否安装成功查看 JDK 版本 一、JDK的安装 1、 打开 Oracle 官方网址 Oracle官网地址:https://www.oracle.com/cn/ 2、点击产品 打开下载的JDK文件…...

LabVIEW液压控制系统开发要点

液压控制系统开发需兼顾高实时性、强抗干扰性和安全性&#xff0c;尤其在重工业场景中&#xff0c;毫秒级响应延迟或数据异常都可能导致设备损坏。本文以某钢厂液压升降平台项目为例&#xff0c;从硬件选型、控制算法、安全机制三方面&#xff0c;详解LabVIEW开发中的关键问题与…...

鸿蒙Flutter实战:18-组合而非替换,现有插件快速鸿蒙化

引言 在对插件鸿蒙化时&#xff0c;除了往期文章现有Flutter项目支持鸿蒙II中讲到的使用 dependency_overrides 来配置鸿蒙适配库的两种方式以外&#xff0c;如果三方插件本身使用了联合插件的形式&#xff0c;也可以通过下面这种方式来添加鸿蒙平台的实现&#xff1a; depen…...

Qt之Service开发

一、概述 基于Qt的用于开发系统服务(守护进程)和后台服务,有以下几个优秀的开源 QtService 框架和库。 1. QtService (官方解决方案) GitHub: https://github.com/qtproject/qt-solutions/tree/master/qtservice 特点: 官方提供的服务框架 支持 Windows 服务和 Linux 守护…...

MFC添加免费版大漠3.1233

先创建一个MFC工程&#xff0c; 添加dm.dll 方法一&#xff1a;通过类向导-添加类-类型库中的MFC类-文件&#xff0c;选择dm.dll&#xff0c;如果没有"添加类型库中的MFC类"选项就用方法二添加 方法二&#xff1a;添加-新建项-MFC-Active或TypeLib-实现接口位置选…...

vue 图片放大到全局

背景&#xff1a; 在vue项目中&#xff0c;el-image组件图片组件用于展示图片&#xff0c;组件自带的属性preview-teleported&#xff0c;设置为true可以控制图片放大到全局 实现效果&#xff1a; 核心代码&#xff1a; //图片地址&#xff1a;BASEUrl /file/ item.file //这…...

人工智能入门(1)

人工智能导引 文章目录 人工智能导引artifiicial intelligence由图灵测试出发的六个领域贝叶斯方法分析成为大多数AI系统中不确定推理的现代方法基础 研究方法 机器学习计算机利用已经有的数据样本&#xff0c;得出某种规律模型&#xff0c;并利用模型预测未来的一种方法 回归算…...

Python爬虫:Feapder 的详细使用和案例

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 1. Feapder 概述1.1 Feapder介绍1.2 Feapder 核心特点1.3 Feapder 主要组件1.4 Feapder的安装2. 基础爬虫编写2.1 创建爬虫2.2 运行爬虫3. 数据采集案例3.1 新闻网站采集3.2 电商商品采集3.3 使用 Spider 类创建更强大爬…...

mybatis里in关键字拼接id问题

我们一般会把ids集合用StrUtil.join(‘,’)转成"1,2,3"这种形式 然后放入in中 我们会这么写: select id, nick_name, icon from tb_user where id in (#{ids}) order by FIELD(id, #{ids})结果发现sql执行是这样的: select id, nick_name, icon from tb_user where…...

在rockylinux9.4安装mongodb报错:缺少:libcrypto.so.10文件库

问题点&#xff1a; rockylinux9.4系统环境报错&#xff1a; ./mongod: error while loading shared libraries: libcrypto.so.10: cannot open shared object file: No such file or directory 解决方法&#xff1a; Ps&#xff1a;解压之后&#xff0c;检查mongodb的依赖环境…...

Spring Boot集成阿里云OSS:对象存储实战指南

Spring Boot集成阿里云OSS&#xff1a;对象存储实战指南 1. OSS是什么&#xff1f;为什么选择阿里云OSS&#xff1f; 对象存储&#xff08;OSS&#xff09; 是一种用于存储非结构化数据&#xff08;如图片、视频、日志文件&#xff09;的云服务&#xff0c;核心功能包括&#…...

【力扣hot100题】(019)旋转图像

比较考验脑子转不转得过来&#xff0c;最好先在纸上画一下图整理思路&#xff0c;不要和我一样上来就无脑套循环。 理解了思路还是好做的&#xff0c;每个小循环转一圈&#xff0c;大循环代表转的第几圈。小循环循环n-2i-1次&#xff0c;大循环循环&#xff08;n1&#xff09;…...

06_约束

文章目录 一、是什么二、实体完整性约束2.1、主键约束2.2、主键自增长2.3、唯一约束 三、域完整性约束3.1、非空约束3.2、默认值 四、引用完整性约束 一、是什么 用于限制加入表的数据的类型和规范&#xff0c;约束是添加在列上的&#xff0c;用来约束列的。 分类&#xff1a; …...

Anolis OS 8.4修复CVE-1999-0554漏洞记录

1. 使用TCP Wrappers配置白名单 通过修改/etc/hosts.allow和/etc/hosts.deny文件&#xff0c;仅允许特定IP访问NFS的mountd服务&#xff08;需确保系统支持TCP Wrappers&#xff09;&#xff1a; 编辑/etc/hosts.allow&#xff0c;添加允许的客户端IP&#xff08;如192.168.1…...

Seata AT模式的一些常见问题及其源码解析

Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式&#xff0c;为用户打造一站式的分布式解决方案。 Seata AT 基于两阶段提交协议的演变&#xff1a; 一阶段&#xff1a;业…...

华为GaussDB数据库的手动备份与还原操作介绍

数据库的备份以A机上的操作为例。 1、使用linux的root用户登录到GaussDB服务器。 2、用以下命令切换到 GaussDB 管理员用户&#xff0c;其中&#xff0c;omm 为当前数据库的linux账号。 su - omm 3、执行gs_dump命令进行数据库备份&#xff1a; 这里使用gs_dump命令进行备…...

2025年3月29日(matlab -ss -lti)

线性时不变系统&#xff08;LTI系统&#xff09;的定义与核心特性 线性时不变系统&#xff08;Linear Time-Invariant System&#xff09;是信号与系统分析中的基础模型&#xff0c;其核心特性包括线性和时不变性。以下从定义、验证方法和应用场景展开说明&#xff1a; 1. 线性…...